後期試験 ・ 2013 年 1 月 25 日 1 時限実施 ・ ページ
授業 科目 |
データ構造とアルゴリズム | 学生番号 | 学科 | 学年 | 組 | 番 | フリ ガナ |
評点 | ||||||||
氏名 | ||||||||||||||||
担当者 | DÜRST, Martin J. |
文書によるアルゴリズムの表現方法の利点と欠点を細かく述べなさい。
利点: 文書なので情報テクノロジーの専門家だけではなく、一般の人にも分かりやすい可能性がある。 形式が決まってないので自由に書けるし、電子メールなどで簡単に交換もできる。
欠点: 自然言語の文書には多くの場合、曖昧さが付きます。曖昧さのない文書が非常に書きにくくて、不自然と感じる。 そのため、正確な表現に限界があります。アルゴリズムは多くの場合、構造 (例えば for ループなど) があるが、文書が流れるだけなので、構造が分かりにくいです。 さらに、文書は自然言語で書きますが、自然言語は多くの種類 (例: 日本語、英語) があるので、その自然言語がわからないとアルゴリズムもわからない。
下記左側にある C 言語のプログラム断片 (変数の定義など省略) について、それぞれの計算量とその理由を右側に書きなさい。
for (i=0; i<n; i++) for (j=0; j<i; j++) total += items[i] / items[j];
二重ループで、j は最初狭い範囲でしか動かないが、合計の割り算と足し算は n*n/2 回ぐらいあるので、O(n2)
int fun(n) { if (n<2) total++; else for (i=0; i<n; i++) fun(n-1); }
n が2以上の時にn 回繰り返して、さらに n-1 で自分を呼ぶので、n*(n-1)*... で O(n!)
a = b + q; b = 20 + a; q = 4 * b;
足し算二つ、掛算ひとつ、代入三つしかしないので、一定時間に終わるので、O(1)
total = 0; while ((n/=2) >= 1) total += 1;
while ループを一回回ると n が半分に減って、さらにループごとの計算量が一定なので、O(log n)
for (w=2; w<=n; w++) for (i=0; i<n-w; i++) for (c=i; c<i+w; c++) total += items[c];
三つのループで、w が小さい時と大きい時には内部の二つのループは O(n) に近いが、w が中間の時に O(n2) なので、全体には O(n3)。(構造的には配列の連鎖乗算の動的計画法と同じ)
後期試験 ・ 2013 年 1 月 25 日 1 時限実施 ・ ページ
ある配列 array
の指数 left
から right
までの範囲をソートする単純なクイックソートのアルゴリズムを疑似コードで書きなさい。
algorithm simple_quicksort inputs: array of items (array), index of leftmost item (left), index of rightmost item (right) output: sorted array return if left ≥ right pivot ← a[right] r ← right-1 l ← left loop while r>1 and array[r]>pivot do r ← r-1 end while array[l]<pivot do l ← l+1 end break if l>r array[l], array[r] ← array[r], array[l] end array[l], array[right] ← array[right], array[l] simple_quicksort(array, left, l-1) simple_quicksort(array, l+1, right) end
次の英語の用語に相当する日本語の用語を書いて、簡単に説明しなさい。日本語の用語ではカタカナをできるだけ避けなさい。
後期試験 ・ 2013 年 1 月 25 日 1 時限実施 ・ ページ
授業 科目 |
データ構造とアルゴリズム | 学生番号 | 学科 | 学年 | 組 | 番 | フリ ガナ |
評点 | ||||||||
氏名 | ||||||||||||||||
担当者 | DÜRST, Martin J. |
下記の三つの事情に合わせて、キューを実装するように頼まれた。 データ構造を選んで、そのデータ構造の名前、仕組みと選んだ理由を記述しなさい。
赤黒木は 2-3-4 木の「実装」といえる。子供が二個、三個、四個の 2-3-4 木の節とそれぞれに相当する赤黒木の部分を図で示しながら 2-3-4 木を赤黒木でどうやって実装するかを説明しなさい。普遍条件にも言及しなさい。
[図省略]
両方の木の普遍条件はまず探索木の普遍条件である。内部節のキーより小さいキーのデータ項目は左、キーが大きいデータ項目が右になります。
2-3-4 木の普遍条件は内部節の子供は二つから四つの間で、木の高さが一定であること。それに対し、赤黒木が二分木ですべての内部節の二つの子供がある。
赤黒木の場合、元の 2-3-4 木の辺が黒で、3個や4個の子供の節を二分木の赤黒木に変換する (図参照、3個の子供の時に、変換は二種類ある) ときにできる
辺は赤になる。2-3-4 木の一定の高さを保つために、赤黒木の場合、根から葉までの黒の辺を一定に保つ、かつ赤の辺を二つ連続にしないことが普遍条件になる。
後期試験 ・ 2013 年 1 月 25 日 1 時限実施 ・ ページ
下記の左側にある図はソートのアルゴリズムの可視化の実行中に撮ったものである。図ごとにソートのアルゴリズムの名前、図にみられるアルゴリズムの特徴 (なぜそのアルゴリズムなのかの理由) を述べ、計算量などを含めアルゴリズムを説明しなさい。
ヒープソート。なぜかというと、ヒープソートは配列を使ってヒープ (優先順位キュー) を作成し、 一番「優先が高い」(大きい) ものを順次ヒープの根から取り出し、ヒープを小さくしながら取り出したものをヒープの後ろに回している。 図のところには完全に整列されている右側 (配列の後ろ) の12個ほどの要素、左側にヒープがみられる。 ヒープの根は一番左側で次に右に移動されるものが整列されてないもののなかの一番おおきもので、ヒープの右側の方は、 ヒープの特徴のせいで完全ではないが徐々に小さくなる傾向が見られる。計算量が O(n log n)。
挿入ソート。 左の部分ではその中が整列済みですが、まだまだ右側の方から左側の部分に挿入する要素が一杯残っている。 挿入ソートは整列済みの部分のすぐ右の要素を、適切な場所が見つかるまでに整列済みの要素を右から一つずつ左にすらしながら挿入するアルゴリズム。 計算量は O(n2) だが、既に殆ど整列されているデータの場合に非常に有効である。
選択ソート。左側に全く変更が必要なくてすでに完璧にソート済みの領域ができて、 右側に左側の領域の一番大きい要素より大きいものしか残らない。そこから選択ソートが次々と残りの一番小さい要素を選んで、 整列済みの領域のすぐ右にある要素と交換し、左側の領域を大きくする。計算量が O((n2) で、 他の同じ計算量のバブルソートや挿入ソートよりデータの移動が少ないので、特に一項目あたりのデータの量が大きい時に有利。
授業で習った文字列照合アルゴリズムのうち、一番速いものを選んで、その速さの理由を中心に説明しなさい。
一番早い文字列照合アルゴリズムは Boyer-Moore アルゴリズムです。なぜかというと、一般の場合、計算量は O(n/m) である。この場合、n は文書の長さで、m は探しているパターンのながさ。Boyer-Moore アルゴリズムの決めては、パターンとの照合を前からのではなく、後ろから行うということです。 パーターンの一番後ろの文字が「合うか合わないか」だけでわなく、合わなかったら文書の文字はどの文字なのかも考慮する。 その文字がパターンのの中に全くない場合、パターン一個分にパターンをすらすことができるので、一番最前の場合、 一個の比較で m 文字進むので、O(n/m) になる。
後期試験 ・ 2013 年 1 月 25 日 1 時限実施 ・ ページ
授業 科目 |
データ構造とアルゴリズム | 学生番号 | 学科 | 学年 | 組 | 番 | フリ ガナ |
評点 | ||||||||
氏名 | ||||||||||||||||
担当者 | DÜRST, Martin J. |
下記の問題のため、下記のアルゴリズムの設計方針や原理を使って、それぞれアルゴリズムの概略を提案し、予想される計算量とその根拠、設計方針を使った場合の問題点について述べなさい。
注: この問題の目的は、できるだけ最適な結果のアルゴリズムの発見よりも、設計方針の知識の応用である。
問題: n 個の品 s1, ..., sn があって、 品 sk の重さが wk で、その値段が pk の場合、最大の重さが wt のナップサックにできるだけ品の合計の値段が高くなるように、どの品を詰めるかを求める。
貪欲アルゴリズム (6 点)
品を「効率」のよい順番に並んで、一番効率のいいものから詰めてみて、 詰められないものを飛ばし、できるだけ一杯になるまで詰めてみる。 ここで品 sk の「効率」は重さに対する価値、すなわち pk/wk にする。 計算量は,品順列が必要なため、O(n log n)。「効率」の順でやっているので結構いいところまで行くと期待されるが、 空きを残して最善解まで行かない可能性もあるのが問題点。
遺伝的アルゴリズム (6 点)
最初は乱数を使って一定の数の解を作る。繰り返し各解から複数の新しい解を作って、 今まで見つけた一番いい解を複数残す。新しい解を作るときに、複数の品を乱数で決め、入れ替える (突然変異)。 それによって幅広く解を試し、良い組み合わせをさらに組み合わせる。 計算量は O(n∙繰り返しの数∙作成する解の数)。組み換えなどにより最大の重さを簡単に超えられるのが一つの問題点。
分割統治法 (6 点)
品を二分に分け、それを再帰的に適用する。 部分の重さを計算し、ナップサックの最大の重さまで足し合わせる。それを超えたら、価値の高い方の部分だけを残す。 分割の回数が O(log n) のため、計算量が O(n log n)。 二つの部分の一つを残す可能性が多いので、荒すぎてあまりいい解が出ない可能性が高いのが問題。 検討した価値があるが、この問題に全く向いてないみたい。
総当たり法 (6 点)
s1 から始まって、 すべての品について「入れる」と「入れない」の両方の選択肢を試す。 一番簡単な実装は再帰です。計算量は解の数の O(2n)。 全ての解をチェックするので、最適解を見つける保証がある。 計算量は指数的なので非常に遅いのが問題。 早く打ちきれるように少しでも早くする工夫が大事。 例えば今まで見つかった最大解の合計の値段と残りの品をすべて詰められる場合の最大の値段を考慮して打ち切るとか。