ID:45670
Title:persistent
Author:David Jones
Date:2008-04-30 16:15:18
Score:26585.3030
Result:265715.00 (cyc: 13, node: 663)
CPU Time:24.3502
Status:Passed
Comments:
Based on:none
Code:
function W = solver(B)

function path = simplepath(row,col)
% fprintf('simple path, r=%d c=%d, r=%d c=%d\n', row(1), col(1), row(2), col(2));
deltar = row(2) - row(1);
deltac = col(2) - col(1);
dr = sign(deltar);
dc = sign(deltac);


% adjacent
if (deltar == 1 && dc == 0) || (dr == 0 && deltac == 1)
    path = [row(1) col(1) row(2) col(2)];
    return
end

% try step to next row
if dr ~= 0
    r = row(1) + dr;
    c = col(1);
    if B(r,c) == 0
        path = simplepath([r ; row(2)], [c ; col(2)]);
        if size(path,1) > 0
            path = [row(1) col(1) r c; path];
            return
        end
    end
end

% try step to next col
if dc ~= 0
    r = row(1);
    c = col(1) + dc;
    if B(r,c) == 0
        path = simplepath([r ; row(2)], [c ; col(2)]);
        if size(path,1) > 0
            path = [row(1) col(1) r c; path];
            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 = abs(row(2)-row(1)) + abs(col(2)-col(1));
        pincount(i,3) = 2*p - d;
    end
end
[s ix] = sort(pincount(:,3),'descend');
pincount = pincount(ix,:);

% fprintf('pincount ...\n');
% pincount
% pause

Nwires = 0;
for i = 1:k
    if pincount(i,2) >= 2
        [row col] = find(B == pincount(i,1));
        p = B(row(1),col(1));
        N = size(row,1);
        link = 1;
        for j = 2:N
            d = abs(row(j)-row(link)) + abs(col(j)-col(link));
            if link == 1
                benefit = 2*p - d;
            else
                benefit = p - d;
            end
    %         fprintf('pin = %3d, dist = %3d, benefit = %3d\n', p, d, benefit);
            if d > 20 || benefit <= 0
    %             fprintf('skip\n');
                continue
            end

            path = simplepath([row(link); row(j)], [col(link); col(j)]);
            if size(path,1) > 0
                W = [W ; path];
                B = addwirepath(B,path);
                link = j;
            else
                continue
            end
        end
    end
end

% fprintf('soln:\n');
% W
% pause
end

%%



%%
function B = addwirepath(B,path)
N = size(path,1);
for i = 1:N
    if B(path(i,1),path(i,2)) == 0
        B(path(i,1),path(i,2)) = -1;
    end
    if B(path(i,3),path(i,4)) == 0
        B(path(i,3),path(i,4)) = -1;
    end
end
end