单输出逻辑电路如何不通过暴力枚举得到指定输出对应的全部输入组合
逻辑电路输入组合求解的非暴力方案
针对你需要获取指定输出对应的所有输入组合的需求,以下是三种成熟的非暴力实现方案:
- SAT求解器适配方案
这个问题本质是求布尔函数的所有可满足解,你可以先将整个电路转换为合取范式(CNF):每个逻辑门对应固定的CNF子句规则:- AND门(z = x AND y)对应子句:
(¬x ∨ ¬y ∨ z) ∧ (x ∨ ¬z) ∧ (y ∨ ¬z) - OR门(z = x OR y)对应子句:
(x ∨ y ∨ ¬z) ∧ (¬x ∨ z) ∧ (¬y ∨ z) - NOT门(z = NOT x)对应子句:
(¬x ∨ ¬z) ∧ (x ∨ z)
将所有逻辑门的CNF子句合并后,加入你要求的输出约束(比如输出为1则添加子句(输出变量),输出为0则添加(¬输出变量)),就可以调用SAT求解器的全解模式直接生成所有符合要求的输入组合。Python生态可以用pycosat库的iter_solve方法迭代生成所有解,在输入变量大于20的场景下,效率比暴力枚举高2~3个数量级。
- AND门(z = x AND y)对应子句:
- 有序二元决策图(OBDD)方案
你可以将逻辑电路转换为OBDD结构,这是布尔函数的标准化紧凑表示形式。OBDD构造完成后,直接遍历从根节点到目标输出节点(1节点或0节点)的所有路径,每条路径对应一组输入取值约束,合并重复约束后即可得到所有满足条件的输入组合,还可以直接输出最简的输入约束表达式,不需要逐个枚举离散的输入组合。Python可以用dd库完成OBDD的构造、遍历操作。 - 反向回溯剪枝方案
不需要依赖第三方库,你可以基于现有的电路实现改造:先对电路的逻辑门按拓扑排序,从输出端要求的取值开始反向推导前级逻辑门的输入约束,一旦出现不可能满足的约束(比如要求OR门输出为0但其中一个输入固定为1),直接剪枝这条推导路径,不需要遍历所有输入组合。这种方案实现门槛最低,适合输入变量规模在30以内的场景。
内容的提问来源于stack exchange,提问作者i'm ashamed with what i asked
相关产品推荐
相关产品推荐

