人工知能入門

Similar documents
グラフの探索 JAVA での実装

Java講座

PowerPoint Presentation

JavaプログラミングⅠ

Javaプログラムの実行手順

JavaプログラミングⅠ

プログラミング基礎I(再)

Microsoft PowerPoint Java基本技術PrintOut.ppt [互換モード]

2

問題 01 以下は コンソールより年齢を入力させ その年齢にあった料金を表示するプログラムである 年齢ごとの金額は以下の通りである 年齢の範囲金額 0 歳以上 6 歳以下 120 円 7 歳以上 65 歳未満 200 円 65 歳以上無料 package j1.exam02; import java

問題1 以下に示すプログラムは、次の処理をするプログラムである

Microsoft PowerPoint ppt

ALG ppt

memo

Microsoft PowerPoint - lec06 [互換モード]

Microsoft Word - NonGenList.doc

untitled

Prog1_3rd

始めに, 最下位共通先祖を求めるための関数 LcaDFS( int v ) の処理を記述する. この関数は値を返さない再帰的な void 関数で, 点 v を根とする木 T の部分木を深さ優先探索する. 整数の引数 v は, 木 T の点を示す点番号で, 配列 NodeSpace[ ] へのカーソル

情報処理Ⅰ

Microsoft PowerPoint - prog03.ppt

文字列操作と正規表現

メソッドのまとめ

Prog1_6th

Prog1_15th

