Значение переменной равно 1, если оно используется

#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. Это ужасная идея, Она невыпуклая.