我目前正在使用 docplex 来优化调度活动。我的目标是尽量减少计划的完成时间和分配的工人数量。为了实现这一目标,我一直在使用
minimize_static_lex
选项,这非常有效。
但是,我遇到了一种情况,当单独优化我的第一个目标(工人数量)时,我立即找到了一个有 2 个工人的解决方案。然而,当我将完工时间合并到词典最小化中时,求解器只能找到 5 个工作人员的解决方案。 10 分钟后,我失去了耐心,因为我知道,仅在最小化工人数量的情况下,10 秒内就能找到解决方案。
我正在使用Python API。除了进行第一次优化然后重新启动第二次优化、添加最多 2 个工作人员的限制之外,我还可以采取其他方法吗?
第二个问题:有没有办法在求解过程中更新约束?我可以分配一个时间段单独优化第一个目标,然后将其修复为约束并优化第二个目标,依此类推。理想情况下,我不想重新生成模型,只需更新约束即可。
使用minimum_static_lex,以下示例可以正常工作
from docplex.cp.model import CpoModel
from docplex.cp.model import CpoParameters
mdl = CpoModel(name='buses')
param=CpoParameters()
param.OptimalityTolerance=0.01
mdl.set_parameters(param)
nbbus50 = mdl.integer_var(0,10,name='nbBus50')
nbbus40 = mdl.integer_var(0,10,name='nbBus40')
nbbus30 = mdl.integer_var(0,10,name='nbBus30')
cost = mdl.integer_var(0,10000,name='cost')
co2emission = mdl.integer_var(0,10000,name='co2emission')
mdl.add(nbbus50*50+nbbus40*40 + nbbus30*30 >= 200)
mdl.add(co2emission==nbbus50*10+nbbus40*11+nbbus30*12)
mdl.add(cost==nbbus40*500 + nbbus30*400+nbbus50*625)
mdl.add(mdl.minimize_static_lex([cost,co2emission]))
msol=mdl.solve()
print(msol[nbbus50]," buses 50 seats")
print(msol[nbbus40]," buses 40 seats")
print(msol[nbbus30]," buses 30 seats")
print(msol[cost])
print(msol[co2emission]/10)
让我通过几个步骤将多目标模型动物园翻译成cpoptimizer
from docplex.cp.model import CpoModel
from docplex.cp.model import CpoParameters
mdl = CpoModel(name='buses')
param=CpoParameters()
param.OptimalityTolerance=0.01
mdl.set_parameters(param)
nbbus50 = mdl.integer_var(0,10,name='nbBus50')
nbbus40 = mdl.integer_var(0,10,name='nbBus40')
nbbus30 = mdl.integer_var(0,10,name='nbBus30')
cost = mdl.integer_var(0,10000,name='cost')
co2emission = mdl.integer_var(0,10000,name='co2emission')
coef = mdl.integer_var(0,1,name='coef')
mdl.add(nbbus50*50+nbbus40*40 + nbbus30*30 >= 200)
mdl.add(co2emission==nbbus50*10+nbbus40*11+nbbus30*12)
mdl.add(cost==nbbus40*500 + nbbus30*400+nbbus50*625)
mdl.minimize(cost+coef*co2emission)
msol=mdl.solve()
print(msol[nbbus50]," buses 50 seats")
print(msol[nbbus40]," buses 40 seats")
print(msol[nbbus30]," buses 30 seats")
print("cost=",msol[cost])
print("co2emission=",msol[co2emission]/10)
print(msol[coef])
#let us not make the cost worse now
mdl.add(cost==msol[cost])
mdl.add(coef==1)
mdl.solve()
print(msol[nbbus50]," buses 50 seats")
print(msol[nbbus40]," buses 40 seats")
print(msol[nbbus30]," buses 30 seats")
print("cost=",msol[cost])
print("co2emission=",msol[co2emission]/10)
注意:
使用 OPL,可以更轻松地使 https://github.com/AlexFleischerParis/zooopl/blob/master/zoomultiobjective.mod 与 CPOptimizer 一起使用
using CP;
int nbKids=200;
float costBus40=500;
float costBus30=400;
float costBus50=625;
dvar int+ nbBus40 in 0..10;
dvar int+ nbBus30 in 0..10;
dvar int+ nbBus50 in 0..10;
dvar int cost;
dvar int co2emission;
minimize
staticLex(cost,co2emission);
subject to
{
cost==costBus40*nbBus40 +nbBus30*costBus30+nbBus50*costBus50;
co2emission==nbBus50*10+nbBus40*11+nbBus30*12;
40*nbBus40+nbBus30*30+nbBus50*50>=nbKids;
}
execute DISPLAY_After_SOLVE
{
writeln("The minimum cost is ",cost);
writeln("CO2 emission is ",co2emission/10);
writeln("We will use ",nbBus40," 40 seats buses ",nbBus30,
" 30 seats buses and ", nbBus50," buses 50 seats");
}