如何在Python中定义objective函数的同时通过doopl调用OPL?

How to call OPL by doopl while defining the objective function in Python?

亲爱的,

我有一个使用 OPL 构建的优化模型。该模型工作正常,但我想使用 Python 中定义的 objective 函数。我的问题是我可以使用 doopl 将 OPL 模型调用到 python 并使用来自 Python(不是来自 OPL)的 objective 函数。

谢谢

你可以用 docplex 做到这一点。

让我用zoo example

在 OPL 中你可以写

int nbKids=300;
float costBus40=500;
float costBus30=400;
 
dvar int+ nbBus40;
dvar int+ nbBus30;
 

 
subject to
{
 40*nbBus40+nbBus30*30>=nbKids;
} 

main
{
  thisOplModel.generate();
  cplex.exportModel("zoo.lp");
}

没有 objective 并且会生成 zoo.lp

Minimize
 obj1:
Subject To
 c1: 40 nbBus40 + 30 nbBus30 >= 300
Bounds
      nbBus40 >= 0
      nbBus30 >= 0
Generals
 nbBus40  nbBus30 
End

然后在python中你可以写

from docplex.mp.model import Model
from docplex.mp.model_reader import ModelReader


mdl = ModelReader.read_model('zoo.lp', model_name='zoo')

for v in mdl.iter_integer_vars():
    print(v)

nbbus40 = mdl.find_matching_vars('nbBus40')[0]
nbbus30 = mdl.find_matching_vars('nbBus30')[0]

print(nbbus40)


mdl.minimize(nbbus40*500 + nbbus30*400)

mdl.solve(log_output=True,)

print("solution is empty : ",mdl.solution.is_empty())

print("obj : ",mdl.solution.get_objective_value())

for v in mdl.iter_integer_vars():
    print(v," = ",v.solution_value)

这将读取约束并添加一个 python objective

mdl.minimize(nbbus40*500 + nbbus30*400)

并给予

obj :  3800.0
nbBus40  =  6.0
nbBus30  =  2.0

可以从 doopl 调用 OPL 模型,将生成将由 docplex

使用的 zoo.lp

同样适用于 COPtimizer

using CP;

int nbKids=300;
float costBus40=500;
float costBus30=400;
 
dvar int+ nbBus40;
dvar int+ nbBus30;
 

 
subject to
{
 40*nbBus40+nbBus30*30>=nbKids;
} 

main
{
  thisOplModel.generate();
  cp.exportModel("zoo.cpo");
} 

生成zoo.cpo

// --------------------------------------------------------------------------
// IBM ILOG CP Optimizer model export file
// Effective workers: 12
// --------------------------------------------------------------------------

// ------ Integer variables: ------------------------------------------------

nbBus40 = intVar(0..intmax);
nbBus30 = intVar(0..intmax);

// ------ Constraints: ------------------------------------------------------

40*nbBus40 + 30*nbBus30 >= 300;

从 docplex.cp.model 导入 CpoModel

mdl = CpoModel(name='buses')

mdl.import_model("zoo.cpo")

vars=mdl.get_all_variables()

for i in vars:
    print(i.name)
    if (i.name=="nbBus40"):
        nbbus40=i
    if (i.name=="nbBus30"):
        nbbus30=i    

mdl.minimize(nbbus40*500 + nbbus30*400)

msol=mdl.solve()

print(msol[nbbus40]," buses 40 seats")
print(msol[nbbus30]," buses 30 seats")

给予

6  buses 40 seats
2  buses 30 seats