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