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

Keep unique values in solution pool 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,则不会生成足够的值。有没有办法指定我只想 return 唯一行,同时保持强度 = 3?我在考虑更换过滤器,但我很难理解这个命令。我需要将它与解决方案池容量命令结合使用吗?

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

如 cplex 文档中所述,

If the solutions you obtain are too similar to each other, try setting SolnPoolReplace to 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
*/