Pyomo:从 Python 代码访问解决方案

Posted

技术标签:

【中文标题】Pyomo:从 Python 代码访问解决方案【英文标题】:Pyomo: Access Solution From Python Code 【发布时间】:2016-12-06 14:44:59 【问题描述】:

我有一个想要求解的线性整数程序。我安装了求解器 glpk(感谢this answer)和 pyomo。我写了这样的代码:

from pyomo.environ import *
from pyomo.opt import SolverFactory

a = 370
b = 420
c = 2

model             = ConcreteModel()
model.x           = Var([1,2], domain=NonNegativeIntegers)
model.Objective   = Objective(expr = a * model.x[1] + b * model.x[2], sense=minimize)
model.Constraint1 = Constraint(expr = model.x[1] + model.x[2] == c)
# ... more constraints

opt = SolverFactory('glpk')

results = opt.solve(model)

这会生成文件results.yaml 的解决方案。

我有很多问题想使用相同的模型解决,但使用不同的abc 值。我想为abc分配不同的值,求解模型,获得model.x[1]model.x[2]的解,并列出ab、@987654337 @、model.x[1]model.x[2]。我阅读了documentation,但示例仅将解决方案写入文件,例如results.yaml

有什么方法可以从代码中获取解决方案值?

谢谢,

【问题讨论】:

暂时不要使用这个库。你不能只访问model.x.value吗?还有model.Objective.value。 @sascha,谢谢。我试过for i in model.x: print(model.x[i].value),它成功了。 @sascha,如果你能告诉我为什么我不应该使用这个库,那就太好了。你的意思是WinGLPK,对吧? 我不建议不要使用它。我讨厌这个界面,但是 pyomo 超级强大。没有太多的选择。 [cvxpy](www.cvxpy.org),如果你坚持凸编程(它通过内部推理构建可证明的凸程序是有代价的;它也更基于矩阵/数学运算;它支持许多不错的函数像规范一样的盒子)。还有pulp。我认为这个只做 MIP。它比 pyomo 更基于数组但更容易。 @ken_a 好的,谢谢。我尝试了其他人,但在很多情况下我什至无法安装它们。 Pyomo/WinGLPK 是迄今为止我唯一可以安装并完成工作的库。现在,我坚持下去。 【参考方案1】:

我不确定这是否是您要查找的内容,但这是一种在我的脚本中打印一些变量的方式。

from pyomo.environ import *
from pyomo.opt import SolverFactory
from pyomo.core import Var

M = AbstractModel()
opt = SolverFactory('glpk')

# Vars, Params, Objective, Constraints....

instance = M.create_instance('input.dat') # reading in a datafile
results = opt.solve(instance, tee=True)
results.write()
instance.solutions.load_from(results)

for v in instance.component_objects(Var, active=True):
    print ("Variable",v)
    varobject = getattr(instance, str(v))
    for index in varobject:
        print ("   ",index, varobject[index].value)

【讨论】:

谢谢。我将 for 循环与我的变量一起放入我的代码中,它显示了我想要访问的值! 我很确定这会遍历所有定义的变量...我不知道。几年前,我在翻阅可怜的 Pyomo 文档后发现了它:)【参考方案2】:

这是脚本的修改版本,它说明了打印变量值的两种不同方式:(1) 通过显式引用每个变量和 (2) 通过迭代模型中的所有变量。

# Pyomo v4.4.1
# Python 2.7
from pyomo.environ import *
from pyomo.opt import SolverFactory

a = 370
b = 420
c = 4

model             = ConcreteModel()
model.x           = Var([1,2], domain=Binary)
model.y           = Var([1,2], domain=Binary)
model.Objective   = Objective(expr = a * model.x[1] + b * model.x[2] + (a-b)*model.y[1] + (a+b)*model.y[2], sense=maximize)
model.Constraint1 = Constraint(expr = model.x[1] + model.x[2] + model.y[1] + model.y[2] <= c)

opt = SolverFactory('glpk')

results = opt.solve(model)

#
# Print values for each variable explicitly
#
print("Print values for each variable explicitly")
for i in model.x:
  print str(model.x[i]), model.x[i].value
for i in model.y:
  print str(model.y[i]), model.y[i].value
print("")

#
# Print values for all variables
#
print("Print values for all variables")
for v in model.component_data_objects(Var):
  print str(v), v.value

这是生成的输出:

Print values for each variable explicitly
x[1] 1.0
x[2] 1.0
y[1] 0.0
y[2] 1.0

Print values for all variables
x[1] 1.0
x[2] 1.0
y[1] 0.0
y[2] 1.0

【讨论】:

【参考方案3】:

我在urbs project 中找到了pyomoio 模块。提取集合、参数、变量等,返回到pandas对象中,非常方便在jupyter notebooks中可视化。

我建立了一个简单的模型

model = ConcreteModel()
model.act = Set(initialize=list('IJK'))
model.goods = Set(initialize=list('ijk'))
u0 = 
u0['i', 'J'] = 2.
u0['k', 'I'] = .3
model.U0 = Param(model.goods, model.act, initialize=u0, default=0)

然后我可以在 pandas DataFrame 中读取它,并适当设置所有标签。

import pyomoio as po
u_df = po.get_entity(model, 'U0').unstack()
print(u_df)

# act      I    J    K
# goods               
# i      0.0  2.0  0.0
# j      0.0  0.0  0.0
# k      0.3  0.0  0.0

【讨论】:

以上是关于Pyomo:从 Python 代码访问解决方案的主要内容,如果未能解决你的问题,请参考以下文章

在不使用 for 循环的情况下检索 Pyomo 解决方案

如何在pyomo中访问目标函数值?

使用 Anaconda (Python) 在 Windows 上安装 Pyomo

Pyomo 是不是支持生成多个解决方案?

从 Python PYOMO 使用 GAMS/CPLEX

PYOMO:使用集合和参数定义数据集以解决优化问题