#python #or-tools #cp-sat-solver
Вопрос:
Например, у меня есть список номеров ниже. И ограничение заключается в том, что разрыв между двумя соседними числами должен быть как положительным, так и отрицательным, или одним из двух чисел, равным нулю, то есть один положительный и один отрицательный(например, 3 и -1) недопустимы.
Номера списков: [15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 18, 17, 20, 19, 22, 25, 25, 25, 25, 25, 25, 25, 25, 22, 20, 23, 22, 21, 18, 15, 15, 15, 15, 15, 15, 15, 18, 21, 24, 24, 24, 27, 30]
Разрыв в цифрах: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, -1, 3, -1, 3, 3, 0, 0, 0, 0, 0, 0, 0, -3, -2, 3, -1, -1, -3, -3, 0, 0, 0, 0, 0, 0, 3, 3, 3, 0, 0, 3, 3]
Поэтому я стараюсь использовать AddMultiplicationEquality
, чтобы добавить ограничение
target=model.NewIntVar(-999999,999999,'target_%s_%s'%(i, i 1))
model.AddMultiplicationEquality(target, [gap[i],gap[i 1]])
model.Add(target>=0)
Но я получил результат ниже. Как я могу это решить? Заранее спасибо.
Not supported
*** Check failure stack trace: ***
@ 0x10956c8ed google::LogMessage::Fail()
@ 0x10956b29e google::LogMessage::SendToLog()
@ 0x10956bebf google::LogMessage::Flush()
@ 0x109570c19 google::LogMessageFatal::~LogMessageFatal()
@ 0x10956cf55 google::LogMessageFatal::~LogMessageFatal()
@ 0x10a7948e4 _ZZN19operations_research3sat17ProductConstraintEN3gtl7IntTypeINS0_20IntegerVariable_tag_EiEES4_S4_ENKUlPNS0_5ModelEE_clES6_
@ 0x10a787dfc operations_research::sat::LoadIntProdConstraint()
@ 0x10a7916da operations_research::sat::LoadConstraint()
@ 0x10a7c36e1 operations_research::sat::CpModelPresolver::Probe()
@ 0x10a7ceba8 operations_research::sat::CpModelPresolver::Presolve()
@ 0x10a7ce756 operations_research::sat::PresolveCpModel()
@ 0x10a7e3f7a operations_research::sat::SolveCpModel()
Комментарии:
1. Какая версия или-инструментов?
2. ортулы. __версия__: 7.7.7810
3. Привет, Лоран, я обновил свои инструменты до 9.0, функция AddMultiplicationEquality работает для меня. Ошибки больше нет. В любом случае, спасибо тебе.
Ответ №1:
Как видно из комментариев, это было исправлено после 7.7
Теперь его неэффективно использовать AddMultiplicationEquality
, если вы не используете результат умножения.
Для каждого номера промежутка я бы создал две логические переменные.
is_gt_zero[i] = model.NewBoolVar('')
model.Add(gap[i] > 0).OnlyEnforceIf(is_gt_zero[i])
model.Add(gap[i] <= 0).OnlyEnforceIf(is_gt_zero[i].Not())
is_lt_zero[i] = model.NewBoolVar('')
model.Add(gap[i] < 0).OnlyEnforceIf(is_lt_zero[i])
model.Add(gap[i] >= 0).OnlyEnforceIf(is_lt_zero[i].Not())
а затем обеспечьте совместимость.
model.AddImplication(is_gt_zero[i], is_lt_zero[i 1].Not())
model.AddImplication(is_lt_zero[i], is_gt_zero[i 1].Not())