Code covered by the BSD License  

Highlights from
MATLAB Contest - Sailing Home

image thumbnail

MATLAB Contest - Sailing Home

by

 

09 Nov 2010 (Updated )

All the files needed to develop and score an entry for the MATLABĀ® Programming Contest.

runcontest(flagVisualize,whichBoards)
function [message,result,solverTime] = runcontest(flagVisualize,whichBoards)
%RUNCONTEST Test an entry.
%   [MESSAGE,RESULTS,TIME] = RUNCONTEST runs the file solver.m against all
%   the problems defined in testsuite_sample.mat. MESSAGE returns a summary
%   of the testing, RESULTS measures how well the entry solved the problem,
%   and TIME measures the time the entry took to compute the answer.
%
%   RUNCONTEST(true) graphically visualize the results.
%
%   RUNCONTEST(true/false, DOBOARDS) runs the file solver.m against the
%   problems enumerated in the vector DOBOARDS as defined in the testsuite.

% Copyright 2010 The MathWorks, Inc.

% The MATLAB Contest Team
% November, 2010

testSuiteFile = 'testsuite_sample.mat';
load(testSuiteFile,'testsuite')

% Argument parsing.
if (nargin<2)
    whichBoards = 1:numel(testsuite); % do all boards in test suite
end
if (nargin < 1)
    flagVisualize = 0;
end

numBoards = numel(whichBoards);
solverTime = zeros(numBoards,1);
solverScore = zeros(numBoards,1);

if flagVisualize
    fh = figure;
end

for i = 1:numBoards
    
    [chart, aIndex, bIndex, maxThrottle] = getboard(testsuite,whichBoards(i));

    if flagVisualize
        visualize(chart,aIndex,bIndex,fh)
        fprintf('Board number %d :\n',whichBoards(i))
        fprintf('    wR   wC    tR   tC    vRf  vCf   Rf   Cf \n')
    end
    
    time0 = cputime;
    
    [thrustRow, thrustCol] = solver(chart, aIndex, bIndex, maxThrottle);
    
    solverTime(i) = cputime-time0;
    
    [thrustRow, thrustCol] = validatesolution(thrustRow, thrustCol, maxThrottle);
    
    [dA,dB] = runsolution(thrustRow, thrustCol, chart, aIndex, bIndex, flagVisualize);
    
    solverScore(i) = scoresolution(dA,dB,thrustRow,thrustCol);
    
    if flagVisualize
        fprintf('  Score: %d \n\n',solverScore(i))
        if i<numBoards
            if mypause(fh)
                break; % stop
            end
        end
    end
end

% Report results.
result     = sum(solverScore);
resultTime = sum(solverTime);
message = sprintf('results: %.2f\ntime: %.2f', result, resultTime);

end

function [thrustRow, thrustCol] = validatesolution(thrustRow, thrustCol, maxThrottle)
% VALIDATESOLUTION Validates the solution vectors given by the solver

% Ensure column vectors and reals
thrustRow = real(thrustRow(:));
thrustCol = real(thrustCol(:));

% Check maximum number of moves
mnmoves = 1000;
if numel(thrustRow) > mnmoves
   thrustRow = thrustRow(1:mnmoves);
end
if numel(thrustCol) > mnmoves
   thrustCol = thrustCol(1:mnmoves);
end

% Ensure integers
if any(rem(thrustRow,1))
    thrustRow = round(thrustRow);
end
if any(rem(thrustCol,1))
    thrustCol = round(thrustCol);
end

% Ensure same length
ntR = numel(thrustRow);
ntC = numel(thrustCol);
if ntR~=ntC
    n = min(ntR,ntC);
    thrustRow = thrustRow(1:n);
    thrustCol = thrustCol(1:n);
end

% Check maximum throttle
h = (abs(thrustRow) + abs(thrustCol)) > maxThrottle;
if any(h)
    % Motor is blown for every turn the throttle exceeds the motor capacity!
    thrustRow(h) = 0;
    thrustCol(h) = 0;
end

end

function [dA, dB] = runsolution(thrustRow, thrustCol, chart, aIndex, bIndex, flagVisualize)
% RUNSOLUTION Simulates the navigation trajectory given the winds and the
% motor thrust.

rowWind = chart(:,:,1);
colWind = chart(:,:,2);
[nR,nC] = size(rowWind);
[AR,AC] = ind2sub([nR,nC],aIndex);
[BR,BC] = ind2sub([nR,nC],bIndex);

% Initialize variables at start point (A)
fR = AR; fC =AC;
fvR = 0; fvC = 0;
dB = (fR-BR)^2 + (fC-BC)^2;

