| Code: | function W = solver(B)
function path = simplepath(row,col,label)
% fprintf('simple path, r=%d c=%d, r=%d c=%d\n', row(1), col(1), row(2), col(2));
deltar = row(1) - row(2);
deltac = col(1) - col(2);
dr = sign(deltar);
dc = sign(deltac);
% adjacent
if (abs(deltar) == 1 && dc == 0) || (dr == 0 && abs(deltac) == 1)
path = [row(1) col(1) row(2) col(2)];
return
end
% try step to next row
if dr ~= 0
r = row(2) + dr;
c = col(2);
if B(r,c) == label
path = [r c row(2) col(2)];
% fprintf('found a wire %d\n', label);
return
end
if B(r,c) == 0
path = simplepath([row(1) r], [col(1) c], label);
if size(path,1) > 0
path = [path; r c row(2) col(2)];
return
end
end
end
% try step to next col
if dc ~= 0
r = row(2);
c = col(2) + dc;
if B(r,c) == label
path = [r c row(2) col(2)];
% fprintf('found a wire %d\n', label);
return
end
if B(r,c) == 0
path = simplepath([row(1) r], [col(1) c], label);
if size(path,1) > 0
path = [path; r c row(2) col(2)];
return
end
end
end
path = zeros(0,4);
end
%% - solver - - - -
% size(B)
W = zeros(0,4);
% make a sorted list of all pins
pin = sort(B(B>0),'descend');
npins = size(pin,1);
if npins < 1
return
end
% pin, count, benefit
pincount = zeros(npins,3);
pincount(1,1) = pin(1);
k = 1;
count = 1;
for i = 2:npins
if pin(i) == pincount(k,1)
count = count + 1;
else
pincount(k,2) = count;
k = k + 1;
count = 1;
pincount(k,1) = pin(i);
end
end
pincount(k,2) = count;
pincount = pincount(1:k,:);
% calculate the benefit of a path
for i = 1:k
if pincount(i,2) >= 2
p = pincount(i,1);
[row col] = find(B == p);
d = 0;
for j = 2:size(row,1);
d = d + abs(row(j)-row(j-1)) + abs(col(j)-col(j-1));
end
pincount(i,3) = pincount(i,2)*p - d;
end
end
[s ix] = sort(pincount(:,3),'descend');
pincount = pincount(ix,:);
% fprintf('pincount ...\n');
% pincount
% pause
for i = 1:k
if pincount(i,2) >= 2
[row col] = find(B == pincount(i,1));
N = size(row,1);
p = B(row(1),col(1));
pinlist = [row(1) col(1)];
npins = 1;
for j = 2:N
connected = false;
link = npins;
while ~connected && link >= 1
rowx = row(j:N);
colx = col(j:N);
distance = abs(rowx - row(link)) + abs(colx - col(link));
[d ix] = sort(distance,'ascend');
if d(1) <= 20
row(j:N) = rowx(ix);
col(j:N) = colx(ix);
path = simplepath([row(link); row(j)], [col(link); col(j)], -p);
if size(path,1) > 0
% fprintf('found path, p = %d, link = %d, j = %d\n', p, link, j);
W = [W ; path];
B = addwirepath(B,path,-p);
pinlist = [pinlist; row(j) col(j)];
npins = npins + 1;
connected = true;
end
end
link = link - 1;
end
end
end
end
% fprintf('soln:\n');
% W
% pause
end
%%
%%
function B = addwirepath(B,path,label)
N = size(path,1);
for i = 1:N
if B(path(i,1),path(i,2)) == 0
B(path(i,1),path(i,2)) = label;
end
if B(path(i,3),path(i,4)) == 0
B(path(i,3),path(i,4)) = label;
end
end
end
|