表上作业法matlab实现,高人帮忙改改,有关表上作业法的C++程序

/*得到了未划去的最小运价所在格的坐标(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;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值