1

我正在编写一个 CPLEX 优化代码来生成一个矩阵,该矩阵将 r 和 n 作为命令行参数,但现在可能假定它们为 2 和 4。

生成矩阵的条件是任意行或任意列的元素之和应等于10,其中元素为0到10之间的整数。(即双随机矩阵)

我把这个条件变成了约束,并生成了矩阵,但它只给出了一个有 10 和 0 的矩阵。

我认为这是因为 CPLEX 总是找到“最佳”解决方案,但对于我想要解决的问题,这并没有太大帮助。

我想要剩下的矩阵有 6、7、8、9、10 和 0~5。

我想生成满足这种条件的所有可能的矩阵(以及稍后添加的更多条件),以便我可以测试所有这些矩阵并穷举案例。

我怎样才能做到这一点?

我正在研究这个解决方案池的事情,这并不容易..

还,

cplex.out() << "解决方案数 = " << cplex.getSolnPoolNsolns() << endl;

这给出了 1... 意味着只有一个解决方案,而我知道有数百万个这样的矩阵。

如果您对如何生成所有“次优”矩阵有任何想法,请帮助我。

谢谢你。

我在 IPGenMat.cpp 中附加了我的代码,aa.sol 是它给我的解决方案。

我也在下面复制了它。

(简而言之,有两个问题:1. 我怎样才能找到“不太理想”的解决方案?2. 我怎样才能找到所有这些解决方案?)

#include<ilcplex/ilocplex.h>
#include<vector>
#include<iostream>
#include<sstream>
#include<string>

using namespace std;

int main(int argc, char** argv) {
    if (argc < 2) {
        cerr << "Error: " << endl;
        return 1;
    }
    else {
        int r, n;
        stringstream rValue(argv[1]);
        stringstream nValue(argv[2]);

        rValue >> r;
        nValue >> n;

        int N=n*r;
        int ds = 10; //10 if doubly-stochastic, smaller if sub-doubly stochastic
        IloEnv env;

        try {
            IloModel model(env);

            IloArray<IloNumVarArray> m(env, N);

            for (int i=0; i<N; i++) {
                m[i] = IloNumVarArray(env, N, 0, 10, ILOINT);

            }


            IloArray<IloExpr> sumInRow(env, N);

            for (int i=0; i<N; i++) {
                sumInRow[i] = IloExpr(env);
            }

            for (int i=0; i<N; i++) {
                for (int j=0; j<N; j++) {
                    sumInRow[i] += m[i][j];
                }
            }

            IloArray<IloRange> rowEq(env, N);

            for (int i=0; i<N; i++) {
                rowEq[i] = IloRange(env, ds, sumInRow[i], 10); //doubly stochastic
            }


            IloArray<IloExpr> sumInColumn(env, N);

            for (int i=0; i<N; i++) {
                sumInColumn[i] = IloExpr(env);
            }

            for (int i=0; i<N; i++) {
                for (int j=0; j<N; j++) {
                    sumInColumn[i] += m[j][i];
                }
            }

            IloArray<IloRange> columnEq(env, N);

            for (int i=0; i<N; i++) {
                columnEq[i] = IloRange(env, ds, sumInColumn[i], 10); //doubly stochastic
            }

            for (int i=0; i<N; i++) {
                model.add(rowEq[i]);
                model.add(columnEq[i]);
            }

            IloCplex cplex(env);
            cplex.extract(model);
            cplex.setParam(IloCplex::SolnPoolAGap,0.0);
            cplex.setParam(IloCplex::SolnPoolIntensity,4);
            cplex.setParam(IloCplex::PopulateLim, 2100000000);
            cplex.populate();//.solve();
            cplex.out() << "solution status = " << cplex.getStatus() << endl;
            cplex.out() << "number of solutions = " << cplex.getSolnPoolNsolns() << endl;
            cplex.out() << endl;
            cplex.writeSolutions("aa.sol");

            for (int i = 0; i < N; i++) {
                for (int j = 0; j < N; j++) {
                    cplex.out() << cplex.getValue(m[i][j]) << " | ";
                }
                cplex.out() << endl;
            }
            cplex.out() << endl;

        }

        catch(IloException& e) {
            cerr << " ERROR: " << e << endl;
        }
        catch(...) {
            cerr << " ERROR: " << endl;
        }
        env.end();
        return 0;
    }
} 
4

3 回答 3

2

您可以尝试使用PORTAvint实用程序或PPL来代替。CPLEX 适用于优化问题,而不是枚举问题。

我要补充一点,虽然您的问题是一个很小的优化问题,但它是一个非常大的枚举问题。您可能知道如何处理更多的解决方案。您可以尝试缩小您想要的范围并尝试使用线性不等式来表达它。

于 2013-05-24T17:43:19.103 回答
0

SolnPoolAGap 为解决方案池中的解决方案设置目标值的绝对容差。根据此度量,比现有解决方案的目标更差的解决方案(在最小化的情况下更大,或者在最大化的情况下更小)不会保留在解决方案池中。

因此,要获得次优解决方案,您应该在此参数中设置高于 0.0 的值

于 2015-03-09T19:05:15.507 回答
0

让我们假设您的解决方案是一些带有条目的矩阵m_i_j。用一组二元决策变量来表达您的问题,例如,m_i_j_v意思是“第 i 行第 i 列的矩阵具有值 v”。然后在解决问题后,您可以添加另一个约束,对所有设置的决策变量求和,并强制它们为 N-1。这将排除此作为解决方案。冲洗重复,直到问题变得不可行。

于 2015-12-03T22:49:46.500 回答