具有变量值的 Pyomo 模型 LP 文件

Pyomo Model LP file with variable values

我已经建立了一个pyomo模型,通过以下我正在编写模型的lp文件:

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

我正在文件夹中获取 model.lp 文件。它看起来像下面这样:

\* 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

我的问题是,我还想保存模型的变量值。

有没有办法强制求解器将模型变量的值写入lp文件?

或者什么东西,用不同的方式做同样的事情?

我想到了两种方法。

很好的旧搜索和替换

使用您的 LP 文件,进行搜索和替换。例如,索引为 2'productA' 的变量 x(在 Pyomo 中:model.x[2,'productA'])在 LP 文件中写为 x(2_productA)。知道这一点后,对于每个变量及其每个索引,以 LP 格式生成它们的名称,并在 LP 文件中搜索所有出现的这些名称,以将它们替换为它们的值。

如果 lpFileContent 是包含在您的 LP 文件中的字符串,这将类似于:

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)

使用表达式

定义约束时,通常采用这种方式(来自 Pyomo 文档):

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)

然后,通过这个小技巧总是可以检索到这个约束的表达式:

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)

这将产生类似

的结果
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

我相信这也是您可以使用的东西(通过搜索和替换或通过在再次构建约束但在求解之后打印变量值)。它赋予了更多自定义输出的能力,易于调试,但如果表达式很长(比如对数千个元素求和),速度会非常慢。