データ構造とアルゴリズム
第二回 (2014年9月
26日)
アルゴリズムの表現と評価
http://www.sw.it.aoyama.ac.jp/2014/DA/lecture2.html
Martin J. Dürst
© 2009-14 Martin
J. Dürst 青山学院大学
目次
- 前回のまとめ・宿題
- アルゴリズムの表現方法
- プログラム言語 Ruby
- アルゴリズムの評価
前回のまとめ
- 授業の位置づけと進め方
- アルゴリズムとデータ構造の魅力
- データ構造の概要 (例: 連結リスト)
- アルゴリズムの概要 (例: 線形探索、2分探索)
前回の宿題 1: 膨大なデータ
提出: 来週の木曜日 (9月27日) 19時00分締切; O 棟
529号室の前の箱に提出; A4 一枚 (両面可) 厳守
(それぞれの問題で、想定の根拠となる理由、参考にした文献など必ず明記のこと)
- 東京証券取引所の第一部の取引で、一株式会社の株が営業時間内に平均で
1分に一回売買されている想定のもと、合計で年間に何項目ぐらいのデータが集まるかを、計算しなさい。
- Google (又は明記の上で他のサーチエンジン)
が対応しているウェブページの数と平均のページあたりのリンク数を調べ、おおよその合計のリンク数を計算しなさい。
- 問題 1 や 2
の結果よりも大きくて実際に計算機で扱えそうなデータ項目の量を考え、説明しなさい
(他人と同じものの場合には減点の対象)。
前回の宿題 2: アルゴリズムの表現方法
別紙「アルゴリズムの表現方法」のアルゴリズムの表現方法をよく見て、それぞれの方法の利点と欠点を考えなさい。
(提出不要)
アルゴリズムの表現方法
- アルゴリズムは抽象的な現象
- 表現方法が必要
- 主な表現方法:
文書
原理: アルゴリズムを自然言語で説明
利点: 素人も含め人間に分かりやすい・書きやすい
欠点:
- 文書の曖昧さ
- 正確な表現の限界
- 構造が不明
- 自然言語に依存
図
例: 流れ図 (flowchart) など
利点: 視覚的な表現
欠点:
- 作成の手間
- データ交換の困難
- 構造化プログラミングとの隔たり
(構造化プログラミング (structured programming): goto
(プログラム内の任意のところへのジャンプ)
の代わり、入れ子の枝分れ、繰返しなどの使用)
疑似コードの概要
(pseudocode)
- プログラム言語 (コード) に近い記述
- 多くの場合の共通点:
- 簡潔な記法 (文末のセミコロンの省略など)
- 変数宣言なし
- 特殊記号の使用 (←、∨、∧、≦など)
- 一部自然言語を使用
疑似コードの評価
利点:
- 自然言語とプログラムの中間
- 作者の好みやアルゴリズムの特徴に合わせるのが可能
- 構造化プログラミングと連結
- アルゴリズムの本質に注目が可能
欠点:
プログラム言語
利点:
欠点:
- 種類が多い
- 必要以上に細かい、環境に依存
- アルゴリズムの本質と違う
Ruby プログラム言語
- 日本発 (まつもと ゆきひろが 1993 年から開発)
- 2000年から欧米でも人気を集める
- 2004年から Ruby on Rails
で更に注目
- 完全なオブジェクト指向言語
- 手軽なスクリプト言語
- 初心者にやさしいが、上級者も大満足
- 卒論などで使用、実装に貢献 (国際化)
- ラブワークも可能
前回の宿題 3: Ruby のインストール
自分のノートパソコン (又は自宅のパソコン) に Ruby
をインストール
インストール方法は主に二つ:
確認方法: Start Command Prompt with Ruby 又は Cygwin Bash Shell/Cygwin
Terminal にて ruby -v
を実行
インストールできない場合、次回授業の前日までに要相談
アルゴリズム表現のための Ruby
- 簡潔な記法
- 変数宣言が不要
- データ構造 (配列など) はデータ型 (整数など)
と独立
- 「動く疑似コード」
- プロファイラなど環境の充実
注: この授業では Ruby を読む必要があるが、Ruby
を書く必要がない
最初の Ruby の例
線形探索と二分探索: 2search.rb
実行:
cd
でダウンロード場所へ移動
ruby 2search.rb
Ruby の記法の基本
#
から改行まではコメント
(本授業では #
はアルゴリズムへのコメント、##
は Ruby
についてのコメント)
- 行末に
;
(セミコロン) が不要
if
/while
などの条件とメソッド
(関数) 呼び出しの一部で ()
が不要
- メソッド (関数) は
def
で定義
class
/def
/if
/while
/do
などに必ず end
が必要 ({}
はなし)
アルゴリズムの評価の概要
主な評価基準:
- 実行時間 ((時間) 計算量)
- メモリ使用量
- 実装のしやすさ
評価のときに必要な情報:
アルゴリズムの計算量の比較
例: 線形探索と2分探索の比較
- 2分探索は線形探索より何秒速い?
- 2分探索は線形探索より何倍速い?
二つのアルゴリズムの比較をしたいときに、一般的な答えが欲しい
実行時間の比較: 具体から抽象へ
- 実行時間の測定
- ステップの数え上げ
- 最悪の場合などのステップの数え上げや想定
- 漸近的な考え方の導入
実行時間の比較: 計測
- 利点:
(条件が合えば) 正確な結果
- 問題点
- ハードウェアによって結果が違う
- 実装の詳細によって結果が違う
- 実行するたびに結果が少し違う
- 実装が前提
⇒ もっと抽象的な比較方法が必要
実行時間の比較: ステップの数え上げ
(ステップ:
一定時間で計算可能な部分、例えば演算、比較、メモリ参照など)
- 利点
ハードウェア依存無し
- 問題点
- 実装によってステップの数が違う
- ステップの数え方は様々
- 入力項目の数や種類によってステップ数が違う
⇒ もっと抽象的な比較方法が必要
宿題 1:
ステップの漸近的増加の例
(漸近的な増加: asymptotic growth)
ステップの数
n (データ項目の数) |
1 |
10 |
100 |
1,000 |
10,000 |
100,000 |
1,000,000 |
線形探索 |
|
|
|
|
|
|
|
2分探索 |
|
|
|
|
|
|
|
宿題 2: 関数の増加の比較
それぞれ二つの関数で、n
が増加すると大きい方はどちらか
100n |
n2 |
1.1n |
n20 |
5 log2 n |
10 log4 n |
20n |
n! |
100·2n |
2.1n |
まとめ
- アルゴリズムの表現方法を適切に選ぶのが大事
- この授業では主に「動く疑似コード」として Ruby
を使用
- アルゴリズムの評価の中心は入力の大きさによる
(時間) 計算量
宿題
(提出不要)
- Ruby
を使って探索アルゴリズムのステップ数を調べ、テーブルを完成
(散布図を作成してもよい)
- 関数の増加の比較で、どちらの関数が「最終的に勝つ」か、そしてその理由を調べなさい
- 高校の教科書やウェブなどで対数 (ln,
log10, log2 など) と極限
(limn→∞など) について調査・再確認