| 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
|