Google OR 工具:如何评估复杂或多级布尔约束

2024-01-04

Set up

我使用 google OR 工具作为约束编程求解器:

from ortools.sat.python import cp_model

我定义了以下 BoolVars

model = cp_model.CpModel()
a = model.NewBoolVar("a")
b = model.NewBoolVar("b")
c = model.NewBoolVar("c")
d = model.NewBoolVar("d")
e = model.NewBoolVar("e")
f = model.NewBoolVar("f")
g = model.NewBoolVar("g")

Question

我需要向模型添加复杂的布尔约束。就像是

(a || b) && (d || e) == g

如何向模型添加这样的复杂布尔约束?

PS:我无法立即在网上找到此信息,但根据我在相关问题上得到的答案找到了解决方案here https://stackoverflow.com/questions/70553100/constraint-optimization-in-python-with-or-tools-how-to-enforce-a-multi-level-co/70554356?noredirect=1#comment124730209_70554356以及另一个人的另一个相关问题here https://stackoverflow.com/questions/27814935/boolean-operations-on-constraints-in-google-or-tools-library。我以问答的形式总结了我的发现,希望它们对某人有用。


这种约束不能立即添加到模型中。约束需要分解为其组件(和 & 或门)。每个基本组件需要设置为等于一个新的 BoolVar。然后将它们组合起来以添加最终约束。

基本组件细分

我们将按如下方式执行此操作:

(a || b) == c
(d || e) == f
(c && f) == g

最后一个方程等价于原始方程:

(a || b) && (d || e) == g

在新的 BoolVars 中存储基本约束

可以使用以下函数计算“OR”类型的方程:

def evaluate_or(a, b, c):
    # Either a or b or both must be 1 if c is 1.
    model.AddBoolOr([a, b]).OnlyEnforceIf(c)

    # The above line is not sufficient, as no constraints are defined if c==0 (see reference documentation of
    # "OnlyEnforceIf". We therefore add another line to cover the case when c==0:

    # a and b must both be 0 if c is 0
    model.AddBoolAnd([a.Not(), b.Not()]).OnlyEnforceIf([c.Not()])

“AND”类型的方程可以类似地用以下函数求值:

def evaluate_and(a, b, c):
    # Both a and b must be 1 if c is 1
    model.AddBoolAnd([a, b]).OnlyEnforceIf(c)

    #What happens if c is 0? This is still undefined thus let us add another line:

    # Either a or b or both must be 0 if c is 0.
    model.AddBoolOr([a.Not(), b.Not()]).OnlyEnforceIf(c.Not())

在这种特定情况下,基本约束是“或”门的两倍。我们将它们存储在 c 和 f 中:

evaluate_or(a, b, c)
evaluate_or(d, e, f)

添加复杂约束

现在这非常简单,可以使用上一步中的 BoolVars 和 AND 门来完成:

evaluate_and(c, f, g)

讨论

可以使用中间 BoolVars 以及上面定义的 OR 和 AND 门函数来添加任何复杂的约束。只需将约束分解为其基本组成部分即可。

完整节目

这是完整的程序:

from ortools.sat.python import cp_model

model = cp_model.CpModel()
a = model.NewBoolVar("a")
b = model.NewBoolVar("b")
c = model.NewBoolVar("c")
d = model.NewBoolVar("d")
e = model.NewBoolVar("e")
f = model.NewBoolVar("f")
g = model.NewBoolVar("g")

def evaluate_or(a, b, c):
    # Either a or b or both must be 1 if c is 1.
    model.AddBoolOr([a, b]).OnlyEnforceIf(c)

    # The above line is not sufficient, as no constraints are defined if c==0 (see reference documentation of
    # "OnlyEnforceIf". We therefore add another line to cover the case when c==0:

    # a and b must both be 0 if c is 0
    model.AddBoolAnd([a.Not(), b.Not()]).OnlyEnforceIf([c.Not()])

def evaluate_and(a, b, c):
    # Both a and b must be 1 if c is 1
    model.AddBoolAnd([a, b]).OnlyEnforceIf(c)

    #What happens if c is 0? This is still undefined thus let us add another line:

    # Either a or b or both must be 0 if c is 0.
    model.AddBoolOr([a.Not(), b.Not()]).OnlyEnforceIf(c.Not())

