論理と計算(2)

Similar documents
論理と計算(2)

Microsoft PowerPoint - ca ppt [互換モード]

プログラミング入門1

PowerPoint Presentation

メソッドのまとめ

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

プログラム言語及び演習Ⅲ

簡単な検索と整列(ソート)

スライド 1

プログラミング入門1

Sort-of-List-Map(A)

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

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

デジタル表現論・第4回

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

オートマトン 形式言語及び演習 1. 有限オートマトンとは 酒井正彦 形式言語 言語とは : 文字列の集合例 : 偶数個の 1 の後に 0 を持つ列からなる集合 {0, 110, 11110,

デジタル表現論・第6回

Microsoft PowerPoint - 13approx.pptx

program7app.ppt

Java講座

Microsoft PowerPoint ppt

JavaプログラミングⅠ

プログラミングA

Microsoft PowerPoint - qcomp.ppt [互換モード]

プログラミング実習I

C プログラミング演習 1( 再 ) 2 講義では C プログラミングの基本を学び 演習では やや実践的なプログラミングを通して学ぶ

Prog1_3rd

ガイダンス

2

Prog1_6th

プログラミング実習I

Prog1_10th

JavaプログラミングⅠ

Microsoft Word - no11.docx

情報処理Ⅰ

2006年10月5日(木)実施

memo

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

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

Microsoft PowerPoint - 09.pptx

Microsoft PowerPoint - algo ppt [互換モード]

オートマトン 形式言語及び演習 3. 正規表現 酒井正彦 正規表現とは 正規表現 ( 正則表現, Regular Expression) オートマトン : 言語を定義する機械正規表現 : 言語

模擬試験問題(第1章~第3章)

PowerPoint プレゼンテーション

Microsoft PowerPoint - prog03.ppt

gengo1-11

Prog2_9th

構造化プログラミングと データ抽象

PG13-6S

プログラミング入門1

Microsoft PowerPoint - prog09.ppt

Javaプログラムの実行手順

人工知能入門

構造化プログラミングと データ抽象

Microsoft PowerPoint - 5.ppt [互換モード]

Microsoft PowerPoint - chap10_OOP.ppt

Prog1_12th

Program Design (プログラム設計)

2

PowerPoint プレゼンテーション

Microsoft PowerPoint - prog09.ppt

文字列操作と正規表現

Microsoft PowerPoint - 3.pptx

Microsoft PowerPoint - ●SWIM_ _INET掲載用.pptx

微分方程式 モデリングとシミュレーション

JavaプログラミングⅠ

次に示す数値の並びを昇順にソートするものとする このソートでは配列の末尾側から操作を行っていく まず 末尾の数値 9 と 8 に着目する 昇順にソートするので この値を交換すると以下の数値の並びになる 次に末尾側から 2 番目と 3 番目の 1

PowerPoint プレゼンテーション

JavaプログラミングⅠ

データ構造

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

Microsoft Word - Javacc.docx

Prog2_10th

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

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

Microsoft PowerPoint ppt

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

Programming D 1/15

Prog1_15th

メソッドのまとめ

基本情報STEP UP演習Java対策

プログラミング基礎

Microsoft PowerPoint - ProD0107.ppt

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

Functional Programming

Javaの作成の前に

スライド 1

Prog1_10th

1

Microsoft PowerPoint - 計算機言語 第7回.ppt

1. 関数 scanf() 関数 printf() は変数の値を画面に表示しますが それに対し関数 scanf() はキーボードで入力した値を変数に代入します この関数を活用することで対話式 ( ユーザーの操作に応じて処理を行う ) プログラムを作ることができるようになります 整数の和

プログラムの基本構成

4 月 東京都立蔵前工業高等学校平成 30 年度教科 ( 工業 ) 科目 ( プログラミング技術 ) 年間授業計画 教科 :( 工業 ) 科目 :( プログラミング技術 ) 単位数 : 2 単位 対象学年組 :( 第 3 学年電気科 ) 教科担当者 :( 高橋寛 三枝明夫 ) 使用教科書 :( プロ

Microsoft PowerPoint - ad11-09.pptx

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

memo

関数の呼び出し ( 選択ソート ) 選択ソートのプログラム (findminvalue, findandreplace ができているとする ) #include <stdiu.h> #define InFile "data.txt" #define OutFile "surted.txt" #def

Prog1_2nd

JavaプログラミングⅠ

DVIOUT

Transcription:

情報科学概論 Ⅰ アルゴリズムと計算 亀山幸義 http://logic.cs.tsukuba.ac.jp/~kam 計算とは? コンピュータが計算できることは? 1 2 関数 = 計算? NO 部分関数と計算 入力 1 入力 2 関数 出力 入力 1 入力 2 部分関数 出力 停止しない 入力 1 入力 2 コンピュータ 止まらないことがある出力 3 入力 1 入力 2 コンピュータ 出力 停止しない 計算 = 部分関数? コンピュータが行う 計算 は 部分関数の一種とみなすことができる 整数 M,N M N 文字列 S,T S 中のTの出現回数 Java 言語のプログラム それをコンパイルした機械語プログラム 5 計算 = 部分関数? 問題 : 部分関数は すべて計算と見なせるか? すべての部分関数は コンピュータのプログラムとして表現できるか? ここでの仮定 コンピュータの入力と出力は文字列 コンピュータは いくらでも長い文字列を扱える ( メモリがいくらでも買い足せる ) 6 1

計算 = 部分関数? の問題 そもそも問題になっているだろうか? いくらコンピュータが高速 大容量になっても 宇宙にある分子の総数より多い文字からなる文字列は扱えないのでは? 入出力の文字列の長さには制限をかけた方がいいのでは? コンピュータは 今もこれからもどんどん進歩する 今の時点で計算できるかどうか なんて考えることに意味があるか? 話を簡単にするため 無視します 計算 = 部分関数? の問題 1 入力 (1 引数 ) の部分関数文字列を 1 つもらって 文字列を返す例 : g(s) = s が tsukuba という文字列を含む回数 ( 自然数 ) を 文字列にしたもの 2 入力 (2 引数 ) 以上の部分関数も同様 7 8 Java プログラム P P を ( 任意の )1 引数の Java プログラムとする入力も出力も文字列と見なす 停止しないかもしれない Java プログラムの実行 1 引数の Java プログラム P に対して P に入力 s を与えて計算させる s は文字列 P(s) この計算が停止して答えを出す P(s) この計算が停止しない ( 無限ループ ) 9 10 Java プログラム H H を以下の計算をする 2 引数の Java プログラムとする H に入力 p と入力 s を与えて計算させる p,s は文字列 H(p,s)=1 p が 1 入力の Java プログラムを表し かつ p(s) のとき H(p,s)=0 それ以外のとき Java プログラム G G を以下の計算をする 1 引数の Java プログラムとする G に入力 p を与えて計算させる p は文字列 G(p)= 無限ループ H(p,p)=1のとき G(p)=1 H(p,p)=0のとき 11 12 2

Java プログラム H と G 2 入力プログラム H H(p,s)=1 p(s) のとき H(p,s)=0 それ以外 1 入力プログラム G G(p)= 無限ループ H(p,p)=1 のとき G(p)=1 それ以外 なんと 既に矛盾している G(G) -> H(G,G)=1 -> G(G) = 無限ループ G(G) -> H(G,G)=0 -> G(G) = 1 13 Java プログラム H と G 朝早くから授業に出ていたのに 矛盾したことを教えられてしまった! のではなく H と G が Java プログラムとして書ける という仮定が誤りということ 2 入力プログラム H H(p,s)=1 p(s) のとき H(p,s)=0 それ以外 1 入力プログラム G (H が書ければ G は書ける ) G(p)= 無限ループ H(p,p)=1 のとき G(p)=1 それ以外 14 Java プログラム H 停止性判定問題 2 入力プログラム H H(p,s)=1 p(s) のとき H(p,s)=0 それ以外 H の本質 1 入力の Java プログラム ( を表す文字列 )p とそれに対する入力 s が与えられたとき p(s) の計算が停止するかどうかを 有限時間で判定する 結論 : このような H は Java プログラムとして決して実現できない 15 Java プログラム p と文字列 s が与えられた時 p(s) の計算が有限時間で停止するかどうかを ( どんな p s に対しても ) 判定する Java プログラムは存在しない 実は Java プログラム に限定されない 任意の C プログラムに対する停止性判定をする C プログラムも存在しないし 任意の Haskell プログラムに対する停止性判定をする Ruby プログラムも存在しない 16 計算 部分関数 文字列をもらって 文字列を返す ( 数学的に定義できる ) 部分関数すべてからなる集合 コンピュータのプログラムとして表現可能な 計算 のすべてからなる集合 (Java でも C でも ML でも同じ ) プログラムの停止性判定問題 17 コンピュータ科学の限界? 停止性判定プログラムが存在しないという定理は 今後 どんなにプログラム言語や計算論が進歩しても成立してしまう コンピュータ科学の進歩には限界があるのか? NO. 計算可能な範囲だけでも極めて豊富な ( 人類がまだ活用していない ) 面白くて有用な世界が広がっている 18 3

Fibonacci 数 (1) = 1 if n = 1, 2 Fib(n-2) + Fib(n-1) if n > 2 アルゴリズムとは? 19 Fib(1) = Fib(2) = 1 Fib(3) = Fib(1) + Fib(2) = 1 + 1 = 2 Fib(4) = Fib(2) + Fib(3) = 1 + 2 = 3 20 Fibonacci 数 (2) Fibonacci 数を求める (1) = 1 if n = 1, 2 Fib(n-2) + Fib(n-1) if n > 2 Fib(5) = 5, Fib(6) = 8, Fib(7) = 13, Fib(10) = 55, Fib(20) = 6765, Fib(30) = 832040 21 class Fib1 { public static int fib (int n) { if (n < 3) return 1; else return (fib(n-2) + fib(n-1)); public static void main (String args[]) { int n = Integer.valueOf(args[0].intValue()); int r = fib(n); System.out.println( fib of + args[0] + is + r); Java プログラム 22 Fibonacci 数を求める (2) Fibonacci 数を求める ( 素朴法 ) 1 n = 1, 2 = Fib(n-2) + Fib(n-1) n > 2 n class Fib1 { public static int fib (int n) { if (n < 3) return 1; else return (fib(n-2) + fib(n-1)); public static void main (String args[]) { int n = Integer.valueOf(args[0].intValue()); int r = fib(n); System.out.println( fib of + args[0] + is + r); Fib(n) 10 55 20 6765 30 832040 40 止まらない 23 1 n = 1, 2 = Fib(n-2) + Fib(n-1) n > 2 関数 Fib ( 入力 n : int) n =1, 2 ならば 1 を返す n>2 ならば r1 = Fib(n-2) r2 = Fib(n-1) r1+r2 を返す 疑似コード ( 疑似プログラム ) による記述 24 4

Fibonacci 数を求める ( メモ化 1) Fibonacci 数を求める ( メモ化 2) 1 n = 1, 2 = Fib(n-2) + Fib(n-1) n > 2 関数 Fib ( 入力 n : int) n =1, 2 ならば Fib(n)=1 をメモして 1 を返す n>2 ならば Fib(n-2) の値からメモから取り出し r1 とする Fib(n-1) の値からメモから取り出し r1 とする Fib(n)=r1+r2 をメモして r1+r2 を返す 25 1 n = 1, 2 = Fib(n-2) + Fib(n-1) n > 2 関数 Fib ( 入力 n : int) n =1, 2 ならば Fib(n)=1 をメモして 1 を返す n>2 ならば Fib(n-2) の値からメモから取り出し r1 とする Fib(n-1) の値からメモから取り出し r1 とする Fib(n)=r1+r2 をメモして r1+r2 を返す Fib(1) = 1 Fib(2) = 1 Fib(3) = 1 + 1 = 2 Fib(4) = 1 + 2 = 3 Fib(5) = 2 + 3 = 5 n Fib(n) 10 55 20 6765 30 832040 40 102334155 50-298632863 Java の int 型として実装した場合 26 Fibonacci 数を求める ( メモ化 3) メモ化法による改善 1 n = 1, 2 = Fib(n-2) + Fib(n-1) n > 2 Int 型がオーバーフロー 下 3 けたのみを計算実際には 最近 2 つの値 のみメモ化すればよい n Fib(n) 10 055 20 765 30 040 40 155 50 025 8000 125 計算速度は向上 素朴法では Fib(30) まで メモ化法では Fib(8000) でも計算可能 メモリは多く使う メモ化のための記憶領域が必要 感覚的な比較ではなく きちんと比較をしたい 速度が 10msec などはあまり意味がない 27 28 アルゴリズム アルゴリズム 問題 に対する 解き方 与えられた基本命令をどう組み合わせて 解を求めるかを記述したもの アルゴリズムとプログラムの違い プログラムは 特定のプログラム言語で記述 その言語の処理系を用いて実行可能 アルゴリズムは より抽象的 一般的な疑似プログラムとして記述する ( 特定のプログラム言語や 特定の実装方式に関する記述を取り除いた記述とする ) そのままでは実行可能でないことが多い 29 アルゴリズムの計算量 計算量 アルゴリズム をはかる尺度 計算の複雑さ とも言う computational complexity 2 つの計算量 時間計算量 time complexity 計算のスピード 実行速度 空間計算量 space complexity メモリ ( アルゴリズムを実行する過程で 瞬間的に使用する最大メモリ量 ) 30 5

具体的な時間計算量 Fib(n) に対する素朴法 足し算の回数 Fib(n) 関数呼び出しの回数 >Fib(n) その他の計算 Fib(n) に対するメモ化法 足し算の回数 n-2 関数呼び出しの回数 n-1 その他の計算 たしかに 後者の方が速い 31 Fib(n) に対する より高速な方法 (1) 準備 : x^n (x の n 乗 ) を 掛け算だけで計算 例 :x^13 を計算 x -> x^2 -> (x^2)^2 = x^4 -> (x^4)^2 = x^8 x * x^4 * x^8 = x^13 一般に x, x^2, x^4, x^8,.. を用意して それらを掛け合わせて x^n を得ることができる nの2 進数表現の桁数を k とするとき 2k-2 回以下の掛け算で x^n が求まる n=13 (2 進で1101) なら k=4 32 2 k - 2 < 2 log_2 n Fib(n) に対する より高速な方法 (2) Fib(n) に対する より高速な方法 (3) メモ化法 : x = Fib(n-1) x = y = Fib(n) y = Fib(n) y = x+y = Fib(n-1)+Fib(n) = Fib(n+1) 0 1 1 1 0 1 1 1 x y n-1 = x y 1 1 = Fib(n) Fib(n+1) 33 A = 0 1 1 1 A -> A^2 -> A^4 ->. -> A^1024 0 1 1 1 n-1 1 1 = Fib(n) Fib(n+1) 34 Fib(n) に対する より高速な方法 (4) 問題 2*2 行列 A の n-1 乗を計算すれば そのあと 1 回の足し算で Fib(n) が求まる 2 つの 2*2 行列の積 8 回の掛け算 4 回の足し算 n 乗の計算は 2log_2 n 回以下の乗算 よって Fib(n) は 16 log_2 (n-1) 回以下の掛け算 8 log_2 (n-1) 回以下の足し算 より高速な方法 は本当に高速か? 整数の乗算 整数の加算 合計 素朴法 0 Fib(n) Fib(n) メモ化法 0 n-2 n-2 より高速な方法 < 16 log n < 8 log n <24 log n 35 36 6

オーダ記法 定数倍 などを無視し n が非常に大きくなったときの関数の振る舞いだけを表す表記方法 素朴法 O(α^n) α=( 5 + 1)/2 メモ化法 O(n) より高速 O(log n) 38 オーダの違いは とんでもない差を生じる 100n と 2^n の差 n =10 1000 1024 n = 20 2000 ほぼ 10^6 n = 30 3000 ほぼ 10^9 計算機が 2 倍のスピードになっても 指数関数的アルゴリズムでは 計算できる n が 1 増えるだけ アルゴリズムの良し悪しの差は ハードウェアの改良だけでは とても埋められない 良いアルゴリズムを考えるのは 今も将来も極めて重要 39 まとめ アルゴリズム 計算量 アルゴリズムの良し悪し 参考 : O(n^k) となるアルゴリズムが存在する問題たちの集合を クラス P と呼ぶ P は多項式を意味する a x^n + b x^(n-1) + 整列アルゴリズム 40 41 整列 ( ソート ) 10 2 8 9 2 1 4 7 6 3 昇順に整列 1 2 2 3 4 6 7 8 9 10 素朴な整列アルゴリズム (1) 10 2 8 9 2 1 4 7 6 3 最小値を探す 10 2 8 9 2 1 4 7 6 3 先頭と最小値をいれかえる 1 10 2 8 9 2 4 7 6 3 42 43 7

素朴な整列アルゴリズム (2) 1 10 2 8 9 2 4 7 6 3 素朴な整列アルゴリズム (3) 1 2 10 8 9 2 4 7 6 3 最小値 ( の 1 つ ) を探す 1 10 2 8 9 2 4 7 6 3 1 2 2 10 8 9 4 7 6 3 先頭と最小値をいれかえる 1 2 10 8 9 2 4 7 6 3 1 2 2 3 10 8 9 4 7 6 44 1 2 2 3 4 6 7 8 9 10 45 素朴な整列アルゴリズム (4) 時間計算量 ( データの個数を n とする ) 2 つのデータの比較 (n-1) + (n-2) + + 1 = n(n-1)/2 データ列における 2 つのデータの交換 n+(n-1) + + 1 = n(n+1)/2 その他 ( ループの制御等 ) は無視 時間計算量は O(n^2) 用途によってはこれでも十分利用価値があるが n が非常に大きなときは 遅すぎる 例 : 筑波大学のすべての科目を科目番号順に整列 46 マージソート ( 併合ソート ) のアルゴリズム (1) 基本アイディア : Divide and Conquer ( 分割統治法 ) 多数のデータ数に対して何らかの解と求める場合 データを 2 つ ( 以上 ) に分割して それぞれの解を求め その結果を用いて全体に対する解を求める方法 47 マージソート ( 併合ソート ) のアルゴリズム (2) 10 2 8 9 2 1 4 7 6 3 2 分割する 10 2 8 9 2 それぞれを別々にソートする 1 4 7 6 3 マージソート ( 併合ソート ) のアルゴリズム (3) 2 2 8 9 10 1 3 4 6 7 2 つのソート済みの列をマージ ( 併合 ) する 1 2 2 3 4 6 7 8 9 10 2 2 8 9 10 1 3 4 6 7 48 49 8

マージ操作 (1) マージ操作 (2) 2 2 8 9 10 1 3 4 6 7 2 > 1 なので 1 を書き込む 2 2 8 9 10 1 3 4 6 7 2 < 3 なので 2 を書き込む 1 1 2 50 51 マージ操作 (3) マージ操作 (4) 2 2 8 9 10 1 3 4 6 7 2 2 8 9 10 1 3 4 6 7 同様にして 小さいものから順に書き込んでいく 1 2 2 3 4 6 7 最後に 残ったデータをコピーする 1 2 2 3 4 6 7 8 9 10 52 53 再帰 (recursion) マージソート ( を含む分割統治法 ) は 再帰を使う 再帰的な関数定義 Fib(n) = if n < 3 then 1 else Fib(n-2)+Fib(n-1) 関数の定義の中で 定義されつつある関数自身を 1 回以上呼ぶ関数 再帰を上手に使うことにより アルゴリズムやプログラムを簡潔明瞭に表現することができる cf. 計算論 ( 計算可能性関数の理論 ) マージソートの計算量 (1) 時間計算量 ( データの個数を n とし n=2^m と仮定 ) 2 つのデータの比較のみをカウントする N 個のデータのマージソートにおける 2 つのデータの比較 回数を T(n) とすると 次の式が成立する T(n) <= T(n/2) + T(n/2) + マージ操作における計算量 n-1 よって T(n) <= 2 T(n/2) + n 1 54 55 9

マージソートの計算量 (2) 時間計算量 ( データの個数を n とし n=2^m と仮定 ) T(n) <= 2 T(n/2) + n 1 T(1) = 0 これらより (n=2^m とおくと ) T(2^m) <= m 2^m + 1 T(n) <= n log n + 1 よって T(n) は O(n log n) である 関数の増大度の差 N N log N N^2 2^N 10 33 10^2 10^3 100 664 10^4 10^30 1000 9966 10^6 10^301 10000 132877 10^8 10^3010 マージソートの時間計算量は O(n log n) 56 57 整列アルゴリズムのあれこれ 古来 多くの整列アルゴリズムが考案されてきた 素朴な方法 ( インサーションソートなど ) O(n^2) マージソート O(n log n) その他 クイックソート ヒープソートなど データに対して 比較 演算のみが許される場合は O(n log n ) が最善であることが証明されている データが 0 から 100 までの整数値 のように有限個の範囲であれば O(n) のソートが可能 バケツソート まとめ 整列問題を取り上げ 素朴なアルゴリズム 分割統治法に基づく効率の良いアルゴリズムについて考えた ポイント アルゴリズムを設計するとはどういうことか そのアルゴリズムの性能 ( 計算量 ) を見積もるのは どうすればよいか O(n^2) と O(n log n) は大差がある 58 59 全体のまとめ 問題 をモデル化し それに対する良いアルゴリズムを考えるのは コンピュータサイエンスにおける最重要問題の 1 つ 良い アルゴリズム 重要な尺度は 時間計算量や空間計算量 : データのサイズを表す n が非常に大きいときの計算量を示す 現実問題の解決にあたって 大きなヒントとなる 60 10