Java 基礎問題ドリル ~ メソッドを理解する ~ 次のプログラムコードに 各設問の条件にあうメソッドを追加しなさい その後 そのメソッドが正しく動作することを検証するためのプログラムコードを main メソッドの中に追加しなさい public class Practice { // ここに各設問

PowerPoint プレゼンテーション

プログラミングA

問題1 以下に示すプログラムは、次の処理をするプログラムである

Program Design (プログラム設計)

プログラミング入門1

Microsoft PowerPoint - chap10_OOP.ppt

K227 Java 2

JAVA とテンプレート

デジタル表現論・第6回

Java プログラミング Ⅰ 7 回目 switch 文と論理演算子 条件判断文 3 switch 文 switch 文式が case の値と一致した場合 そこから直後の break; までを処理し どれにも一致しない場合 default; から直後の break; までを処理する 但し 式や値 1

メソッドのまとめ

ただし 無作為にスレッドを複数実行すると 結果不正やデッドロックが起きる可能性がある 複数のスレッド ( マルチスレッド ) を安全に実行する ( スレッドセーフにする ) ためには 同期処理を用いるこ とが必要になる 同期処理は 予約語 synchronized で行うことができる ここでは sy

: : : TSTank 2

2

デジタル表現論・第4回

Exam : 1z1-809-JPN Title : Java SE 8 Programmer II Vendor : Oracle Version : DEMO Get Latest & Valid 1z1-809-JPN Exam's Question and Answers 1 from Ac

プログラミング入門1

Javaセキュアコーディングセミナー東京 第2回 数値データの取扱いと入力値の検証 演習解説

JavaプログラミングⅠ

Javaセキュアコーディングセミナー東京 第3回 入出力(File, Stream)と例外時の動作 演習解説

基礎計算機演習 実習課題No6

Microsoft Word - NonGenTree.doc

プログラミング入門1

スライド 1

(Microsoft PowerPoint - \223\306\217KJAVA\221\346\202R\224\ ppt)

3 Java 3.1 Hello World! Hello World public class HelloWorld { public static void main(string[] args) { System.out.println("Hello World");

Method(C 言語では関数と呼ぶ ) メソッドを使うと 処理を纏めて管理することができる 処理 ( メソッド ) の再実行 ( 再利用 ) が簡単にできる y 元々はC 言語の関数であり 入力値に対する値を 定義するもの 数学では F(x) = 2x + 1 など F(x)=2x+1 入力値 (

Javaセキュアコーディングセミナー2013東京第1回 演習の解説

GEC-Java

Microsoft PowerPoint - prog09.ppt

明解Javaによるアルゴリズムとデータ構造

プログラミング入門1

8 if switch for while do while 2

Microsoft PowerPoint - prog09.ppt

た場合クラスを用いて 以下のように書くことが出来る ( 教科書 p.270) プログラム例 2( ソースファイル名 :Chap08/AccountTester.java) // 銀行口座クラスとそれをテストするクラス第 1 版 // 銀行口座クラス class Account String name

(1) プログラムの開始場所はいつでも main( ) メソッドから始まる 順番に実行され add( a,b) が実行される これは メソッドを呼び出す ともいう (2)add( ) メソッドに実行が移る この際 add( ) メソッド呼び出し時の a と b の値がそれぞれ add( ) メソッド

ALG2012-C.ppt

3,, となって欲しいのだが 実際の出力結果を確認すると両方の配列とも 10, 2, 3,, となってしまっている この結果は代入後の配列 a と b は同じものになっていることを示している つまり 代入演算子 = によるの代入は全要素のコピーではなく 先をコピーする ため 代入後の a と b は

JavaプログラミングⅠ

memo

1.SqlCtl クラスリファレンス SqlCtl クラスのリファレンスを以下に示します メソッドの実行中にエラーが発生した場合は標準エラー出力にメッセージを出力します (1)Connect() メソッド データベースへ connect 要求を行います boolean Connect(String

1. はじめに 二分木ヒープ 様々なアルゴリズムにおいて ある要素の集合またはリストから 最小 な要素を取り 出す必要がある そのような場合に使われる標準的データ構造が二分木ヒープ (binary heap) である あるオブジェクトO を考える そのオブジェクトは ラベル O. label と値

アルゴリズムとデータ構造1

離散数学

PowerPoint プレゼンテーション

2. データ構造ヒープに保存するデータは 番号付けられて保存される 従って リスト L として保存することとする 3. アルゴリズム 3.1. 要素の追加新しい要素の追加は リストの終端に置くことで開始する つまり 最下層の一番右 または新たに最下層を生成してその一番左となる この後 この要素を正し

Javaによるアルゴリズムとデータ構造

<4D F736F F D2091E F196E291E889F090E C4816A82CC838C E646F6378>

JavaプログラミングⅠ

新・明解Javaで学ぶアルゴリズムとデータ構造

JavaプログラミングⅠ

Java プログラミング Ⅰ 7 回目 switch 文と論理演算子 今日の講義講義で学ぶ内容 switch 文 論理演算子 条件演算子 条件判断文 3 switch 文 switch 文 式が case のラベルと一致する場所から直後の break; まで処理しますどれにも一致致しない場合 def

JavaプログラミングⅠ

break 文 switch ブロック内の実行中の処理を強制的に終了し ブロックから抜けます switch(i) 強制終了 ソースコード例ソースファイル名 :Sample7_1.java // 入力値の判定 import java.io.*; class Sample7_1 public stati

問 次の Fortran プログラムの説明及びプログラムを読んで、設問に答えよ。

オブジェクト指向プログラミング・同演習 5月21日演習課題

Taro-再帰関数Ⅱ(公開版).jtd

** 平成 16 年度 FE 午後問題 Java** 示現塾プロジェクトマネージャ テクニカルエンジニア ( ネットワーク ) など各種セミナーを開催中!! 開催日 受講料 カリキュラム等 詳しくは 今すぐアクセス!! 平成 16

PowerPoint Presentation


基本情報STEP UP演習Java対策

メディプロ1 Javaプログラミング補足資料.ppt

Javaの作成の前に

Microsoft PowerPoint - Pro110111

memo


PowerPoint プレゼンテーション

Microsoft Word - keisankigairon.ch doc

< F2D B838A835882CC8CF68EAE2E6A7464>

10K pdf

グラフと組み合わせ 課題 7 ( 解答例 ) 2013/5/27 1 列挙 n 個の文字の集合 { } S = a, a,, an の全てからなる文字列 つまり同じ文字を含まない 長さ n の文字列を列挙する 方法を考える 1. 何通りの文字列があるかを答えなさい また そのことが正しい

alg2015-6r3.ppt

スライド 1

目的 泡立ち法を例に Comparableインターフェイスの実装 抽象クラスの利用 型パラメタの利用 比較 入替 の回数を計測

Transcription:

藤田悟 黄潤和

探索とは 探索問題 探索解の性質 探索空間の構造 探索木 探索グラフ 探索順序 深さ優先探索 幅優先探索

探索プログラムの作成 バックトラック 深さ優先探索 幅優先探索

n 個の ueen を n n のマスの中に 縦横斜めに重ならないように配置する 簡単化のために 4-ueen を考える 正解

全状態の探索プログラム 全ての最終状態を生成した後に 最終状態が解であるかどうかを判定する 深さ優先探索プログラム 中間状態についても判定を行い 枝刈りを実施 解の条件を満たす限り 探索を深堀りする 幅優先探索プログラム 深さが同じ中間状態をすべて探索した後に 次の深さの中間状態を生成する

void start() { 初期化 (); search( 状態, 0); boolean search( 状態, depth) { if(depth == n) { // 最終状態の深さに到達 if( 最終状態判断 ( 状態 )) return true; // 解が見つかった else return false; // 解ではなかったので バックトラック // 状態の下に存在する新たな状態を生成する for(int i = 0; i < width; i++) { 新状態 = update( 状態, i); // 新状態に対して 探索を再帰的に呼び出す if (search( 新状態, depth+1)) { return true; return false; 再帰呼び出しがポイント

search(state, 0) search(state, 1) search(state, 2) search(state, 3) search(state, 4) return false

void start() { 初期化 (); search( 状態, 0); boolean search( 状態, depth) { // 状態の下に存在する新たな状態を生成する for(int i = 0; i < width; i++) { 新状態 = update( 状態, i); if( 中間状態判定 ( 新状態 )) { // 中間状態が矛盾ない場合だけ 探索を深く行う if(depth == n) { // 最終状態の深さに到達 return true; // 深さ n まで矛盾のない状態が作れたので 探索成功 else { // 新状態に対して 探索を再帰的に呼び出す if(search( 新状態, depth+1)) { return true; return false; 可能性のなくなった枝は false を返してバックトラック ( 一つ上の search に戻る ) する

search(state, 0) search(state, 1) search(state, 1) search(state, 2) return false; search(state, 2) search(state, 3) return false; search(state, 2) search(state, 3) search(state, 4) return true;

public class ueendepth { // nueen のサイズ int n = 4; // 全解探索の時には初期値を 0 にして 解の数を計算 // -1 の時は 単独解の探索 int count = 0; public static void main(string[] args) { new ueendepth().start(); void start() { int[] board = init(); // 初期化 In your Eclipse, please make Java Project Name: AI-0 Package Name: nueen Java Class Name: ueendepth search(board, 0); // 探索 if(count >= 0) { System.out.println(count);

// 初期化 int[] init() { int[] board = new int[n]; for(int i = 0; i < n; i++) { board[i] = -1; return board; // 結果のコンソール出力 void print(int[] board) { System.out.println(); for(int i = 0; i < n; i++) { String line = ""; for(int j = 0; j < n; j++) { if(board[i] == j) { line += "*"; else { line += "."; System.out.println(line); 2 solutions board[0] = -1 board[1] = -1 board[2] = -1 board[3] = -1.*.....* *.....*...*. *......*.*.. board[0] = 1 board[1] = 3.

// 探索 boolean search(int[] board, int depth) { n=4 // ブランチの数だけ探索を行う for(int i = 0; i < n; i++) { // 中間状態の生成 board[depth] = i; // 中間状態を評価し 真なら次の深さを探索 if(check(board, depth)) { if (depth + 1 == n) { // 正解に到達 print(board); if(count >= 0) { count++; else { return true; else { if(search(board, depth + 1) && count < 0) { return true; return false; 可能性のなくなった枝は false を返して

// 条件判定 boolean check(int[] board, int depth) { for(int i = 0; i < depth; i++) { // 縦チェック if(board[i] == board[depth]) { return false; // 斜め左上チェック if(board[depth] - (depth - i) == board[i]) { return false; // 斜め右上チェック if(board[depth] + (depth - i) == board[i]) { return false; return true;

void start() { 初期化 (); search(); boolean search() { state = poll(); // ueue から状態を 1 個取り出す if(state == null) { return false; // ueue が空になったので終了 // 状態の下に存在する新たな状態を生成する for(int i = 0; i < width; i++) { 新状態 = update( 状態, i); if( 中間状態判定 ( 新状態 )) { // 中間状態が矛盾ない場合だけ 探索を深く行う if(state.depth == n) { return true; // 深さ n の解が見つかったので 終了 else { offer( 新状態 ); // 新状態を ueue に詰め込む return search(); // 下位のノードを全て作り終わったところで search() を再帰呼び出しする

offer 1 search() 1 offer poll 1 5 4 3 2 2 3 4 5 search() 5 4 3 poll 2 6 7 offer 7 6 5 4 3 探索の途中で ueue に残っているノード ( 状態 ) の集合を オープンリスト と呼ぶ

offer 1 search() 1 offer poll 1 5 4 3 2 2 3 4 5 search() 5 4 3 poll 2 6 7 8 9 10 11 offer 7 6 5 4 3 12 13 14 15 探索の途中で ueue に残っているノード ( 状態 ) の集合を オープンリスト と呼ぶ 16 17

ueue の状態 poll 3 offer [ 8 7 6 5 4 ] poll 4 offer [ 9 8 7 6 5 ]???

ueue の状態 poll 3 offer [ 8 7 6 5 4 ] poll 4 offer [ 9 8 7 6 5 ] poll 5 offer [ 11 10 9 8 7 6 ] poll 6 offer [ 11 10 9 8 7 ] poll 7 offer [ 12 11 10 9 8 ] poll 8 offer [ 13 12 11 10 9 ] poll 9 offer [ 14 13 12 11 10 ] poll 10 offer [ 15 14 13 12 11 ] poll 11 offer [ 15 14 13 12 ] poll 12 offer [ 15 14 13 ] poll 13 offer [ 16 15 14 ] poll 14 offer [ 17 16 15 ] poll 15 offer [ 17 16 ] poll 16 解です! If (count = -1) 終了!Else (count>= 0) 続き offer [ 17 ] poll 17 解です! offer [ ] 終了!

public class ueenwidth { // nueen のサイズ int n = 4; // 全解探索の時には初期値を 0 にして 解の数を計算 // -1 の時は 単独解の探索 int count = 0; public static void main(string[] args) { new ueenwidth().start(); void start() { init(); // 初期化 search(); // 探索 if(count >= 0) { System.out.println(count); search() の引数がなくなっている以外は ueendepth と同じコード

class State { int[] board; int depth; 内部クラス盤面の配列と 探索の深さを格納 /** * 初期化 * @return 初期化された盤面 */ void init() { State state = new State(); state.depth = 0; state.board = new int[n]; for(int i = 0; i < n; i++) { state.board[i] = -1; offer(state); ueue に探索のルートノードを入れて 初期化完了

boolean search() { State state = poll(); // ueue にデータがなくなったら終了 if(state == null) return false; // ブランチの数だけ探索を行う for(int i = 0; i < n; i++) { State state0 = copy(state); // 中間状態の生成 state0.board[state.depth] = i; // 中間状態を評価し 真なら次の深さを探索 if(check(state0)) { state0.depth++; // depth を 1 増加させる if(state0.depth == n) {// 正解に到達 print(state0); if(count >= 0) { count++; else { ueue からデータを取り出す 可能な下位ノードを展開し ueue に格納 // 単独解が見つかったら終了 return true; else { offer(state0); 中間状態 - OK でも正解に到達ではない return search(); // 可能な中間状態をueueに入れた後で 次のsearch() を行う 探索を継続

後ろの state を入れる 先頭の state を取る // 中間状態を保存する配列 State[] states = new State[1000]; int statesstart = 0; int statesend = 0; void offer(state state) { State poll() { states[statesend] = state; statesend++; if(statesend == states.length) statesend = 0; if(statesend == statesstart) { System.out.println(" 配列の大きさが不足しています "); RuntimeException e = new RuntimeException("Array Overflow"); throw(e); if(statesstart == statesend) return null; State state = states[statesstart]; statesstart++; if(statesstart == states.length) statesstart = 0; return state; データ構造とアルゴリズムで学ぶ可変長配列 リストを使うコードの方が良いが 今回は 簡単化のため 固定長配列で実装 配列の大きさに注意が必要 statesstart( 読む ) statesend( 書く )

boolean check(state s) { // 深さ優先探索のコードと同等なので省略 void print(state s) { // 深さ優先探索のコードと同等なので省略 // 中間状態のコピー State copy(state b) { State state = new State(); state.board = new int[n]; for(int j = 0; j < n; j++) { state.board[j] = b.board[j]; state.depth = b.depth; 状態をコピーした新しい状態を生成するメソッド return state;

1. 配布プログラムを使ってし 深さ優先探索プログラムの search() メソッドを入力してコードを完成させ 動作させよ 2. 深さ優先探索プログラムを改造して 幅優先探索プログラムを作成して 動作させよ 1. 余裕があれば ueueの実装を List を使うなど 独自の実装に変えてみよ 3. start() メソッドの最初と最後で System.nanoTime() を 実行し その差分を計算することで 深さ優先探索と幅優先探索の実行時間を計測し 考察せよ 1. ueen の数を変化させる 2. 単解探索か全解探索かの条件を変える

幅優先探索プログラムは 再帰を利用して書かれているが これを while 文に書き直して動作させよ 幅優先探索プログラムの ueue を改造すると 深さ優先探索プログラムに変化する どのように改造すればよいか考え 実装してみよ