7

I have a linear integer programme I want to solve. I installed solver glpk (thanks to this answer) and pyomo. I wrote code like this:

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)

This produces solution to file results.yaml.

I have many problems I want to solve using the same model but with different a, b, and c values. I want to assign different values to a, b, and c, solve the model, obtain solution of model.x[1] and model.x[2], and have a listing of a, b, c, model.x[1] and model.x[2]. I read documentation but examples only write solutions to file such as results.yaml.

Is there any way I can access to solution values from code?

Thanks,

Community
  • 1
  • 1
Ken
  • 157
  • 1
  • 1
  • 6
  • Di not use this lib in a while. Can't you just access model.x.value? And also model.Objective.value. – sascha Aug 01 '16 at 18:43
  • @sascha, thanks. I tried `for i in model.x: print(model.x[i].value)`, and it worked. – Ken Aug 02 '16 at 03:47
  • @sascha, also it would be nice if you tell me why I should not use this lib. You mean [WinGLPK](http://winglpk.sourceforge.net/), right? – Ken Aug 02 '16 at 05:50
  • I did not recommend not using it. I hate the interface, but pyomo is super-powerful. There are not much alternatives. [cvxpy](www.cvxpy.org), if you stick to convex-programming (it constructs provable convex-programs by internal reasoning at a cost; it's also more matrix/math-ops based; it supports many nice functions out of the box like norms). There is also [pulp](https://github.com/coin-or/pulp). This one is doing MIP-only i think. It's more array-based but easier than pyomo. @ken_a – sascha Aug 02 '16 at 10:41
  • Okay, thanks. I tried others but in many cases I could not even install them. Pyomo/WinGLPK is so far the only library that I could install and get my job done. For now, I stick with it. – Ken Aug 02 '16 at 10:48
  • That's ok if it works for you. Pyomo should be very robust and seems to be the one which powers the most *industrial* applications (it's there for some years). It's also the only good one supporting MINLP and co. cvxpy is more modern and research-driven (convex only; not nice to install on Windows). pulp was always easy to install as i recall and it brings a better MIP-solver out of the box (cbc > glpk in my opinion). The only problem of pyomo (besides the interface) is the documentation. cvxpy shines here, while pulp is simple enough (that the docs available are enough). @ken_a – sascha Aug 02 '16 at 10:53
  • And one more remark: if you are working in academics, where the commercial solvers sometimes are free to use: [Gurobi](http://www.gurobi.com/) (and [Mosek](https://www.mosek.com/); no Integer-programming support i think) both bring good python-interfaces (which are still evolving). These are mostly comparable to pulps approach. These should be the most stable and most documented. But, formulated once, only one solver is accepted. @ken_a – sascha Aug 02 '16 at 11:01

3 Answers3

14

Here's a modified version of your script that illustrates two different ways of printing variable values: (1) by explicitly referencing each variable and (2) by iterating over all variables in the model.

# 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

Here's the output generated:

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
Bill Hart
  • 359
  • 2
  • 15
12

I'm not sure if this is what you are looking for, but this is a way that I have some variables being printed in one of my scripts.

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)
OneCricketeer
  • 179,855
  • 19
  • 132
  • 245
0

I found the pyomoio module in the urbs project. It extracts sets, parameters, variables, and so on, and the returns them in pandas objects, which are very convenient for visualization in jupyter notebooks.

I build a simple model

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)

I can then read it in a pandas DataFrame, with all the labels set appropriately.

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
billjoie
  • 808
  • 8
  • 17