虽然学了单纯形,但学得很差,终于看着书把最简单的例子给写出来了,对不起白老师啊(教我们运筹学的老师)。
该程序执行的初试条件是自己把初试单纯形表搞出来,本程序只负责进行迭代,(偷笑)。
唉,希望有人能得到帮助,本来做这个题是为了去解一个线性规划的题的,但感觉有点麻烦,还是先歇着吧,看以后变强了再来A这个实数幻方的题
该题链接:http://122.207.68.93/OnlineJudge/problem.php?cid=2031&pid=9
Problem J: Real Numbers Magic Square
咳咳,以后再说吧
贴代码:
View Code
1 //这里在找进基变量和出基变量时有时会出现死循环,尽管概率很低 2 //可以使用勃兰特规则,该程序没有写,勃兰特规则自己百度,或参考运筹学教材,清华大学出版社出版,36页,退化那一块 3 #include <cstdio> 4 #define MAXN 100 5 #define INF 0x7fffffff 6 int ind ,outd; 7 double a[MAXN][MAXN]; 8 double cb[MAXN],b[MAXN]; 9 int xb[MAXN],nxb[MAXN]; 10 double theta[MAXN],c[MAXN]; 11 int n,m; 12 void init() 13 { 14 for(int i=1; i<=m; ++i) 15 for(int j=1; j<=n; ++j) 16 scanf("%lf",&a[i][j]); 17 for(int i=1; i<=n; ++i) 18 scanf("%lf",&c[i]); 19 for(int i=1; i<=m; ++i) 20 scanf("%lf%d%lf",&cb[i],&xb[i],&b[i]); 21 for(int i=1; i<=n-m; ++i) 22 scanf("%d",&nxb[i]); 23 } 24 void print() 25 { 26 for(int i=1; i<=m; ++i) 27 { 28 for(int j=1; j<=n; ++j) 29 { 30 printf("a[%d][%d] = %lf ",i,j,a[i][j]); 31 } 32 puts(""); 33 } 34 // for(int i=1; i<=n; ++i) 35 // { 36 // printf("c[%d] = %lf ",i,c[i]); 37 // } 38 // puts(""); 39 for(int i=1; i<=m; ++i) 40 { 41 printf("cb[%d] = %lf xb[%d] =%d b[%d] = %lf\n",i,cb[i],i,xb[i],i,b[i]); 42 } 43 for(int i=1; i<=n-m; ++i) 44 { 45 printf("nxb[%d] = %d\n",i,nxb[i]); 46 } 47 } 48 int findInVarible()//找进基变量 49 { 50 double max = 0; 51 ind = -1; 52 for(int i=1; i<=n-m; ++i) 53 { 54 int j = nxb[i]; 55 double sig = c[j]; 56 for(int k =1; k<=m; ++k) 57 { 58 sig -= cb[k]*a[k][j]; 59 } 60 bool flag = true; 61 if(sig > 0) 62 { 63 for(int k=1; k<=m; ++k) 64 { 65 if(a[k][j] > 0) 66 { 67 flag = false; 68 break; 69 } 70 } 71 if(flag) return -2;//出现无界解 72 if(sig > max) 73 { 74 printf("sig = %lf\n",sig); 75 max = sig; 76 ind = i; 77 } 78 } 79 } 80 return ind; 81 } 82 int findOutVarible()//找出基变量 83 { 84 double min = INF; 85 outd = -1; 86 int j = nxb[ind]; 87 for(int k=1; k<=m; ++k) 88 { 89 if(a[k][j] > 0 && b[k]/a[k][j] < min) 90 { 91 min = b[k]/a[k][j] ; 92 outd = k; 93 printf("theta = %lf\n",min); 94 } 95 } 96 return outd; 97 } 98 void Guass(int x,int y)//高斯变换化进基变量所在列为单位向量 99 { 100 double de = a[y][x]; 101 for(int j = 1; j<=n; ++j) 102 a[y][j] = a[y][j]/de; 103 b[y] = b[y]/de; 104 for(int i=1; i<=m; ++i) 105 { 106 if(i == y) continue; 107 de = a[i][x]; 108 for(int j=1; j<=n; ++j) 109 a[i][j] =a[i][j]-a[y][j]*de; 110 b[i] =b[i]-b[y]*de; 111 } 112 } 113 int main() 114 { 115 // freopen("in.cpp","r",stdin); 116 // freopen("out.cpp","w",stdout); 117 while(~scanf("%d%d",&m,&n)) 118 { 119 init();//建立初始单纯形表,这里为了简化,直接输入的就是已经初试化好了的单纯形表 120 print(); 121 int ind,outd;//进基变量和出基变量的序号 122 while(1) 123 { 124 ind = findInVarible(); 125 if(ind == -2 || ind == -1) break; 126 outd = findOutVarible(); 127 printf("ind = %d outd = %d\n",nxb[ind],xb[outd]); 128 Guass(nxb[ind],outd); 129 int tmp = nxb[ind]; 130 nxb[ind] = xb[outd]; 131 xb[outd] = tmp; 132 cb[outd] = c[tmp]; 133 print(); 134 } 135 if(ind == -2) printf("No solution\n"); 136 else 137 { 138 double sum = 0; 139 for(int i=1; i<=m; ++i) 140 sum += cb[i]*b[i]; 141 printf("sum = %lf\n",sum);//输出最后的解 142 } 143 } 144 return 0; 145 }