Download presentation
Presentation is loading. Please wait.
Published byWendy Shipley Modified over 10 years ago
1
Two algorithms for checking emptiness
2
How to check for emptiness? Is L (A) = ; ? Need to check if there exists an accepting computation (passes through an accepting state infinitely often).
3
Emptiness and accepting runs If there is an accepting computation, then it contains at least one accepting state an infinite # of times. This state must appear in a cycle. So, find a reachable accepting state on a cycle. How ?
4
Emptiness and accepting runs There can be an exponential number of cycles in a graph! But we want stay polynomial in the size of the graph …
5
Finding accepting runs Rather than looking for cycles, look for SCCs: A maximal Strongly Connected Component (SCC): a maximal set of nodes where each node is reachable from all others. Find a reachable SCC with an accepting node.
6
Finding accepting runs Finding SCC s is linear in the size of the graph. Relies on a modified DFS, in which the finishing time (the time leaving a node) is recorded. Let us recall DFS..
7
Depth First Search Program DFS For each initial state s dfs(s) end DFS Procedure dfs(s) for each s such that R(s,s ) do If new(s ) then dfs(s ) end dfs.
8
Start from an initial state q3 q4 q2 q1 q5 q1 Stack: Hash table: 1 Mark in each node: - Start time - Finish time
9
Continue with a successor q3 q4 q2 q1 q5 q1 q2 q1 q2 Stack: Hash table: 1 2 Mark in each node: - Start time - Finish time
10
One successor of q2. q3 q4 q2 q1 q5 q1 q2 q4 q1 q2 q4 Stack: Hash table: 1 2 3 Mark in each node: - Start time - Finish time
11
Backtrack to q2 (no new successors for q4). q3 q4 q2 q1 q5 q1 q2 q4 q1 q2 Stack: Hash table: 1 2 34 Mark in each node: - Start time - Finish time
12
Backtracked to q1 q3 q4 q2 q1 q5 q1 q2 q4 q1 Stack: Hash table: 1 2 34 5 Mark in each node: - Start time - Finish time
13
Second successor to q1. q3 q4 q2 q1 q5 q1 q2 q4 q3 q1 q3 Stack: Hash table: 1 2 34 5 6 Mark in each node: - Start time - Finish time
14
Backtrack again to q1. q3 q4 q2 q1 q5 q1 q2 q4 q3 q1 Stack: Hash table: 1 2 34 5 67 8 Mark in each node: - Start time - Finish time
15
An algorithm for finding SCCs We need the following definition for describing the algorithm: The transpose of G, written G T, is derived from G by reversing its edges. G GTGT
16
An algorithm for finding SCCs Strongly-Connected-Components(G) 1.Call DFS(G) to compute finish[v] for each vertex in G. 2.Call Modified-DFS(G T ), where the main loop of Modified- DFS(G T ) processes vertices in order of decreasing finish[v]. 3.Each tree in the depth-first forest of Modified-DFS(G T ) is a strongly connected component of G. Running time = running time of DFS = (V + E)
17
109 Example 1 23 4 56 7 8 11 12 13 14 1516 Compute DFS Finish times
18
15 Example 6 7 10 11 12 14 16 Finish times
19
Example GTGT 15 6 7 11 1216 Swapped the direction of edges 1014
20
Example 6 7 10 11 12 14 1516 GTGT DFS from decreasing finish times: every tree is an SCC.
21
An alternative algorithm The algorithm we saw so far for checking emptiness: Identify SCC s Return yes if one of them contains an accepting state We will see a better alternative.
22
Notation The automaton A: h, S, S 0, T, F i Denote by succ(s) the successors of s 2 S in A.
23
The Double DFS algorithm The first DFS finds a state f 2 F The second DFS attempts to close a loop around it. The trick is: how to avoid exploring the entire graph for each accepting state ? dfs1 dfs2
24
The Double-DFS algorithm DFS1(s) { push(s,Stack1); hash(s,Table1); for each t 2 Succ (s) {if t Table1 then DFS1(t);} if s 2 F then DFS2(s); pop(Stack1); } DFS2(s) { push(s, Stack2); hash(s, Table2) ; for each t 2 Succ (s) do { if t is on Stack1 exit(not empty); else if t Table2 then DFS2(t) } pop( Stack2); } Upon finding an accepting cycle, Stack1, Stack2, t, determines a witness: an accepting cycle reached from an initial state.
25
The Double DFS algorithm (full version) procedure Main() { foreach s 2 S_0 { if s Table1 then DFS1(s); } output(empty); exit; } procedure DFS1(s) { push(s,Stack1); hash(s,Table1); foreach t 2 Succ (s) { if t Table1 then DFS1(t); } if s 2 F then DFS2(s); pop(Stack1); } procedure DFS2(s){ push(s, Stack2); hash(s, Table2) ; for each t 2 Succ (s) do { if t is on Stack1 exit(not empty); else if t Table2 then DFS2(t) } pop(Stack2); } Input: A Initialize: Stack1:={}, Stack2:={} Table1:={}, Table2:={}
26
dfs1 1 234 8 56 7 Stack 1 = {1 – 6} Table 1 = {1 – 6} The Double DFS algorithm
27
dfs1 1 234 8 56 7 Stack 1 = {1 – 7} Table 1 = {1 – 7} The Double DFS algorithm
28
dfs1 1 234 8 56 7 Stack 1 = {1 – 6} Table 1 = {1 – 7} For the first time we identified an accepting state for which all the successors were already explored. Now its DFS2s turn to try to close the loop. The Double DFS algorithm
29
dfs2 1 234 8 56 7 Stack 1 = {1 – 6}Stack 2 = {7} Table 1 = {1 – 7}Table 2 = {7} The Double DFS algorithm
30
dfs1 1 234 8 56 7 Stack 1 = {1 – 4}Stack 2 = {} Table 1 = {1 – 7}Table 2 = {7} Still has successors… The Double DFS algorithm
31
dfs1 1 234 8 56 7 Stack 1 = {1 – 4,8}Stack 2 = {} Table 1 = {1 – 8}Table 2 = {7} The Double DFS algorithm
32
dfs1 1 234 8 56 7 Stack 1 = {1 – 4}Stack 2 = {} Table 1 = {1 – 8}Table 2 = {7} Again we identified a bad state for which all successors were already explored. Now its DFS2 turn to try to close the loop. The Double DFS algorithm
33
dfs2 1 234 8 56 7 Stack 1 = {1 – 4}Stack 2 = {5 - 6} Table 1 = {1 – 8}Table 2 = {5 - 7} No point continuing to what is already in Table 2 (why?) The Double DFS algorithm
34
dfs2 1 234 8 56 7 Stack 1 = {1 – 4}Stack 2 = {8} Table 1 = {1 – 8}Table 2 = {5 – 8} Bingo! Found a cycle ! (DFS2 progresses to node 3 which is on Stack1 but not in Table 2)
35
The Double-DFS algorithm outputs empty iff L (A) = ;. If it outputs not empty, then content of Stack1 + Stack2 + t defines an accepted (looping) word. The algorithm runs in (worst-case) time and space: O(|A|). Theorems about the D-DFS algorithm
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.