binary tree traversal preorder visit int u Graph
離散数学 二分木の巡回 (binary tree traversal) 行きがけ順 (pre-order) visit (int u, Graph g) { print u; if (g. left(u)) visit(g. left(u), g); if (g. right(u)) visit(g. right(u), g); } 通りがけ順 (in-order) visit (int u, Graph g) { if (g. left(u)) visit(g. left(u), g); print u; if (g. right(u)) visit(g. right(u), g); } 3 left visit (int u, Graph g) { if (g. left(u)) visit(g. left(u), g); if (g. right(u)) visit(g. right(u), g); print u; } 1 2 4 1 3 3 4 5 5 6 7 2 7 6 right 帰りがけ順 (post-order) 4 6 7 5
離散数学 疑似コード enum State {unvisited, visiting}; State state[N]; visit(int u, Graph g); visit_all (Graph g) { for (int i = 0; i < N; i++) state[i] = unvisited; for (int i = 0; i < N; i++) if (state[i] == unvisited) visit(i); } visit (int u, Graph g) { state[u] = visiting; print u; foreach (int v in g. adjacents(u) ) if (state[v] == unvisited) visit(v, g); }
離散数学 動作 visit(a) a visit(b) b a unvisited ? visit(b) visit(a) a visit(b) b d c b d d c > abc visit(a) visit(b) b b > abc d ? b > abcd d ? d b visit(d) c > abcd c d > abc visit(b) visit(d) c visit(c) a visit(b) visit(d) c a visit(b) b visit(c) c a visit(b) b >a a a visit(b) visit(c) c visit(a) d c > abcd d a : unvisited a : visiting a : visited
離散数学 無向グラフの閉路の検出(修正) enum State {unvisited, visiting}; State state[N]; visit(int u, int w, Graph g); visit (int u, int w, Graph g) { state[u] = visiting; print u; find_cycle_undir (Graph g) { for (int i = 0; i < N; i++) state[i] = unvisited; for (int i = 0; i < N; i++) if (state[i] == unvisited) visit(i, − 1, g); } foreach (int v in g. adjacents(u) ) if (v != w) if (state[v] == unvisited) visit(v, u, g); else // if (state[v] == visiting) print “cycle found!”; // (*) }
離散数学 閉路がある場合の動作 visit(a, ? ) a a visit(b, a) b visit(c, b) c visit(a, ? ) visit(c, b) d visit(d, c) > abcd a : unvisited a : visiting a : visited c b unvisited ? visit(c, b) d visit(d, c) c d visit(d, c) > abcd v == w ?
離散数学 有向グラフ用閉路の検出 enum State {unvisited, visiting, visited}; State state[N]; visit(int u, Graph g); visit (int u, Graph g) { state[u] = visiting; print u; find_cycle_dir (Graph g) { for (int i = 0; i < N; i++) state[i] = unvisited; for (int i = 0; i < N; i++) if (state[i] == unvisited) visit(i); } foreach (int v in g. adjacents(u) ) if (state[v] == unvisited) visit(v, g); else if (state[v] == visiting) print “cycle found!”; // (*) state[u] = visited; }
離散数学 トポロジカル・ソートの疑似コード enum State {unvisited, visiting, visited}; State state[N]; queue q; visit (int u, Graph g); visit (int u, Graph g) { state[u] = visiting; queue topological_sort (Graph g) { for (int i = 0; i < n; i++) state[i] = unvisited; q. empty(); for (int i = 0; i < n; i++) if (state[i] == unvisited) visit(i, g); } return q. reverse(); foreach (v in adjacents(u) ) if (state[v] == unvisited) visit(v, G); else if (state[v] == visiting) print “not a DAG!”; // (*) state[u] = visited; q. append(u); // add to tail }
離散数学 証明 F ∞ 12 ∞ 0 V p V : visited U : unvisited F : frontier U 10 q ∞ 11 ∞
離散数学 Dijkstra 法: 擬似コード 4 8 3 1 6 start 4 2 1 5 goal Wu, v : 辺u vの重み(距離) dijkstra (s, G) { V = {}; D = new int[n]; for (i = 0; i < n; i++) { if (i == s) D[i] = 0; else D[i] = ; } while (V A) { pick u V that minimizes D; V = V + { u }; for v adjacents(u) { d = D[u] + Wu, v ; if (d < D[v]) D[v] = d; } } }
- Slides: 82