首页 > 解决方案 > 在解决方案池 Cplex 中保留唯一值

问题描述

在我的合并问题中,我使用解决方案池来找到所有可行的非线性解决方案。但是,由于时间段不同,并且可能合并时卡车的容量不受限制,我的输出显示了很多重复。这是我的 .mod 文件:

t sol2 = <total_cost, exp_fixed_cost_total, exp_fixed_cost_g_total, exp_fixed_cost_h_total, exp_cons_cost_total, exp_penalty_cost_total, exp_emission_cost_total, exp_emission_cost_g_total, exp_emission_cost_h_total>; //All costs for each feasible alternative

execute {
writeln("Total cost = ", total_cost);
writeln("Total expected fixed costs = ", exp_fixed_cost_total);
writeln("Total expected fixed non-consolidated costs = ", exp_fixed_cost_g_total);
writeln("Total expected fixed consolidated costs = ", exp_fixed_cost_h_total);
writeln("Total expected consolidation costs = ", exp_cons_cost_total);
writeln("Total expected penalty costs = ", exp_penalty_cost_total);
writeln("Total expected emission costs = ", exp_emission_cost_total);
writeln("Total expected emission non-consolidated costs = ", exp_emission_cost_g_total);
writeln("Total expected emission consolidated costs = ", exp_emission_cost_h_total);
writeln();}  

main {var outputfile=new IloOplOutputFile("sols2.dat");
outputfile.writeln("sols2={");
 
cplex.solnpoolintensity = 3;

thisOplModel.generate();
cplex.solve();
if (cplex.populate()) {
  var nsolns = cplex.solnPoolNsolns;
  
  writeln("Number of solutions found = ", nsolns);
  writeln();
  for (var s=0; s<nsolns; s++) {
    thisOplModel.setPoolSolution(s);
    thisOplModel.postProcess();
    outputfile.writeln(thisOplModel.sol2,",");
    }
}
outputfile.writeln("};");
outputfile.close();

}

.dat 文件中的输出如下所示:(不是每个输出)

<2274 1200 975 225 54 20 1000 850 150>,
<2274 1200 975 225 54 20 1000 850 150>,
<2274 1200 975 225 54 20 1000 850 150>,
<2274 1200 975 225 54 20 1000 850 150>,
......

正如你所看到的,我得到了很多重复。如果我将强度更改为 = 2,我不会生成足够的值。有没有办法指定我只想返回唯一的行,同时保持强度 = 3?我正在考虑更换过滤器,但我很难理解这个命令。我需要将它与解决方案池容量命令结合使用吗?

非常感谢你的帮助!亲切的问候

标签: cplex

解决方案


正如 cplex 文档中所说,

如果您获得的解决方案彼此过于相似,请尝试将 SolnPoolReplace 设置为 2。

您还可以尝试的是:依靠您自己的流量控制而无需解决方案池。

https://github.com/AlexFleischerParis/zooopl/blob/master/zooenumeratewithoutsolutionpool.mod中的示例

int nbiter=5;
range iter=1..nbiter;

int nbKids=300;
float costBus40=500;
float costBus30=400;

dvar int+ nbBus40;
dvar int+ nbBus30;

// Not to get again those previous solutions
dvar int nbBus40prevSol[1..nbiter];
dvar int nbBus30prevSol[1..nbiter];
 
minimize
 costBus40*nbBus40^2  +nbBus30^2*costBus30;
 
subject to
{
 40*nbBus40+nbBus30*30>=nbKids;
 
 forall(i in iter) (nbBus40!=nbBus40prevSol[i]) || (nbBus30!=nbBus30prevSol[i]);
} 

execute
{
  writeln(nbBus40," buses 40 seats and ",nbBus30," buses 30 seats");
  writeln("cost : ",cplex.getObjValue());
}

main
{
  thisOplModel.generate();
  for(var i in thisOplModel.iter)
  {
    cplex.solve();
    thisOplModel.postProcess();
    var sol40=thisOplModel.nbBus40.solutionValue;
    var sol30=thisOplModel.nbBus30.solutionValue;
    thisOplModel.nbBus40prevSol[i].UB=sol40;
    thisOplModel.nbBus40prevSol[i].LB=sol40;
    thisOplModel.nbBus30prevSol[i].UB=sol30;
    thisOplModel.nbBus30prevSol[i].LB=sol30;
    
  }
  
  
  1;
}

/*
which gives
4 buses 40 seats and 5 buses 30 seats
cost : 18000
5 buses 40 seats and 4 buses 30 seats
cost : 18900
3 buses 40 seats and 6 buses 30 seats
cost : 18900
6 buses 40 seats and 2 buses 30 seats
cost : 19600
6 buses 40 seats and 3 buses 30 seats
cost : 21600
*/

推荐阅读