我正在编写一个CPLEX优化代码来生成一个矩阵,它将r和n作为命令行参数,但现在它们可以假定为2和4。
生成矩阵的条件是任何行或任何列中的元素总和应等于10,其中元素是0到10之间的整数。(即双随机矩阵)
我把这个条件变成了约束,并生成了矩阵,但它只给出了一个10s和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;
}
}
答案 0 :(得分:2)
您可以尝试使用PORTA的vint
实用程序或PPL。 CPLEX适用于优化问题,而不是枚举问题。
我补充说,虽然你的问题是一个很小的优化问题,但这是一个非常庞大的枚举问题。可能会有更多解决方案,您知道如何处理。您可以尝试缩小您想要的范围并尝试使用线性不等式来表达它。
答案 1 :(得分:0)
SolnPoolAGap设置解决方案池中解决方案的目标值的绝对容差。更糟糕的解决方案(在最小化的情况下更大,或在最大化的情况下更少)比根据此措施的现有解决方案的目标更难保留在解决方案池中。
因此,要获得次优解,您应该设置一个高于0.0的值 在此参数中
答案 2 :(得分:0)
让我们假设你的解决方案是一些带有条目m_i_j
的矩阵。根据一组二元决策变量表达您的问题,例如: m_i_j_v
含义&#34;第i行和第i列的矩阵具有值v&#34;。然后在解决问题之后,可以添加另一个约束,该约束对所有设置的决策变量求和,并强制它们为N-1。这将排除此作为解决方案。冲洗重复,直到问题变得不可行。