#Add the constraints
evaluate_or(a, b, c)
evaluate_or(d, e, f)
evaluate_and(c, f, g)


# Solve the model.
solver = cp_model.CpSolver()
solver.parameters.enumerate_all_solutions = True
status = solver.Solve(model, cp_model.VarArraySolutionPrinter([a, b, c, d, e, f, g]))

Output

获得以下输出:

Solution 0, time = 0.00 s
  a = 0   b = 0   c = 0   d = 1   e = 0   f = 1   g = 0 
Solution 1, time = 0.00 s
  a = 0   b = 0   c = 0   d = 1   e = 1   f = 1   g = 0 
Solution 2, time = 0.00 s
  a = 0   b = 0   c = 0   d = 0   e = 1   f = 1   g = 0 
Solution 3, time = 0.00 s
  a = 0   b = 0   c = 0   d = 0   e = 0   f = 0   g = 0 
Solution 4, time = 0.00 s
  a = 0   b = 1   c = 1   d = 0   e = 0   f = 0   g = 0 
Solution 5, time = 0.00 s
  a = 0   b = 1   c = 1   d = 1   e = 0   f = 1   g = 1 
Solution 6, time = 0.00 s
  a = 0   b = 1   c = 1   d = 1   e = 1   f = 1   g = 1 
Solution 7, time = 0.00 s
  a = 0   b = 1   c = 1   d = 0   e = 1   f = 1   g = 1 
Solution 8, time = 0.00 s
  a = 1   b = 1   c = 1   d = 0   e = 1   f = 1   g = 1 
Solution 9, time = 0.00 s
  a = 1   b = 1   c = 1   d = 1   e = 1   f = 1   g = 1 
Solution 10, time = 0.00 s
  a = 1   b = 1   c = 1   d = 1   e = 0   f = 1   g = 1 
Solution 11, time = 0.00 s
  a = 1   b = 1   c = 1   d = 0   e = 0   f = 0   g = 0 
Solution 12, time = 0.00 s
  a = 1   b = 0   c = 1   d = 0   e = 0   f = 0   g = 0 
Solution 13, time = 0.00 s
  a = 1   b = 0   c = 1   d = 0   e = 1   f = 1   g = 1 
Solution 14, time = 0.00 s
  a = 1   b = 0   c = 1   d = 1   e = 1   f = 1   g = 1 
Solution 15, time = 0.00 s
  a = 1   b = 0   c = 1   d = 1   e = 0   f = 1   g = 1 
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Google OR 工具:如何评估复杂或多级布尔约束 的相关文章

  • DPI 无法正确缩放

    我创建了一个自定义 UserControl 其功能与 numbericUpDown 非常相似 但具有各种增强功能 例如 它可以显示分数 但是 此控件的缩放比例不如窗体上的其他一些控件 这迫使我的 UI 看起来很尴尬 我尝试了控件及其父控件的

