ID:45676
Title:getting worse
Author:nathan q
Date:2008-04-30 18:07:36
Score:31745.7446
Result:317390.00 (cyc: 14, node: 614)
CPU Time:0.9491
Status:Passed
Comments:
Based on:none
Code:
function W = solver(B)

% wifi2: keep track of voltage to avoid crossings

V=B;    % voltage map

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,V] = pathfinder1(pinLocs2D(iPin,:), pinLocs2D(iDistMin,:), V);
    
    if any(wLink)
        W=[W; wLink];
    end
end


return


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [W,V] = pathfinder1(loc1,loc2,V);

% 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]; 
    V = updateV(V,W);
    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(V(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)' ];
        V = updateV(V,W);
        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(V(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 ];
        V = updateV(V,W);
        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 ~V(i1,j2)
    [W1,V] = pathfinder1([i1 j1],[i1 j2],V);
    if any(W1)
        [W2,V] = pathfinder1([i1 j2],[i2 j2],V);
        if any(W2)
            W=[W1; W2];
            V = updateV(V,W);
            return
        end
    end
elseif ~V(i2,j1)
    [W1,V] = pathfinder1([i1 j1],[i2 j1],V);
    if any(W1)
        [W2,V] = pathfinder1([i2 j1],[i2 j2],V);
        if any(W2)
            W=[W1; W2];
            V = updateV(V,W);
            return
        end
    end
end

% if we get this far, we've failed

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


function V = updateV(V,W)
% Update the voltage map with a new set of connectors.
n = size(W,1);
v = V(W(1,1),W(1,2));

% this loop could be faster
for i=2:n;
    V(W(i,3),W(i,4)) = v;
end

return

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

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