为什么 Z3 对于很小的搜索空间来说很慢?

2024-05-03

我正在尝试制作一个 Z3 程序(在 Python 中),它生成执行某些任务的布尔电路(例如,添加两个 n 位数字),但性能非常糟糕,以至于对整个解决方案空间进行强力搜索将导致快一点。这是我第一次使用 Z3,所以我可能会做一些影响我性能的事情,但我的代码看起来不错。

以下是从我的代码复制的here https://github.com/leoadberg/smt_fun/blob/master/adder.py:

from z3 import *

BITLEN = 1 # Number of bits in input
STEPS = 1 # How many steps to take (e.g. time)
WIDTH = 2 # How many operations/values can be stored in parallel, has to be at least BITLEN * #inputs

# Input variables
x = BitVec('x', BITLEN)
y = BitVec('y', BITLEN)

# Define operations used
op_list = [BitVecRef.__and__, BitVecRef.__or__, BitVecRef.__xor__, BitVecRef.__xor__]
unary_op_list = [BitVecRef.__invert__]
for uop in unary_op_list:
    op_list.append(lambda x, y : uop(x))

# Chooses a function to use by setting all others to 0
def chooseFunc(i, x, y):
    res = 0
    for ind, op in enumerate(op_list):
        res = res + (ind == i) * op(x, y)
    return res

s = Solver()
steps = []

# First step is just the bits of the input padded with constants
firststep = Array("firststep", IntSort(), BitVecSort(1))
for i in range(BITLEN):
    firststep = Store(firststep, i * 2, Extract(i, i, x))
    firststep = Store(firststep, i * 2 + 1, Extract(i, i, y))
for i in range(BITLEN * 2, WIDTH):
    firststep = Store(firststep, i, BitVec("const_0_%d" % i, 1))
steps.append(firststep)

# Generate remaining steps
for i in range(1, STEPS + 1):
    this_step = Array("step_%d" % i, IntSort(), BitVecSort(1))
    last_step = steps[-1]

    for j in range(WIDTH):
        func_ind = Int("func_%d_%d" % (i,j))
        s.add(func_ind >= 0, func_ind < len(op_list))

        x_ind = Int("x_%d_%d" % (i,j))
        s.add(x_ind >= 0, x_ind < WIDTH)

        y_ind = Int("y_%d_%d" % (i,j))
        s.add(y_ind >= 0, y_ind < WIDTH)

        node = chooseFunc(func_ind, Select(last_step, x_ind), Select(last_step, y_ind))
        this_step = Store(this_step, j, node)

    steps.append(this_step)

# Set the result to the first BITLEN bits of the last step
if BITLEN == 1:
    result = Select(steps[-1], 0)
else:
    result = Concat(*[Select(steps[-1], i) for i in range(BITLEN)])

# Set goal
goal = x | y
s.add(ForAll([x, y], goal == result))

print(s)
print(s.check())
print(s.model())

该代码基本上将输入布局为单独的位,然后在每个“步骤”,5 个布尔函数之一可以对上一步的值进行运算,其中最后一步表示最终结果。

在本例中,我生成了一个电路来计算两个 1 位输入的布尔 OR 值,并且电路中提供了 OR 函数,因此解决方案很简单。

我的解空间只有 5*5*2*2*2*2=400:

  • 5 可能的功能(两个功能节点)
  • 每个函数有 2 个输入,每个输入有两个可能的值

这段代码需要几秒钟的时间才能运行并提供正确的答案,但我觉得它应该立即运行,因为只有 400 种可能的解决方案,其中相当多的解决方案是有效的。如果我将输入增加到两位长,则解决方案空间的大小为 (5^4)*(4^8)=40,960,000 并且永远不会在我的计算机上完成,尽管我觉得这应该可以使用 Z3 轻松实现。

我还有效地尝试了相同的代码,但用 Arrays/Store/Select 替换了 Python 列表,并使用我在 choiceFunc() 中使用的相同技巧“选择”了变量。代码是here https://github.com/leoadberg/smt_fun/blob/master/adder2.py它的运行时间与原始代码的运行时间大致相同,因此没有加速。

我是否做了一些会大大减慢求解器速度的事情?谢谢!


你有一个重复的__xor__在你的op_list;但这并不是真正的主要问题。当你增加位大小时,速度减慢是不可避免的,但乍一看你可以(并且should)避免在这里将整数推理与布尔值混合。我会给你编码chooseFunc如下:

def chooseFunc(i, x, y):
    res = False;
    for ind, op in enumerate(op_list):
        res = If(ind == i, op (x, y), res)
    return res

