我正在尝试使用 Z3 (Python) 解决包含线性整数模理论的 SMT 问题。该问题类似于 Knuth 的可满足性书第 14f 页上的“学习布尔函数”示例。我的问题有一组布尔值公式(数百个),每个公式包含要求解的同一组未知整数和布尔变量(数十个),优化目标是最大化真实公式的数量作为这些公式的函数未知数。我正在努力提高解决问题的速度。这些公式包含混合布尔变量,其表达式如 (x <= const) 或 (x1 + x2 <= const) 或 (x == x1 + x2) 对于整数 x、x1、x2、const。
来自实验 I'已经了解到:(1)使用 z3.Solver() 在决策问题上使用二分法(反复求解目标函数 >= 给定常量)似乎比直接使用 z3.Optimize() 快得多; (2) 使用“dt2bv”策略似乎可以大大提高速度。然而,解决一个大问题仍然需要数小时或数天的运行时间。
看起来 Z3 有 100 多种策略,总共超过 9000 个选项,尽管其中大部分似乎都分配给非常专业的问题类型。任何关于在哪里寻找使运行速度更快的帮助将不胜感激。如果有帮助的话,我很乐意发布示例运行的诊断输出。预先感谢您的回复。
以下是一些可以提高 Z3 优化问题求解速度的技巧:
问题表述和建模:
- 简化约束条件: 尽可能简化约束条件。使用更简单的等效表达式,并尝试减少约束和变量的数量。
- 选择合适的变量类型: 确保为你的问题选择了最具体的变量类型。例如,如果一个变量只能取几个整数值,请使用枚举类型而不是整数。
- 利用问题结构: 如果你的问题有特定的结构(例如,线性,凸,差分逻辑),请使用 Z3 中支持这些结构的特定 API 或策略。
- 增量求解: 如果你要解决一系列相似的问题,请使用 Z3 的增量求解功能。这允许你在解决第一个问题后添加或删除约束,而无需从头开始重新求解。
求解器配置:
-
选择合适的策略:
Z3 提供了许多不同的策略,可以针对不同类型的问题进行优化。尝试使用
z3.tactics.portfolio()
函数来自动选择策略,或者查阅 Z3 文档以找到适合你问题的策略。 - 调整策略参数: 许多策略都有可以调整的参数。尝试修改这些参数以查看它们对求解时间的影响。
- 并行求解: 对于大型问题,可以尝试使用 Z3 的并行求解功能。这允许你同时使用多个核心或处理器来求解问题。
其他技巧:
- 使用预求解: 尝试在调用 Z3 之前对你的问题进行预求解。这可以通过简化约束条件,消除冗余变量或识别冲突来完成。
-
使用断言:
使用
assert()
函数来添加对变量的约束条件。这可以帮助 Z3 更快地找到解决方案。 -
提供提示:
如果可以,请向 Z3 提供有关解决方案的提示。这可以通过使用
assert_soft()
函数添加软约束条件来完成,该函数表示希望满足但不是必需满足的约束条件。
分析诊断输出:
-
使用
set_option("verbose", 1)
或更高版本来启用 Z3 的详细输出。 - 分析输出以了解 Z3 在做什么以及它在哪些方面遇到了困难。
- 尝试根据诊断输出调整问题表述或求解器配置。
其他资源:
请记住,提高 Z3 性能没有万能的方法。最佳方法取决于问题的具体情况。尝试不同的方法并分析结果以找到最佳解决方案。
标签:python,performance,z3,smt From: 78809424