如何将 CPLEX 中的所有解决方案转换为 MIP
How to get all solutions in CPLEX to a MIP
更新:现在我得到了解决方案的数量,但是当我试图找出它们时,它只给我相同的时间表。我在下面添加了 Alex 建议的代码。例如,它给出了 4 种不同的解决方案,但当我编写 X 矩阵时,它们是相同的。谁能帮我这个?我想要四种不同的解决方案。
我正在为单循环赛制定时间表。
它在 CPLEX 中建模为 MIP,在我的解决方案池中,目前有四个具有相同最佳 objective 值的解决方案。
我想得到这四个解决方案中的每一个,以便可以单独打印和检查它们。这可能吗?
// Create Parameters:
{string} G1 = ...; // Set of teams in first group
{string} G2 = ...; // Set of teams in second group
{string} Teams = G1 union G2;
tuple Match {string team1; string team2;}
{Match} Matches_G1 = {<t1,t2>| ordered t1,t2 in G1};
{Match} Matches_G2 = {<t1,t2>| ordered t1,t2 in G2};
{Match} MD1 = ...;
{Match} MD2 = ...;
{Match} MD3 = ...;
{Match} M = Matches_G1 union Matches_G2; //All matches for the two groups
{Match} matchForTeam[t in Teams] = {m| m in M : m.team1 == t || m.team2 == t}; //List of all teams
{string} S =...; //Set of stadiums
{string} T = ...; //Set of kick off times
{string} D = ...; //Set of kick off days
int K[D][S][T] = ...; //Predetermined schedule between stadium and kickoff time
float VT[M][T] = ...; //Value of match if played on Matchday M at Time T according to TV distribution
// Decision Variables:
dvar int X[M][S][T] in 0..1; // if match M is played at time T
dvar int Dist; //Object function for distribution
//////////// OBJECTIVE FUNCTION ///////////////
maximize
Dist;
//////////// CONSTRAINTS ///////////////
subject to{
Dist == sum(m in M, s in S, t in T) (VT[m][t])*X[m][s][t];
//A match can only be played one time
forall(m in M)
sum(s in S, t in T) X[m][s][t] == 1;
//Simultaneous Kickoff on matchday 3
sum(s in S)X[<"A1", "A4">][s]["22.00"] == sum(s in S)X[<"A2", "A3">][s]["22.00"];
//only one match on possible kick off times at matchday 1
forall(t in T : t != "18.00")
sum(s in S, m in MD1) X[m][s][t]==1;
//only one match on possible kick off times at matchday 2
forall(t in T : t != "18.00")
sum(s in S, m in MD2) X[m][s][t]==1;
//two matches per possible kick off times at matchday 3
forall(t in T : t in {"18.00", "22.00"})
sum(s in S, m in MD3) X[m][s][t]==2;
//One match per stadium on matchday 1
forall(s in S)
sum(m in MD1, t in T: t != "18.00") X[m][s][t] == 1;
//One match per stadium on matchday 2
forall(s in S)
sum(m in MD2, t in T: t != "18.00") X[m][s][t] == 1;
//one match per stadium on matchday 3
forall(s in S)
sum(m in MD3, t in T: t in {"18.00", "22.00"}) X[m][s][t] == 1;
//Each team can play at most two matches per stadium
forall(i in Teams, s in S)
sum(t in T, m in matchForTeam[i]) X[m][s][t] <= 2;
//Each team can play at most two matches per kickoff time
forall(i in Teams, t in T)
sum(s in S, m in matchForTeam[i]) X[m][s][t] <= 2;
forall(s in S, t in T, m in MD1)
X[m][s][t] <= K["1"][s][t];
forall(s in S, t in T, m in MD2)
X[m][s][t] <= K["2"][s][t];
forall(s in S, t in T, m in MD3)
X[m][s][t] <= K["3"][s][t];
}
execute{
writeln("schedule: ", X);
var cd = new IloOplOutputFile("resbi2.txt");
for(var m in M)
for(var s in S)
for(var t in T)
cd.writeln(thisOplModel.X[m][s][t]);
cd.close();
}
main{
cplex.solnpoolintensity=4;
cplex.solnpoolagap=0;
thisOplModel.generate();
cplex.solve();
if (cplex.populate()) {
var nsolns = cplex.solnPoolNsolns;
writeln("number of solutions: ", nsolns);
writeln("average object value: ", cplex.getSolnPoolMeanObjValue());
writeln();
for (var s=0; s<nsolns; s++) {
thisOplModel.setPoolSolution(s);
var cd = new IloOplOutputFile("resAB" +s+".txt");
cd.writeln(thisOplModel.X);
cd.close();
thisOplModel.postProcess();
}
}
}
是的,在脚本中,您可以从解决方案池循环到所有解决方案。
见https://github.com/AlexFleischerParis/zooopl/blob/master/zooseveral.mod
int nbKids=300;
float costBus40=500;
float costBus30=400;
dvar int+ nbBus40;
dvar int+ nbBus30;
//minimize
//costBus40*nbBus40 +nbBus30*costBus30;
subject to
{
40*nbBus40+nbBus30*30>=nbKids;
}
execute
{
writeln("nbBus40 = ",nbBus40," and nbBus30 = ",nbBus30," and the cost is ",costBus40*nbBus40 +nbBus30*costBus30);
}
main {
cplex.solnpoolintensity=4;
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();
}
}
}
更新:现在我得到了解决方案的数量,但是当我试图找出它们时,它只给我相同的时间表。我在下面添加了 Alex 建议的代码。例如,它给出了 4 种不同的解决方案,但当我编写 X 矩阵时,它们是相同的。谁能帮我这个?我想要四种不同的解决方案。
我正在为单循环赛制定时间表。 它在 CPLEX 中建模为 MIP,在我的解决方案池中,目前有四个具有相同最佳 objective 值的解决方案。 我想得到这四个解决方案中的每一个,以便可以单独打印和检查它们。这可能吗?
// Create Parameters:
{string} G1 = ...; // Set of teams in first group
{string} G2 = ...; // Set of teams in second group
{string} Teams = G1 union G2;
tuple Match {string team1; string team2;}
{Match} Matches_G1 = {<t1,t2>| ordered t1,t2 in G1};
{Match} Matches_G2 = {<t1,t2>| ordered t1,t2 in G2};
{Match} MD1 = ...;
{Match} MD2 = ...;
{Match} MD3 = ...;
{Match} M = Matches_G1 union Matches_G2; //All matches for the two groups
{Match} matchForTeam[t in Teams] = {m| m in M : m.team1 == t || m.team2 == t}; //List of all teams
{string} S =...; //Set of stadiums
{string} T = ...; //Set of kick off times
{string} D = ...; //Set of kick off days
int K[D][S][T] = ...; //Predetermined schedule between stadium and kickoff time
float VT[M][T] = ...; //Value of match if played on Matchday M at Time T according to TV distribution
// Decision Variables:
dvar int X[M][S][T] in 0..1; // if match M is played at time T
dvar int Dist; //Object function for distribution
//////////// OBJECTIVE FUNCTION ///////////////
maximize
Dist;
//////////// CONSTRAINTS ///////////////
subject to{
Dist == sum(m in M, s in S, t in T) (VT[m][t])*X[m][s][t];
//A match can only be played one time
forall(m in M)
sum(s in S, t in T) X[m][s][t] == 1;
//Simultaneous Kickoff on matchday 3
sum(s in S)X[<"A1", "A4">][s]["22.00"] == sum(s in S)X[<"A2", "A3">][s]["22.00"];
//only one match on possible kick off times at matchday 1
forall(t in T : t != "18.00")
sum(s in S, m in MD1) X[m][s][t]==1;
//only one match on possible kick off times at matchday 2
forall(t in T : t != "18.00")
sum(s in S, m in MD2) X[m][s][t]==1;
//two matches per possible kick off times at matchday 3
forall(t in T : t in {"18.00", "22.00"})
sum(s in S, m in MD3) X[m][s][t]==2;
//One match per stadium on matchday 1
forall(s in S)
sum(m in MD1, t in T: t != "18.00") X[m][s][t] == 1;
//One match per stadium on matchday 2
forall(s in S)
sum(m in MD2, t in T: t != "18.00") X[m][s][t] == 1;
//one match per stadium on matchday 3
forall(s in S)
sum(m in MD3, t in T: t in {"18.00", "22.00"}) X[m][s][t] == 1;
//Each team can play at most two matches per stadium
forall(i in Teams, s in S)
sum(t in T, m in matchForTeam[i]) X[m][s][t] <= 2;
//Each team can play at most two matches per kickoff time
forall(i in Teams, t in T)
sum(s in S, m in matchForTeam[i]) X[m][s][t] <= 2;
forall(s in S, t in T, m in MD1)
X[m][s][t] <= K["1"][s][t];
forall(s in S, t in T, m in MD2)
X[m][s][t] <= K["2"][s][t];
forall(s in S, t in T, m in MD3)
X[m][s][t] <= K["3"][s][t];
}
execute{
writeln("schedule: ", X);
var cd = new IloOplOutputFile("resbi2.txt");
for(var m in M)
for(var s in S)
for(var t in T)
cd.writeln(thisOplModel.X[m][s][t]);
cd.close();
}
main{
cplex.solnpoolintensity=4;
cplex.solnpoolagap=0;
thisOplModel.generate();
cplex.solve();
if (cplex.populate()) {
var nsolns = cplex.solnPoolNsolns;
writeln("number of solutions: ", nsolns);
writeln("average object value: ", cplex.getSolnPoolMeanObjValue());
writeln();
for (var s=0; s<nsolns; s++) {
thisOplModel.setPoolSolution(s);
var cd = new IloOplOutputFile("resAB" +s+".txt");
cd.writeln(thisOplModel.X);
cd.close();
thisOplModel.postProcess();
}
}
}
是的,在脚本中,您可以从解决方案池循环到所有解决方案。
见https://github.com/AlexFleischerParis/zooopl/blob/master/zooseveral.mod
int nbKids=300;
float costBus40=500;
float costBus30=400;
dvar int+ nbBus40;
dvar int+ nbBus30;
//minimize
//costBus40*nbBus40 +nbBus30*costBus30;
subject to
{
40*nbBus40+nbBus30*30>=nbKids;
}
execute
{
writeln("nbBus40 = ",nbBus40," and nbBus30 = ",nbBus30," and the cost is ",costBus40*nbBus40 +nbBus30*costBus30);
}
main {
cplex.solnpoolintensity=4;
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();
}
}
}