随机推荐

  • 片段 onHiddenChanged 未调用

    我最近将 Fragments 添加到我的应用程序中 对于新的应用程序 我需要获得 显示我的片段后立即通知 所以我可以尽快做一些计算 片段再次显示 我的 Fragment 与 TabIndicator 一起使用 并且仅使用一个 Fragmen
  • REXML::Document.new 我们可以在这一行给出编码参数吗?

    doc REXML Document 新文件 每当我的 xml 文件包含 UTF 8 以外的一些特殊字符时 我的代码就会失败 REXML ParseException
  • 在配置私有 GKE 集群时了解 --master-ipv4-cidr

    我试图进一步了解当我在 Google 的 Kubernetes Engine 中配置私有集群时到底发生了什么 Google 在此提供了一个配置私有集群的示例 其中控制平面服务 例如 Kubernetes API 位于172 16 0 16
  • 如何获取访问Google Play开发者API的授权

    我正在尝试访问 Google Play 开发者 APIhttps developers google com android publisher https developers google com android publisher 为
  • 以编程方式在 WinForms VB.NET/C# 中聚焦/突出显示 ListView 列标题

    在 WinForms ListView 上 将鼠标悬停在列标题上会导致其聚焦或强调 例如 我需要动态地执行此操作 因为在我的程序中使用左右键切换焦点列 尽管广泛搜索了以下属性 ListView Columns i ListView Colu
  • Haskell 在现实世界中的用途是什么? [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 关于 Haskell 有很多炒作 但是 很难获得有关如何在现实世界应用程序中使用它的信息 Haskell 最流行的项目 用法是什么 为什么它擅长
  • typeahead.js 预取不起作用

    我无法让 typeahead js 中的预取函数工作 但它对于本地数据工作得很好 我首先尝试链接到返回 json 对象或列表的 servlet 但过了一会儿我放弃了 并开始检查提供的示例 因此 他们的示例链接到的页面如下所示 http tw
  • 每 10 秒调用一个函数 Angular2

    我正在尝试创建一个Timer这称为API call每 10 秒 我使用setTimeOut但问题是 它变成了无限循环 即使我推送到另一个页面 它也会继续加入 if 条件 例子 我在启动 10 秒 API 调用的方法上调用此方法 setTim
  • 将字典从 Swift 发送到 PHP

    如何将 Swift 生成的字典作为 PHP URL 中的参数发布 具体来说 任务是更新托管数据库上的许多字段 我不是将每个字段的新值定义为单独的参数 而是希望传递一个字典 其中键是字段名称 值是新值 该数据已经作为Dictionary
  • c++:程序设置 - boost.PropertyTree 还是 boost.program_options?

    我正在寻找一种在 C 中存储程序设置或选项或配置的解决方案 这些可能是在 GUI 中公开的设置 需要在代码运行之间保存 在我的搜索中我遇到了boost PropertyTree http www boost org doc libs 1 4
  • Matlab 中的矩阵到向量转换

    我有一个 MxN 矩阵 想转换为向量 MNx1 其中矩阵中行的所有元素作为向量的元素 我尝试使用reshape但我没有成功 这是小代码片段和预期结果 S 0 1 1 0 1 1 1 1 预期结果 S prime 0 1 1 0 1 1 1
  • 是否有使用 sun.jdbc.odbc.JdbcOdbcDriver 的替代方法? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我最近将我们工作中的一个旧应用程序从 Java 1 5 迁移到 1 6 我注意到在构建过程中 我现在收
  • 如何使命名路由出口与 loadChildren 一起工作?

    我创建了两个关于路由的 loadChildren 和出口导航问题的插件 由于某种原因 加载的子模块中具有空的基本路径不适用于出口导航 In this https plnkr co edit ps0ZiD3mHTte227Ws69T p pr
  • Java HashMap 检测冲突

    有没有办法检测 Java Hash map 中的冲突 任何人都可以指出某些可能发生大量碰撞的情况吗 当然 如果你重写一个对象的哈希码并简单地返回一个常量值 那么肯定会发生冲突 我不是在谈论这个 我想知道除了前面提到的之外 在什么情况下会发生
  • WebBrowser 控件 - 安装 IE 11 后页面呈现错误

    我对 Winforms NET 类 WebBrowser 有问题安装后Internet Explorer 11 预览版 当我调用我的网页时 它看起来像是禁用了 javascript If your WebBrowser基于应用程序和您的网页
  • 将文件上传到 Azure 存储会导致错误:此流不支持超时

    我有一个表单 其中包含上传到 Azure 存储的文件 这是调用 ToStream 方法的地方 Image img Image FromStream file InputStream true true if img Height heigh
  • docker-compose:定义绑定挂载和托管挂载的挂载

    我正在使用 docker compose 来定义我的服务 在docker中 docker卷有两个概念 首先是关于bind mount 挂载在主机存储上 docker run d name web app v HOST location co
  • jQuery UI datepicker 将焦点放在输入上,而无需在 IE 中再次加载日历?

    我知道如果用鼠标选择日期 jQuery UI 日期选择器会失去焦点 我希望能够将焦点集中在该输入字段上 所以我做了这样的事情 patientDob live click function patientDob datepicker onSe
  • 在numpy数组中查找连续的

    如何找到连续的数量1以下 numpy 数组的每一行中的 s 或任何其他值 我需要一个纯 numpy 解决方案 array 0 1 0 1 1 0 0 1 1 0 0 0 0 0 1 0 0 1 2 0 0 1 1 1 0 0 0 4 1 0
  • Google OR 工具:如何评估复杂或多级布尔约束

    Set up 我使用 google OR 工具作为约束编程求解器 from ortools sat python import cp model 我定义了以下 BoolVars model cp model CpModel a model