ID:45743
Title:wire out 01
Author:Alfonso Nieto-Castanon
Date:2008-05-01 06:08:06
Score:18791.5649
Result:187382.00 (cyc: 49, node: 2669)
CPU Time:26.4914
Status:Passed
Comments:
Based on:none
Code:
function W=solver(B);

W=zeros(0,4);
sB=size(B);
B0=zeros(sB);
idx0=find(B(:));
[b,I,J]=unique(B(idx0));

L0=zeros(size(b));
for n1=1:length(b),
	idx10{n1}=find(J==n1);
	L0(n1)=length(idx10{n1});
end
L0(L0==1)=0;
[nill,sortN]=sort(L0.*b);

for nsortN=length(sortN):-1:1+sum(L0==0),
	N=sortN(nsortN);
	L1=L0(N);
	idx1=idx10{N};

	if L1>1,
		R=cell(2*L1-1,2*L1-1);C=R;Q=R; % connecting paths
		D=zeros(2*L1-1,2*L1-1); D(:)=inf; % distances
		E=zeros(2*L1-1,2*L1-1); % gain
		IDX=zeros(2*L1-1,1); IDX(1:L1)=1; % valid clusters
		[r,c]=ind2sub(sB,idx0(idx1));
		for n1=1:L1, RR{n1}=r(n1); CC{n1}=c(n1); QQ{n1}=[]; end % clusters
		EE=zeros(2*L1-1,1); EE(1:L1)=b(N);
		WW=cell(2*L1-1,1);
		
		% first pass
		LL=2/L1/(L1-1);
		e=0; idx=[];
		for n1=1:L1, 
			for n2=n1+1:L1, 
				[R{n1,n2},C{n1,n2},Q{n1,n2},D(n1,n2)]=findpath(B,r(n1),c(n1),r(n2),c(n2)); 
				E(n1,n2)=EE(n1)+EE(n2)-D(n1,n2)+1;
				if E(n1,n2)>e || (E(n1,n2)==e&&e>0&&rand<LL), e=E(n1,n2); idx=[n1,n2]; end
			end
		end
		K=L1; 
		if e>0, % something
			while ~isempty(idx),
				% new cluster
				K=K+1; 
				Rnow=R{idx(1),idx(2)}; Cnow=C{idx(1),idx(2)}; Qnow=Q{idx(1),idx(2)}; 
				RR{K}=cat(1,RR{idx(1)},Rnow((2:end-1)'),RR{idx(2)});
				CC{K}=cat(1,CC{idx(1)},Cnow((2:end-1)'),CC{idx(2)});
				QQ{K}=cat(1,QQ{idx(1)},Qnow,QQ{idx(2)});
				EE(K)=EE(idx(1))+EE(idx(2))-D(idx(1),idx(2))+1;
				WW{K}=cat(1,WW{idx(1)},WW{idx(2)},[Rnow(1:end-1),Cnow(1:end-1),Rnow(2:end),Cnow(2:end)]);
				IDX(idx)=0;
				n1=K; N2=find(IDX);
				IDX(K)=1;
				if ~isempty(N2), 
					for n2=N2(:)', 
						if idx(1)<n2, mi1=idx(1);ma1=n2; else, mi1=n2;ma1=idx(1); end
						if idx(2)<n2, mi2=idx(2);ma2=n2; else, mi2=n2;ma2=idx(2); end
						if D(mi1,ma1)<D(mi2,ma2)
							R{n2,n1}=R{mi1,ma1};
							C{n2,n1}=C{mi1,ma1};
							D(n2,n1)=D(mi1,ma1);
							E(n2,n1)=EE(n1)+EE(n2)-D(n2,n1)+1;
						else, 
							R{n2,n1}=R{mi2,ma2};
							C{n2,n1}=C{mi2,ma2};
							D(n2,n1)=D(mi2,ma2);
							E(n2,n1)=EE(n1)+EE(n2)-D(n2,n1)+1;
						end
						if D(idx(1),idx(2))>2,
							% recompute distances
							LL=1/length(N2);
							[Rt,Ct,Qt,Dt]=findpath(B,Rnow((2:end-1)'),Cnow((2:end-1)'),RR{n2},CC{n2},1); 
							if Dt<D(n2,n1), R{n2,n1}=Rt;C{n2,n1}=Ct;Q{n2,n1}=Qt;D(n2,n1)=Dt; end
							%[R{n2,n1},C{n2,n1},Q{n2,n1},D(n2,n1)]=findpath(B,RR{n1},CC{n1},RR{n2},CC{n2},1); 
							E(n2,n1)=EE(n1)+EE(n2)-D(n2,n1)+1;
						end
					end
					
					idx=[];
					IDX1=find(IDX);N1=length(IDX1);d=D(IDX1,IDX1);
					[sortd,idxd]=sort(d(:)); % closest path
					[r1,c1]=ind2sub([N1,N1],idxd(1:N1*(N1-1)/2));
					idxfirst=find(E(IDX1(r1)+size(E,1)*(IDX1(c1)-1))>max(EE(IDX1(r1)),EE(IDX1(c1))));  % first increasing gain
					if ~isempty(idxfirst), idx=[IDX1(r1(idxfirst(1))),IDX1(c1(idxfirst(1)))]; end
				else, idx=[]; end
			end
		end
		if K>L1,
			for n1=1:K,EE(n1)=EE(n1)-25*sum(B0(RR{n1}+sB(1)*(CC{n1}-1))>0);end
			[maxEE,K]=max(EE);
			if maxEE>0,
				W=cat(1,W,WW{K});
				%for n3=1:size(QQ{K},1), 
				%	B(QQ{K}(n3,1),QQ{K}(n3,2))=-1; 
				%end
				for n3=1:length(RR{K}), 
					B(RR{K}(n3),CC{K}(n3))=-1; 
					if B0(RR{K}(n3),CC{K}(n3))>0, W=cat(1,W,[RR{K}(n3),CC{K}(n3),RR{K}(n3),CC{K}(n3)]);
					else, B0(RR{K}(n3),CC{K}(n3))=1; end
				end
			end
		end
	end
end

function [R,C,Q,L]=findpath(B,r1,c1,r2,c2,xtra);
% finds straight path from r1 c1 to r2 c2 in map B
if nargin<6, xtra=0; end
Q=[];
L1=length(r1); L2=length(r2);
A=abs(r1(:,ones(1,L2))-r2(:,ones(1,L1))')+abs(c1(:,ones(1,L2))-c2(:,ones(1,L1))');
[a,idx]=sort(A(:));
for n1=1:length(a),
	i2=ceil(idx(n1)/L1);
	i1=idx(n1)-(i2-1)*L1;
	% From B(c1(i1),r1(i1)) to B(c2(i2),r2(i2))
	if c1(i1)==c2(i2), % vertical
		C=c1(i1);
		if r2(i2)<r1(i1), R=(r1(i1):-1:r2(i2))';
		else, R=(r1(i1):r2(i2))'; end
		L=length(R);
		if L<3||~any(B(R(2:end-1),C)), % yup
			C=C(ones(L,1));
			return;
		end
	end
	if r1(i1)==r2(i2), % horizontal
		R=r1(i1);
		if c2(i2)<c1(i1), C=(c1(i1):-1:c2(i2))';
		else, C=(c1(i1):c2(i2))'; end
		L=length(C);
		if L<3||~any(B(R,C(2:end-1))), % yup
			R=R(ones(L,1));
			return;
		end
	end
	if ~B(r2(i2),c1(i1)),
		C1=c1(i1); % vertical portion
		if r2(i2)<r1(i1), R1=(r1(i1):-1:r2(i2))';
		else, R1=(r1(i1):r2(i2))'; end
		L=length(R1);
		if ~any(B(R1(2:end-1),C1)), % maybe
			C1=C1(ones(L,1));
			R2=r2(i2); % horizontal portion
			if c2(i2)<c1(i1), C2=(c1(i1):-1:c2(i2))';
			else, C2=(c1(i1):c2(i2))'; end
			L=length(C2);
			if L<3||~any(B(R2,C2(2:end-1))), % yup
				R2=R2(ones(L,1));
				R=cat(1,R1,R2(2:end));
				C=cat(1,C1,C2(2:end));
				Q=[r2(i2),c1(i1)];
				L=length(R);
				return;
			end
		end
	end
	if ~B(r1(i1),c2(i2)),
		R1=r1(i1); % horizontal portion
		if c2(i2)<c1(i1), C1=(c1(i1):-1:c2(i2))';
		else, C1=(c1(i1):c2(i2))'; end
		L=length(C1);
		if ~any(B(R1,C1(2:end-1))), % maybe
			R1=R1(ones(L,1));
			C2=c2(i2); % vertical portion
			if r2(i2)<r1(i1), R2=(r1(i1):-1:r2(i2))';
			else, R2=(r1(i1):r2(i2))'; end
			L=length(R2);
			if L<3||~any(B(R2(2:end-1),C2)), % yup
				C2=C2(ones(L,1));
				R=cat(1,R1,R2(2:end));
				C=cat(1,C1,C2(2:end));
				Q=[r1(i1),c2(i2)];
				L=length(R);
				return;
			end
		end
	end
end
if ~xtra,
	for n1=1:length(a),
		i2=ceil(idx(n1)/L1);
		i1=idx(n1)-(i2-1)*L1;
		if r1(i1)>1&&~B(r1(i1)-1,c1(i1)),
			[R,C,Q,L]=findpath(B,r1(i1)-1,c1(i1),r2(i2),c2(i2),1);
			if ~isempty(R), 
				R=cat(1,r1(i1),R);
				C=cat(1,c1(i1),C);
				Q=cat(1,[R(1),C(1)],Q);
				L=L+1;
				return;
			end
		end
		if r1(i1)<size(B,1)&&~B(r1(i1)+1,c1(i1)),
			[R,C,Q,L]=findpath(B,r1(i1)+1,c1(i1),r2(i2),c2(i2),1);
			if ~isempty(R), 
				R=cat(1,r1(i1),R);
				C=cat(1,c1(i1),C);
				Q=cat(1,[R(1),C(1)],Q);
				L=L+1;
				return;
			end
		end
		if c1(i1)>1&&~B(r1(i1),c1(i1)-1),
			[R,C,Q,L]=findpath(B,r1(i1),c1(i1)-1,r2(i2),c2(i2),1);
			if ~isempty(R), 
				R=cat(1,r1(i1),R);
				C=cat(1,c1(i1),C);
				Q=cat(1,[R(1),C(1)],Q);
				L=L+1;
				return;
			end
		end
		if c1(i1)<size(B,2)&&~B(r1(i1),c1(i1)+1),
			[R,C,Q,L]=findpath(B,r1(i1),c1(i1)+1,r2(i2),c2(i2),1);
			if ~isempty(R), 
				R=cat(1,r1(i1),R);
				C=cat(1,c1(i1),C);
				Q=cat(1,[R(1),C(1)],Q);
				L=L+1;
				return;
			end
		end
		if r2(i2)>1&&~B(r2(i2)-1,c2(i2)),
			[R,C,Q,L]=findpath(B,r1(i1),c1(i1),r2(i2)-1,c2(i2),1);
			if ~isempty(R), 
				R=cat(1,R,r2(i2));
				C=cat(1,C,c2(i2));
				Q=cat(1,[R(1),C(1)],Q);
				L=L+1;
				return;
			end
		end
		if r2(i2)<size(B,1)&&~B(r2(i2)+1,c2(i2)),
			[R,C,Q,L]=findpath(B,r1(i1),c1(i1),r2(i2)+1,c2(i2),1);
			if ~isempty(R), 
				R=cat(1,R,r2(i2));
				C=cat(1,C,c2(i2));
				Q=cat(1,[R(1),C(1)],Q);
				L=L+1;
				return;
			end
		end
		if c2(i2)>1&&~B(r2(i2),c2(i2)-1),
			[R,C,Q,L]=findpath(B,r1(i1),c1(i1),r2(i2),c2(i2)-1,1);
			if ~isempty(R), 
				R=cat(1,R,r2(i2));
				C=cat(1,C,c2(i2));
				Q=cat(1,[R(1),C(1)],Q);
				L=L+1;
				return;
			end
		end
		if c2(i2)<size(B,2)&&~B(r2(i2),c2(i2)+1),
			[R,C,Q,L]=findpath(B,r1(i1),c1(i1),r2(i2),c2(i2)+1,1);
			if ~isempty(R), 
				R=cat(1,R,r2(i2));
				C=cat(1,C,c2(i2));
				Q=cat(1,[R(1),C(1)],Q);
				L=L+1;
				return;
			end
		end
	end
end
C=[];R=[];L=inf;