Нахождение всех возможных субоптимальных (не оптимальных!!!) решений в оптимизации

Я пишу код оптимизации 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;
    }
} 

person Eric Na    schedule 24.05.2013    source источник


Ответы (3)


Вы можете попробовать использовать утилиту vint PORTA или PPL. CPLEX предназначен для решения задач оптимизации, а не задач перечисления.

Я бы добавил, что, хотя ваша проблема является крошечной проблемой оптимизации, это действительно огромная проблема перечисления. Вероятно, будет гораздо больше решений, с которыми вы будете знать, что делать. Вы можете попытаться сузить то, что вы хотите, и попытаться выразить это с помощью линейного неравенства.

person tmyklebu    schedule 24.05.2013
comment
Я работаю над моделью гуроби на основе Python, у меня есть ограничение a+b+c+d+e‹10 и a,b,c,d,e‹=5, что дает окончательное решение как 5a и 5b. Есть ли способ получить решение, которое дает распределенное/неоптимальное значение? (например, 2а, 3б, 4в, 1г, 2д) - person Akshay Sapra; 02.01.2020

SolnPoolAGap Задает абсолютный допуск целевого значения для решений в пуле решений. Решения, которые хуже (либо лучше в случае минимизации, либо меньше в случае максимизации), чем цель существующего решения в соответствии с этой мерой, не сохраняются в пуле решений.

Таким образом, для получения неоптимальных решений следует установить значение этого параметра выше 0,0.

person pablomadoery    schedule 09.03.2015

Давайте просто предположим, что ваше решение представляет собой некоторую матрицу с элементами m_i_j. Выразите свою проблему в терминах набора бинарных переменных решения, например. m_i_j_v означает, что «матрица в строке i и столбце i имеет значение v». Затем, после того как вы решите проблему, вы можете добавить еще одно ограничение, которое суммирует все установленные переменные решения, и заставить их быть равными N-1. Это исключит это как решение. Промывайте повтор до тех пор, пока проблема не станет неразрешимой.

person Ant6n    schedule 03.12.2015