I'm trying to run the CPLEX .mod file within Python. An instructor on how to do this exists in the following link:
How to run a .mod file (CPLEX) using python?
But it seems that (maybe) only the tuple is sent from Python into CPLEX. In my case, there is a loop in the CPLEX .mod file like the following:
for (var i = lowerBound; i <= upperBound; i++) {
...
}
I want to send parameters lowerBound and upperBound from Python to CPLEX .mod file. For this aim, I define a variable inside the CPLEX .mod file, before the for loop, as follows:
var lowerBound = ...;
var upperBound = ...;
Then, I use the following command in Python:
from doopl.factory import *
with create_opl_model(model="model.mod") as opl:
opl.set_input("upperBound", 50)
opl.set_input("lowerBound", 1)
opl.run()
but the following error comes out:
ERROR at 17:18 model.mod: Scripting parser error: missing expression.
I would like to say that in the CPLEX .mod lines 17 and 18 are:
var lowerBound = ...;
var upperBound = ...;
Question: I wonder if only tuples are sent with opl.set_input ()
?
To understand this, I did something like the followings:
Inside CPLEX .mod:
tuple bounds {
int lowerBound;
int upperBound;
}
for (var i = lowerBound; i <= upperBound; i++) {
...
}
Inside Python:
from doopl.factory import *
Bounds = [
(1, 50),
]
with create_opl_model(model=" model.mod") as opl:
opl.set_input("bounds", Bounds)
opl.run()
But this time, there is an error like the following:
ERROR at 20:7 model.mod: Scripting parser error: missing ';' or newline between statements.
I would like to say that in the CPLEX .mod file line 20 is related to the definition of tuple bounds, which is:
tuple bounds {
int lowerBound;
int upperBound;
}
What could be the solution to this?
you need to use tuple sets but in
tuple bounds {
int lowerBound;
int upperBound;
}
that s not what you do.
You should write
tuple typebounds {
int lowerBound;
int upperBound;
}
{typebounds} bounds=...;
in your .mod file
Let me share a full example:
from doopl.factory import *
# Data
Buses=[
(40,500),
(30,400)
]
MinAndMax=[(1,5)]
# Create an OPL model from a .mod file
with create_opl_model(model="zootuplesetwithminandmax.mod") as opl:
# tuple can be a list of tuples, a pandas dataframe...
opl.set_input("buses", Buses)
opl.set_input("singletonMinAndMax", MinAndMax)
# Generate the problem and solve it.
opl.run()
# Get the names of post processing tables
print("Table names are: "+ str(opl.output_table_names))
# Get all the post processing tables as dataframes.
for name, table in iteritems(opl.report):
print("Table : " + name)
for t in table.itertuples(index=False):
print(t)
# nicer display
for t in table.itertuples(index=False):
print(t[0]," buses ",t[1], "seats")
with zootuplesetwithminandmax.mod
int nbKids=300;
// a tuple is like a struct in C, a class in C++ or a record in Pascal
tuple bus
{
key int nbSeats;
float cost;
}
// This is a tuple set
{bus} buses=...;
tuple minandmax
{
int m;
int M;
}
{minandmax} singletonMinAndMax=...;
int minBuses=first(singletonMinAndMax).m;
int maxBuses=first(singletonMinAndMax).M;
// asserts help make sure data is fine
assert forall(b in buses) b.nbSeats>0;
assert forall(b in buses) b.cost>0;
// decision variable array
dvar int+ nbBus[buses] in minBuses..maxBuses;
// objective
minimize
sum(b in buses) b.cost*nbBus[b];
// constraints
subject to
{
sum(b in buses) b.nbSeats*nbBus[b]>=nbKids;
}
tuple solution
{
int nbBus;
int sizeBus;
}
{solution} solutions={<nbBus[b],b.nbSeats> | b in buses};