现在的位置: 首页 > 综合 > 正文

线性规划 单纯形算法

2013年10月07日 ⁄ 综合 ⁄ 共 4999字 ⁄ 字号 评论关闭
线性规划 单纯形算法

根据单联通区域求极值的想法得来的算法思想,故而叫做simplex algorithm。
暂且将写下的程序贴出,做个备份。
具体算法分析待看完证明后贴出。

此算法实现完全是对《算法导论》上算法框架的实现。
注:要使用g++编译器,vc要将变量定义做一些更改。

  1. #include <iostream>
  2. #include <set>
  3. #include <vector>
  4. #include <ctime>
  5. #include <climits>
  6. #include <cmath>
  7. using namespace std;
  8. int const BUF = 100;
  9. set<int> N,B;
  10. set<int>::iterator p,q;
  11. double bi[BUF];
  12. double ci[BUF];
  13. double v;
  14. double A[BUF][BUF];
  15. double res[BUF];
  16. int Num;
  17. //question:
  18. //      request: max v+ci*x (ci=0,if and only if x[i] not in N)
  19. //      constraint: y = bi+A*x (x[i] is in B and y[i] is in B)
  20. //      solution: res and v
  21. //  output the form of the question's equalities.
  22. //  you can invoke this function after "pivot" function to see the changes.
  23. void output()
  24. {
  25.     set<int>::iterator pt;
  26.     printf("z    = %.2lf ",v);
  27.     
  28.     p = N.begin();
  29.     
  30.     while(p!=N.end()){
  31.         pt = p;
  32.         pt++;
  33.         if(pt!=N.end()){
  34.             if(ci[*p]>0)
  35.                 printf(" + %.2lf*x(%d) ",ci[*p],*p);
  36.             else 
  37.                 printf(" - %.2lf*x(%d) ",fabs(ci[*p]),*p);
  38.         }else {
  39.             if(ci[*p]>0)
  40.                 printf(" + %.2lf*x(%d)/n",ci[*p],*p);
  41.             else 
  42.                 printf(" - %.2lf*x(%d)/n",fabs(ci[*p]),*p);
  43.         }
  44.         p++;
  45.     }
  46.     
  47.     for(p=B.begin();p!=B.end();p++){
  48.         
  49.         printf("x(%d) = %.2lf ",*p,bi[*p]);
  50.         
  51.         q = N.begin();
  52.         
  53.         while(q!=N.end()){
  54.             pt = q;
  55.             pt++;
  56.             if(pt!=N.end()){
  57.                 if(A[*p][*q]>0)
  58.                     printf(" - %.2lf*x(%d)",A[*p][*q],*q);
  59.                 else 
  60.                     printf(" + %.2lf*x(%d)",fabs(A[*p][*q]),*q);
  61.             }else {
  62.                 if(A[*p][*q]>0)
  63.                     printf(" - %.2lf*x(%d)/n",A[*p][*q],*q);
  64.                 else 
  65.                     printf(" + %.2lf*x(%d)/n",fabs(A[*p][*q]),*q);
  66.             }
  67.             q++;
  68.         }
  69.     }
  70.     printf("/n");
  71. }
  72. // input format:
  73. //      first line one number Num representing
  74. //      the num of all variables including the elements of N and B
  75. //      next Num lines representing A[i][j] which is the coefficient of x[i]
  76. //      next two lines each includes Num numbers --- the ci and bi respectively
  77. //  for example
  78. /*
  79. input:@file = "t.in"
  80.     
  81. 6
  82. 0 0 0 0 0 0 
  83. 0 0 0 0 0 0
  84. 0 0 0 0 0 0
  85. 1 1 3 0 0 0
  86. 2 2 5 0 0 0
  87. 4 1 2 0 0 0
  88. 3 1 2 0 0 0
  89. 0 0 0 30 24 36
  90. 0
  91. representing the standard format:
  92. z    = 3*x(0)  + x(1)  + 2*x(2)
  93. x(3) = 30  - 1*x(0) - x(1) - 3*x(2)
  94. x(4) = 24  - 2*x(0) - 2*x(1) - 5*x(2)
  95. x(5) = 36  - 4*x(0) - *x(1) - 2*x(2)
  96. */
  97. void init()
  98. {
  99.     freopen("t.in","r",stdin);
  100.     freopen("t.out","w",stdout);
  101.     
  102.     scanf("%d",&Num);
  103.         
  104.     for(int i=0;i<Num;i++)
  105.         for(int j=0;j<Num;j++)
  106.             scanf("%lf",&A[i][j]);
  107.     
  108.     
  109.     for(int i=0;i<Num;i++)
  110.         scanf("%lf",&ci[i]);
  111.         
  112.     for(int i=0;i<Num;i++)
  113.         scanf("%lf",&bi[i]);
  114.         
  115.     scanf("%lf",&v);
  116.     
  117.     for(int i=0;i<Num;i++)
  118.         ci[i]!=0 ? N.insert(i):B.insert(i);
  119.     
  120.     output();
  121.     
  122.     srand((unsigned)clock());
  123. }
  124. // relex each x[i]'s coefficient the main part of this algorithm.
  125. //x[e] is the new basic variable. x[l] is changed into nonbasic variable.
  126. void pivot(int l,int e) 
  127. {
  128.     bi[e] = bi[l]/A[l][e];
  129.     
  130.     for(p=N.begin();p!=N.end();p++)
  131.         A[e][*p] = A[l][*p]/A[l][e];
  132.     
  133.     A[e][l] = 1/A[l][e];
  134.     
  135.     for(p=B.begin();p!=B.end();p++){
  136.         
  137.         if(*p==l)continue;
  138.         
  139.         bi[*p] -= A[*p][e]*bi[e];
  140.         
  141.         for(q=N.begin();q!=N.end();q++)
  142.             if(*q!=e)
  143.                 A[*p][*q] -= A[*p][e]*A[e][*q];
  144.         
  145.         A[*p][l] = -1*A[*p][e]*A[e][l];
  146.     }
  147.     
  148.     v += ci[e]*bi[e];
  149.     
  150.     for(p=N.begin();p!=N.end();p++)
  151.         if(*p!=e)
  152.             ci[*p] -= ci[e]*A[e][*p];
  153.         
  154.     ci[l] = -1*ci[e]*A[e][l];
  155.     
  156.     N.insert(l),N.erase(e);
  157.     B.insert(e),B.erase(l);
  158. }
  159. //  basing a little random selection on selecting
  160. //  which x[i] will be changed into basic variables
  161. void simplex()
  162. {
  163.     double temp = INT_MAX;
  164.     
  165.     vector<int> v;
  166.     
  167.     while(1){
  168.         
  169.         temp = INT_MAX;
  170.         
  171.         v.clear();
  172.         
  173.         for(p=N.begin();p!=N.end();p++)
  174.             if(ci[*p]>0)
  175.                 v.push_back(*p);
  176.         
  177.         if(v.size()==0){
  178.             temp = 0;
  179.             break;
  180.         }
  181.         
  182.         int t = rand()%v.size();
  183.         
  184.         int tn;
  185.         
  186.         for(q=B.begin();q!=B.end();q++)
  187.             if(A[*q][t]>0){
  188.                 
  189.                 double tk = bi[*q]/A[*q][t];
  190.             
  191.                 if(temp>tk)temp=tk,tn=*q;
  192.             }
  193.         
  194.         printf("l = %d  e = %d/n",tn,t);
  195.         
  196.         if(temp==INT_MAX)
  197.             break;
  198.         else 
  199.             pivot(tn,t);
  200.             
  201.         output();
  202.         
  203.     }
  204.     
  205.     if(temp==INT_MAX){
  206.         printf("no answer/n"); 
  207.         //which means unbounded,i.e. the question has no answer
  208.         exit(0);
  209.     }
  210. }
  211.     
  212. void result()
  213. {
  214.     printf("/n");
  215.     
  216.     for(p=B.begin();p!=B.end();p++)
  217.         res[*p] = bi[*p];
  218.     
  219.     printf("ans seq: ");
  220.     for(int i=0;i<Num;i++)
  221.         printf("%.2lf ",res[i]);
  222.         
  223.     printf("/nmax: %.2lf/n",v);
  224. }
  225. int main()
  226. {
  227.     init();
  228.     
  229.     simplex();
  230.     
  231.     result();
  232.     
  233.     return 0;
  234. }

抱歉!评论已关闭.