#python #optimization #binary #linear-programming #pyomo
Вопрос:
У меня есть задача оптимизации , которая находит минимальную стоимость суммы capacity[] * weight[]
, написанную с помощью pyomo.
Mid
имеет начальное значение 0,03. North
и South
имеет начальные значения 0.
Mid
, North
, и South
имеют значения спроса 0,01.
Ограничение, позволяющее перемещать начальные значения между узлами ( Mid
, North
, и South
), которое ограничено только пропускной способностью линии.
Я выбрал переменные емкости как двоичные, поэтому, если используется строка(цветные линии на рисунке), то пропускная способность этой строки будет равна 1. И это создает затраты в целевой функции. Если он не используется, то значение емкости этой строки равно 0.
Вопрос: Я хотел бы установить переменные емкости как реальные, а не двоичные файлы, и если они используются, должно быть ограничение pyomo, которое затем уравняет их значения до 1.
Двоичный Случай:
# m.capacity->binary, m.flow->real
# m.flow is transfering the initial values depending on the not capped demand values.
# Lines are represented by the indices of these variables.
# If a flow variable has a value,
# then capacity value equalizes to 1 because of this constraint
def capacity_rule(m, sin, sout, tra):
return m.flow[sin, sout, tra] <= m.capacity[sin, sout, tra]
То, чего я хочу достичь, — это что-то вроде следующего:
# m.capacity->real, m.flow->real
def capacity_rule(m, sin, sout, tra):
return m.flow[sin, sout, tra] <= m.capacity[sin, sout, tra]
def some_rule(m, sin, sout, tra):
if m.capacity has a value other than 0:
return m.capacity[sin, sout, tra] == 1
else:
return m.capacity[sin, sout, tra] == 0
Проблема в том, что я не могу проверить, имеет ли емкость значение, отличное от 0, потому что оно не рассчитывается до выполнения оптимизации. Есть ли какой-нибудь способ?
Основная идея состоит в том, чтобы реализовать ограничение, которое имеет тот же эффект установки переменной емкости, что и двоичный код в pyomo.
Вот LP-файл с системой из 2 узлов: https://justpaste.it/840wq
Это сработало бы, но тогда линейная проблема становится нелинейной. Есть ли альтернатива?:
def capacity_real_rule(m, sin, sout, tra):
return m.capacity[sin, sout, tra] - m.capacity[sin, sout, tra]*m.capacity[sin, sout, tra] == 0
Ответ №1:
Если я правильно это интерпретирую, я бы предложил изменить ситуацию:
if use=0 then flow=0
else flow is unrestricted
Это можно смоделировать следующим образом:
flow <= cap*use
где cap-это просто экзогенная (постоянная), использование-двоичная переменная, а поток-непрерывная переменная (с границами 0 и cap).
Комментарии:
1. Я попытался объяснить этот вопрос здесь math.stackexchange.com/questions/4184983/… , основная проблема в том, что я хочу избавиться от двоичных файлов, сохранив при этом двоичный файл. Поэтому использование двоичного кода не будет работать для меня 🙁
2. Отличная идея. Если это сработает, нам больше не понадобятся решатели MIP.
3. Хорошо 🙂 очень хорошо сказано! Просто вопрос: как вы думаете, если бы я реализовал ограничение
x-x^2=0
вместо того, чтобы выбирать x в качестве двоичного, было бы эффективнее решать qp вместо mip?4. Это ужасная идея, Она невыпуклая.