Как реализовать ограничение логического ИЛИ в CPLEX Python - PullRequest
0 голосов
/ 21 июня 2019

Как я могу реализовать ограничение типа x [0,0] == 0 ИЛИ x [0,0]> = 2 в CPLEX Python MP?

Похоже на работу для полуинтегратора, но semiinteger_var_matrix ()недоступно в версии CPLEX Python, которую я использую в среде Watson Studio DO.Я мог бы использовать semiinteger_var_list (), который доступен, но хотел бы сделать это с помощью логического ограничения ИЛИ, чтобы научить себя.Я пробовал x [0,0]! = 1, но MP не обрабатывает NE.Поэтому я решил, что смогу сделать это с помощью логического ограничения ИЛИ, показанного выше.Посмотрел документ и источник docplex.mp.model, но пока не могу понять, как это сделать.Я на начальной стадии изучения CPLEX Python.

Ответы [ 3 ]

1 голос
/ 22 июня 2019

Позвольте привести небольшой пример из истории с автобусом:

from docplex.mp.model import Model

mdl = Model(name='buses')
nbbus40 = mdl.integer_var(name='nbBus40')
nbbus30 = mdl.integer_var(name='nbBus30')
mdl.add_constraint(nbbus40*40 + nbbus30*30 >= 300, 'kids')
mdl.minimize(nbbus40*500 + nbbus30*400)

mdl.solve()

for v in mdl.iter_integer_vars():
   print(v," = ",v.solution_value)

print()
print("with nb buses 40 less than 3 or more than 7")



mdl.add((nbbus40<=3) + (nbbus40>=7) >=1)


mdl.minimize(nbbus40*500 + nbbus30*400)

mdl.solve()

for v in mdl.iter_integer_vars():
    print(v," = ",v.solution_value)

, который дает

nbBus40  =  6.0
nbBus30  =  2.0

with nb buses 40 less than 3 or more than 7
nbBus40  =  7.0
nbBus30  =  1.0

Примечание: вы также можете написать

from docplex.mp.model import Model

mdl = Model(name='buses')
nbbus40 = mdl.integer_var(name='nbBus40')
nbbus30 = mdl.integer_var(name='nbBus30')
mdl.add_constraint(nbbus40*40 + nbbus30*30 >= 300, 'kids')
mdl.minimize(nbbus40*500 + nbbus30*400)

mdl.solve()

for v in mdl.iter_integer_vars():
   print(v," = ",v.solution_value)

print()
print("with nb buses 40 less than 3 or more than 7")

option1=mdl.binary_var(name='option1')
option2=mdl.binary_var(name='option2')

mdl.add(option1==(nbbus40<=3))
mdl.add(option2==(nbbus40>=7))

mdl.add(1==mdl.logical_or(option1,option2))

mdl.minimize(nbbus40*500 + nbbus30*400)

mdl.solve()

for v in mdl.iter_integer_vars():
    print(v," = ",v.solution_value)

Много других крошечных примеров Python в docplex на https://www.linkedin.com/pulse/making-optimization-simple-python-alex-fleischer/

1 голос
/ 24 июня 2019

Правда, semiinteger_matrix не существует.Но semiinteger_dict делает.Таким образом, вы можете сделать что-то вроде

x = model.semiinteger_var_dict((i, j) for i in range(I) for j in range(J))

и после этого вы можете ссылаться на переменные как x[0,0] и т. Д.

0 голосов
/ 21 июня 2019

Классическая формулировка, предполагающая также верхнюю границу u выглядит следующим образом:

introduce fresh binary variable b

post

x <= u * b
x >= l * b

В вашем случае l=2.

Значение u зависит от проблемыи важно сделать его как можно меньше для лучшего расслабления.(вводное сообщение в блоге по теме)

...