1

コマンド ライン引数として r と n を取る行列を生成する CPLEX 最適化コードを作成していますが、現時点では 2 と 4 を想定している可能性があります。

行列を生成するための条件は、任意の行または任意の列の要素の合計が 10 に等しく、要素が 0 ~ 10 の整数であることです (つまり、二重確率行列)。

この条件を制約に変えて行列を生成しましたが、10 と 0 の行列しか得られません。

CPLEXは常に「最適な」解決策を見つけるからだと思いますが、解決したい問題については、これはあまり役に立ちません。

残りは 6、7、8、9、10、0 ~ 5 の行列が必要です。

そのような条件 (および後で追加される条件) を満たすすべての可能な行列を生成して、それらすべてをテストし、ケースを使い果たすことができるようにしたいと考えています。

どうやってやるの?

このソリューション プールのことを調べていますが、簡単ではありません..

また、

cplex.out() << "解の数 = " << cplex.getSolnPoolNsolns() << endl;

これにより 1... が得られます。これは、解が 1 つしかないことを意味しますが、これらの行列が何百万もあることがわかっています。

すべての「最適ではない」行列を生成する方法があれば、助けてください。

ありがとうございました。

コードを IPGenMat.cpp に添付すると、aa.sol が解決策になりました。

こちらも下にコピペしました。

(要するに、2 つの質問: 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

0

SolnPoolAGap ソリューション プール内のソリューションの目標値に絶対許容誤差を設定します。この尺度に従って現在のソリューションの目標よりも悪い (最小化の場合は大きい、または最大化の場合は小さい) ソリューションは、ソリューション プールに保持されません。

したがって、次善のソリューションを取得するには、このパラメーターに 0.0 よりも高い値を設定する必要があります。

于 2015-03-09T19:05:15.507 に答える