| Code: | function W = solver(B)
W = [];
% find all pins
values = unique(B);
% find number of pins
for pin = 2:length(values)
pins(pin-1).value = values(pin);
[pins(pin-1).rows,pins(pin-1).cols] = find(B==pins(pin-1).value);
pins(pin-1).num = length(pins(pin-1).rows);
end
[c,index]=min(cost(B,pins)');
workB = B;
current_pin.rows = pins(index).rows;
current_pin.cols = pins(index).cols;
solder.rows = [];
solder.cols = [];
solder.rows(length(solder.rows)+1)=current_pin.rows(1);
solder.cols(length(solder.cols)+1)=current_pin.cols(1);
current_pin.rows = removerows(current_pin.rows,1);
current_pin.cols = removerows(current_pin.cols,1);
num = 1;
while num < pins(index).num
[from to] = findShortestPath(solder,current_pin);
[newMoves, workB, solder] = moveTo(from, to, workB, solder, pins(index).value);
toIndex=intersect(find(current_pin.rows==to(1)),find(current_pin.cols==to(2)));
current_pin.rows = removerows(current_pin.rows,toIndex);
current_pin.cols = removerows(current_pin.cols,toIndex);
W = [W; newMoves];
num = num + 1;
end
end
function c=cost(B,pins)
for pin = 1:length(pins)
c(pin) = (pins(pin).num*pins(pin).value/(max(pins(pin).rows)-min(pins(pin).rows))/(max(pins(pin).cols)-min(pins(pin).cols)))^-1;
if (c(pin)==0)
c(pin) = inf;
end
end
end
function [from, to]=findShortestPath(solder,current_pin)
shortest = inf;
from = [];
to = [];
for pinLooper = 1:length(current_pin.rows)
for solderLooper = 1:length(solder.rows)
if abs(solder.rows(solderLooper)-current_pin.rows(pinLooper)) + abs(solder.cols(solderLooper)-current_pin.cols(pinLooper)) < shortest
shortest = abs(solder.rows(solderLooper)-current_pin.rows(pinLooper)) + abs(solder.cols(solderLooper)-current_pin.cols(pinLooper));
to = [current_pin.rows(pinLooper) current_pin.cols(pinLooper)];
from = [solder.rows(solderLooper) solder.cols(solderLooper)];
end
end
end
end
function [newMoves, workB, solder] = moveTo(from, to, workB, solder, val)
newMoves = [];
fromRow = from(1);
fromCol = from(2);
toRow = to(1);
toCol = to(2);
xDir = sign(toCol - fromCol);
yDir = sign(toRow - fromRow);
if fromCol+xDir > 0 && fromCol+xDir < length(workB(1,:)) && (workB(fromRow,(fromCol + xDir))==0 && xDir ~= 0)
workB(fromRow,fromCol+xDir)=-val;
[tmpMove, tmpWorkB, tmpSolder] = moveTo([fromRow,(fromCol + xDir)],to,workB,solder,val);
newMoves = [tmpMove; fromRow, fromCol, fromRow, fromCol+xDir];
solder.rows = [tmpSolder.rows; fromRow];
solder.cols = [tmpSolder.cols; fromCol+xDir];
workB=tmpWorkB;
workB(fromRow,fromCol+xDir)=-val;
elseif fromRow+yDir > 0 && fromRow+yDir < length(workB(:,1)) && (workB((fromRow+yDir),fromCol)==0 && yDir ~= 0)
workB(fromRow+yDir,fromCol)=-val;
[tmpMove, tmpWorkB, tmpSolder] = moveTo([(fromRow+yDir),fromCol],to,workB,solder,val);
newMoves = [tmpMove; fromRow, fromCol, fromRow+yDir, fromCol];
solder.rows = [tmpSolder.rows; fromRow+yDir];
solder.cols = [tmpSolder.cols; fromCol];
workB=tmpWorkB;
workB(fromRow+yDir,fromCol)=-val;
elseif (fromCol + xDir)==toCol && yDir == 0
newMoves = [fromRow, fromCol, fromRow, fromCol+xDir];
solder.rows = [solder.rows; fromRow];
solder.cols = [solder.cols; fromCol+xDir];
elseif (fromRow + yDir)==toRow && xDir == 0
newMoves = [fromRow, fromCol, fromRow+yDir, fromCol];
solder.rows = [solder.rows; fromRow+yDir];
solder.cols = [solder.cols; fromCol];
elseif fromCol-xDir > 0 && fromCol-xDir < length(workB(1,:)) && (workB(fromRow,(fromCol - xDir))==0 && xDir ~= 0)
workB(fromRow,fromCol-xDir)=-val;
[tmpMove, tmpWorkB, tmpSolder] = moveTo([fromRow,(fromCol - xDir)],to,workB,solder,val);
newMoves = [tmpMove; fromRow, fromCol, fromRow, fromCol-xDir];
solder.rows = [tmpSolder.rows; fromRow];
solder.cols = [tmpSolder.cols; fromCol-xDir];
workB=tmpWorkB;
workB(fromRow,fromCol-xDir)=-val;
elseif fromRow-yDir > 0 && fromRow-yDir < length(workB(:,1)) && (workB((fromRow-yDir),fromCol)==0 && yDir ~= 0)
workB(fromRow-yDir,fromCol)=-val;
[tmpMove, tmpWorkB, tmpSolder] = moveTo([(fromRow-yDir),fromCol],to,workB,solder,val);
newMoves = [tmpMove; fromRow, fromCol, fromRow-yDir, fromCol];
solder.rows = [tmpSolder.rows; fromRow-yDir];
solder.cols = [tmpSolder.cols; fromCol];
workB=tmpWorkB;
workB(fromRow-yDir,fromCol)=-val;
end
end |