概述
传送门
题解:
虽然标程挂了,不过还是勉强能用的。
初始条件:
max∑jcjaj∑jai,jxj≤bjxi≥0
max
∑
j
c
j
a
j
∑
j
a
i
,
j
x
j
≤
b
j
x
i
≥
0
最优化过程:
假设一开始满足所有 bj≥0 b j ≥ 0 。
1.找到 ci c i 为正数的 xi x i 。
2.找到 bjxj,i b j x j , i 最小的 j j
3.pivot(j,i)。
初始解:
1.找到任意的
j
j
.
2.找到任意的
i
i
.
3.pivot(j,i).
无解条件:
init失败,即且不存在
i
i
.
无限解条件:
任意时刻基变量没有限制
pivot操作:
xe=bi−∑jai,jxj−xn+iai,e
x
e
=
b
i
−
∑
j
a
i
,
j
x
j
−
x
n
+
i
a
i
,
e
对于其他行矩阵减法即可。
#include <bits/stdc++.h>
using namespace std;
typedef long double LD;
const int N=26;
int n,m,type,q[N],id[N*2];
double a[N][N],ans[N];
namespace LP {
const double eps=1e-8, INF=1e15;
inline void pivot(int l,int e) {
swap(id[l+n],id[e]);
double t=a[l][e]; a[l][e]=1;
for(int i=0;i<=n;i++) a[l][i]/=t;
int p=0;
for(int i=0;i<=n;i++) if(fabs(a[l][i])>eps) q[++p]=i;
for(int i=0;i<=m;i++) if(i!=l && fabs(a[i][e])>eps) {
double t=a[i][e]; a[i][e]=0;
for(int j=1;j<=p;j++) a[i][q[j]]-=t*a[l][q[j]];
}
}
inline bool init() {
while(true) {
int l=0,e=0;
for(int i=1;i<=m;i++)
if(a[i][0]<-eps && (!l || (rand()%2))) l=i;
if(!l) break;
for(int j=1;j<=n;j++)
if(a[l][j]<-eps && (!e || (rand()%2))) e=j;
if(!e) return puts("Infeasible"), false;
pivot(l,e);
} return true;
}
inline bool simplex() {
while(true) {
int l=0,e=0; double mn=INF;
for(int j=1;j<=n;j++)
if(a[0][j]>eps) {e=j; break;}
if(!e) break;
for(int i=1;i<=m;i++)
if(a[i][e]>eps && mn>a[i][0]/a[i][e])
mn=a[i][0]/a[i][e], l=i;
if(!l) return puts("Unbounded"), false;
pivot(l,e);
} return true;
}
inline void solve() {
for(int i=1;i<=n;i++) id[i]=i;
if(init() && simplex()) {
printf("%.8lfn",-a[0][0]);
for(int i=1;i<=m;i++) ans[id[n+i]]=a[i][0];
if(type) for(int i=1;i<=n;i++) printf("%.8lf ",ans[i]);
}
}
}
int main() {
cin>>n>>m>>type;
for(int i=1;i<=n;i++) cin>>a[0][i];
for(int i=1;i<=m;i++) {
for(int j=1;j<=n;j++) cin>>a[i][j];
cin>>a[i][0];
} LP::solve();
}
最后
以上就是含蓄玫瑰为你收集整理的UOJ#179. 线性规划(单纯形)的全部内容,希望文章能够帮你解决UOJ#179. 线性规划(单纯形)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复