0

I have a list of numbers below for example. And the constrain is that two adjacent numbers' gap should be both positive or negative, or one of two numbers equaling to zero, that is to say that one positive and one negative(eg. 3 and -1) is unacceptable.

List numbers: [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]

Numbers' gap: [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]

So I try to use AddMultiplicationEquality to add a constrain

target=model.NewIntVar(-999999,999999,'target_%s_%s'%(i, i+1))
model.AddMultiplicationEquality(target, [gap[i],gap[i+1]])
model.Add(target>=0)

But I got the result below. How can I solve this? Thanks in advance.

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()
MindHacks
  • 931
  • 2
  • 7
  • 9

1 Answers1

3

As seen in the comments, this was fixed after 7.7

Now, it is inefficient to use AddMultiplicationEquality if you do not use the result of the multiplication.

For each gap number, I would create two Boolean variables.

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())

and then enforce the compatibility.

model.AddImplication(is_gt_zero[i], is_lt_zero[i + 1].Not())
model.AddImplication(is_lt_zero[i], is_gt_zero[i + 1].Not())
Stradivari
  • 2,626
  • 1
  • 9
  • 21
Laurent Perron
  • 8,594
  • 1
  • 8
  • 22