for i = 1:numel(thrustRow)
    ivR = fvR + thrustRow(i) + rowWind(fR,fC);
    ivC = fvC + thrustCol(i) + colWind(fR,fC);
    iR = fR + ivR;
    iC = fC + ivC;
    if iR>nR || iR<1 || iC>nC || iC<1
        break % out of bounds
    end
    if flagVisualize
        plot([fC iC],[fR iR],'r-')
        plot(iC,iR,'ro','MarkerFaceColor','r')
        fprintf('  %4d %4d  %4d %4d  %4d %4d  %4d %4d\n',...
            rowWind(fR,fC),colWind(fR,fC),thrustRow(i),thrustCol(i),ivR,ivC,iR,iC)
    end
    fR = iR;
    fC = iC;
    fvR = ivR;
    fvC = ivC;
    % Verify if this is the closest point to B
    if ((fR-BR)^2 + (fC-BC)^2) < dB
         dB = (fR-BR)^2 + (fC-BC)^2;    
    end
end
dA = (fR-AR)^2 + (fC-AC)^2; % Final distance to A
end

function score = scoresolution(dA,dB,thrustRow,thrustCol)
% SCORESOLUTION Calculates the score for the solution.
score = dB + dA + sum(abs(thrustRow)) + sum(abs(thrustCol));
end

function  [chart, aIndex, bIndex, maxThrottle] = getboard(testsuite,i)
% GETBOARD Gets the i-th problem from the loaded testsuite
i = round(min(max(1,i),numel(testsuite)));
chart = testsuite(i).chart;
aIndex = testsuite(i).aIndex;
bIndex = testsuite(i).bIndex;
maxThrottle = testsuite(i).maxThrottle;
end

function visualize(chart,aIndex,bIndex,fh)
% VISUALIZE draws the board in a figure window indicating the wind, the
% start position and the target position.

colWind = chart(:,:,1);
rowWind = chart(:,:,2);
[nR,nC] = size(colWind);

% Sets the figure
figure(fh)
clf
set(fh,'color',[1 1 1]);

% Sets the axes
cla
axis equal
set(gca,'Ydir','reverse')
hold on
box off
axis([0 nC 0 nR]+.5)
set(gca,'xtick',1:nC)
set(gca,'ytick',1:nR)

% Draws the blue grid (the sea)
for i = 1:nR
    for j = 1:nC
        rectangle('Position', [j-.5,i-.5,1,1],'linewidth',3,'EdgeColor',[.8 .9 1])
    end
end

% Draws the start position and the target position
[Ri,Ci] = ind2sub([nR,nC],aIndex);
rectangle('Position', [Ci-.45,Ri-.45,.9,.9], 'Curvature',[.7 .7],'FaceColor',...
    [.8 1 .8],'EdgeColor',[0 .7 0])
[Ri,Ci] = ind2sub([nR,nC],bIndex);
rectangle('Position', [Ci-.45,Ri-.45,.9,.9], 'Curvature',[.7 .7],'FaceColor',...
    [1 .8 .8],'EdgeColor',[1 0 0])

% Draw the arrows for the wind
for i = 1:nR
    for j = 1:nC
        wind = rowWind(i,j);
        d = sign(wind);
        n = abs(wind);
        for k = 1:n
             patch(j+[-.3 .3 .2 .2 .3].*d,i+[0 0 -.05 .05 0]-.3+(k).*.6/(n+1),...
                 [.7 .7 .7],'EdgeColor',[.7 .7 .7])
        end
        wind = colWind(i,j);
        d = sign(wind);
        n = abs(wind);
        for k = 1:n
             patch(j+[0 0 -.05 .05 0]-.3+(k).*.6/(n+1),i+[-.3 .3 .2 .2 .3].*d,...
                 [.7 .7 .7],'EdgeColor',[.7 .7 .7])
        end
    end
end
end

function flag = mypause(fh)
% Implements an uicontrol to pasuse and resume the simulation
flag = false;
h1 = uicontrol('Position', [20 5 100 20], 'String', 'Next Problem', ...
    'Callback', 'uiresume(gcbf)');
h2 = uicontrol('Position', [140 5 100 20], 'String', 'Stop', ...
    'Callback', 'set(gcbo,''userdata'',1);uiresume(gcbf)');
uiwait(fh);
if ishandle(h1)
    delete(h1);
end
if ishandle(h2)
    flag = ~isempty(get(h2,'userdata')); % stop?
    delete(h2);
end
end

Contact us