アルゴリズム入門 アルゴリズムとは • • • • 問題を解くための計算手順 曖昧さのない形式的な記述 計算機による実行も可能。 通常は、問題のどのような事例に対しても、 停止することを要請。 データ構造とは • データの計算機上での表現方法 • 同じデータにも多数の表現方法がある。 例えば、集合を表現するには、 – 辞書 – ハッシュ表 – 優先度つき待ち行列、2分探索木 – トライ、平衡木、MFSET • 様々なデータ構造 – リスト、スタック、待ち行列、写像 –木 – グラフ アルゴリズムとデータ構造 • アルゴリズム+データ構造=プログラム • 具体的なデータ構造に対して、 アルゴリズムを計算機に実行可能な形式、 すなわちプログラミング言語によって 記述したものがプログラムである。 • データ構造が違えば、アルゴリズムも異なる。 • すると、プログラムの効率も違って来る。 アルゴリズムの計算量 • 入力のサイズに従って、 計算の手間がどのように増えるか。 • 時間計算量 – 計算にかかる時間 • 領域計算量 – 計算に費やされるメモリの量 – つまり、計算の過程において、 中間結果を保持するためにどのくらいの メモリが必要か。 例:線形探索 static int search(int[] a, int key) { int n = a.length; for (int i = 0; i < n; i++) if (a[i] == key) return i; return -1; 等しさは== } 代入は= 配列について • 整数の配列 int[] a; • このように変数を宣言しただけでは、 配列の本体はまだない。(aの値はnull) • 配列の生成 a = new int[100]; 変数aは、配列への参照(reference)を保持している。 • 宣言+生成 int[] a = new int[100]; • 配列の長さ a.length • 配列を引数として渡したり、配列をメソッドの値として 返したりりすることができるが、それはすべて、 参照をやりとりしている。 sort(a, 0, a.length-1) for文 for (int 制御変数 = 初期値; 条件; 更新部) { ... ... } • 条件 i<n i<=n • 更新部 i++ i = i+1 i += 2 i += 1 例:二分探索 static int search(int[] a, int key) { int low = 0; int high = a.length-1; while (low <= high) { int middle = (low + high) / 2; if (key == a[middle]) return middle; else if (key < a[middle]) high = middle -1; else low = middle + 1; } return -1; } 二分探索の計算量 • 配列の大きさをnとする。 • whileループを回る度に、 探索する範囲が半分(以下)に減るので、 log2nに比例した時間(以下)で keyが見つかるか、 keyが見つからずに終了して-1が返る。 • 時間計算量はO(log2n) – この場合は、最悪の計算量 • 線形探索の計算量はO(n) バブルソート static void bubblesort(int[] a, int from, int to) { for (int i = from; i <= to; i++) for (int j = to; j > i; j--) if (a[j-1] > a[j]) { int w = a[j]; a[j] = a[j-1]; a[j-1] = w; } } 配列のランダムな初期設定 static void random(int[] a, int from, int to) { java.util.Random r = new java.util.Math.Random(); for (int i = from; i <= to; i++) a[i] = r.nextInt(65536); } public static void main(String[] args) { int[] a = new int[10]; random(a, 0, 9); print(a, 0, 9); bubblesort(a, 0, 9); print(a, 0, 9); } ソーティングの計算量 • 選択ソートおよびバブルソートは、 配列の大きさをnとしたとき、 時間計算量はO(n2) • 配列によらない。 時間の計測 • SystemクラスのcurrentTimeMillis()という スタティック・メソッドを用いることができる。 long t0 = System.currentTimeMillis(); ... long t1 = System.currentTimeMillis(); System.out.println(t1-t0); 演習 • Sortingにおいて、 long t0 = System.currentTimeMillis(); bubblesort(a, 0, 19999); long t1 = System.currentTimeMillis(); System.out.println(t1-t0); のようにして、ソーティングにかかる時間を 計測してみよ。 古典的な教科書 • データ構造とアルゴリズム – A.V.エイホ・J.E.ホップクロフト・J.D.ウルマン著 – 大野義夫訳 – 培風館 • • • • 基本的なデータ構造とそのアルゴリズム ソート アルゴリズムの解析法 アルゴリズムの設計法 基本的なデータ構造 • リスト、スタック、待ち行列、写像 • 木 – 2分木 • 集合を表現するデータ構造 – 辞書 – ハッシュ表 – 優先度つき待ち行列、2分探索木 – トライ、平衡木、MFSET • 有向グラフ • 無向グラフ 基本的なアルゴリズム • 有向グラフ – 最短経路問題 – 強成分 • 無向グラフ – コスト最小の極大木 – 関節点と二重連結成分 – グラフのマッチング • ソート – クイックソート、ヒープソート – ビンソート、基数ソート – 比較によるソートの下限 アルゴリズムの設計法 • 分割統治アルゴリズム • 動的計画法(ダイナミックプログラミング) – ワールドシリーズの賭け率 – 三角形分割問題 • 欲ばりアルゴリズム – 巡回セールスマン問題 • バックトラッキング – ゲームの木・巡回セールスマン問題 • 局所的な探索アルゴリズム – 最小コストの極大木・巡回セールスマン問題 より新しい教科書 • Introduction to Algorithms – Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest – The MIT Press and McGraw-Hill Book Company, 1989 C言語を対象とした教科書 • Cプログラマのための アルゴリズムと データ構造 近藤嘉雪【著】 SOFT BANK Publishing 具体的なプログラムが豊富。 演習 • 選択ソートおよびバブルソートに対して、配列 を大きくして、時間計算量を実測してみよ。 • クイックソートの計算量について考察せよ。 • クイックソートのプログラムに、既にソート済 みの配列を与えた場合、時間計算量はどの ようになるか。 ⇒ 計算量の回
© Copyright 2024 ExpyDoc