单纯形法
单纯形法
发现自己不会线性规划,学了一下单纯形法,差点猝死。
没法完全理解,先背板子。
\(Code:\)
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstdlib>
#include<cmath>
#include<ctime>
#define N 55
#define db double
using namespace std;
const db eps=1e-7;
int n,m,t,id[N];
db a[N][N],ans[N];
void pivot(int l,int e)
{
swap(id[n+l],id[e]);
db t(a[l][e]);
a[l][e]=1;
for (int i=0;i<=n;++i)
a[l][i]/=t;
for (int i=0;i<=m;++i)
if (i!=l && fabs(a[i][e])>eps)
{
db t(a[i][e]);
a[i][e]=0;
for (int j=0;j<=n;++j)
a[i][j]-=t*a[l][j];
}
}
int main()
{
srand(time(NULL));
scanf("%d%d%d",&n,&m,&t);
for (int i=1;i<=n;++i)
scanf("%lf",&a[0][i]);
for (int i=1;i<=m;scanf("%lf",&a[i][0]),++i)
for (int j=1;j<=n;scanf("%lf",&a[i][j]),++j);
for (int i=1;i<=n;++i)
id[i]=i;
for (;;)
{
int e(0),l(0);
for (int i=1;i<=m;++i)
if (a[i][0]<-eps && (!l || (rand() & 1)))
l=i;
if (!l)
break;
for (int i=1;i<=n;++i)
if (a[l][i]<-eps && (!e || (rand() & 1)))
e=i;
if (!e)
{
puts("Infeasible");
return 0;
}
pivot(l,e);
}
for (;;)
{
int e(0),l(0);
for (int i=1;i<=n;++i)
if (a[0][i]>eps)
{
e=i;
break;
}
if (!e)
break;
db mn(1e15);
for (int i=1;i<=m;++i)
if (a[i][e]>eps && a[i][0]/a[i][e]<mn)
l=i,mn=a[i][0]/a[i][e];
if (!l)
{
puts("Unbounded");
return 0;
}
pivot(l,e);
}
printf("%.8lf\n",-a[0][0]);
if (t)
{
for (int i=1;i<=m;++i)
ans[id[n+i]]=a[i][0];
for (int i=1;i<=n;++i)
printf("%.8lf ",ans[i]);
putchar('\n');
}
return 0;
}