📅  最后修改于: 2023-12-03 15:28:47.047000             🧑  作者: Mango
这是一个涉及布尔逻辑的问题。给定 n 个布尔变量,每个变量可以是真或假,共有 $2^n$ 种可能的组合。在本问题中,我们要编写一个程序,该程序将输入表示一个布尔函数的真值表,输出该布尔函数的最小门集合,其中每个门可以是 NOT、AND、OR、XOR。
考虑一个布尔函数 f(x_1, x_2, ..., x_n),其中每个变量 x_i 可以是T或F。输入表示 f(x_1, x_2, ..., x_n) 的所有可能组合的真值表。例如,如果 n = 2,则真值表如下所示:
| x1 | x2 | f(x1,x2) |
|----|----|----------|
| T | T | T |
| T | F | F |
| F | T | F |
| F | F | F |
这个布尔函数是以下表达式的简写:
((x1 AND x2) OR (NOT x1 AND NOT x2))
问题是找到此布尔函数的一个最小门级组合,其中每个门都可以是 NOT、AND、OR 或 XOR 操作。 每个元素都可以出现多次,其中:
在上面的例子中,最小门集合是:
NOT(x1) XOR x2
这个问题是一个经典的问题,可以使用基于卡诺图和奎因-麦克拉斯基方法的变量消除算法来解决。这些解决方案旨在找到最小化逻辑门的布尔函数表示.
这里提供一种基于布尔公式缩减的解决方案,利用 Quine-McCluskey 算法与 Petrick’s 方法。具体步骤如下:
构建一个真值表并转换成布尔函数的标准表示。
将此表达式化简为Sum of Products(SOP)或 Product of Sum(POS)表达式。
将缩减后的表达式转换回最终布尔函数表示。
输入给定 $2^n$ 行,每行 n+1 个字符,其中最后一个字符表示相应的布尔函数的输出值。对于第 i 行,输入表示为:
x_i,1 x_i,2 ... x_i,n y_i
其中,y_i 表示布尔函数输出值,可以是 0 或 1,x_i,j 是布尔变量 i 的第 j 个值。例如,如果 n = 2,则以下是真值表的一部分。
T T T
T F F
F T F
F F F
我们首先将真值表化成布尔函数的标准表达式。具体而言,可以先化为 SOP 表达式,然后再简化为最小的 SOP。决策得 S算法可以帮助我们找到最小 SOP 表达式。
最后,通过 Petrick’s 方法将最小的 SOP 表达式转换为最小的门级逻辑表示,以便可轻松地实现。最小化布尔函数时,可以利用 Quine-McCluskey 算法和Petrick's 方法。有许多库和软件工具可以执行这个最小化过程。
这里展示生成最小门级逻辑的示例 Python 代码:
from qm import QuineMcCluskey
from itertools import chain, combinations
def bool_minimizer(truth_table):
vars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"[:len(truth_table[0])-1]
def implicants(minterms, vars):
qmc = QuineMcCluskey(use_xor=False)
qmc.set_coverage(vars)
imp = qmc.simplify(minterms)
return [ set(filter(lambda x: x.isupper(), i)) for i in imp ]
def full_impl(minterms):
impl = implicants(minterms, vars)
nn = len(impl)
s = [ set() ] + [ set(impl[i]) for i in range(nn) ]
res = set()
for r in chain.from_iterable(combinations(range(1,nn+1), i) for i in range(nn+1)):
if len(s[r[0]].intersection(*(s[k] for k in r[1:]))) == 0:
res.add(frozenset().union(*(s[k] for k in r)))
return list(sorted(res, key=(lambda k: len(k))))[:10]
def to_sum(f):
return ' OR '.join([ ' AND '.join(v if c=='1' else 'NOT '+v for (v,c) in zip(vars,w)) for w in f ])
n_values = len(truth_table)
minterms = set(i for i in range(n_values) if truth_table[i][-1])
mins = full_impl(minterms)
results = []
for m in mins:
terms = []
for v in vars:
pos = frozenset( q | {v} for q in m if v not in q )
neg = frozenset( q | {'!'+v} for q in m if '!'+v not in q )
terms.append( f'({to_sum(pos)}) AND ({to_sum(neg)})' )
results.append(' OR '.join(terms))
return results
# 示例输入
truth_table = [
['T', 'T', 'T', 'T'],
['T', 'F', 'F', 'F'],
['F', 'T', 'F', 'F'],
['F', 'F', 'F', 'F']
]
# 输出最小化布尔函数的门级逻辑
print(bool_minimizer(truth_table))
这个 Python 代码定义了一个函数 bool_minimizer(truth_table)
。 truth_table
是一个由行列表示的真值表。函数返回一个最小化布尔函数的门级逻辑的列表(字符串)。
此功能的实现需要 qmc
模块,因此需要安装它包括 pip install qmc
。
此函数的工作原理是将真值表递交给 Quine-McCluskey 算法进行化简,以获得最小的 SOP 表达式。然后,我们在运用 Petrick 方法生成与原始真值表具有相同输出值的最短逻辑表达式。结果是表示最短逻辑表达式的一组门级逻辑。