0

Dears,

I have an optimization model that was built using OPL. The model works fine but I would like to use an objective function that is defined in Python. My question is can I use doopl to call the OPL model into python and use the objective function from Python (not from OPL).

Thanks

4

1 回答 1

1

you can do that with docplex.

Let me use the zoo example

In OPL you can write

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");
}

that has no objective and will generate zoo.lp

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

And then in python you can write

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)

that will read the constraint and add a python objective

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

and give

obj :  3800.0
nbBus40  =  6.0
nbBus30  =  2.0

The call to the OPL model can be done from doopl , will generate zoo.lp that will be used by docplex

And the same works with CPOptimizer

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");
} 

generates 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;

And

from docplex.cp.model import 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")

gives

6  buses 40 seats
2  buses 30 seats
于 2021-03-12T12:50:26.933 回答