单纯形法

单纯形法

资料1

资料2

发现自己不会线性规划,学了一下单纯形法,差点猝死

没法完全理解,先背板子。

\(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;
}
posted @ 2021-04-25 21:01  GK0328  阅读(70)  评论(0编辑  收藏  举报