Конвертация из AMPL в Pyomo

Я пытаюсь преобразовать модель AMPL в Pyomo (у меня нет опыта использования). Мне сложно адаптировать синтаксис, особенно разделы ограничений и целей. Я уже связал свой компьютер с python, anaconda, Pyomo и GLPK, и мне просто нужно загрузить фактический код. Я начинающий программист, так что простите меня, если мой код написан плохо. Все еще пытаюсь понять это!

Вот данные из кода AMPL:

set PROD := 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30;

set PROD1:= 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30;

ProdCost    414 3   46  519 876 146 827 996 922 308 568 176 58  13  20  974 121 751 130 844 280 123 275 843 717 694 72  413 65  631

HoldingCost 606 308 757 851 148 867 336 44  364 960 69  428 778 485 285 938 980 932 199 175 625 513 536 965 366 950 632 88  698 744

Demand  105 70  135 67  102 25  147 69  23  84  32  41  81  133 180 22  174 80  24  156 28  125 23  137 180 151 39  138 196 69

А вот модель:

set PROD;  # set of production amounts
set PROD1; # set of holding amounts

param ProdCost {PROD} >= 0;     # parameter set of production costs

param Demand {PROD} >= 0;     # parameter set of demand at each time

param HoldingCost {PROD} >= 0;     # parameter set of holding costs

var Inventory {PROD1} >= 0;     # variable that sets inventory amount at each time

var Make {p in PROD} >= 0;  # variable of amount produced at each time

minimize Total_Cost: sum {p in PROD} ((ProdCost[p] * Make[p]) + (Inventory[p] * HoldingCost[p]));

               # Objective: minimize total cost from all production and holding cost

subject to InventoryConstraint {p in PROD}: Inventory[p] = Inventory[p-1] + Make[p] - Demand[p];

                # excess production transfers to inventory

subject to MeetDemandConstraint {p in PROD}: Make[p] >= Demand[p] - Inventory[p-1];

               # Constraint: holding and production must exceed demand

subject to InitialInventoryConstraint: Inventory[0] = 0;

                # Constraint: Inventory must start at 0

Вот что у меня есть на данный момент. Не уверен, правильно это или нет:

from pyomo.environ import *

demand=[105,70,135,67,102,25,147,69,23,84,32,41,81,133,180,22,174,80,24,156,28,125,23,137,180,151,39,138,196,69]

holdingcost=[606,308,757,851,148,867,336,44,364,960,69,428,778,485,285,938,980,932,199,175,625,513,536,965,366,950,632,88,698,744]

productioncost=[414,3,46,519,876,146,827,996,922,308,568,176,58,13,20,974,121,751,130,844,280,123,275,843,717,694,72,413,65,631]

model=ConcreteModel()

model.I=RangeSet(1,30)
model.J=RangeSet(0,30)
model.x=Var(model.I, within=NonNegativeIntegers)
model.y=Var(model.J, within=NonNegativeIntegers)

model.obj = Objective(expr = sum(model.x[i]*productioncost[i]+model.y[i]*holdingcost[i] for i in model.I))

def InventoryConstraint(model, i):
    return model.y[i-1] + model.x[i] - demand[i] <= model.y[i]
InvCont = Constraint(model, rule=InventoryConstraint)

def MeetDemandConstraint(model, i):
    return model.x[i] >= demand[i] - model.y[i-1]
DemCont = Constraint(model, rule=MeetDemandConstraint)

def Initial(model):
    return model.y[0] == 0
model.Init = Constraint(rule=Initial)

opt = SolverFactory('glpk')
results = opt.solve(model,load_solutions=True)
model.solutions.store_to(results)
results.write()

Спасибо!


person Community    schedule 04.03.2019    source источник


Ответы (1)


Единственные проблемы, которые я вижу, связаны с некоторыми вашими объявлениями ограничений. Вам нужно прикрепить ограничения к модели, и первым переданным аргументом должен быть набор индексации (который, как я предполагаю, должен быть model.I).

def InventoryConstraint(model, i):
    return model.y[i-1] + model.x[i] - demand[i] <= model.y[i]
model.InvCont = Constraint(model.I, rule=InventoryConstraint)

def MeetDemandConstraint(model, i):
    return model.x[i] >= demand[i] - model.y[i-1]
model.DemCont = Constraint(model.I, rule=MeetDemandConstraint)

Синтаксис, который вы используете для решения модели, немного устарел, но должен работать. Другой вариант:

opt = SolverFactory('glpk')
opt.solve(model,tee=True) # The 'tee' option prints the solver output to the screen
model.display() # This will print a summary of the model solution

Другая команда, полезная для отладки, - model.pprint(). Это отобразит всю модель, включая выражения для ограничений и целей.

person Bethany Nicholson    schedule 05.03.2019
comment
Спасибо! Теперь, когда я запускаю код, я получаю эту ошибку: SolverFactory не удалось создать solver = glpk и вернул неизвестный объект решения. Есть какие-нибудь советы, как это исправить? Спасибо! - person ; 07.03.2019
comment
Похоже, исполняемый файл glpk может оказаться не на вашем пути. Вы должны иметь возможность открыть командную строку Anaconda и запустить командуglpsol -h и увидеть список параметров glpk. - person Bethany Nicholson; 07.03.2019
comment
У меня все еще та же проблема. Я не мог понять, как решить проблему из командной строки Anaconda, как вы предложили. Есть ли более простые решатели, чем glpk? Для моего проекта мне просто нужно запустить любой решатель с моим lp файлом в pyomo. Спасибо! - person ; 07.03.2019
comment
Успешно ли выполнилась предыдущая команда, которую я предложил? glpk - самый простой в использовании решатель, поскольку его можно установить через Anaconda. Вы использовали команду conda install -c conda-forge glpk для его первоначальной установки? - person Bethany Nicholson; 08.03.2019
comment
Мне удалось заставить его работать с помощью вашей команды установщика glpk! Должно быть, я раньше неправильно его установил. После этой команды мне просто нужно было исправить несколько ошибок в списке, но теперь это работает. Огромное спасибо! - person ; 08.04.2019