アルゴリズムとデータ構造 はじめに 第1章 アルゴリズムと計算量

Slides:



Advertisements
Similar presentations
オブジェクト指向言語・ オブジェクト指向言語演習 中間試験回答例. Jan. 12, 2005 情報処理技術基礎演習 II 2 オブジェクト指向言語 中間試験解説 1  (1) 円柱の体積(円柱の体積 = 底面の円の面積 x 高さ) を求めるプログラムを作成しなさい。ただし、出力結果は、入 力した底面の円の半径.
Advertisements

情報・知能工学系 山本一公 プログラミング演習Ⅱ 第3回 配列(1) 情報・知能工学系 山本一公
プログラミング演習II 2004年11月 30日(第6回) 理学部数学科・木村巌.
プログラムのパタン演習 解説.
プログラミング基礎I(再) 山元進.
プログラミング言語としてのR 情報知能学科 白井 英俊.
配列(2) 第10回[平成15年6月26日(木)]:PN03-10.ppt 今日の内容 1 素数を求める(教科書の例):復習
データ構造とアルゴリズム 第10回 mallocとfree
システムプログラミング 第5回 情報工学科 篠埜 功 ヒアドキュメント レポート課題 main関数の引数 usageメッセージ
基礎プログラミングおよび演習 第9回
第2回ネットワークプログラミング 中村 修.
アルゴリズムとデータ構造 第1章 アルゴリズムと計算量 4月26日
2009/10/9 良いアルゴリズムとは 第2講: 平成21年10月9日 (金) 4限 E252教室 コンピュータアルゴリズム.
基礎プログラミング 第13回(2007年5月28日) 「関数」の補足説明 Report-Fの解説.
C言語 配列 2016年 吉田研究室.
情報科学1(G1) 2016年度.
第6章 2重ループ&配列 2重ループと配列をやります.
プログラミング入門2 第2回 複合文、繰り返し 情報工学科 篠埜 功.
関数 関数とスタック.
精密工学科プログラミング基礎Ⅱ 第3回資料 今回の授業で習得してほしいこと: 2次元配列の使い方 (前回の1次元配列の復習もします.)
第7回 条件による繰り返し.
ちょっとした練習問題① 配列iroを['R', 'W', 'R', 'R', 'W' , 'W' , 'W']を宣言して、「W」のときの配列の番号をprintfで表示するようなプログラムを記述しなさい。
プログラミング言語入門 手続き型言語としてのJava
プログラミング2 関数
関数と配列とポインタ 1次元配列 2次元配列 配列を使って結果を返す 演習問題
関数の定義.
第10回関数 Ⅱ (ローカル変数とスコープ).
2011/06/21-24 情報知能学科「アルゴリズムとデータ構造」 担当:白井英俊
講義では、Cプログラミングの基本を学び 演習では、やや実践的なプログラミングを通して学ぶ
第7回 条件による繰り返し.
第7回 プログラミングⅡ 第7回
復習 前回の関数のまとめ(1) 関数はmain()関数または他の関数から呼び出されて実行される.
アルゴリズムとデータ構造 第3章 ヒープ 6月10日分
アルゴリズムとデータ構造 第1章 アルゴリズムと計算量 4月22日
プログラミング基礎a 第7回 C言語によるプログラミング入門 ファイル入出力
復習 2次元配列 4列 j = 0 j = 1 j = 2 j = 3 i = 0 i = 1 i = 2 3行
アルゴリズムとデータ構造 第1章 アルゴリズムと計算量 4月15日
第2回課題 配布した通り.氏名・学生番号を忘れないこと.
第5章 計算とプログラム 本章で説明すること ・計算の概観と記述法 ・代表的な計算モデル ・プログラムとプログラム言語.
プログラムの基本構造と 構造化チャート(PAD)
アルゴリズムとデータ構造 2011年7月8日課題の復習
Cプログラミング演習資料.
アルゴリズムとデータ構造 第3章 ヒープ 5月31日分
情報知能学科「アルゴリズムとデータ構造」
アルゴリズムとデータ構造 第3章 ヒープ 5月31日分の復習
アルゴリズムとプログラミング (Algorithms and Programming)
復習 2次元配列 4列 j = 0 j = 1 j = 2 j = 3 i = 0 i = 1 i = 2 3行
補講:アルゴリズムと漸近的評価.
データ構造とアルゴリズム (第5回) 静岡大学工学部 安藤和敏
アルゴリズムからプログラムへ GRAPH-SEARCH
プログラミング入門2 第6回 関数 情報工学科 篠埜 功.
復習 breakとcontinueの違い int i; for (i = 1; i <= 100; i++) { ・・・処理1・・・・
復習 Cにおけるループからの脱出と制御 break ループを強制終了する.if文と組み合わせて利用するのが一般的. continue
計算機プログラミングI 第4回 2002年10月31日(木) 問題解決とアルゴリズム クラスメソッドと手続きの抽象化 最大公約数
第5回 プログラミングⅡ 第5回
復習 breakとcontinueの違い int i; for (i = 1; i <= 100; i++) { ・・・処理1・・・・
ヒープソート.
情報処理Ⅱ 2007年12月3日(月) その1.
コンパイラ 2012年10月11日
プログラミング基礎a 第7回 C言語によるプログラミング入門 ファイル入出力
プログラミング入門2 第6回 関数 情報工学科 篠埜 功.
第7章 そろそろ int 以外も使ってみよう! ~データ型 double , bool~
高度プログラミング演習 (07).
オブジェクト指向言語論 第三回 知能情報学部 新田直也.
プログラミング演習II 2004年11月 2日(第3回) 理学部数学科・木村巌.
プログラミング入門2 第5回 配列 変数宣言、初期化について
プログラミング入門2 第3回 条件分岐(2) 繰り返し文 篠埜 功.
第2章 数値の入力と変数 scanfと変数をやります.
計算技術研究会 第5回 C言語勉強会 関数(function)を使う
岩村雅一 知能情報工学演習I 第7回(後半第1回) 岩村雅一
Presentation transcript:

アルゴリズムとデータ構造 はじめに 第1章 アルゴリズムと計算量 アルゴリズムとデータ構造 はじめに 第1章 アルゴリズムと計算量 情報知能学科 白井英俊

教科書の確認 杉原厚吉 (2001) 『データ構造とアルゴリズム』. 東京:共立出版. 講義の時は必ず持ってくること (4月中はあまり参照しないかもしれないが) 定期試験の時に持ち込み可 (書き込み自由)

アルゴリズムとは 与えられたデータから目的の情報を見つけ出したり、作り出したりするための手続き 誰のための手続き? → 人間も計算機も 誰のための手続き? → 人間も計算機も 本講義でとりあげる「アルゴリズム」は、計算機で実行できるよう(つまり、プログラムが欠けるよう)、明確に書かれることが要求される

データ構造とは アルゴリズムを実行するための『データ』や、アルゴリズムの対象となる『情報』を、計算機(プログラム)で表す(表現する)方法 よく用いられるデータ構造の例:   配列、リスト、スタック、キュー、グラフ、木、ハッシュ

アルゴリズム+データ構造=プログラム 本講義は「プログラミング」の講義ではない。  つまり、特定のプログラミング言語に習熟することが目的ではない 使用するプログラミング言語に依存せず、ある目的を達成するためのプログラムを作るための「基本的な知識と技術の習得」が目的 プログラムを作ることは要求する。それは、「アルゴリズム」や「データ構造」が正しく実現されているか、という検証のため

たとえて言えば… 入力 例えて言えば、  アルゴリズムは料理のレシピ 出力

例えて言えば... アルゴリズムは料理のレシピ 入力 ... 料理の材料 (小麦粉、キャベツなど) 入力 ... 料理の材料 (小麦粉、キャベツなど) 出力 ... 料理 (お好み焼き、カレーライスなど) 料理を作るには材料をどんな手順でどのように調理するか、が必要 ... アルゴリズム データ構造は、料理のための道具 レシピが読めても、料理を作れないのでは意味がない!⇒ ちゃんと動くプログラムを書けなければ意味がない。。。さらに効率性も大事。。。

アルゴリズムの例 入力 出力 問題(教科書p.1): n個の実数x1, x2, …, xnが与えられて、その中の最大値を求める

アルゴリズムの例(続) より明確な記述(p.2) 入力: 正の整数nとn個の実数値x1, x2, …, xn  手続き: 1. y ← x1 (yは「それまでの最大値」を記録) 2. i = 2,3,…,nに対して順に次を行う:    xi > y ならば y ← xi 3. yを出力する 「変数y に x1の値を代入する」

アルゴリズムの例(続) 「プログラム」風(p.3) Algorithm MAX(n, x1, x2, …, xn): 入力(Input): 正整数 n と n 個の実数x1, x2, …, xn 出力(Output): x1, x2, …, xnの中の最大値 手続き(Procedure):   1. y ← x1 ; 2. for i ← 2 until n do    if xi > y then y ← xi ; 3. return y; 記法の注意:ここではプログラムの 命令の後に「;」を書く ここでの記法についてはウェブページの「教科書のアルゴリズムの記述とRUBY言語の対応」参照 アルゴリズムにおいて「出力する」とは、 printするという意味でなく、returnによって 値を「返す」ということ

アルゴリズムの検証 このアルゴリズムがちゃんと動くかは 頭で考え、手を動かす アルゴリズムを反映したプログラムを作り、 アルゴリズムを反映したプログラムを作り、    適切な入力を与えて動かし、結果を調べる ことで検証する、つまり、正しいかどうかを確認する

アルゴリズムからRubyプログラムへ 2ページと3ページのどちらの記述でもよいがそれに基づいてRubyプログラムを書く

データ構造の出番 「入力:正整数 n と n 個の実数x1, x2, …, xn」 の中の n 個の実数x1, x2, …, xn をRubyのプログラムでどのように表現するか? 複数個の実数を「まとめて」表すための標準的な方法は「配列」というデータ構造を使うこと ところで、Rubyの配列って? 「標準的」とは、よく用いられる、という意味 このように、いくつかのオブジェクトをまとめて記憶する データ構造を「入れ物」と呼ぶことがあります

Rubyの配列 配列とは:変数は一個のオブジェクト(物)しか記憶できないが、配列は複数のオブジェクトを記憶する 書き方:オブジェクトをカンマで区切って並べ、全体を大括弧でくくる。  例: [ 1, 2, 3, “a”, “ab”, “abc” ] Rubyでは、配列はArray(アレイ)と呼ばれるオブジェクト

Rubyの配列(続) 配列[インデックス] 配列自体が一つのオブジェクトなので、これを変数の値とすることができる。 例: x = [ 1, 2, 3, “a”, “ab”, “abc” ] 配列の要素の値を調べる(取り出す)には… 配列[インデックス] 「インデックス」とは、配列における要素の位置を表す数のこと。 先頭の要素のインデックスが0、次が1、…となる。

Rubyの配列(続) x = [ 1, 2, 3,“a”,“ab”,“abc” ] とすると、xの値となっている配列に対し、   インデックスが3の要素は… “abc”のインデックスは… 試してみよう。  x[3]   この他にも x[0], x[5], x[6], x[-1] など [ 1, 2, 3,“a”,“ab”,“abc” ][3]

Rubyの配列(続) size (もしくは length) というメソッドを使う 配列の大きさ:配列の要素の数はどうやって分かる? メソッドとは、オブジェクトに対する操作のこと。関数ともいう。オブジェクトによっていろいろなメソッドが用意されている。 試してみよう。  x.size [ 1, 2, 3,“a”,“ab”,“abc” ].length

配列を使ったプログラム 問題1.変数aには配列が値として入っている。 たとえば、 a= [ 1, 2, 3,“a”,“ab”,“abc” ]

アルゴリズムからRubyプログラムへ(続き:代入と配列の使用) 入力は、変数nとxとする。ただし、nの値は正整数、xの値は実数を要素とする配列 手続きの最初をRubyで書くのは簡単… Algorithm MAX(n, x1, x2, …, xn): 入力(Input): 正整数 n と n 個の実   数x1, x2, …, xn 出力(Output): x1, x2, …, xnの中    の最大値 手続き(Procedure):   1. y ← x1 ; 2. for i ← 2 until n do     if xi > y then y ← xi ; 3. return y; y = x[1] 実はこれだと問題があるが、今はこれで進める

アルゴリズムからRubyプログラムへ(続き:繰り返し) 2番目の手続きは「繰り返し」  Rubyには、『繰り返し』のメソッドはいろいろある: while, for, downto, times, … (適切なものを選べるようにしよう!) ここではforを使うのが適切 Algorithm MAX(n, x1, x2, …, xn): 入力(Input): 正整数 n と n 個の実   数x1, x2, …, xn 出力(Output): x1, x2, …, xnの中    の最大値 手続き(Procedure):   1. y ← x1 ; 2. for i ← 2 until n do     if xi > y then y ← xi ; 3. return y; 実はこれだと問題があるが、今はこれで進める 書き方: for i in 2..n 繰り返される処理 end

アルゴリズムからRubyプログラムへ(続き:条件分岐) 「繰り返される処理」は ここでは「条件分岐」である。  Rubyの条件文の書き方:  if (条件式)   「条件式が成り立つ時の処理」  else   「条件式が不成立の時の処理」 end Algorithm MAX(n, x1, x2, …, xn): 入力(Input): 正整数 n と n 個の実   数x1, x2, …, xn 出力(Output): x1, x2, …, xnの中    の最大値 手続き(Procedure):   1. y ← x1 ; 2. for i ← 2 until n do     if xi > y then y ← xi ; 3. return y; elseと「条件式が不成立の時の処理」は、なくても可

アルゴリズムからRubyプログラムへ(2番目の処理のまとめ) 2番目の処理をまとめると以下のように書ける: for i in 2..n if (x[i] > y) y = x[i] end Algorithm MAX(n, x1, x2, …, xn): 入力(Input): 正整数 n と n 個の実   数x1, x2, …, xn 出力(Output): x1, x2, …, xnの中    の最大値 手続き(Procedure):   1. y ← x1 ; 2. for i ← 2 until n do     if xi > y then y ← xi ; 3. return y;

アルゴリズムからRubyプログラムへ(3番目の処理) 3番目の return y はyの値を返すもの。 でも、どこに返すのか? ここでの選択  (1) 画面に表示する(printを使う)  (2) アルゴリズムMAXの結果として返す ここでは(2)を考える。 でも、「アルゴリズムMAXの結果として返す」とはどういうこと? Algorithm MAX(n, x1, x2, …, xn): 入力(Input): 正整数 n と n 個の実   数x1, x2, …, xn 出力(Output): x1, x2, …, xnの中    の最大値 手続き(Procedure):   1. y ← x1 ; 2. for i ← 2 until n do     if xi > y then y ← xi ; 3. return y;

アルゴリズムからRubyプログラムへ (関数/メソッド) 「アルゴリズムMAXの結果として返す」とは、 Ruby の関数(メソッド)をつくり、それにmaxと名をつけ、maxの関数の処理として1から3までの処理をやらせるように書く、 ということ Algorithm MAX(n, x1, x2, …, xn): 入力(Input): 正整数 n と n 個の実   数x1, x2, …, xn 出力(Output): x1, x2, …, xnの中    の最大値 手続き(Procedure):   1. y ← x1 ; 2. for i ← 2 until n do     if xi > y then y ← xi ; 3. return y; Rubyでは関数名を大文字にできないのでmaxとする

アルゴリズムを関数として表現 関数: 入力を取り、それに基づいて一連の手続き(計算)を行い、その結果を出力する(返す)、というプログラムの単位

は仮引数という。『定義』のための仮のもの 関数について 関数定義の引数(xとy) は仮引数という。『定義』のための仮のもの 関数名を func とすると  関数の定義の書き方:       def func(x,y) … プログラム(「コード」とも)…          …どこかにreturn文が必要… end 関数の呼び出し: ans = func(3,5) 関数呼出の引数(3と5) は実引数。計算に用いられる実物。

関数の利点 一連の手続きに『名前』をつけ、入力と出力を明示することで、その手続きが何をしているかが明確になる プログラムを関数に分けることで、そのプログラムの構造が明確になる 関数ごとにデバッグをすることで、誤りが発見しやすい。また変更も容易になる 同じような処理をする場合に、冗長性が減る 『再帰』は関数を使わないと書けない

アルゴリズムからRubyプログラムへ (完成) 関数は以下のようにdef を使って定義する: def max(n,x) y = x[1] for i in 2..n if (x[i] > y) y = x[i] end return y Algorithm MAX(n, x1, x2, …, xn): 入力(Input): 正整数 n と n 個の実   数x1, x2, …, xn 出力(Output): x1, x2, …, xnの中    の最大値 手続き(Procedure):   1. y ← x1 ; 2. for i ← 2 until n do     if xi > y then y ← xi ; 3. return y; # if # for Rubyのプログラムでは、endがdefやforやifなどと対応するため対応関係がわかりにくい。そこで、インデント(段付け)をして対応が分かるように書く # def

実際に検証してみよう 先のプログラムは単に「アルゴリズム」をプログラムに直しただけ。 それがちゃんと期待通りに計算するかは、 (1) 具体的な(入力)データを与える  (2) アルゴリズムが返した結果を表示させる ということが必要。

実際に検証してみよう(続き) この内容をmax.rbとして、実行させてみると… 具体的には以下のようなプログラムを作る: def max(n,x) y = x[1] for i in 2..n if (x[i] > y) y = x[i] end return y # ここからが検証用のデータ print max(10, [0.3, 0.1, 0.7, 0.9. 1.1, 0.2, 0.5, 0.8, 0.4, 1.0]) # if # for # def この内容をmax.rbとして、実行させてみると…

動かない… ちゃんと書いたはずなのだが、以下のようなエラーメッセージが出て動かない… max.rb:5:in `max': undefined method `>' for nil:NilClass (NoMethodError) from max.rb:4:in `each' from max.rb:4:in `max' from max.rb:12

めげない! エラーメッセージに理由が書いてある。それを読んで、理由を理解して、直してみよう。 講義用のウェブページにある「Rubyのエラーメッセージとその対処 」を読んでみよう。 これはそのうちのどこにあたるか?

プログラムの修正 「(5) 未定義(undefined)なメソッド(method)/関数によるエラー 」に相当することが分かる 解釈:この場合は、5行目に使われている> という「未定義なわけがない」演算子がやり玉にあがっている。 ここは、つまり「for nil:NilClass」が問題。つまり「nil」には > が使えない、と言っている。 対処法:このようなエラーが起きるのは、配列の要素の指定が間違っているか、要素の値の初期化(例えば0にする)ことを忘れている場合が多い

プログラムの修正(続き) わかっただろうか?配列の要素の指定に問題があったのである。 プログラムを見てみよう: def max(n,x) y = x[1] for i in 2..n if (x[i] > y) y = x[i] end return y yに配列の先頭の要素を与えた「つもり」 配列の2番目の要素から最後の要素まで、要素を一つ一つ調べている「つもり」 # if Rubyの配列のインデックスは、いくつから始まり、いくつが最後の要素をさすものだったかな? # for # def

プログラムの修正(完成) # maxアルゴリズムの検証 def max(n,x) y = x[0] for i in 1..(n-1) if (x[i] > y) y = x[i] end return y # ここからが検証用のデータ print max(10, [0.3, 0.1, 0.7, 0.9, 1.1, 0.2, 0.5, 0.8, 0.4, 1.0]) 実行させた結果は… # if # for # def

参考 プログラミング言語Cで書くと: float max(int n, float x[ ]) { int i; float y=x[0]; for (i=1; i < n; i++) { if (x[i] > y) { y=x[i]; } } return y; 実際には以下のプログラムに挿入 #include <stdio.h> #define Num 10 /* ここにいれる */ int main() { static float data[Num] = { 0.3, 0.1, 0.7, 0.9. 1.1, 0.2, 0.5, 0.8, 0.4, 1.0}; printf(“%f\n”, max(Num,data)); }

練習問題(1) n個の実数x1, x2, …, xnが与えられて、その中の最小値を求める アルゴリズムを書く プログラムを書く 適当なデータを与えて、プログラムを実行してみる。そして最小値を返すことを確認する。

練習問題(2) n個の実数x1, x2, …, xnが与えられて、その中の2番目に大きな数を求める アルゴリズムを書く プログラムを書く 適当なデータを与えて、プログラムを実行してみる。そして最小値を返すことを確認する。

課題(1と2は提出を求める宿題) プログラムを書くために、Rubyを復習しよう 次の問題にチャレンジしてみよう  (1)最古のアルゴリズム(ユークリッドの互除法)をプログラム化する  (2) ファイルから実数を読み込み、その中の最大値を答える(つまり、数がファイルに書いてある)  (3) 最大値と最小値からなる配列を返す (4) 最大値と最小値からなる配列を答えるだけではなく、それらが何番目の要素であるかも答える 宿題の提出期限は4月12日(月曜日)。あて先はウェブページ参照

プログラム課題提出の注意 (これこれの問題を解く)「プログラムを書け」、もしくは「アルゴリズムを書け」という課題が多く出される この時に求められているのは「プログラム(やアルゴリズム)」だけではないことに注意 要求事項がちゃんと満たされていることも示す(検証する)必要がある そのために、プログラムの中身、その実行例(複数個の例題)、実行結果の吟味(ちゃんと目的を果たしているかどうか)を示す

ユークリッドの互除法 入力:正整数p, q 出力:pと q の最大公約数 手続き:   1. q > p ならば、 p と q の値を入れ替える   2. r ← (p の q による剰余) 3. r = 0 ならば、q が最大公約数(終了) さもなくば、 p ← q, q ← r として、1へ。 p = 72, q = 30 として、試してみよう

基本的な用語の確認 aとbの公約数:aもbも正整数であることが前提 aの約数とbの約数で共通する数のこと  例: 30 の約数は 1, 2, 3, 5, 6, 10, 15, 30 72の約数は 1, 2, 3, 4, 6, 8, 9, 12, …, 36, 72 aとbの最大公約数(GCD):aとbに共通する公約数のうち最大のもの 30と72の最大公約数(これをGCD(30,72)と書く)は…