DFA 最小化(python 暴力)
https://rusunoi.github.io/books/National-Team-Thesis/2021.pdf
#!/bin/env python3
from collections import defaultdict, deque
def rebuild(tr, P, q0):
tot = 0
drn = {}
for S in P:
for nd in S:
drn[nd] = tot
tot += 1
newtr = {}
tot = 0
for S in P:
for nd in S:
acc, trs = tr[nd]
break
newtr[tot] = acc, tuple(map(lambda nd: drn[nd], trs))
tot += 1
return newtr, drn[q0]
def search_dfa(tr, st):
q = [st]
vis = {st}
l = 0
while l < len(q):
u = q[l]
l += 1
for v in tr[u][1]:
if v not in vis:
vis.add(v)
q.append(v)
return {nd: tr[nd] for nd in q}
def hopcroft(tr):
sgm = 0
for nd, (acc, trs) in tr.items():
sgm = len(trs)
break
Q = frozenset({nd for nd, (acc, trs) in tr.items()})
F = frozenset({nd for nd, (acc, trs) in tr.items() if acc})
P = {F, Q - F}
W = {F}
while W:
A = W.pop()
for c in range(sgm):
X = {nd for nd, (acc, trs) in tr.items() if trs[c] in A}
Ys = {(Y, U, V) for Y in P if (U := Y - X) and (V := Y & X)}
for Y, U, V in Ys:
P.remove(Y)
P.add(U)
P.add(V)
if Y in W:
W.remove(Y)
W.add(U)
W.add(V)
else:
if len(U) < len(V):
W.add(U)
else:
W.add(V)
return P
def solve(tr, q0):
tr = search_dfa(tr, q0)
P0 = [frozenset({nd}) for nd, (acc, trs) in tr.items()]
tr, q0 = rebuild(tr, P0, q0)
P = hopcroft(tr)
return rebuild(tr, P, q0)
def print_dfa(tr, q0):
F = []
print("{", end="")
for i in range(len(tr)):
acc, trs = tr[i]
if acc:
F.append(i)
print("{", end="")
print(*trs, sep=",", end="},")
print("}")
print("q0:", q0)
print("ACC:", end=" ")
print(*F, sep=",")
一个 dfa 是一个 dict,键为结点,值是元组套元组 (acc, (tr[0], tr[1], ...)),acc 表示该状态是否是接受状态,tr[0] 那些就是转移状态。
solve(tr, q0) 用于化简 dfa,q0 是初始状态。print_dfa(tr, q0) 输出一个被 solve 过的 dfa。
本文来自博客园,作者:caijianhong,转载请注明原文链接:https://www.cnblogs.com/caijianhong/p/18841671
浙公网安备 33010602011771号