wiki 伪代码看上去一直以为怪。发现葡萄牙语和俄罗斯语那里的 if 推断都还缺少一个条件。
国内的资料比較少。这几份学习资料不错。比我稀里糊涂的思路要好,分享下:
http://www.liafa.univ-paris-diderot.fr/~carton/Enseignement/Complexite/
ENS/Redaction/2008-2009/yingjie.xu.pdf
http://www8.cs.umu.se/kurser/TDBC92/VT06/final/1.pdf
http://arxiv.org/pdf/1010.5318.pdf
对于一个确定型自己主动机 D = (Q, Σ, δ, q0, F)。Q 的一系列恒等关系 ρi (i ≥ 0) 被定义为:
ρ0 = {(p, q)|p, q ∈ F} ∪ {(p, q)|p, q ∈ Q − F},
ρi+1 = {(p, q) ∈ ρi|(∀a ∈ Σ)(δ(p, a), δ(q, a)) ∈ ρi}.
ρi有例如以下关系:
ρ0 ⊇ ρ1 ⊇ · · · .
若 ρi = ρi+1 则对于 ρi = ρj (j > i).
存在 0 ≤ k ≤ |Q| 满足 ρk = ρk+1.
对于 ρi ≠ ρi+1,存在下面性质Equation 1:
ρi ≠ ρi+1 ⇔ (∃p, q ∈ Q, a ∈ Σ) (p, q) ∈ ρi and (δ(p, a), δ(q, a)) ∉ ρi
⇔ (∃U ∈ Q/ρi , a ∈ Σ) p, q ∈ U and (δ(p, a), δ(q, a)) ∉ ρi
⇔ (∃U, V ∈ Q/ρi , a ∈ Σ) p, q ∈ U and δ(p, a) ∈ V and δ(q, a) ∉ V
⇔ (∃U, V ∈ Q/ρi , a ∈ Σ) δ(U, a) ∩ V ≠ ∅ and δ(U, a) ∉ V
算法抽象:
1: Q/θ ← {F, Q − F}
2: while (∃U, V ∈ Q/θ, a ∈ Σ) s.t. Equation 1 holds do
3: Q/θ ← (Q/θ − {U}) ∪ {U ∩ δ^-1(V, a), U − U ∩ δ^-1(V, a)}
4: end while
算法细化:
1:W ← {F, Q − F} # 有些版本号上仅仅是 W ← {F }
2: P ← {F, Q − F}
3: while W is not empty do
4: select and remove S from W
5: for all a ∈ Σ do
6: la ← δ^-1(S, a)
7: for all R in P such that R ∩ la ≠ ∅ and R ∉ la do
8: partition R into R1 and R2: R1 ← R ∩ la and R2 ← R − R1
9: replace R in P with R1 and R2
10: if R ∈ W then
11: replace R in W with R1 and R2
12: else
13: if |R1| ≤ |R2| then
14: add R1 to W
15: else
16: add R2 to W
17: end if
18: end if
19: end for
20: end for
21: end while
复杂度:
O(n log n)
另一个优化的代码:
1: P = {F, Q − F}
2: for all a ∈ A do
3: Add((min(F, Q − F), a), S)
4: while S ≠ ∅ do
5: get (C, a) from S (we extract (C, a) according to the
strategy associated with S: FIFO/LIFO/...)
6: for each B ∈ P split by (C, a) do
7: B′, B′′ are the sets resulting from splitting of B w.r.t. (C, a)
8: Replace B in P with both B′ and B′′
9: for all b ∈ A do
10: if (B, b) ∈ S then
11: Replace (B, b) by (B′, b) and (B′′, b) in S
12: else
13: Add((min(B′,B′′), b), S)
找出无用状态:
state_graph1 = {
'total_states': [ 'A', 'B', 'C', 'D', 'E' ],
'initial_states': [ 'A' ],
'termination_states': [ 'D' ],
'state_transition_map': {
'A': { 'a': 'B', 'b': 'C' },
'B': { 'a': 'B', 'b': 'D' },
'C': { 'a': 'B' },
'E': { 'a': 'E', 'b': 'E', },
'D': { 'a': 'B' },
},
'cins': [ 'a', 'b' ],
}
def get_unreachable_states( G ):
reachable_states = set( G['initial_states'] )
new_states = set( G['initial_states'] )
total_states = set( G['total_states'] )
cins = G['cins']
state_transition_map = G['state_transition_map']
while True:
temp_set = set()
for state in new_states:
for char in cins:
try:
next_state = state_transition_map[state][char]
temp_set.update( next_state )
except KeyError:
pass
new_states = temp_set - reachable_states
reachable_states.update( temp_set )
if new_states == set():
break
unreachable_states = total_states - reachable_states
return unreachable_states
print get_unreachable_states( state_graph1 )
Hopcroft:
import random
from copy import deepcopy
state_graph1 = {
'total_states': [ '1', '2', '3', '4', '5', '6', '7' ],
'initial_states': [ '1' ],
'termination_states': [ '6', '7' ],
'state_transition_map': {
'1': { 'a': '3', 'b': '2' },
'2': { 'a': '4', 'b': '2' },
'3': { 'c': '3', 'b': '6', 'd': '5' },
'4': { 'b': '7', 'd': '5', 'c': '3' },
'5': { 'a': '4' },
'6': { 'b': '6' },
'7': { 'b': '6' },
},
'cins': [ 'a', 'b', 'c', 'd' ],
}
state_graph2 = {
'total_states': [ 'A', 'B', 'C', 'D', 'E', 'F', 'S' ],
'initial_states': [ 'A' ],
'termination_states': [ 'C', 'D', 'E', 'F' ],
'state_transition_map': {
'S': { 'a': 'A', 'b': 'B' },
'A': { 'a': 'C', 'b': 'B' },
'B': { 'a': 'A', 'b': 'D' },
'C': { 'a': 'C', 'b': 'E' },
'D': { 'a': 'F', 'b': 'D' },
'E': { 'a': 'F', 'b': 'D' },
'F': { 'a': 'C', 'b': 'E' },
},
'cins': [ 'a', 'b' ],
}
state_graph3 = {
'total_states': [ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H' ],
'initial_states': [ 'A' ],
'termination_states': [ 'C' ],
'state_transition_map': {
'A': { '0': 'B', '1': 'F' },
'B': { '0': 'G', '1': 'C' },
'C': { '0': 'A', '1': 'C' },
'D': { '0': 'C', '1': 'G' },
'E': { '0': 'H', '1': 'F' },
'F': { '0': 'C', '1': 'G' },
'G': { '0': 'G', '1': 'E' },
'H': { '0': 'G', '1': 'C' }
},
'cins': [ '0', '1' ],
}
def hopcroft_algorithm( G ):
cins = set( G['cins'] )
termination_states = set( G['termination_states'] )
total_states = set( G['total_states'] )
state_transition_map = G['state_transition_map']
not_termination_states = total_states - termination_states
def get_source_set( target_set, char ):
source_set = set()
for state in total_states:
try:
if state_transition_map[state][char] in target_set:
source_set.update( state )
except KeyError:
pass
return source_set
P = [ termination_states, not_termination_states ]
W = [ termination_states, not_termination_states ]
while W:
A = random.choice( W )
W.remove( A )
for char in cins:
X = get_source_set( A, char )
P_temp = []
for Y in P:
S = X & Y
S1 = Y - X
if len( S ) and len( S1 ):
P_temp.append( S )
P_temp.append( S1 )
if Y in W:
W.remove( Y )
W.append( S )
W.append( S1 )
else:
if len( S ) <= len( S1 ):
W.append( S )
else:
W.append( S1 )
else:
P_temp.append( Y )
P = deepcopy( P_temp )
return P
print hopcroft_algorithm( state_graph1 )
print hopcroft_algorithm( state_graph2 )
print hopcroft_algorithm( state_graph3 )
岛津义弘:
“真田幸村,这片 ‘ 战国 ’ 的土地上有太多的冷漠和争斗。
一个人想要在这种 ‘ 乱世 ’ 中心存温和。他前进的道路定然会非常痛苦,
可是最后能走到 ‘ 武 ’ 之巅峰的人,却往往又都是那样内心温和的人。
由于这份温和可以让人变得非常强壮。
希望你即便面对的是你的敌人,挥舞自己的 ‘ 双枪 ’ 时,也不要失去这份温和。”
版权声明:本文博客原创文章,博客,未经同意,不得转载。