如何使用相加乘法等式来添加约束?

Posted

技术标签:

【中文标题】如何使用相加乘法等式来添加约束?【英文标题】:How to use AddMultiplicationEquality to add constrain? 【发布时间】:2021-06-21 02:29:35 【问题描述】:

例如,我在下面有一个数字列表。并且约束是两个相邻数的差距应该是正数或负数,或者两个数之一等于0,也就是说一个正数和一个负数(例如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()

【问题讨论】:

or-tools 的哪个版本? ortools.__version__: 7.7.7810 嗨 Laurent,我已将我的 ortools 更新到 9.0,AddMultiplicationEquality 函数对我有用。没有错误了。还是谢谢你。 【参考方案1】:

从 cmets 中可以看出,这在 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())

【讨论】:

以上是关于如何使用相加乘法等式来添加约束?的主要内容,如果未能解决你的问题,请参考以下文章

添加除法不等式约束

拉格朗日乘法与KKT条件

Scipy.optimize 不等式约束 - 考虑不等式的哪一侧?

具有两个不等式约束的歧义

如何在 C++ 中使用约束满足来实现密码算法

在 Java 中使用 google or-tools 进行除法不等式约束