У меня есть переменная t, и я хотел бы иметь следующие ограничения:
a <= t <= b
and
(c <= t <= d) or (e <= t <= f)
Вот код, который я использовал в Джулии:
using JuMP, Cbc, StatsBase
import Random
model = Model(with_optimizer(Cbc.Optimizer));
@variable(model, T, Int);
@constraint(model, 5 <= T <= 1000);
@constraint(model, (100 <= T <= 200) | (1100 <= T <= 1300) );
# which fails with error:
# ERROR: LoadError: In `@constraint(model, (100 <= T[i] <= 200) | (1100 <= T[i] <= 1300))`: Unrecognized sense |
Есть ли способ линеаризовать эти ограничения? Или, в качестве альтернативы, существует ли нелинейный решатель, который может справиться с этими ограничениями?
Особый случай:
5 ≤ T ≤ 1000
and
(100 ≤ T ≤ 200) or (1100 ≤ T ≤ 1300)
легко. Результат просто:
100 ≤ T ≤ 200
В целом:
a ≤ t ≤ b
and
(c ≤ t ≤ d) or (e ≤ t ≤ f)
(где a,b,c,d,e,f — константы) можно линеаризовать с помощью двоичных переменных:
a ≤ t ≤ b
c + (a-c)δ ≤ t ≤ d + (b-d)δ
e + (a-e)(1-δ) ≤ t ≤ f + (b-f)(1-δ)
δ ∈ {0,1}
Теперь бонусный вопрос: как сделать
a ≤ t ≤ b
and
(c ≤ t ≤ d) or (e ≤ t ≤ f) or (g ≤ t ≤ h)
Опять же, единственная переменная здесь — t
. Все остальные величины являются постоянными. Ниже приведено прямое продолжение того, что мы делали раньше:
a ≤ t ≤ b
c + (a-c)δ1 ≤ t ≤ d + (b-d)δ1
e + (a-e)δ2 ≤ t ≤ f + (b-f)δ2
g + (a-g)δ3 ≤ t ≤ h + (b-h)δ3
δ1+δ2+δ3 = 2
δ1,δ2,δ3 ∈ {0,1}
@tucson Почти то же самое. Я добавил это к ответу.
Отличный материал. Спасибо.
Хорошо, спасибо. Что делать, если у меня есть несколько диапазонов для вторых условий, например: (c <= t <= d) или (e <= t <= f) или (g <= t <= h) и т. д. Есть ли способ сгенерировать эквивалентные линейные ограничения?