Создание правила (ограничения) типа if..then в Pyomo

Я новичок в Pyomo. Я хочу добавить ограничение типа if..then .. к моей задаче линейного программирования. У меня есть абстрактная модель, и это пример того, что я хотел бы сделать:

если узел j1 получает менее половины своей потребности в воде, минимальный расход в линии между j2 и j1 должен быть установлен на значение потребности в j1 (A и B - переменные модели, d - известный параметр).

if A(j1)<0.5 then B(j2,j1)>=d(j1)

Я пробовал следующее, когда определял ограничения модели. Но поскольку модель еще не создала экземпляр из своего файла данных, она не распознает j1 и j2.

def rule_(model):
    term1=floor(model.A[j1]/0.5)
    return (term1*model.B[j1,j2]>term1*mdoel.demand[j1])
model.rule=Constraint(rule=rule_)

Если я возьму эти строки после создания экземпляра модели с использованием файла данных, я думаю, что ограничение вообще не будет реализовано.

Кто-нибудь может помочь с этим, пожалуйста? Спасибо.


person Majed Khadem    schedule 10.09.2018    source источник


Ответы (1)


Выражения «Если / то» и floor() не являются линейными, поэтому их нельзя вставить непосредственно в линейную программу. Однако вы можете получить тот же эффект, установив двоичный флаг и используя его для активации и деактивации ограничения. Обратите внимание, что двоичные переменные также не являются линейными, но они обычно обрабатываются решателями смешанных целых чисел.

model.flag = Var(within=Binary)
def set_flag_rule(model):
    # force the flag to be set if A[j1] < 0.5
    return ((1 - model.flag) * 0.5 <= model.A[j1])
model.set_flag = Constraint(rule=set_flag_rule)

def rule(model):
    # force B[j1, j2] to meet demand if the flag is set
    return (model.B[j1,j2] >= model.flag * model.demand[j1])
model.rule=Constraint(rule=rule)
person Matthias Fripp    schedule 12.09.2018
comment
Спасибо. Ваш ответ очень помог. Однако я хотел бы отметить, что предложенное вами ограничение для принудительной установки флага не будет работать должным образом. A [j1] находится между 0 и 1, возможно, мне следовало упомянуть об этом в своем вопросе. Я думаю, что лучший способ - установить флаг, используя два ограничения: def set_flag_rule_one (model): return ((1 - model.flag) * 0.5 ›= model.A ['j1'] - 0.5) model.set_flag_one = Constraint ( rule = set_flag_rule_one) def set_flag_rule_two (model): return (-model.flag * 0.5 ‹= model.A ['j1] -10) model.set_flag_two = Ограничение (rule = set_flag_rule_two) - person Majed Khadem; 13.09.2018
comment
Но есть одна проблема. Даже с этими двумя ограничениями (и без использования ограничения «правило») модель дает разные решения по сравнению с тем, когда не было ни одной из этих линий. Почему так происходит ?! - person Majed Khadem; 13.09.2018