?? lp_simplex.cpp
字號:
# include <iostream.h>
# include <stdlib.h>
# include "rat.h"
# define MAX 100
int n,m,i,j,s,t,L[MAX],R[MAX];
rat z[MAX],c[MAX],a[MAX][MAX],b[MAX],max,second_c[MAX],v,min,temp;
bool B[MAX],flag;
int digit(int a)
{
if(a==0) return 1;
int k=0;
while(a){
k++;
a/=10;
}
return k;
}
int cal(rat x)
{
int count=0;
if(x<0) count++;
if(x.Q!=1) count+=1+digit(x.Q);
count+=digit(abs(x.P));
return count;
}
int output(rat x)
{
int tmd;
for(tmd=cal(x);tmd<=6;tmd++) cout<<' ';
cout<<x;
return 0;
}
int table()
{
for(i=0;i<m;i++){
for(j=0;j<n;j++) output(a[i][j]);
cout<<'|';output(b[i]);
cout<<endl;
}
for(i=0;i<n;i++) cout<<"_______";
cout<<"+_______"<<endl;
for(i=0;i<n;i++) output(z[i]);
cout<<'|';output(v);cout<<endl;
return 0;
}
int main()
{
while(cin>>n>>m) {
//輸入a,b,c:系數(shù),目標,約束
for(i=0;i<m;i++)
for(j=0;j<n;j++) cin>>a[i][j];
for(i=0;i<n;i++) cin>>second_c[i];
for(i=0;i<m;i++) cin>>b[i];
//每行補s,構成第一階段完整的表
for(i=0;i<m;i++)
for(j=0;j<m;j++)
if(i==j) a[i][j+n]=1;
else a[i][j+n]=0;
//當前基及目標:
for(i=0;i<n;i++) {
B[i]=0;
c[i]=0;
}
for(i=n;i<n+m;i++) {
B[i]=1;
c[i]=1;
}
for(i=0;i<m;i++) {
R[i]=n+i;
L[n+i]=i;
}
n+=m;
//計算了z 和 v
//如果是第一階段,直接加就可以了,可是這樣移植性差
for(i=0;i<n;i++){
z[i]=0;
for(j=0;j<m;j++) z[i]=z[i]+c[R[j]]*a[j][i];
z[i]=z[i]-c[i];
}
v=0;
for(i=0;i<m;i++){
v=v+c[R[i]]*b[i];
}
cout<<"第一階段要解決的問題是:"<<endl;
cout<<"min z = ";
for(i=0;i<m-1;i++) cout<<'s'<<i+1<<" + ";
cout<<'s'<<i+1<<endl;
table();
int flag2=0;
while(1){
max=z[0];s=0;
for(i=0;i<n;i++)if(z[i]>max) {
s=i;
max=z[i];
}
if(max<0||max==0){
if(v!=0) {
flag2=1;
cout<<"沒有可行解"<<endl;
}
break;
}
flag=0;min=1000000;
for(i=0;i<m;i++)if(a[i][s]>0){
flag=1;
if((b[i]/a[i][s])<min) {
min=b[i]/a[i][s];
t=i;
}
}
if(!flag) {
cout<<"unbound"<<endl;
break;
}
//新表
cout<<"樞元素為:L"<<t+1<<s+1<<" = "<<a[t][s]<<endl;
cout<<"得新表:"<<endl;
temp=a[t][s];
b[t]=b[t]/temp;
for(i=0;i<n;i++) a[t][i]=a[t][i]/temp;// 系數(shù)變1
for(i=0;i<m;i++)if(i!=t){
temp=a[i][s];
b[i]=b[i]-temp*b[t];
for(j=0;j<n;j++)
a[i][j]=a[i][j]-temp*a[t][j];
}
temp=z[s];
for(i=0;i<n;i++) z[i]=z[i]-a[t][i]*temp;
v=v-b[t]*temp;
B[s]=1;B[R[t]]=0;L[s]=L[R[t]];R[t]=s;
table();
}
if(flag2) break;
cout<<"下面是第二階段的運算:"<<endl;
n-=m;
//重算z,c和v
for(i=0;i<n;i++) c[i]=second_c[i];
for(i=0;i<n;i++){
z[i]=0;
for(j=0;j<m;j++) z[i]=z[i]+c[R[j]]*a[j][i];
z[i]=z[i]-c[i];
}
v=0;
for(i=0;i<m;i++){
v=v+c[R[i]]*b[i];
}
table();
while(1){
max=z[0];s=0;
for(i=0;i<n;i++)if(z[i]>max) {
s=i;
max=z[i];
}
if(max<0||max==0){
cout<<"最優(yōu)解是:"<<v<<endl;
for(i=0;i<n;i++) if(B[i])
cout<<'x'<<i+1<<" = "<<b[L[i]]<<endl;
cout<<"其余變量值為0"<<endl;
break;
}
flag=0;min=1000000;
for(i=0;i<m;i++)if(a[i][s]>0){
flag=1;
if((b[i]/a[i][s])<min) {
min=b[i]/a[i][s];
t=i;
}
}
if(!flag) {
cout<<"沒有最優(yōu)解,即趨于負無窮"<<endl;
break;
}
//新表
cout<<"樞元素為:L"<<t+1<<s+1<<" = "<<a[t][s]<<endl;
cout<<"得新表:"<<endl;
temp=a[t][s];
b[t]=b[t]/temp;
for(i=0;i<n;i++) a[t][i]=a[t][i]/temp;// 系數(shù)變1
for(i=0;i<m;i++)if(i!=t){
temp=a[i][s];
b[i]=b[i]-temp*b[t];
for(j=0;j<n;j++)
a[i][j]=a[i][j]-temp*a[t][j];
}
temp=z[s];
for(i=0;i<n;i++) z[i]=z[i]-a[t][i]*temp;
v=v-b[t]*temp;
B[s]=1;B[R[t]]=0;L[s]=L[R[t]];R[t]=s;
table();
}
}
return 0;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -