编程语言:MATLAB
定理储备:
1.每个空格都对应唯一的闭回路,该闭回路以所在空格为起点,其余结点全是数字格;
2.闭回路上每个结点的行和列上至少(除本身外)还有一个结点。
算法:设(i,j)为空格,为了寻找(i,j)的闭回路,可以将(i,j)设为数字格,抹去行和列上只有一个数字格的的点,反复遍历,直到未抹去的点的行和列上至少有2个数字格。
代码实现:
function [Sigma] = lockcircle1(h_,l_,A_x,B)
%lockcircle 求取闭回路
%h_所要求取的闭回路起点行索引
%l_所要求取的闭回路起点列索引
%A_x为基变量标识矩阵(为基变量则对应位置为1,反之为0)
A_x(h_,l_)=1;
[A_c,A_r]=size(A_x);
change=1;
node=0;
%抹点法求闭回路
%当无法抹去点时得到所有闭回路所经过的节点
while(change>0)
change=0;
for i=1:A_c
for j=1:A_r
if(A_x(i,j)==1&&hl(i,j,A_c,A_r,A_x))
A_x(i,j)=0;
change=change+1;
end
end
end
end
for i=1:A_c
for j=1:A_r
if(A_x(i,j)==1)
node=node+1;
end
end
end
%得到闭回路的排序序列
po=[];
po(1,1)=h_;%po(2,1)是空格所处列,po(1,1)是空格所处行
po(2,1)=l_;
A_x(h_,l_)=0;
for p=1:node-1
finish=0;
for i=1:A_c
if(A_x(i,po(2,p))==1)
po(1,p+1)=i;
po(2,p+1)=po(2,p);
A_x(i,po(2,p))=0;
finish=1;%在列上找到了数字格
break;
end
end
if(finish==0)
for j=1:A_r
if(A_x(po(1,p),j)==1)
po(1,p+1)=po(1,p);
po(2,p+1)=j;
A_x(po(1,p),j)=0;
break;
end
end
end
end
Sigma=0;
for p=1:node
if(mod(p,2)==0)
B(po(1,p),po(2,p))=-B(po(1,p),po(2,p));
end
Sigma=Sigma+B(po(1,p),po(2,p));
end
end
function [A]=ClosedloopAdjustment(h_,l_,A)
%闭回路调整法
A_x=~isnan(A);
A_x(h_,l_)=1;
[A_c,A_r]=size(A_x);
change=1;
node=0;
%当无法抹去点时得到所有闭回路所经过的节点
while(change>0)
change=0;
for i=1:A_c
for j=1:A_r
if(A_x(i,j)==1&&hl(i,j,A_c,A_r,A_x))
A_x(i,j)=0;
change=change+1;
end
end
end
end
for i=1:A_c
for j=1:A_r
if(A_x(i,j)==1)
node=node+1;
end
end
end
%得到闭回路的排序序列
po=[];
po(1,1)=h_;
po(2,1)=l_;
A_x(h_,l_)=0;
for p=1:node-1
finish=0;
for i=1:A_c
if(A_x(i,po(2,p))==1)
po(1,p+1)=i;
po(2,p+1)=po(2,p);
A_x(i,po(2,p))=0;
finish=1;
break;
end
end
if(finish==0)
for j=1:A_r
if(A_x(po(1,p),j)==1)
po(1,p+1)=po(1,p);
po(2,p+1)=j;
A_x(po(1,p),j)=0;
break;
end
end
end
end
%以(_h,_l_)为调入格,得到新的调运表
a=[];
po_=[];
po_(:,1)=po(:,2);
a(1)=A(po_(1,1),po_(2,1));
%%取po的偶数列po_
for p=1:node
if mod(p,2)==0
i=p/2;
po_(1,i)=po(1,p);
po_(2,i)=po(2,p);
end
end
%%取闭回路上具有(-1)的数字格的最小者
for i=1:node/2
a(i)=A(po_(1,i),po_(2,i));
[min_a,index]=min(a);
end
%%按闭回路上的正负号加上或减去该值
A(po(1,1),po(2,1))=0;
A(po(1,2*index),po(2,2*index))=NaN;
for i=1:node
if mod(i,2)~=0
A(po(1,i),po(2,i))= A(po(1,i),po(2,i))+min_a;
else
A(po(1,i),po(2,i))= A(po(1,i),po(2,i))-min_a;
end
end
end