看看这是否能以任何有意义的方式改善运行时间。如果没有,接下来要做的就是尽可能摆脱数组。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么 Z3 对于很小的搜索空间来说很慢? 的相关文章

  • Matplotlib 标准化颜色条 (Python)

    我正在尝试使用 matplotlib 当然还有 numpy 绘制轮廓图 它有效 它绘制了它应该绘制的内容 但不幸的是我无法设置颜色条范围 问题是我有很多图 并且需要所有图都具有相同的颜色条 相同的最小值和最大值 相同的颜色 我复制并粘贴了在
  • 如何用 python 和 sympy 解决多元不等式?

    我对使用 python 和 Sympy 还很陌生 并且遇到了使用 sympy 解决多元不等式的问题 假设我的文件中有很多函数 如下所示 cst sqrt x 2 cst exp sqrt cst x 1 4 log log sqrt cst
  • 类属性在功能上依赖于其他类属性

    我正在尝试使用静态类属性来定义另一个静态类属性 我认为可以通过以下代码来实现 f lambda s s 1 class A foo foo bar f A foo 然而 这导致NameError name A is not defined
  • NLTK、搭配问题:需要解包的值太多(预期为 2)

    我尝试使用 NLTK 检索搭配 但出现错误 我使用内置的古腾堡语料库 I wrote alice nltk corpus gutenberg fileids 7 al nltk corpus gutenberg words alice al
  • 无法包含外部 pandas 文档 Pycharm v--2018.1.2

    我无法包含外部 pandas 文档Pycharm v 2018 1 2 例如 numpy gt http docs scipy org doc numpy reference generated module name element na
  • python ttk treeview:如何选择并设置焦点在一行上?

    我有一个 ttk Treeview 小部件 其中包含一些数据行 如何设置焦点并选择 突出显示 指定项目 tree focus set 什么也没做 tree selection set 0 抱怨 尽管小部件明显填充了超过零个项目 但未找到项目
  • 当x轴不连续时如何删除冗余日期时间 pandas DatetimeIndex

    我想绘制一个 pandas 系列 其索引是无数的 DatatimeIndex 我的代码如下 import matplotlib dates as mdates index pd DatetimeIndex 2000 01 01 00 00
  • Python:随时接受用户输入

    我正在创建一个可以做很多事情的单元 其中之一是计算机器的周期 虽然我将把它转移到梯形逻辑 CoDeSys 但我首先将我的想法放入 Python 中 我将进行计数 只需一个简单的操作 counter 1 print counter 跟踪我处于
  • 行为:如何从另一个文件导入步骤?

    我刚刚开始使用behave http pythonhosted org behave 一个Pythonic BDD框架 使用小黄瓜语法 http docs behat org guides 1 gherkin html 行为需要一个特征 例
  • 如何为多组精灵创建随机位置?

    我尝试使用 blit 和 draw 方法进行 for 循环 并为 PlayerSprite 和 Treegroup 使用不同的变量 for PlayerSprite in Treegroup surface blit PlayerSprit
  • 在wxpython中使用wx.TextCtrl并在按钮单击后显示数据的简单示例 - wx新手

    我正在学习 python 并尝试使用 wxpython 进行 UI 开发 也没有 UI exp 我已经能够创建一个带有面板 按钮和文本输入框的框架 我希望能够在文本框中输入文本 并让程序在单击按钮后对输入框中的文本执行操作 我可以获得一些关
  • 在 Mac 上安装 Pygame 到 Enthought 构建中

    关于在 Mac 上安装 Pygame 有许多未解答的问题 但我将在这里提出我的具体问题并希望得到答案 我在 Mac 上安装 Pygame 时遇到了难以置信的困难 我使用 Enthought 版本 EPD 7 3 2 32 位 它是我的默认框
  • 如何逐像素绘制正方形(Python,PIL)

    在空白画布上 我想使用 Pillow 逐像素绘制一个正方形 我尝试使用 img putpixel 30 60 155 155 55 绘制一个像素 但它没有执行任何操作 from PIL import Image def newImg img
  • 在pycharm中调试python代码

    这个问题类似于this https stackoverflow com questions 10240018 how to use pycharm to debug python script一 我正在尝试调试pyethapp https
  • Python 矩阵每一行的总和

    lista 1 2 3 4 5 6 7 8 9 print lista def filas lista res for elemento in lista x sum lista elemento res append x print re
  • Scrapy 蜘蛛无法工作

    由于到目前为止没有任何效果 我开始了一个新项目 python scrapy ctl py startproject Nu 我完全按照教程操作 创建了文件夹和一个新的蜘蛛 from scrapy contrib spiders import
  • asyncio - 多次等待协程(周期性任务)

    我正在尝试为异步事件循环创建定期任务 如下所示 但是我收到 RuntimeError 无法重用已等待的协程 异常 显然 asyncio 不允许等待相同的可等待函数 如中讨论的这个错误线程 https bugs python org issu
  • Google App Engine 中的自定义身份验证

    有谁知道或知道我可以在哪里学习如何使用 Python 和 Google App Engine 创建自定义身份验证流程 我不想使用 Google 帐户进行身份验证 并且希望能够创建自己的用户 如果不是专门针对 Google App Engin
  • 从时间序列生成日期特征

    我有一个数据框 其中包含如下列 Date temp data holiday day 01 01 2000 10000 0 1 02 01 2000 0 1 2 03 01 2000 2000 0 3 30 01 2000 200 0 30
  • 使用 numpy 加速 for 循环

    下一个 for 循环如何使用 numpy 获得加速 我想这里可以使用一些奇特的索引技巧 但我不知道是哪一个 这里可以使用 einsum 吗 a 0 for i in range len b a numpy mean C d e f b i

随机推荐