/*得到了未划去的最小运价所在格的坐标(I0,J0)和最小运价Cmin */
if(k>0)
{if(Cmin==1.0e15&&cpi(k-1)==0)
{for(l1=0;l1
if(x(l1,cpj(k-1))==1.0e15)
{x(l1,cpj(k-1))=0;
}
}
else if(Cmin==1.0e15&&cpi(k-1)!=0)
{for(l1=0;l1
if(x(cpi(k-1),l1)==1.0e15)
{x(cpi(k-1),l1)=0;
}
}
}
if(b(I0)
{
cpi(k)=I0;cpj(k)=-1;
x(I0,J0)=b(I0);
#ifdef debug
printf("I0=%d,J0=%d,x(I0,J0)=%8.4f,k=%d,cpi(k)=%d,cpj(k)=%d\n",I0,J0,x(I0,J0),k,cpi(k),cpj(k));
#endif
a(J0)-=b(I0);
b(I0)=0;
}
else
{
cpi(k)=-1;cpj(k)=J0;
x(I0,J0)=a(J0);
#ifdef debug
printf("I0=%d,J0=%d,x(I0,J0)=%8.4f,k=%d,cpi(k)=%d,cpj(k)=%d\n",I0,J0,x(I0,J0),k,cpi(k),cpj(k));
#endif
b(I0)-=a(J0);
a(J0)=0;
}
} /*END FOR K 用最小元素法求得了初使可行解*/
/*输出初始可行解*/
printf("\n=============init Solution===================\n");
sum=0;
for(i=0;i
{
for(j=0;j
{
if(x(i,j)>=1.0e15)
printf("%10s","******");
else
{printf("%10.3f",x(i,j));
sum+=(x(i,j)*c(i,j));
}
}
printf("\n");
}
printf("\n\n\tThe Cost is: %-10.4f\n",sum);
getch();
/***************循环换入换出,直到检验数为非负数*****************************/
/*循环决定换入变量 */
while(1)
{
/*位势置初值Ui,Vi=1.0e15 */
for(i=0;i
u(i)=1.0e15;
for(j=0;j
v(j)=1.0e15;
/*求位势*/
l=0;u(0)=0;
for(i=0;i
{
for(j=0;j
{
if(u(i)>=1.0e15&&v(j)>=1.0e15&&x(i,j)<1.0e15)
{
cpi(l)=i;cpj(l)=j;l++; /*记录未求过位势的位置*/
}
else if(x(i,j)<1.0e15&&u(i)<1.0e15)
{v(j)=c(i,j)-u(i);}
else if(x(i,j)<1.0e15&&v(j)<1.0e15)
{u(i)=c(i,j)-v(j);}
}/*end for j */
}/*end for i */
/*按记录位置求其余位势*/
if(l>0)
{
while(1)
{
ip=0;
for(k=0;k
{
i=cpi(k);j=cpj(k);
if((u(i)>=1.0e15)&&(v(j)>=1.0e15)&&(x(i,j)<1.0e15))
{
cpi(ip)=i;cpj(ip)=j;ip++; /*记录未求过位势的位置*/
}
else if(x(i,j)<1.0e15&&u(i)<1.0e15)
{v(j)=c(i,j)-u(i);}
else if(x(i,j)<1.0e15&&v(j)<1.0e15)
{u(i)=c(i,j)-v(j);}
}/*end for k */
if(ip==0)break;
l=ip;
}/*end for while */
} /*end if l */
#ifdef debug
printf("\nU(i):");
for(i=0;i
{printf("%10.2f",u(i));
}
printf("\nV(j):");
for(j=0;j
{printf("%10.2f",v(j));
}
printf("\n");
#endif
/*求检验数*/
for(i=0;i
{
for(j=0;j
{ s(i,j)=1.0e15;
if(x(i,j)>=1.0e15) s(i,j)=c(i,j)-u(i)-v(j);
}
}
/*求最小检验数*/
Cmin=1.0e15;
for(i=0;i
{
for(j=0;j
{
if(Cmin>s(i,j))
{Cmin=s(i,j);I0=i;J0=j;}
}
}
#ifdef debug
printf("\ncheck number:\n");
for(i=0;i
{
for(j=0;j
{
printf("s(%d,%d)=%-10.2f\n",i,j,s(i,j));
}
printf("\n");
}
printf("Smin=%-10.2f",Cmin);
getch();
#endif
if(Cmin>=0) return; /*已经得到最优解,返回主程序*/
/*此时找到了入基变量X(I0,J0) */
/*求闭回路*/
for(k=0;k
{
cpf(k)=-1;
}/*end for k */
cpi(0)=I0;cpj(0)=J0;
k=0;
while(1)
{
f=cpf(k);
/*设置闭回路搜索方向*/
while(1)
{
i=cpi(k);j=cpj(k);
fc=0;
f++;
cpf(k)=f;
if(f>=4)break;
/*避免反向搜索*/
if(k>0)
{
if(f==0&&cpf(k-1)==2) continue;
else if(f==1&&cpf(k-1)==3)continue;
else if(f==2&&cpf(k-1)==0)continue;
else if(f==3&&cpf(k-1)==1)continue;
}
if(f==0)
{/*沿J+方向搜索*/
while(1)
{
j++;
if(j>=n){fc=2;break;}
if((i==I0)&&(j==J0))
{fc=1;break;}
if(s(i,j)>=1.0e15)
{fc=3;break;}
}
}/*end j+ */
else if(f==1)
{ /*沿i-方向搜索*/
while(1)
{ i--;
if(i<0){fc=2;break;}
if((i==I0)&&(j==J0)){fc=1;break;}
if(s(i,j)>=1.0e15){fc=3;break;}
}
}/*end if=1 */
else if(f==2)
{/*沿J-方向搜索*/
while(1)
{
j--;
if(j<0){fc=2;break;}
if((i==I0)&&(j==J0)){fc=1;break;}
if(s(i,j)>=1.0e15){fc=3;break;}
}
} /*end f==2 */
else if(f==3)
{/*沿I+方向搜索*/
while(1)
{
i++;
if(i>=m){fc=2;break;}
if((i==I0)&&(j==J0)){fc=1;break;}
if(s(i,j)>=1.0e15){fc=3;break;}
}
}/*end f==3 */
if((fc==1)||(fc==3))break;
}/*end while flag 2 */
if(fc==0)
{/*沿些方向搜索失败,退回回到前一点*/
k--;
}
else if(fc==1)break; /*搜索完成*/
else if(fc==3)
{/*沿此方向搜索成功,前进一点*/
k++;
cpi(k)=i;cpj(k)=j;
#ifdef debug
printf("\n");
printf("k=%d,cpi(k)=%d,cpj(k)=%d,cpf(k)=%d,x(i,j)=%8.4f\n",k,cpi(k),cpj(k),cpf(k),x(cpi(k),cpj(k)));
getch();
#endif
cpf(k)=-1;
}
}/*end while */
/*去除闭回路中的非转折点*/
l=0;
while(l
{ i=l+1;
while(i<=k)
{if(cpf(l)==cpf(i)) i++;
else break;
}
if(i>(l+1))
{j=l+1;
k1=k-(i-j);
/*如果某些点前进方向相同,则去除中间各点*/
while(i<=k)
{cpi(j)=cpi(i);
cpj(j)=cpj(i);
cpf(j)=cpf(i);
i++;j++;
}
l+=2;
k=k1;
}
else l++;
}/*end while l
/*查找闭回路上基本解的最小值*/
Cmin=x(cpi(1),cpj(1));
Imin=cpi(1);Jmin=cpj(1);
for(i=3;i<=k;i+=2)
{if(Cmin>x(cpi(i),cpj(i)))
{Cmin=x(cpi(i),cpj(i));
Imin=cpi(i);Jmin=cpj(i);
}
}
/*换入基变量*/
x(I0,J0)=Cmin;
for(i=1;i<=k;i+=2)
{x(cpi(i),cpj(i))-=Cmin;
if((i+1)<=k) x(cpi(i+1),cpj(i+1))+=Cmin;
}
x(Imin,Jmin)=1.0e15;
}
free(CP);
free(V);
free(U);
free(S);
QUIT: return;
}