Файл LP Pyomo Model со значениями переменных - PullRequest
0 голосов
/ 22 января 2019

Я построил модель 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

Моя проблема в том, что я хотел бы также сохранить значения переменных модели.

Есть ли способ заставить solver записывать значения переменных модели в файл lp?

или что-то, что делает то же самое по-разному?

1 Ответ

0 голосов
/ 30 января 2019

Два способа приходит на ум.

Старый добрый поиск и замена

С вашим файлом LP выполните поиск и замену. Например, переменная x с индексами 2 и 'productA' (в 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 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)

Затем всегда можно получить выражение этого ограничения, выполнив этот маленький трюк:

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

Я считаю, что это также то, что вы можете использовать (с поиском и заменой или путем печати значений переменных при повторном построении ограничений, но после решения). Он предоставляет больше возможностей для настройки выходных данных, его легко отлаживать, но он будет очень медленным, если выражение длинное (как при суммировании по тысячам элементов).

...