幅優先探索アルゴリズム - 法政大学...
TRANSCRIPT
1
• 幅優先探索アルゴリズム • 復習
• Javaでの実装
• 深さ優先探索 • 復習
• Javaでの実装
2
探索アルゴリズムの一覧
問題を解決するための探索 幅優先探索 深さ優先探索 深さ制限探索 均一コスト探索 反復深化法 欲張り探索 山登り法 最良優先探索 ……
3 3
Breadth-first search (幅優先探索)
アルゴリズムの流れ:
1. キューを作成し、スタートノードを加える.
2. ループ:
- もしキューが空なら探索失敗として探索を終了する
- 先頭のノードを開きキューから取り除く
- もし開いたノードがゴールなら、それを解決策として探索を終了する.
- 開いたノードの子ノードをキューの後ろに追加する
探索アルゴリズムはノードやリンクからなる階層的なツリー構造で構成された状態空間を探索するアルゴリズムです。
幅優先探索アルゴリズムは根ノード(Root node)から隣接している全てのノードを順番に探索していき、これを繰り返すことでゴールノードをみつけます。ゴールノードが見つかるか、すべてのノードが探索されたら探索は終了です。つまり、ある階層をすべて調べ、それが終わるとひとつ深い階層をすべて調べることを繰り返します
※横型探索ともいいます
4
例:
1-> 2->3->4->5->6 -> ……
5
子ノードを最後に追加するFIFO型(First In First Out)のデータ構造キューが実装に用いられる
6
擬似コード(幅優先探索) ArrayList queue = new ArrayLsit() ;
1 queue.add(initialNode) ;
2 while (queue.size()> 0) {
3 SearchNode testNode = (SearchNode)queue.firstElement() ;
queue.remove(0) ;
3.1 if (testNode.state.equals(goalState)) return testNode ;//ゴールを発見
3.2 if (!testNode.expanded) {
testNode.expand(queue,SearchNode.LAST);
}
}
return null ;
}
8
public void breadthFirst() { ArrayList<Node> open = new ArrayList<Node>(); open.add(start); ArrayList<Node> closed = new ArrayList<Node>(); boolean success = false; int step = 0; g.setColor(Color.RED); while (true) { System.out.println("STEP:" + (step++)); System.out.println("OPEN:" + open.toString()); System.out.println("closed:" + closed.toString()); if (open.size() == 0) { success = false; break; } else { Node node = open.get(0); open.remove(0); if (node == goal) { success = true; break; }else { ArrayList<Node> children = node.getChildren(); closed.add(node); for (int i = 0; i < children.size(); i++) { Node m = children.get(i); if (!open.contains(m) && !closed.contains(m)) { num++; m.setPointer(node);
if (m == goal) { open.add(0, m); node.getHm().get(m).draw(g, num); sleep(); break; } else { open.add(m); node.getHm().get(m).draw(g, num); sleep(); } } } } } } if (success) { String result = printSolution(goal, ""); showDaialog(result); reset.setVisible(true); } else { String result = "探索失敗"; showDaialog(result); reset.setVisible(true); } }
9
講義内の課題
なぜ2つのArrayList(open, closed)を使用するのか説明しなさい:
Figure 1において, • openに保存されているノードを書きなさい [ ] • Closedに保存されているノードを書きなさい
[ ]
Figure 1
10 10
Depth-first search(深さ優先探索)
アルゴリズムの流れ:
1. キューを作成し、スタートノードを加える.
2. ループ:
- もしキューが空なら探索失敗として探索を終了する
- 先頭のノードを開きキューから取り除く
- もし開いたノードがゴールなら、それを解決策として探索を終了する.
- 開いたノードの子ノードをキューの先頭に追加する
深さ優先探索アルゴリズムはルートノード木の最初のノード(Root node)から、ゴールノードが見つかるか葉(子の無いノードLeaf node)に行き着くまで深く掘り下げて探索を行います。もしゴールノードが見つからなかったら引き返し、次のまだ通っていないノードから葉ノードに到達するまで探します。つまり、深く進んでいき、行き止まったら引き返して、また深く進みながらゴール目指します
※縦型探索ともいう
11
例:
12
子ノードを先頭に追加するLIFO型(Last In First Out)のデータ構造キューが実装に用いられる
13
擬似コード(深さ優先探索) ArrayList queue = new ArrayLsit() ;
1 queue.add(initialNode) ;
2 while (queue.size()> 0) {
3 SearchNode testNode = (SearchNode)queue.firstElement() ;
queue.remove(0) ;
3.1 if (testNode.state.equals(goalState)) return testNode ;//ゴールを発見
3.2 if (!testNode.expanded) {
testNode.expand(queue,SearchNode.FRONT);
}
}
return null ;
}
15
public void breadthFirst() { ArrayList<Node> open = new ArrayList<Node>(); open.add(start); ArrayList<Node> closed = new ArrayList<Node>(); boolean success = false; int step = 0; g.setColor(Color.RED); while (true) { System.out.println("STEP:" + (step++)); System.out.println("OPEN:" + open.toString()); System.out.println("closed:" + closed.toString()); if (open.size() == 0) { success = false; break; } else { Node node = open.get(0); open.remove(0); if (node == goal) { success = true; break; }else { ArrayList<Node> children = node.getChildren(); closed.add(node); for (int i = 0; i < children.size(); i++) { Node m = children.get(i); if (!open.contains(m) && !closed.contains(m)) { num++; m.setPointer(node);
if (m == goal) { open.add(0, m); node.getHm().get(m).draw(g, num); sleep(); break; } else { open.add(m); node.getHm().get(m).draw(g, num); sleep(); } } } } } } if (success) { String result = printSolution(goal, ""); showDaialog(result); reset.setVisible(true); } else { String result = "探索失敗"; showDaialog(result); reset.setVisible(true); } }
赤文字が子ノードを調べてArrayListに追加している部分。 どう変更すべきか?
16
講義内の課題 1. breathFirst() メソッドを理解する 2. SearchingApplet.javaを実行する 3. breathFirst() メソッドと depthFirst()で異なる点を書く
4. 参考サイト http://el-tramo.be/jsearchdemo/
17
宿題
• プログラムのコメントを参考にしてApplet上に表示する都市の数を増やす
• breathFirst()メソッドを理解し depthFirst()メソッドを実装する
• depthFirst()メソッドのコードと説明をA4の紙に印刷して再来週提出(提出日:10月24日).