ID:45674
Title:this is not easy
Author:nathan q
Date:2008-04-30 17:37:47
Score:31970.4478
Result:319638.00 (cyc: 14, node: 522)
CPU Time:0.9148
Status:Passed
Comments:
Based on:none
Code:
function W = solver(B)

Bv = B(:);
sizeB = size(B);
W = zeros(0,4);

BvNZ = Bv(logical(Bv));   % non-zero elements

pinIDs = sort(unique(BvNZ),'descend');
nIDs = numel(pinIDs);    % there is always a zero in the list

if isempty (pinIDs) return; end


% loop over possible nets
for i=1:nIDs

    % start with the highest-valued group (first in the list)
    pinID = pinIDs(i);

    % number of pins in this net
    nPins = sum(BvNZ==pinID);
    if nPins<=1
        continue
    end

    %locations of pins in this net
    pinLocs2D = zeros(nPins,2);

    pinLocs1D = find(Bv==pinID);
    for j=1:nPins
        [pinLocs2D(j,1) pinLocs2D(j,2)] = ind2sub(sizeB,pinLocs1D(j));   % this could probably be faster
    end

    % for the first pin on the list, just find its nearest neighbour and connect them
    iPin = 1;   % first pin in the net
    %staircase distance from pin1 to every other pin
    dist = sum(abs(pinLocs2D(iPin*ones(nPins,1),:) - pinLocs2D),2);
    dist(iPin) = Inf;
    [distMin,iDistMin] = min(dist);
    wLink = pathfinder1(pinLocs2D(iPin,:), pinLocs2D(iDistMin,:), B);
    
    if any(wLink)
        W=[W; wLink];
    end
end


return


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function W = pathfinder1(loc1,loc2,B);

% return a series of moves (links) from loc1 to loc2 on the board B
% this is pathfinder 1 - looks for simple horiz and vert paths only

i1=loc1(1);
j1=loc1(2);
i2=loc2(1);
j2=loc2(2);

W=[];

% check for very special case - pins are adjacent
if abs(i1-i2)+abs(j1-j2)==1   
    W = [i1 j1 i2 j2]; 
    return
end

% less special - on the same row
if i1==i2
    if j2<j1
        [j2,j1]=copyVar(j1,j2); [i2,i1]=copyVar(i1,i2);
    end
    if sum(B(i1,j1+1:j2-1)) == 0    % clear path between them
        L = ones(j2-j1,1);   % length of path
        W = [ i1*L (j1:j2-1)' i2*L (j1+1:j2)' ];
        return
    else
        return
    end
end

% less special - on the same column
if j1==j2
    if i2<i1
        [j2,j1]=copyVar(j1,j2); [i2,i1]=copyVar(i1,i2);
    end
    if sum(B(i1+1:i2-1,j1)) == 0    % clear path between them
        L = ones(i2-i1,1);   % length of path
        W = [ (i1:i2-1)' j1*L (i1+1:i2)' j2*L ];
        return
    else
        return
    end
end

% if we get this far, pins are not on the same row or col. 
% Try the 2 possible routes around the sides of a rectangle, using this function
% recursively to get to the corner.

if ~B(i1,j2)
    W1 = pathfinder1([i1 j1],[i1 j2],B);
    if any(W1)
        W2 = pathfinder1([i1 j2],[i2 j2],B);
        if any(W2)
            W=[W1; W2];
            return
        end
    end
elseif ~B(i2,j1)
    W1 = pathfinder1([i1 j1],[i2 j1],B);
    if any(W1)
        W2 = pathfinder1([i2 j1],[i2 j2],B);
        if any(W2)
            W=[W1; W2];
            return
        end
    end
end


return % end of pathfinder1
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%



function[b1,b2] = copyVar(a1,a2)
b1=a1;
b2=a2;
return