-1

I've build a pyomo model, and via following I am writing the lp file of the model:

# write LP file
filename = os.path.join(os.path.dirname(__file__), 'model.lp')
model.write(filename, io_options={'symbolic_solver_labels': True})

I am getting the model.lp file in the folder. And it looks like following:

\* Source Pyomo model name=urbs *\

min 
obj:
+1 costs(Environmental)
+1 costs(Fixed)
+1 costs(Fuel)
+1 costs(Invest)
+1 costs(Variable)

s.t.

c_e_res_vertex(1_Mid_Biomass_Stock)_:
+1 e_co_stock(1_Mid_Biomass_Stock)
-1 e_pro_in(1_Mid_Biomass_plant_Biomass)
= 0

c_e_res_vertex(1_Mid_Coal_Stock)_:
+1 e_co_stock(1_Mid_Coal_Stock)
-1 e_pro_in(1_Mid_Coal_plant_Coal)
= 0

My problem is, I would like to also save the variable values of the model.

Is there a way to force solver to write values of the variables of the model into the lp file?

or something, which does the same thing with different manner?

oakca
  • 1,408
  • 1
  • 18
  • 40
  • Adding values to an LP file would make it no longer an LP file and solvers could not consume it. – Erwin Kalvelagen Jan 24 '19 at 11:51
  • well okay, lets call it a notLP file but something else. I just wanna know is something like that possible? – oakca Jan 24 '19 at 13:29
  • 1
    Well, maybe it is not the answer you are looking for sorry for that, but there are many long ways of doing this. Can you provide an example of the output you want to obtain? Do you want it written clearly (easily readable by human), or it has to strictly follow the LP file format (but with variable values instead of variable names)? – V. Brunelle Jan 24 '19 at 16:13
  • @V.Brunelle "Do you want it written clearly", well for that you can always do `variable_name.pprint()`, it would be best "but with variable values instead of variable names" – oakca Jan 25 '19 at 09:45
  • Pleas look here https://stackoverflow.com/questions/38700214/pyomo-access-solution-from-python-code. – kur ag Jan 25 '19 at 11:15
  • Ok. And is writing the expressions of constraints and objective function such as "3*4+2*5+1*8" is ok? It is not on the LP file format, but could be an easy avenue for you. – V. Brunelle Jan 25 '19 at 14:40
  • @V.Brunelle following way would be better `'3 4 + 2 5 + 1 8'`, but yours is also okay. (coefvariablevalue + coefvarvalue), I just need to be able to recognize constraints, coefficients and values, then all kind of format would be good – oakca Jan 25 '19 at 14:53

1 Answers1

1

Two ways comes to my mind.

Good old search and replace

With your LP file, do a search and replace. For example, the variable x with indices 2 and 'productA' (in Pyomo: model.x[2,'productA']) is written in the LP file as x(2_productA). Knowing this, for each variable and for each of their indices, generate their name in the LP format, and search all occurences of these in the LP file, to replace them with their value.

If lpFileContent is the string that is contained in your LP file, this will look like:

for v in model.component_objects(Var, active=True):
    varName = str(v)
    varObject = getattr(model, varName)
    for index in varObject:
        indexStr = str(index)
        # Convert your index string:
        indexStr.replace(",","_")
        indexStr.replace(" ","_")
        indexStr.replace("'","") # Add more as you need.  
        #Replace by value:
        lpFileContent.replace(varName + "(" + indexStr + ")", varObject[index].value)
with open("output.txt", "w") as outputFile
    outputFile.write(lpFileContent)

Using exressions

When defining constraints, it is comon to do it this way (from Pyomo doc):

model.A = RangeSet(1,10)
model.a = Param(model.A, within=PositiveReals)
model.ToBuy = Var(model.A)
def bud_rule(model, i):
    return model.a[i]*model.ToBuy[i] <= i
aBudget = Constraint(model.A, rule=bud_rule)

Then, it is always possible to retrieve the expression of this constraint by doing this little trick:

model.A = RangeSet(1,10)
model.a = Param(model.A, within=PositiveReals)
model.ToBuy = Var(model.A)
def bud_rule(model, i):
    print(str(model.a[i]*model.ToBuy[i]) + " <= " + str(i))
    return model.a[i]*model.ToBuy[i] <= i
aBudget = Constraint(model.A, rule=bud_rule)

which will yield something like

1 * model.ToBuy[1] <= 1
2 * model.ToBuy[2] <= 2
3 * model.ToBuy[3] <= 3
4 * model.ToBuy[4] <= 4
... #It goes on
10 * model.ToBuy[10] <= 10

I believe that this is also something you can use (with search and replace or by printing variable values while building your constraints again but after solving). It grants more ability to customize your output, is easy to debug, but will be extremely slow if the expression is long (like with a summation on thousands of elements).

V. Brunelle
  • 1,038
  • 11
  • 29
  • It might work, I am not sure if the code works. However, since u spent time on it, I am going to accept it as answer :) ty! – oakca Jan 31 '19 at 17:30
  • Thanks for letting me know if this answer needs improvements, if you do find the time to add this in your code. – V. Brunelle Jan 31 '19 at 17:40