数学:单纯形

据说一些网络流也可以解决线性规划问题只不过不够经典?

BZOJ1061网络流建模经典难题

题我就不看了,直接把结论拿出来上方法

首先第一步要做的就是把线性规划转化成容易处理的,标准型

列出线性规划方程之后:

min{2x1+5x2+2x3}

x1+0+0>=2

x1+x2+0>=3

0+x2+x3>=4

这个方程等价于:

max{2x1+3x2+4x3}

x1+x2+0<=2

0+x2+x3<=5

0+0+x3<=2

然后套模版?

这个转化刚开始我以为是用前面的方式处理成标准形式,然而不是

它是求了一个矩阵的转秩变过来的

不过我不太明白他到底是怎么划过来的

单纯形法刘汝佳直接略过了,可能是因为我菜吧

这里补一个dalao的论文PPT:https://wenku.baidu.com/view/ce5784754a7302768f99391d

日后再说

样例是这样给的,三天里每天至少需要2人,3人,4人

第一类志愿者费用是2,第二类费用是5,第三类费用是2

他们的工作时间为第一类1-2,第二类2-3,第三类3

根据题意就能够得到上面描述的第一种的线性规划

目标函数为2x1+5x2+2x3(这里是最小)

 1 #include<cstdio>
 2 const int maxn=1005;
 3 const int maxm=10005;
 4 int n,m,p,id;
 5 double ans;
 6 double c[maxn],b[maxm];
 7 double a[maxm][maxn];
 8 void pvt(int id,int p)
 9 {
10     a[id][p]=1/a[id][p],b[id]*=a[id][p];
11     for(int i=1;i<=n;i++) if(i^p) a[id][i]*=a[id][p];
12     for(int i=1;i<=m;i++) if((i^id)&&a[i][p])
13     {
14         for(int j=1;j<=n;j++) if(j^p) a[i][j]-=a[i][p]*a[id][j];
15         b[i]-=a[i][p]*b[id],a[i][p]*=-a[id][p];
16     } 
17     for(int i=1;i<=n;i++) if(i^p) c[i]-=c[p]*a[id][i];
18     ans+=c[p]*b[id],c[p]*=-a[id][p];
19 }
20 double simplex()
21 {
22     while(1)
23     {
24         for(p=1;p<=n;p++) if(c[p]>0) break;
25         if(p==n+1) return ans;
26         double fz=0x3f3f3f3f;
27         for(int i=1;i<=m;i++)
28             if(a[i][p]>0&&b[i]/a[i][p]<fz)
29                 fz=b[i]/a[i][p],id=i;
30         if(fz==0x3f3f3f3f) return fz;
31         pvt(id,p);
32     }
33 }
34 int main()
35 {
36     int l,r;
37     scanf("%d%d",&n,&m);
38     for(int i=1;i<=n;i++) scanf("%lf",&c[i]);  //需求,用来增广 
39     for(int i=1;i<=m;i++)
40     {
41         scanf("%d%d%lf",&l,&r,&b[i]);  //时间和费用 
42         for(int j=l;j<=r;j++) a[i][j]=1;  //矩阵 
43     }
44     printf("%.0lf",simplex()); 
45     return 0;
46 }

 

posted @ 2018-09-04 19:52  静听风吟。  阅读(318)  评论(0编辑  收藏  举报