【发布时间】:2021-01-23 18:09:24
【问题描述】:
在我的启发式算法中,我使用不同的数据多次求解模型,每次求解后,我需要向现有模型添加一些新约束并再次求解。我想在 Cplex Script(流控制)中执行此操作。
【问题讨论】:
标签: cplex opl flow-control
在我的启发式算法中,我使用不同的数据多次求解模型,每次求解后,我需要向现有模型添加一些新约束并再次求解。我想在 Cplex Script(流控制)中执行此操作。
【问题讨论】:
标签: cplex opl flow-control
我不确定这是否是最佳方法(但我没有找到更好的方法),但如果您的约束具有已知结构,您可以(在运行时)编辑 .dat 中的一组边界文件并让 CPLEX 从中生成约束。
dvar float k;
{float} bounds = ...; //data.dat: bounds = {4.0};
main {
var model = thisOplModel
model.generate()
cplex.solve()
writeln(cplex.getObjValue())
var model2 = new IloOplModel(model.modelDefinition, cplex)
var data = model.dataElements
data.bounds.add(3.0)
model2.addDataSource(data)
model2.generate()
cplex.solve()
writeln(cplex.getObjValue())
}
maximize k;
subject to {
forall (b in bounds) k <= b;
}
然后是输出
4
3
【讨论】:
/* 很多时候,在求解模型之后,我们需要添加新的变量和约束。我们可以通过编写新模型来做到这一点,但我们也可以渐进式地做到这一点。 假设我们首先需要知道如果我们需要有相同数量的 40 座和 30 座公共汽车,然后在模型中允许 50 座公共汽车会发生什么。 我们可以写 诠释 nbKids=300; 浮动成本Bus40=500; 浮动成本Bus30=400; 浮动成本Bus50=700;
dvar int+ nbBus40;
dvar int+ nbBus30;
dvar int+ nbBus50;
minimize
costBus40*nbBus40 +nbBus30*costBus30+nbBus50*costBus50;
subject to
{
ctKids:40*nbBus40+nbBus30*30+nbBus50*50>=nbKids;
nbBus30==nbBus40;
nbBus50==0;
}
execute DISPLAY_After_SOLVE
{
writeln("The minimum cost is ",costBus40*nbBus40 +nbBus30*costBus30+costBus50*nbBus50);
writeln("We will use ",nbBus40," 40 seats buses ",nbBus30," 30 seats buses and ",
nbBus50," buses 50 seats");
}
which will give
The minimum cost is 4500
We will use 5 40 seats buses 5 30 seats buses and 0 buses 50 seats
and then if we comment
nbBus50==0;
which means we allow 50 seats buses then we ll get
The minimum cost is 4100
We will use 3 40 seats buses 3 30 seats buses and 2 buses 50 seats
But to do that we generate 3 times the matrix which can take time.
We can do that in a main and be incremental. And then we do not generate new matrixes but rely on incremental changes.
The technique is simply to have spare decision variables and constraints:
*/
int nbKids=300;
float costBus40=500;
float costBus30=400;
dvar int+ nbBus40;
dvar int+ nbBus30;
dvar int+ emptyVar;
minimize
costBus40*nbBus40 +nbBus30*costBus30;
subject to
{
ctKids:40*nbBus40+nbBus30*30>=nbKids;
ctEmpty:0<=0;
}
execute DISPLAY_After_SOLVE
{
writeln("The minimum cost is ",costBus40*nbBus40 +nbBus30*costBus30);
writeln("We will use ",nbBus40," 40 seats buses and ",nbBus30," 30 seats buses ");
writeln();
}
main
{
thisOplModel.generate();
writeln("Basic model");
cplex.solve();
thisOplModel.postProcess();
writeln("Let us add a row : saying that nbBus40 and nbBus30 should be equal");
thisOplModel.ctEmpty.setCoef(thisOplModel.nbBus40,1);
thisOplModel.ctEmpty.setCoef(thisOplModel.nbBus30,-1);
thisOplModel.ctEmpty.setBounds(0,0);
cplex.solve();
thisOplModel.postProcess();
writeln("Let us add a column : saying that nbBus50 could also be used and their cost is 700");
cplex.setObjCoef(thisOplModel.emptyVar,700);
thisOplModel.ctKids.setCoef(thisOplModel.emptyVar,50);
cplex.solve();
writeln("The minimum cost is ",
thisOplModel.costBus40*thisOplModel.nbBus40.solutionValue +thisOplModel.nbBus30.solutionValue*thisOplModel.costBus30
+700*thisOplModel.emptyVar.solutionValue);
writeln("We will use ",thisOplModel.nbBus40.solutionValue," 40 seats buses ",thisOplModel.nbBus30.solutionValue,
" 30 seats buses and "+thisOplModel.emptyVar.solutionValue," 50 seats buses");
}
/*
gives
Basic model
The minimum cost is 3800
We will use 6 40 seats buses and 2 30 seats buses
Let us add a row : saying that nbBus40 and nbBus30 should be equal
The minimum cost is 4500
We will use 5 40 seats buses and 5 30 seats buses
Let us add a column : saying that nbBus50 could also be used and their cost is 700
The minimum cost is 4100
We will use 3 40 seats buses 3 30 seats buses and 2 50 seats buses
Of course we get the same results.
*/
来自https://www.linkedin.com/pulse/making-decision-optimization-simple-alex-fleischer/
【讨论】: