例如,下面有一个数字列表。约束条件是两个相邻数字的间隔应该是正或负,或者两个数字中的一个等于零,也就是说一个正和一个负(例如3和-1(是不可接受的。
列出编号:[15,15,15,15,15,15,15,15,15,18,17,20,19,22、25、25、22、20、23、22、21、18、15、15,15,15,15,15,18,21,24,24,24,27,30]
数字的间距:[0,0,0,0,0,0,0,0,0,3,1,3,0,0,0,0,0,0、-3、-2、3、-1、-1、-3、-3、0、0、3、3、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()
如评论所示,这是在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())