使用 doopl 的 opl.set_input() 作为参数的正确方法(不是元组)
Proper way to use opl.set_input() of doopl for parameters (not tuple)
我正在尝试 运行 Python 中的 CPLEX .mod 文件。以下 link:
中有关于如何执行此操作的讲师
How to run a .mod file (CPLEX) using python?
但似乎(也许)只有元组从 Python 发送到 CPLEX。就我而言,CPLEX .mod 文件中有一个循环,如下所示:
for (var i = lowerBound; i <= upperBound; i++) {
...
}
我想将参数 lowerBound 和 upperBound 从 Python 发送到 CPLEX .mod 文件。为此,我在 CPLEX .mod 文件中的 for 循环之前定义了一个变量,如下所示:
var lowerBound = ...;
var upperBound = ...;
然后,我在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()
但是出现如下错误:
ERROR at 17:18 model.mod: Scripting parser error: missing expression.
我想说的是,在 CPLEX 中。mod 第 17 行和第 18 行是:
var lowerBound = ...;
var upperBound = ...;
问题: opl.set_input ()
是否只发送元组?
为了理解这一点,我做了类似以下的事情:
CPLEX 内部。mod:
tuple bounds {
int lowerBound;
int upperBound;
}
for (var i = lowerBound; i <= upperBound; i++) {
...
}
里面 Python:
from doopl.factory import *
Bounds = [
(1, 50),
]
with create_opl_model(model=" model.mod") as opl:
opl.set_input("bounds", Bounds)
opl.run()
但是这次出现了如下错误:
ERROR at 20:7 model.mod: Scripting parser error: missing ';' or newline between statements.
我想说在CPLEX.mod文件中第20行与元组边界的定义有关,即:
tuple bounds {
int lowerBound;
int upperBound;
}
有什么解决办法?
您需要使用元组集,但在
tuple bounds {
int lowerBound;
int upperBound;
}
那不是你做的。
你应该写
tuple typebounds {
int lowerBound;
int upperBound;
}
{typebounds} bounds=...;
在您的 .mod 文件中
让我分享一个完整的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")
和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};
我正在尝试 运行 Python 中的 CPLEX .mod 文件。以下 link:
中有关于如何执行此操作的讲师How to run a .mod file (CPLEX) using python?
但似乎(也许)只有元组从 Python 发送到 CPLEX。就我而言,CPLEX .mod 文件中有一个循环,如下所示:
for (var i = lowerBound; i <= upperBound; i++) {
...
}
我想将参数 lowerBound 和 upperBound 从 Python 发送到 CPLEX .mod 文件。为此,我在 CPLEX .mod 文件中的 for 循环之前定义了一个变量,如下所示:
var lowerBound = ...;
var upperBound = ...;
然后,我在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()
但是出现如下错误:
ERROR at 17:18 model.mod: Scripting parser error: missing expression.
我想说的是,在 CPLEX 中。mod 第 17 行和第 18 行是:
var lowerBound = ...;
var upperBound = ...;
问题: opl.set_input ()
是否只发送元组?
为了理解这一点,我做了类似以下的事情:
CPLEX 内部。mod:
tuple bounds {
int lowerBound;
int upperBound;
}
for (var i = lowerBound; i <= upperBound; i++) {
...
}
里面 Python:
from doopl.factory import *
Bounds = [
(1, 50),
]
with create_opl_model(model=" model.mod") as opl:
opl.set_input("bounds", Bounds)
opl.run()
但是这次出现了如下错误:
ERROR at 20:7 model.mod: Scripting parser error: missing ';' or newline between statements.
我想说在CPLEX.mod文件中第20行与元组边界的定义有关,即:
tuple bounds {
int lowerBound;
int upperBound;
}
有什么解决办法?
您需要使用元组集,但在
tuple bounds {
int lowerBound;
int upperBound;
}
那不是你做的。
你应该写
tuple typebounds {
int lowerBound;
int upperBound;
}
{typebounds} bounds=...;
在您的 .mod 文件中
让我分享一个完整的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")
和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};