2回目講義内容 情報科学入門 計算機の仕組み (1.1,4.1,4.2,4.3) プログラムとプログラム言語 (1.2,4.5, 5.1) ソフトウェアとハードウェアの階層性 (1.3) アルゴリズムの重要性 (1.4) 土屋担当分 1 2 2進法 計算機の仕組み p.164 例.4ビットの補数表現 I/O Devices CPU 1000 1001 … 1111 0000 … 0111 Memory (Storage) -8 -7 -1 0 7 3 2値の演算 p.161 NOT(¬) 4 トランジスタによる演算の実現 AND(∧) OR (∨) トランジスタ 入力 出力 0 1 1 0 入力 出力 入力 出力 00 0 01 0 10 0 11 1 x y 入力 出力 00 0 01 1 10 1 11 1 x y 大きい 例 5V 出力 入力 電圧 小さい ドモルガンの法則 • ¬(A ∧ B) = ¬ A ∨¬ B • ¬(A ∨ B) = ¬ A ∧¬ B 入力 5 0V 出力 6 1 加算 フリップフロップによる値の記憶 p.169, 図4.11 (b) 同じ桁 入力 出力 00 0 01 1 10 1 11 0 (a) 桁上がり 入力 出力 00 0 01 0 10 0 11 1 p.163, 図4.6 入力信号 出力 制御信号 7 8 1.2 プログラムとプログラム言語 実行可能な操作 プログラム言語 I/O Devices CPU Memory (Storage) プログラムを書くための言葉 機械語に変換されて実行 高水準言語(c, Java, … 理解しやすい) 変換系 +,* 変換 機械語(最も原始的,理解しにくい (p.182)) フリップフロップ どの操作を行うかを指定する命令の列(プログラム)は メモリに保存 変換系(p.212) コンパイラ インタプリタ (例.cc, gcc: C言語のコンパイラ,C言語はコンパイラ型言語) 9 1.3 ソフトウェアとハードウェアの 階層 10 1.4 アルゴリズムの重要性 アルゴリズムの良さ 直感的な評価 応用ソフトウェア システムソフトウェア 速さ 使用するメモリ量 理論的,数学的分析 アルゴリズムの存在性 問題の難しさ,アルゴリズムの複雑さ ハードウェア 11 計算可能性(computability) (3.1節) 計算量(complexity) (3.2節) 12 2 3回目講義内容 アルゴリズム,プログラム,言語 (2.1) アルゴリズム,プログラム アルゴリズム,プログラム プログラムとプログラム言語 (Programming Language) 構文 (2.2, 5.3) 意味 (2.2) アルゴリズム(algorithm) プロセッサが処理(プロセス)をどのように行うかを記 述したもの 入力(input)を受け取り出力(output)を行う. 停止する(terminate). プログラム アルゴリズムを計算機が理解・実行できる形で記述し たもの. 13 14 COBOL プログラムとプログラム言語 事務処理用の言語 日付と時間の表示プログラム IDENTIFICATION DIVISION. PROGRAM-ID. TEST010. AUTHOR. K-NISHIYAMA. ENVIRONMENT DIVISION. CONFIGURATION SECTION. SOURCE-COMPUTER. PC-9800. OBJECT-COMPUTER. PC-9800. DATA DIVISION. WORKING-STORAGE SECTION. 01 W-INPUTYMD PIC 9(6). 01 W-INPUTHMS PIC 9(8). PROCEDURE DIVISION. ACCEPT W-INPUTYMD FROM DATE. ACCEPT W-INPUTHMS FROM TIME. DISPLAY "DATE = " W-INPUTYMD UPON CONSOLE. DISPLAY "TIME = " W-INPUTHMS UPON CONSOLE. STOP RUN. 様々な言語が存在 例.Pascal, Basic, COBOL, FORTRAN, C, C++, Java, Perl, Ada, Lisp, ML, … その理由(p.18) 分野の新しさ 目的の多様性 再発明への傾向 15 FORTRAN C 数値処理用の言語 システム開発等 int main(void) { int cn, cnn, i, m, max, min, n, nn; int *data_i, *ip, *work; max = 3; min = 1; 0010 C ----- EXAMPLE 1 ----0020 REAL VELO, ALPHA, RAD, TIME, PAI, GRAV, X, H 0030 PAI = 3.14159 0040 GRAV = 9.8 0050 READ(*,*)VELO, ALPHA, TIME 0060 RAD = ALPHA*PAI / 180. 0070 X = VELO*TIME*COS(RAD) 0080 H = -GRAV*TIME**2*0.5 + VELO*TIME*SIN(RAD) 0090 WRITE(*,*)'V0=', VELO, ' A=', ALPHA, ' T=', TIME 0100 WRITE(*,*)'X=', X, ' H=', H 0110 STOP 0120 END 16 data_i = mkdata_i(n, 1, 99); data_c = mkdata_c(cn, 'A', 'z'); if(data_i == NULL || data_c == NULL || data_d == NULL || data_s == NULL || work == NULL) { fprintf(stderr, "Error : out of memory¥n"); exit(-1); } } 17 18 3 構文と意味 構文の例 プログラムは計算機が正しく解釈できるように書 かれていなければならない. 文 → 主語 動詞 目的語 主語 → 冠詞 名詞 冠詞 → the 名詞 → elephant | peanut 動詞 → eats | ate 目的語 → 冠詞 名詞 3種類の正しさ 構文(syntax)の正しさ 意味(semantics)の正しさ 論理(logic)の正しさ 文 A | B は,AかBの何れかを選ぶことを表す 構文上正しい文の例 p.68, p.227, p.228 the elephant ate the peanut 他には? 主語 動詞 冠詞 名詞 目的語 冠詞 名詞 the elephant ate the peanut 19 Backus-Naur形式(BNF) 20 例.数式 生成規則(production rule)の集合により構文を 定義(p.219~) 選択 A → B|C|D AはBかCかD S → ( S ) | 符号 S | S 演算子 S | 非負整数 演算子 → + | - | * | / 符号 → + | 非負整数 → 0 | 正整数 正整数 → 数字1{数字2} 数字1 → 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 数字2 → 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 0回以上の繰り返し A → {B} Aはε(空文),B, BB, BBB, … プログラムの構文誤りは,コンパイル(プログラ ムを機械語に翻訳すること)時に検出される. 21 意味に関する正しさ 論理の正しさ 意味誤り 構文上は正しいが意味的に正しくない場合 22 例.the elephant ate the peanut 論理的な誤り プログラムでは構文誤りと異なり,実行時にしか 検出できない場合が多い. 間違ったアルゴリズム. 間違ったアルゴリズムの実装(プログラム化). 例. int a[5]; /* a[0], a[1], .., a[4]という変数を用意 */ int b = 10; printf(“%d¥n”, a[b]); プログラム実行前に発見できる意味誤り 例.宣言されていない変数の参照 23 24 4 4回目講義内容 復習:Backus-Naur形式(BNF) 前回の復習 … Backus-Naur 形式 (5.3) アルゴリズムの洗練 (2.3) 連続,選択,繰返し (2.4, 2.5, 2.6) p.219~ 選択 A → B|C|D アルゴリズムの基本構造 AはBかCかD 0回以上の繰り返し A → {B} Aはε(空文),B, BB, BBB, … 25 2.3 アルゴリズムの洗練 (1) 2.3 アルゴリズムの洗練 (2) アルゴリズムはあらゆる場合に対応できるように 設計されなければならない. 26 プログラムは基本的な操作(命令)の集合 設計に関する厳密な方法論が必要. アルゴリズムの設計においてもある程度の詳細化が 必要. 例.時刻表から飛行機の飛行時間を調べるアルゴリ ズム(p.24) 段階的洗練,トップダウン設計 プログラムの作成においては,その言語で指定できる 命令のレベルまで,詳細化しなければならない. 例1.ロボットに対するコーヒーを入れるためのアルゴリズム (pp.25~27) 27 例2 28 注釈 二つの整数の値を入れかえるプログラム main() { int a, b, c; a = 10; b= 20; 理解を助けるためのコメントで,実行されない部分 【 PASCAL】 { コメント } 注1.教科書で使用 【 C】 ? /* コメント */ 注2.「//コメント」 も利用できる場合が多い printf(“a:%d, b:%d¥n”, a, b); 【UNIXシェルスクリプト】 # コメント } 結果 a:20, b:10 29 30 5 2.4 連続(列,sequence) アルゴリズムの(制御に関する)基本構 造 2.4 連続(列,sequence) 2.5 選択 (selection) 2.6 繰返し (iteration) 順次ステップを実行していくという構造 すべてのアルゴリズムの基本 例.半径xの円の面積を表示するアルゴリズム xの二乗x2を求める x2 に円周率をかける 結果を表示する x 31 2.5 選択(selection) (if-then) 連続の問題点 32 if 条件 then ステップ 例.x/yを表示するアルゴリズム x/yを求める 結果を表示する 例.x/yを表示するアルゴリズム if y≠0 then x/y を計算 結果を表示 何が問題か? y が0なら単 に停止. 33 2.5 選択(selection) (if-then-else) 例 if 条件 then ステップ1 else ステップ2 実際のプロ グラム言語 34 最も大きい数を選択するアルゴリズム (p.32) if a > b then aを表示 else bを表示 【PASCAL】 if 条件 then 条件が成り立っている場合の処理 else そうでない場合の処理 【C】 if (条件) {条件が成り立っている場合の処理} else {そうでない場合の処理} a,b,c の3変数の場合は? 35 入れ子(nesting)を利用 36 6 最も大きい数を選択するアルゴリズム2 もし入力の変数(x1, x2, …)の数が予め決めら れていなかったら? 2.6 繰返し(iteration) (repeat-until) repeat ループの本体(body) until 条件 if x1 > x2 then if x1 > x3 then if x1 > x4 then if x1 > x5 then if x1 > x6 then if … 条件が成り立つまでループ本体を繰返し実行 実際のプロ グラム言語 何が問題?何が必要? 【PASCAL】 repeat 処理 until 条件 ループ (loop) 【C】 do { 処理 } while (!条件) 37 38 繰返し(iteration) (while) 最大値を持つ変数の選択 1番目の値を現在の最大値とする repeat if 次の値 > 現在の最大値 then 最大値を更新 until すべての変数を調べる while 条件 do ループの本体(body) max = x[0]; i = 1; do { if (x[i] > max) max = x[i]; i = i + 1; } while (!(i > n)) •C言語のプログラム n変数(x[0]~x[n-1])の場合 条件が成り立っている間ループ本体を繰返し実 行 実際のプロ グラム言語 【C】 【PASCAL】 while (条件) while 条件 do { 処理 } 処理 39 5回目講義内容 まとめ 連続 (Sequence) 選択 (Selection) if condition then step 40 if condition then step 1 else step 2 前回の復習 … 連続,選択,繰返し (2.4, 2.5, 2.6) 連続,選択,繰返しのまとめ (2.7) 繰返し (iteration) repeat loop body until condition while condition do loop body 41 42 7 選択(selection) (if-then-else) 例:最大値を持つ変数の選択 • a,bの2変数の場合 if 条件 then ステップ1 else ステップ2 実際のプロ グラム言語 if a > b then aを表示 else bを表示 【PASCAL】 if 条件 then 条件が成り立っている場合の処理 else そうでない場合の処理 【C】 if (条件) {条件が成り立っている場合の処理} else {そうでない場合の処理} • a,b,cの3変数の場合 if a > b then if a > c then aを表示 else cを表示 else if b > c then bを表示 else cを表示 43 繰返し repeat ループの本体(body) until 条件 事後検査(post-tested) 【C】 do { 処理 } while (!条件) 44 最大値を持つ変数の選択 1番目の値を現在の最大値とする repeat if 次の値 > 現在の最大値 then 最大値を更新 until すべての変数を調べる while 条件 do ループの本体(body) 事前検査(pre-tested) n=1の場合でもうまく行くか? 【C】 while (条件) { 処理 } 45 繰返し (その他) 無限回の繰返し repeat ループの本体(body) forever 【C】 while (1) { 処理 } 46 応用 N回の繰返し(Nは定数) repeat N回 ループの本体(body) 【C】 for (i=0; i<N; i++) { 処理 } 47 素数の判定 最大公約数の計算 ソーティング(Sorting, 並び換え) 48 8 素数の判定1 素数の判定2 Naïveなアルゴリズム (p.36の上) 素数の候補を1とそれ自身の間のすべての数で割る if どの数でも割り切れない then 素数である i = 2; divisible = 0; else 素数ではない while ( i < n ) { if ( n % i == 0) { divisible = 1;} i = i + 1; } if (divisible == 0) { printf(“%dは素数¥n”, n);} else { printf(“%dは素数ではない¥n”, n);} よりsmartなアルゴリズム (p.36 (2.10)) 約数の候補を2とする repeat 素数の候補を約数の候補で割る 約数の候補を1増やす until 割り切れた,あるいは 約数の候補>(素数の候補)1/2 if どの数でも割り切れない then 素数である else 素数ではない i = 2; divisible = 0; sq = sqrt(n); do { if ( n % i == 0) { divisible = 1;} i = i + 1;} while (!((divisible == 1) | (i > sq))); if (divisible == 0) { printf(“%dは素数¥n”, n);} else {printf (“%dは素数ではない¥n”, n);} 49 最大公約数の計算 50 ソーティング(並び換え) •Euclidのアルゴリズム (p.39) y > 0 ならば,GCD(x, y) = GCD(y, x/yの余り) y = 0 ならば,GCD(x, y) = x a[0] = 10 a[1] = 8 a[2] = 2 a[3] = 12 a[4] = 9 例.GCD(24, 9) = GCD(9, 6) = GCD(6, 3) = GCD(3, 0) = 3 while ( y != 0 ) { mod = x % y; x = y; y = mod; } printf(“答え %d¥n”, x); while y≠0 do x/yの余りを求める xをyで置き換える yを余りで置き換える 答えxを書く a[0] = 2 a[1] = 8 a[2] = 9 a[3] = 10 a[4] = 12 配列の大きさ n = 5 51 バブルソート(bubble sort) 52 6回目講義内容 最も単純なソーティングアルゴリズムの一つ 配列の大きさ n = 5 a[0] = 10 a[1] = 8 a[2] = 2 a[3] = 12 a[4] = 9 8 10 2 12 9 前回の復習 … 連続,選択,繰返し (2.7) 8 2 10 12 9 8 2 10 12 9 8 2 10 9 12 バブルソートを例として. モジュール性 (2.8) a[i] と a[i+1]を比較し,a[i]の方が大きければ交換 この処理を入れ替えが起こらなくなるまで繰り返す. 53 54 9 バブルソート(bubble sort) バブルソート(bubble sort) ソーティング(並び替え)アルゴリズムの一種 元のリスト sun dogma dogma sun typical typical body body dog dog dogma sun typical body dog dogma sun body typical dog 1回目終了 dogma sun body dog typical 1回目終了 時のリスト dogma sun body dog typical dogma sun body dog typical dogma body sun dog typical パス1 dogma body dog sun typical パス 2 •各パスにおいて, •先頭から順に,各要素を次の要素と比較 •順序が逆なら交換 •順序が逆の要素対が無くなるまでパスを繰り返す 55 バブルソート(bubble sort) 3回目終了 body dogma dog sun typical body dog dogma sun typical 56 最初のアルゴリズム 2回目終了 時のリスト dogma body dog sun typical body dog dogma sun typical body dog dogma sun typical sun dogma typical body dog dogma sun typical body dog dogma sun typical body dog dogma sun body typical dog dogma sun body dog typical N: 要素の数 各パスで N-1回の比較が必要 while リストが順に並んでいない do リストの先頭から始める 順に並んでいるか1ステップ では判断できない! repeat N – 1 回 if その要素と次の要素が逆順 then その要素と次の要素を交換 次の要素を考える パス3 57 リストが順に並んでいるか否かの判定 sun dogma typical body dog 各パスで交換があったか記憶しておく 元のリスト 1回目 2回目 3回目 4回目 sun dogma typical body dog dogma sun body dog typical dogma body dog sun typical body dog dogma sun typical body dog dogma sun typical Yes Yes 交換があった? Yes 58 最終的なアルゴリズム キーアイデア 2回目終了 dogma body dog sun typical No 整列済み ! 59 dogma sun typical body dog dogma sun typical body dog dogma sun body typical dog dogma sun body dog typical repeat リストの先頭から始める repeat N – 1 回 if その要素と次の要素が逆順 then その要素と次の要素を交換 交換したことを覚えておく 次の要素を考える until このパスで交換が行われなかった 60 10 C言語のプログラム モジュール do { flag = 0; for (i=0; i< n-1; i++) { if (a[i] > a[i+1]) { tmp = a[i]; a[i] = a[i+1];a[i+1] = tmp; flag = 1; } } } while (!(flag == 0)); repeat リストの先頭から始める repeat N – 1 回 if その要素と次の要素が逆順 then その要素と次の要素を交換 交換したことを覚えておく 次の要素を考える until このパスで交換が行われなかった do-whileを whileに変更 したもの 何度も利用するようなアルゴリズムの一部の機 能をまとめ,アルゴリズムの一つの構成要素とし たもの. 別の呼び方 flag = 1; while (flag) { flag = 0; for (i=0; i< n-1; i++) { if (a[i] > a[i+1]) { tmp = a[i]; a[i] = a[i+1]; a[i+1] = tmp; flag = 1; } } } 手続き procedure ルーチン routine サブルーチン subroutine 関数 function 61 例: 二つの三角形を書くというプロセス 例: 二つの三角形を書くアルゴリズム 仮定: 同時に引ける線は一本 (x1, y1) 仮定: 同時に引ける線は一本 (x2, y2) draw a line from (x1, y1) to (x2, y2) draw a line from (x2, y2) to (x3, y3) draw a line from (x3, y3) to (x1, y1) (x4, y4) (x5, y5) (x3, y3) 62 (x6, y6) draw a line from (x4, y4) to (x5, y5) draw a line from (x5, y5) to (x6, y6) draw a line from (x6, y6) to (x4, y4) 頂点の座標 以外同じ 63 64 仮引数と実引数 モジュール化の例 三角形を描くモジュール module triangle (a1, b1, a2, b2, a3, b3) draw a line from (a1, b1) to (a2, b2) draw a line from (a2, b2) to (a3, b3) draw a line from (a3, b3) to (a1, b1) Module module モジュール名 (p1,p2, …, pn) … body of the module (a1, b1) (a3, b3) Call (a2, b2) 上のモジュールを用いたアルゴリズム 仮引数 モジュール名 (x1,x2, …, xn) 実引数 triangle(x1,y1,x2,y2,x3,y3) triangle(x4,y4,x5,y5,x6,y6) •仮引数を実引数に置き換えて,モジュールは実行される. •仮引数と実引数の数や,種類が一致していなければ,意味誤り となる. 65 66 11 モジュール化の意義 教科書の例 モジュールの仕様を厳密に定めておくことで,モ ジュール自体の設計と,それを用いるプログラム の設計を分離することができる. 二つの正方形を描くアルゴリズム B A 段階的なトップダウン設計に有用. 設計の容易化. アルゴリズムの理解の容易化. 再利用性. 使える命令 •move(x) •left(x) •right(x) •raise •lower 67 68 モジュール化なし モジュール化した場合 二つの正方形を描くアルゴリズム B 二つの正方形を描くアルゴリズム B module A square(size) lower repeat 4回 move(size) left(90) raise A left(45) move(501/2) left(135) lower repeat 4回 move(10) left(90) raise right(135) move(501/2) left(135) lower repeat 4回 move(20) left(90) raise left(45) move(501/2) left(135) square(10) right(135) move(501/2) left(135) square(20) 引数の一致だけでなく,前提となっている約束事(仕様) に注意すること(例.終了時にペンがどうなっているか). 69 7回目講義内容 モジュール化の実際(Cの関数) int a, b, c, d, mod; a = 30; b = 21; c = 42; d = 12; while ( b != 0 ) { mod = a % b; a = b; b = mod; } printf(“答え %d¥n”, a); void GCD(int x, int y) { int mod; while ( y != 0 ) { mod = x % y; x = y; y = mod; } printf(“答え %d¥n”, x); } while ( d != 0 ) { mod = c % d; c = d; d = mod; } printf(“答え %d¥n”, c); main{ int a, b, c, d; a = 30; b = 21; c = 42; d = 12; GCD(a,b); GCD(c,d); } 70 71 再帰性 (2.9) 72 12 再帰性(2.9) 再帰(recursion) 再帰の例.階乗の計算 アルゴリズムで,自分自身を呼び出すような処理のこ と 1, 2, 3, …, N の積 fN = 1 × 2 × … × N-2 × N-1 × N 再帰的アルゴリズム(recursive algorithm) 自然数 N の階乗 (N!) 繰返しを用いたアルゴリズム product を1とする i を1とする repeat N 回 product に iをかける i に1足す 再帰を用いたアルゴリズムのこと 73 漸化式(recurrence) 74 それ自身を呼ぶアルゴリズム 自然数 N の階乗 (N!) fN = 1 × 2 × … × N-2 × N-1 × N fN-1 fN = N × fN-1 (N > 1) fN = 1 (N = 1) 自然数 N の階乗 (N!) fN = 1 × 2 × … × N-2 × N-1 × N fN-1 別の表現 fN = N × fN-1 (N > 1) fN = 1 (N = 1) module factorial(N) if N = 1 then 答えは 1 else N と factorial (N - 1)の積を求める 漸化式 (Recurrence, Recurrence relation) fn を i < n であるようなfi の組合せで表したもの 75 N=3の場合の実行 factorial(3): 非再帰アルゴリズム vs. 再帰アルゴ リズム module module factorial(N) factorial(N) ififNN==11 then 答えは then 答えは11 else elseNNととfactorial factorial(N (N--1)の積を求める 1)の積を求める if 3 = 1 then else 3 と factorial(2)の積を求める 76 6 if 2 = 1 then else 2 と factorial(1)の積を求める 2 if 1 = 1 1 then 答えは 1 else … product を1とする i を1とする repeat N 回 product に iをかける i に1足す 77 module factorial(N) if N = 1 then 答えは 1 else N と factorial(N-1)の積を求める どの再帰アルゴリズムにも同じプロセスを行う非再 帰アルゴリズムが存在 再帰アルゴリズムは理解・設計が容易なことが多い 非再帰アルゴリズムの方が計算機では高速に実行 できることが多い 78 13 Euclidのアルゴリズム(最大公約数の計 算) 再帰の例.文字列の反転 例.Factorial → lairotcaF reverse(c1 c2 c3 … cn) = reverse(c2 c3 reverse(c1) = c1 … cn) c1 GCD(x, y) = GCD(y, x/yの余り) if y > 0 GCD(x, y) = x if y = 0 x y 例: GCD(24, 9) = GCD(9, 6) (24 = 9 × 2 + 6) GCD(9, 6) = GCD(6, 3) (9 = 6 × 1 + 3) GCD(6, 3) = GCD(3, 0) (6 = 3 × 2 + 0) GCD(3, 0) = 3 while y≠0 do x/yの余りを求める xをyで置き換える yを余りで置き換える 答えxを書く (2文字以上) (1文字) module reverse(s) if sの長さが1 then その文字を書く else 最初の文字をとる reverse(sの残り) 取っていた文字を加える x/yの余り 24 = 23 × 3 9 = 32 79 80 再帰的なEuclidのアルゴリズムの実行 再帰的なEuclidのアルゴリズム GCD(24, 9)を計算 GCD(x, y) = GCD(y, x/yの余り) GCD(x, y) = x if y > 0 if y = 0 if 9 = 0 then else GCD(9, 6)を計算 module module GCD(x, GCD(x, y) y) ifif yy == 00 then 答えは xx then答えは else else GCD(y, GCD(y, x/y x/yの余り の余り)) 3 if 6 = 0 then else GCD(6, 3)を計算 module GCD(x, y) if y = 0 then 答えは x else GCD(y, x/y の余り) if 3 = 0 then else GCD(3, 0)を計算 if 0 = 0 then answer is 3 else … 3 3 3 81 再帰を用いた場合とそうでない場合 の比較 82 再帰アルゴリズムの他の例 while y≠0 do x/yの余りを求める xをyで置き換える yを余りで置き換える 答えxを書く module GCD(x, y) if y = 0 then 答えは x else GCD(y, x/y の余り) 83 ハノイの塔 マージソート 84 14 ハノイの塔 一番下の円盤をBに動かす には, 上のN-1枚の円盤を Cに動かさなければならな い. A 目的 必ず経なければならない状態 B C 塔全てを別の棒に移 動すること 規則 同時に動かせるのは 1つの円盤のみ 円盤を小さい円盤の 上に置いてはいけな い いずれは必ず一番下の円盤を Bに動かさなければならない. 86 85 再帰性 (N > 1) アルゴリズム C A A B movetower(N-1, A, C, B) B (1) movetower(N-1, A, C, B) C movetower(N, A, B, C) •N: 円盤の数 •A: source •B: target •C: workspace (2) AからBへ残った1枚を移動 module movetower(N, x, y, z) if N = 1 then 円盤をxからyに移動 else movetower(N-1, x, z, y) xに残った1枚をyに移動 movetower(N-1, z, y, x) movetower(N-1, C, B, A) (3) movetower(N-1, C, B, A) 87 アルゴリズムの実行 (N=3) movetower(3, a, b, c): a 88 ハノイの塔アルゴリズムについて b c module movetower(N, source, target, workspace) if N = 1 then円盤を source から target に移動 else movetower(N-1, source, workspace, target) 円盤を source から target に移動 movetower(N-1, workspace, target, source) if 3 = 1 then else movetower(2, a, c, b) if 2 = 1 then else movetower(1, a, b, c) if 1 = 1 then move 1 disk from a to b else move 1 disk from a to c movetower(1, b, c, a) if 1 = 1 then move 1 disk from b to c else … 簡潔で明快な解. 繰返しによるアルゴリズムも存在するが,簡潔では なく,導出にはかなりの洞察力が必要. 再帰はアルゴリズムの設計において強力な道具となる. … move 1 disk from a to b movetower(2, c, b, a) 89 90 15 マージソート(2) マージソート sort(0~4) sort(0~2) module sort(配列a) if aの大きさが1 then その値を返す else aを半分に分け,bとcとする. sort(b)を計算しb’とする sort(c)を計算しc’とする b’とc’をマージ(併合)する a[0] = 10 a[1] = 8 a[2] = 2 a[3] = 12 a[4] = 9 10 8 2 12 9 10 8 2 12 9 10 8 sort(0~1) sort(0) sort(1) sort(2) sort(3~4) sort(3) sort(4) 8 10 2 8 10 9 12 2 8 9 10 12 a[0] = 10 a[1] = 8 a[2] = 2 a[3] = 12 a[4] = 9 10 8 2 12 9 10 10 8 2 12 8 2 8 10 9 12 8 10 9 91 92 8回目講義内容 マージソートの実行 sort([10, 8, 2, 12, 9]) if 5 > 1 then sort([10, 8, 2]) if 3 > 1 then sort([10, 8]) if 2 > 1 then sort([10]) sort([ 8]) merge two halves [8, 10] sort([2]) merge two halves sort([12, 9]) if 2 > 1 then sort([12]) sort([9]) [9, 12] merge two halves merge two halves 再帰性(2.9) データ構造(2.11) ハノイの塔 [2, 8, 10] [2, 8, 9, 10, 12] 93 ハノイの塔 a N 塔全てを別の棒に移 動すること 規則 94 アルゴリズム 目的 2 8 9 10 12 N-1 同時に動かせるのは 1つの円盤のみ 円盤を小さい円盤の 上に置いてはいけな い b c module movetower(N, a, b, c) if N = 1 then 円盤をaからbに移動 else movetower(N-1, a, c, b) xに残った1枚をyに移動 movetower(N-1, c, b, a) • N-1 95 • いずれは必ず一番下の円盤 をbに動かさなければならな い. 一番下の円盤をbに動かす には, 上のN-1枚の円盤をc に動かさなければならない. 96 16 伝説 実行時間 module movetower(N, x, y, z) if N = 1 then 円盤をxからyに移動 else movetower(N-1, x, z, y) xに残った1枚をyに移動 movetower(N-1, z, y, x) 1 TN-1 1 TN-1 TN = 2TN-1 + 1 T1 = 1 TN = ? TN = 2 N - 1 TNN = 2NN - 1 B A 僧が64個の円盤を移動.完了した時,世界が 終わる. 世界が終わるまであと何日? N = 64 TN=64 = 264 -1 = 18446744073709551615 C 1秒に一回移動した場合 584942417355 years 97 列 (Sequence) データ構造(2.11) データ構造(data structure) 個々のデータを関係付け,管理や操作を行うための 構造 列 列を実現するデータ構造 列 (sequence) 98 配列(array)とリスト(list) スタック(stack)とキュー(queue) 配列 リスト (参考まで) 列におけるデータの挿入や削除といった処理に 制限を置いた抽象化されたデータ構造 グラフ(graph) データが一列にならんだもの 木(tree) スタック キュー(行列) 99 配列(Array)とリスト(List) - 参照(アクセス) 配列(Array)とリスト(List) - 削除と挿入 配列 100 位置(添字)によって識別 a[1]=10, a[2] = 2, a[3] = 8, … 配列 削除や挿入に手間がかかる a[1]=10, a[2] = 2, a[3] = 8, a[4] = 7… 削除 ランダムにアクセスできる リスト(参考) a[1]=2, a[2] = 8, a[3] = 7, … … … 各要素はデータと次の要素へのポインタ リスト 10 2 削除や挿入が容易 削除 8 ランダムアクセスはできない. 10 2 8 データ構造の大切さ 101 102 17 スタック(stack)とキュー(queue) 列におけるデータの挿入や削除といった処理に 制限を置いた抽象化されたデータ構造 下位のデータ構造は捨象してある(配列でもリストで もよい). 要素の追加,削除がLIFO(Last-in-first-out,後入れ先出 し)に従うようなデータ構造 応用例1.逆ポーランド記法の数式計算(HP社の電卓) スタック 元の数式 4 * 7 - (5 + 3) 逆ポーランド記法 4 7 * 5 3 + a = pop b = pop push(4) push(7) push (a*b) 要素の追加,削除がLIFO(Last-in-first-out,後入れ 先出し)に従うようなデータ構造 スタック(stack) 追加:push 取出し:pop キュー 要素の追加,削除がFIFO(First-in-first-out,先入れ 先出し)に従うようなデータ構造 7 4 4 4 7 28 * 3 5 28 5 28 5 3 8 28 20 + - 103 スタック(stack) キュー(queue) 応用例2.ウェブブラウザー ページBでリンクAをクリック ページBで戻るボタン 104 要素の追加,削除がFIFO(First-in-first-out,先 入れ先出し)に従うようなデータ構造 スタック1で push(B), スタック2を破棄,Aに進む 追加:enqueue 取出し:dequeue スタック1で A = pop, スタック2で push(B), Aに進む ページBで進むボタン 28 5 スタック1でpush(B),スタック2で A = pop, Aに進む www.1.com リンクをクリック www.2.com リンクをクリック 1 戻る 1 3 進む enqueue(3) 28 5 3 www.3.com 2 1 a = dequeue 5 3 2 1 105 木 (Tree) 106 データ構造としての木 グラフの一種 根 (root) 節 (node) 枝(branch) (一般には辺 (edge)) データを節に関連付ける. 階層的な関係の表現に適する. Japan … Osaka Kyoto 葉 (leaf) … 葉 (leaf) Suita … Ibraki Toyonaka 107 108 18 2分木 (Binary Tree) 整列2分木 各節点から出る枝が高々2本であるような木 T 順序を持つデータの管理方法 各節にデータを次のように割り当てる Tの左部分木=T’ Tの右部分木 左部分木のどのデータよりも順番が後 右部分木のどのデータよりも順番が前 8 4 T’の左部分 木 T’の右部分木 10 15 6 3 12 109 110 outputtree module --- 小さい値から順に出 力するアルゴリズム 2分木を用いたソーティング ツリーソート 2分木を中間的なデータ構造として使用 入力 8 buildtree(L, T) 10 15 4 3 3 6 12 8 4 出力 outputtree(T) 3 10 6 module outputtree(T) if Tが空でない then outputtree(Tの左の部分木) 3, 4, 6 Tの根の値を書く outputtree(Tの右の部分木) 15 4 6 8 10 12 15 各節のデータ 12 整列2分木 8 8 10, 12, 15 4 6 3 左部分木のどのデータより も順番が後 右部分木のどのデータより も順番が前 112 buildtree module 2分木を用いたソーティング ツリーソート module buildtree(L, T) 表 L の最初から始める while L が尽きていない do add (次の値, T) 2分木を中間的なデータ構造として使用 8 buildtree(L, T) 10 15 4 3 3 6 12 8 4 出力 outputtree(T) 3 10 6 15 15 12 111 入力 10 4 6 8 10 12 15 8 10 15 4 3 6 12 12 整列2分木 113 8 Input 4 3 10 6 15 12 114 19 整列2分木へのデータの追加 ツリーソート module add (data, T) if T が空である then data が根にあるような新しい部分木をつくる else if data が T の根にある値よりも前のものである then add(data, Tの左部分木) else add(data, Tの右部分木) add(6, T’) 3 8 8 outputtree(T) buildtree(L, T) 10 4 10 15 module sort(L) 4 空の Tで始める 3 3 buildtree(L, 6 T) 15 6 12 outputtree(T) 12 8 T add(6, T) add(6, T) 2分木を中間的なデータ構造として使用 入力 4 T’ 10 6 15 出力 3 4 6 8 10 12 15 整列部分木 115 116 試験予定,講義のURL等 12月15日 試験 持ちこみ可 講義で配った資料,過去問 ホームページからダウンロード可 http://www-kiku.ics.es.osaka-u.ac.jp/~t-tutiya 質問など t-tutiya@ist.osaka-u.ac.jp 117 20
© Copyright 2024 Paperzz