python 中的 DFA 最小化器
DFA minimizer in python
我正在使用 python 构建一个 DFA 最小化器,但我被卡住了。我正在使用我在网上找到的算法,但它没有给我正确的结果,我也不知道为什么。
functions = {'p1,c': 'p2', 'p1,d': 'p6', 'p2,c': 'p7', 'p2,d': 'p3', 'p3,c': 'p1', 'p3,d': 'p3', 'p4,c': 'p3',
'p4,d': 'p7', 'p5,c': 'p8', 'p5,d': 'p6', 'p6,c': 'p3', 'p6,d': 'p7', 'p7,c': 'p7', 'p7,d': 'p5',
'p8,c': 'p7', 'p8,d': 'p3'}
DS = ['p1', 'p2', 'p3', 'p4', 'p5', 'p6', 'p7', 'p8']
acceptedStates = ['p3']
symbols = ['c', 'd']
# ---- some more code here that's currently not important ----
dist = []
for pair in pairs: #pairs is a list of lists with all possible pairs of states
if (pair[0] in acceptableStates and par[1] not in prihvatljivaStanja) or (pair[0] not in acceptableStates and par[1] in acceptableStates):
dist.append(pair)
for pair in pairs:
for symbol in symbols:
priv1 = functions[par[0] + ',' + symbol]
priv2 = functions[par[1] + ',' + symbol]
if (priv1 in acceptableStates and priv2 not in acceptableStates) or (priv1 not in acceptableStates and priv2 in acceptableStates):
dist.append(pair)
for i in pairs:
if i not in dist:
print(i)
基本上我想做的是在最后打印出所有无法区分的状态。正确的结果是(对于我正在使用的例子)是:
dist = [['p1', 'p5'], ['p2', p8'], ['p4', 'p6']]
我得到的结果是:
dist = [['p1', 'p5'] #correct
['p1', 'p7']
['p2', 'p8'] #correct
['p4', 'p6'] #correct
['p5', 'p7']]
如您所见,所有当前的都在其中,但它有一些不应该在此处的额外内容。在浏览代码时,我可以看到为什么会发生这种情况,但我不确定如何解决它。有任何想法吗?
首先我将输入 DFA 组织成更易于管理的形式:
dfa = {'p1': {'c': 'p2', 'd': 'p6'},
'p2': {'c': 'p7', 'd': 'p3'},
'p3': {'c': 'p1', 'd': 'p3'},
'p4': {'c': 'p3', 'd': 'p7'},
'p5': {'c': 'p8', 'd': 'p6'},
'p6': {'c': 'p3', 'd': 'p7'},
'p7': {'c': 'p7', 'd': 'p5'},
'p8': {'c': 'p7', 'd': 'p3'}}
final = {'p3'}
这是我实现该算法的尝试。在比较对时,我 运行 遇到了顺序问题,所以我将所有内容都转换为 frozenset
,而不是元组或列表。
from itertools import combinations
pairs = set(map(frozenset, combinations(dfa, 2)))
dist = set()
for pair in pairs:
p, q = pair
if (p in final and q not in final) or (p not in final and q in final):
dist.add(pair)
repeat = True
while repeat:
repeat = False
for pair in pairs:
print(dist)
if pair in dist:
continue
p, q = pair
for a in dfa[p]:
dpair = frozenset((dfa[p].get(a), dfa[q].get(a)))
if dpair in dist:
dist.add(pair)
repeat = True
break
print(pairs - dist)
# {frozenset({'p1', 'p5'}), frozenset({'p8', 'p2'}), frozenset({'p6', 'p4'})}
我正在使用 python 构建一个 DFA 最小化器,但我被卡住了。我正在使用我在网上找到的算法,但它没有给我正确的结果,我也不知道为什么。
functions = {'p1,c': 'p2', 'p1,d': 'p6', 'p2,c': 'p7', 'p2,d': 'p3', 'p3,c': 'p1', 'p3,d': 'p3', 'p4,c': 'p3',
'p4,d': 'p7', 'p5,c': 'p8', 'p5,d': 'p6', 'p6,c': 'p3', 'p6,d': 'p7', 'p7,c': 'p7', 'p7,d': 'p5',
'p8,c': 'p7', 'p8,d': 'p3'}
DS = ['p1', 'p2', 'p3', 'p4', 'p5', 'p6', 'p7', 'p8']
acceptedStates = ['p3']
symbols = ['c', 'd']
# ---- some more code here that's currently not important ----
dist = []
for pair in pairs: #pairs is a list of lists with all possible pairs of states
if (pair[0] in acceptableStates and par[1] not in prihvatljivaStanja) or (pair[0] not in acceptableStates and par[1] in acceptableStates):
dist.append(pair)
for pair in pairs:
for symbol in symbols:
priv1 = functions[par[0] + ',' + symbol]
priv2 = functions[par[1] + ',' + symbol]
if (priv1 in acceptableStates and priv2 not in acceptableStates) or (priv1 not in acceptableStates and priv2 in acceptableStates):
dist.append(pair)
for i in pairs:
if i not in dist:
print(i)
基本上我想做的是在最后打印出所有无法区分的状态。正确的结果是(对于我正在使用的例子)是:
dist = [['p1', 'p5'], ['p2', p8'], ['p4', 'p6']]
我得到的结果是:
dist = [['p1', 'p5'] #correct
['p1', 'p7']
['p2', 'p8'] #correct
['p4', 'p6'] #correct
['p5', 'p7']]
如您所见,所有当前的都在其中,但它有一些不应该在此处的额外内容。在浏览代码时,我可以看到为什么会发生这种情况,但我不确定如何解决它。有任何想法吗?
首先我将输入 DFA 组织成更易于管理的形式:
dfa = {'p1': {'c': 'p2', 'd': 'p6'},
'p2': {'c': 'p7', 'd': 'p3'},
'p3': {'c': 'p1', 'd': 'p3'},
'p4': {'c': 'p3', 'd': 'p7'},
'p5': {'c': 'p8', 'd': 'p6'},
'p6': {'c': 'p3', 'd': 'p7'},
'p7': {'c': 'p7', 'd': 'p5'},
'p8': {'c': 'p7', 'd': 'p3'}}
final = {'p3'}
这是我实现该算法的尝试。在比较对时,我 运行 遇到了顺序问题,所以我将所有内容都转换为 frozenset
,而不是元组或列表。
from itertools import combinations
pairs = set(map(frozenset, combinations(dfa, 2)))
dist = set()
for pair in pairs:
p, q = pair
if (p in final and q not in final) or (p not in final and q in final):
dist.add(pair)
repeat = True
while repeat:
repeat = False
for pair in pairs:
print(dist)
if pair in dist:
continue
p, q = pair
for a in dfa[p]:
dpair = frozenset((dfa[p].get(a), dfa[q].get(a)))
if dpair in dist:
dist.add(pair)
repeat = True
break
print(pairs - dist)
# {frozenset({'p1', 'p5'}), frozenset({'p8', 'p2'}), frozenset({'p6', 'p4'})}