Search code examples
pythonsolverpyomo

Pyomo Model LP file with variable values


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?


Solution

  • 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).