我目前正在使用python api for z3来计算bitvectors的权重。
在搜索python API以获得更直接的方法之后,我正在以下列方式为bitvector st1
实现权重函数:
Sum([( (st1 & (2**(i)))/(2**(i)) ) for i in range(bits)])
我的问题相对简单,是否有更容易/更有效的方式?
我遇到的问题包含1500多个这些重量限制,并希望确保我尽可能高效地做事。
编辑:我将添加以下说明,我试图计算的是一个名字(它是汉明重量),我知道在命令式语言中实现功能的超高效方法,但< strong>最终我正在寻找的是,如果有任何基础方法可以访问z3位向量的各个位。
答案 0 :(得分:1)
我在你在问题中发布的例子中玩了一点:
我认为不满意的实例很难解决,因为问题似乎有许多对称性。 如果是这种情况,我们可以通过包含“对称破坏约束”来提高性能。 对于这种问题,Z3不能自动打破对称性。
这是一个次要的编码改进。表达式((st1 & (2**(i)))/(2**(i))
实质上是提取第i位。我们可以使用Extract(i, i, st1)
来提取第i位。结果是一个大小为1的位向量。然后,我们必须“扩展”它以避免溢出。问题中的位向量最多为28位。因此,5位足以避免溢出。因此,我们可以使用ZeroExt(4, Extract(i, i, st1))
。也就是说,我们替换
Sum([( (st1 & (2**(i)))/(2**(i)) ) for i in range(bits)])
与
Sum([ ZeroExt(4, Extract(i,i,st1)) for i in range(bits) ])
我得到了适度的2倍加速。所以,Z3仍然无法解决6位不饱和实例:(
答案 1 :(得分:-1)
你应该尝试使用递归方法,也许你可以看看这个Dynamic programming