可行方法陷入无限循环

时间:2016-11-27 12:16:40

标签: c++ simplex

我运行了以下用C ++编写的单纯形法。代码如下:

#include<bits/stdc++.h>
#include<cstdio>
using namespace std;

#define maxm 500
#define maxn 500
double inf = 1e100;
double eps = 1e-13;

int row,col;
double A[maxm][maxn];
double B[maxn];
///////////////////////////////////////////////////////////////////////////////////////////
// Simon Lo's
// Simplex algorithm on augmented matrix a of dimension (m+1)x(n+1)
// returns 1 if feasible, 0 if not feasible, -1 if unbounded
// returns solution in b[] in original var order, max(f) in ret
// form: maximize sum_j(a_mj*x_j)-a_mn s.t. sum_j(a_ij*x_j)<=a_in
// in standard form.
// To convert into standard form:
// 1. if exists equality constraint, then replace by both >= and <=
// 2. if variable x doesn't have nonnegativity constraint, then replace by
// difference of 2 variables like x1-x2, where x1>=0, x2>=0
// 3. for a>=b constraints, convert to -a<=-b
// note: watch out for -0.0 in the solution, algorithm may cycle
// eps = 1e-7 may give wrong answer, 1e-10 is better



void pivot(int m, int n, double a[maxm][maxn], int B[maxm], int N[maxn], int r, int c) {
        int i, j;
        swap(N[c], B[r]);
        a[r][c]=1/a[r][c];
        for (j=0; j<=n; j++)if (j!=c) a[r][j]*=a[r][c];
        for (i=0; i<=m; i++)if (i!=r) {
                for (j=0; j<=n; j++)if (j!=c)
                        a[i][j]-=a[i][c]*a[r][j];
                a[i][c] = -a[i][c]*a[r][c];
        }
}
int feasible(int m, int n, double a[maxm][maxn], int B[maxm], int N[maxn]) {
        int r, c, i; double p, v;
        while (1) {
                for (p=inf, i=0; i<m; i++) if (a[i][n]<p) p=a[r=i][n];
                if (p>-eps) return 1;
                for (p=0, i=0; i<n; i++) if (a[r][i]<p) p=a[r][c=i];
                if (p>-eps) return 0;
                cout<<"Sultan"<<endl;
                p = a[r][n]/a[r][c];
                for (i=r+1; i<m; i++) if (a[i][c]>eps) {
                        v = a[i][n]/a[i][c];
                        if (v<p) r=i, p=v;
                }
                pivot(m, n, a, B, N, r, c);
        }
}
int simplex(int m, int n, double a[maxm][maxn], double b[maxn], double& ret)
 {
        int B[maxm], N[maxn], r, c, i; double p, v;
        for (i=0; i<n; i++) N[i]=i;
        for (i=0; i<m; i++) B[i]=n+i;
        if (!feasible(m, n, a, B, N)) return 0;
        while (1) {
                for (p=0, i=0; i<n; i++) if (a[m][i]>p)
                        p=a[m][c=i];
                if (p<eps) {
                        for (i=0; i<n; i++) if (N[i]<n)
                                b[N[i]]=0;
                        for (i=0; i<m; i++) if (B[i]<n)
                                b[B[i]]=a[i][n];
                        ret = -a[m][n];
                        return 1;
                }
                for (p=inf, i=0; i<m; i++) if (a[i][c]>eps) {
                        v = a[i][n]/a[i][c];
                        if (v<p) p=v, r=i;
                }
                if (p==inf) return -1;
                pivot(m, n, a, B, N, r, c);
        }
}
//////////////////////////////////////////////////////////////////////////////////////////////

void read_file()
{
    freopen("Dimen.txt","r",stdin);

    scanf("%d",&row);
    scanf("%d",&col);

    row = 30 ;
    col = 100;

    cout << row << " "<<col<<endl;

    freopen("A1.txt","r",stdin);
    for(int i=0;i<row;i++)
       for(int j=0;j<col;j++)
         scanf("%lf",&A[i][j]);
    cout<"Completed A";

    freopen("B1.txt","r",stdin);
    for(int i=0;i<row;i++){
       scanf("%lf",&A[i][col]);
    }
    cout<"Completed B";

    freopen("F1.txt","r",stdin);
    for(int j=0;j<col;j++){
        scanf("%lf",&A[row][j]);
        //B[i]=-B[i];
    }
    cout<"Completed F";


}

int main()
{
    read_file();
    double value,opt=0;
    int flag = simplex(row,col, A,B, value);
    freopen("opt.txt","r",stdin);
    scanf("%lf",&opt);
    if(flag != -1)
    {
        cout<<"The result is "<<(value+opt);
    }
    else
    {
        cout<<"The result is infeasible";
    }

    return 0;
}

但是这段代码在无限循环中运行。可行的方法陷入无限循环。我该如何解决这个错误?请帮我 。

1 个答案:

答案 0 :(得分:1)

让我们从修复代码中不明确的位开始:

#include<bits/stdc++.h>  

您不应该使用以bits/开头的任何包含包含标准标题的包含。

#include<cstdio>
using namespace std;

使用std是不好的做法,它可能会混淆大型项目中的编译器,并选择一个函数/模板/无论您不想要的任何内容。

#define maxm 500
#define maxn 500

至少将这些更改为

#define maxm (500)
#define maxn (500)

所以宏观替代不会混淆。更好地使用c ++ 11并使用

constexpr int maxm = 500; 
constexpr int maxn = 500; 

double inf = 1e100;
double eps = 1e-13;

找到infeps

的正确值有标准方法
double inf = std::numeric_limits<double>::max();

从你的代码我认为你真的意味着max double。 对于eps我想知道你是否需要

double eps = std::numeric_limits<double>::epsilon();

double eps = std::numeric_limits<double>::round_error();