後期試験 ・ 2009 年 1 月 23 日 1 時限実施 ・ ページ
授業 科目 |
データ構造とアルゴリズム | 学生番号 | 学科 | 学年 | 組 | 番 | フリ ガナ |
評点 | ||||||||
氏名 | ||||||||||||||||
担当者 | DÜRST, Martin J. |
次の英語の用語に相当する日本語の用語を書いて、簡単に説明しなさい。日本語の用語ではカタカナをできるだけ避けなさい。
知り合いがある問題を解ける速いアルゴリズムを見つけようとしていたが、失敗した。 もしかすると NP-困難な問題かもしれないと言っている。事実の確認の方法と、 確認された場合の具体性のある対策について細かいアドバイスを書きなさい。
NP-困難な問題かどうかの確認として、判定問題に変換し、 数多くのNP完全な問題の一つに帰着してみることがいい。帰着というのは問題を多項式時間でもう一つの問題に 変換し、その問題を解き、解を逆変換するということ。具体的な対策としては実際に解けたいときのデータの分析、 これに合わせもうちょっと簡単な万代にならないか、そして完璧なものをあきらめ、問題に特化したもしくは一般的な (例えばシミュレーテッドアニーリングや遺伝的アルゴリズム) 近似法が考えられる。
アルゴリズムの表現方法を三つ選んで、その利点と欠点を説明しなさい。
後期試験 ・ 2009 年 1 月 23 日 1 時限実施 ・ ページ
辞書という抽象データ型には様々な実装がある。各実装の計算量を下記の表に記入しなさい。
方法 | 探索 | 挿入 | 削除 |
---|---|---|---|
整列済み配列 | O (log n) | O (n) | O (n) |
整列無し配列 | O (n) | O (1) | O (n) |
整列済み連結リスト | O (n) | O (n) | O (n) |
整列無し連結リスト | O (n) | O (1) | O (n) |
二分探索木 (平均) | O (log n) | O (log n) | O (log n) |
二分探索木 (最悪) | O (n) | O (n) | O (n) |
平衡木 | O (log n) | O (log n) | O (log n) |
ハッシュ (平均) | O (1) | O (1) | O (1) |
ハッシュ (最悪) | O (n) | O (n) | O (n) |
配列によって実装すれば新しいヒープは O (n) の計算量で作れる。
下 (配列の後ろ) から順次 heapify_down
を適応する。しかし、合計の要素の数が n で、
最大に heapify_down
に掛かる計算量は O (log n) なので、合計で
O (n log n)
になるのも不思議ではない。n = 2a-1 の場合に限って、
計算量が O (n) であることを式を使って示しなさい。
n = 2a-1 というのは、ヒープを二分木で見ると 各深さ毎に完全に埋まっているということです。即ち層ごとに 1, 2, 4, 8,..., 2a-2, 2a-1 項目がある。深さが浅い項目ほど heapify_down は時間がかかり、 一項目あたりの計算量は深さと逆比例する。合計の計算量は 1*a + 2*(a-1) + 4*(a-2) + 8*(a-3) + ... + 2a-2*2 + 2a-1*1 で、これは 2a + 2a-1 + 2a-2 + 2a-3 + ... + 4 + 2 + 1 で、2a+1 より小さいなので O(n) である。
授業で説明した文字列照合のアルゴリズムの一つを選んで明記の上、その仕組みと特徴を例を使って細かく説明しなさい。
右記の二分探索木の下記の辿り方のノードの順番を書きなさい。
後期試験 ・ 2009 年 1 月 23 日 1 時限実施 ・ ページ
授業 科目 |
データ構造とアルゴリズム | 学生番号 | 学科 | 学年 | 組 | 番 | フリ ガナ |
評点 | ||||||||
氏名 | ||||||||||||||||
担当者 | DÜRST, Martin J. |
下記の三つの事情に合わせて、順列のアルゴリズムを実装するように頼まれた。 アルゴリズムを選んで、そのアルゴリズムの名前、仕組み、選んだ理由と実装の場合特に注意すべき点を記述しなさい。
公開されたハッシュ表の実装に対し、サービス拒否攻撃 (攻撃されたマシーンが膨大な計算を強いられるため、本来の役割ができない) が報告された。 具体例はユーザのデータがハッシュ表に登録され、 膨大の数の架空なユーザ登録でサービスへの登録やログインがどんどん遅くなったものである。 ハッシュ表の知識を生かし、その攻撃が可能である理由と対策方法を詳しく述べなさい。
ハッシュ表の実相の多くはチェイン法を使用している。 一つだけのチェインがどんどん長くなるともともとのハッシュ表の最大の利点の (挿入、削除など) の O(1) の時間がなくなり、そのチェインにおいて各種の操作が O(n) になる。 普通のデータではそうならないが、実装が公表されていると全てハッシュ値が同じになるユーザ名をわざわざたくさん登録して、効率を悪くすることが出来る。 対策としては万能ハッシュ法を使って、サーバのスタート時点で乱数で決めた値に依存するハッシュ関数を使うのがよい。