4-3:高度なソートアルゴリズム① (分割統治法にもとづくソート)

Slides:



Advertisements
Similar presentations
1 線形代数学. 2 履修にあたって 電子情報システム学科 必修 2005 年度1セメスタ開講 担当 草苅良至 (電子情報システム学科) 教官室: G I 511 内線: 2095 質問等は上記のいずれかに行なうこと。 注意計算用のノートを準備すること。
Advertisements

0章 数学基礎.
4.3 マージソート.
4.ソート問題とアルゴリズム 4-1.ソート問題について 4-2.簡単なソートアルゴリズム 4-3.高度なソートアルゴリズム
離散システム特論 整列(sorting)アルゴリズム 2.
アルゴリズムイントロダクション第2章 主にソートに関して
4.ソート 4-1.ソート問題について 4-2.簡単なソートアルゴリズム 4-3.高度なソートアルゴリズム
近似アルゴリズム 第10章 終了時刻最小化スケジューリング
第11回 整列 ~ シェルソート,クイックソート ~
アルゴリズムとデータ構造1 2005年7月8日
算法数理工学 第1回 定兼 邦彦.
情報知能学科「アルゴリズムとデータ構造」
2009/10/9 良いアルゴリズムとは 第2講: 平成21年10月9日 (金) 4限 E252教室 コンピュータアルゴリズム.
4.整列のアルゴリズム.
アルゴリズムとデータ構造 --- 理論編 --- 山本 真基
第10回 ソート(1):単純なソートアルゴリズム
データ構造と アルゴリズム 第二回 知能情報学部 新田直也.
 Combinations(2)        古川 勇輔.
香川大学工学部 富永浩之 情報数学1 第2-2章 合同式の逆元と応用 香川大学工学部 富永浩之
データ構造とアルゴリズム 分割統治 ~ マージソート~.
9.NP完全問題とNP困難問題.
岩井 儀雄 コンピュータ基礎演習  ー探索、整列ー 岩井 儀雄
データ構造と アルゴリズム 第八回 知能情報学部 新田直也.
非線形方程式の近似解 (2分法,はさみうち法,Newton-Raphson法)
第11回 整列 ~ シェルソート,クイックソート ~
7.時間限定チューリングマシンと   クラスP.
プログラミング基礎a 第8回 プログラムの設計 アルゴリズムとデータ構造
二分探索木によるサーチ.
7-3.高度な木 (平衡木) AVL木 平衡2分木。回転操作に基づくバランス回復機構により平衡を保つ。 B木
アルゴリズムとデータ構造 2012年6月28日
アルゴリズムとデータ構造 2011年6月27日
第25章 単一始点最短路 3節 Bellman-Fordのアルゴリズム
ソートアルゴリズムの種類 選択ソート (selection sort) バブルソート (bubble sort)
2011/06/21-24 情報知能学科「アルゴリズムとデータ構造」 担当:白井英俊
情報工学概論 (アルゴリズムとデータ構造)
第7回 条件による繰り返し.
わんくま同盟茶藝部顧問 Microsoft MVP for VC episthmh
ルンゲクッタ法 となる微分方程式の解を数値的に解く方法.
アルゴリズムとデータ構造1 2005年7月1日
クイックソート.
大岩 元 慶応大学環境情報学部 再帰 データ構造とプログラミング(8) 大岩 元 慶応大学環境情報学部
25. Randomized Algorithms
アルゴリズムとプログラミング (Algorithms and Programming)
変換されても変換されない頑固ベクトル どうしたら頑固になれるか 頑固なベクトルは何に使える?
プログラミング基礎a 第8回 プログラムの設計 アルゴリズムとデータ構造
プログラミング 4 整列アルゴリズム.
プログラミング 4 探索と計算量.
情報とコンピュータ 静岡大学工学部 安藤和敏
アルゴリズムとデータ構造1 2006年7月11日
アルゴリズムとデータ構造 2011年6月23日
プログラミング演習Ⅲ- Sorting Quick Sort and Merge Sort
5.サーチ 5-1.線形探索 5-2.2分探索 5-3.ハッシュ.
補講:アルゴリズムと漸近的評価.
データ構造とアルゴリズム (第5回) 静岡大学工学部 安藤和敏
5.チューリングマシンと計算.
アルゴリズムとプログラミング (Algorithms and Programming)
アルゴリズムとデータ構造 2013年7月1日
情報工学概論 (アルゴリズムとデータ構造)
ソートのプログラムの流れ 配列の中身を小さい順に並び替える a[1],a[2],…a[n]の値を順に出力する
11.動的計画法と擬多項式時間アルゴリズム.
精密工学科プログラミング基礎 第7回資料 (11/27実施)
4.プッシュダウンオートマトンと 文脈自由文法の等価性
2008年6月5日 非線形方程式の近似解 2分法,はさみうち法,Newton-Raphson法)
参考:大きい要素の処理.
精密工学科プログラミング基礎Ⅱ 第2回資料 今回の授業で習得してほしいこと: 配列の使い方 (今回は1次元,次回は2次元をやります.)
関数と再帰 教科書13章 電子1(木曜クラス) 2005/06/22(Thu.).
第10回 関数と再帰.
Q q 情報セキュリティ 第7回:2005年5月27日(金) q q.
7.木構造 7-1.データ構造としての木 7-2.2分探索木 7-3.高度な木.
プログラミング論 バイナリーサーチ 1.
Presentation transcript:

4-3:高度なソートアルゴリズム① (分割統治法にもとづくソート)

クイックソート

クイックソートの方針 方針 問題を小分けにして、あとで組み合わせる。(分割統治法) 前半部分に特定要素(ピボット)より小さい要素を集め、 後半部分にピボットより大きく要素を集める。 ピボットの位置を確定し、 小分けした問題は、再帰的にソートする。 1 2 3 4 5 6 7 13 A 5 9 8 1 4 3 2 ピボット 3 9 A 1 2 8 5 4 13 小さい 大きい

説明上の注意 全てのデータが異なるとして、 説明します。 クイックソートのアルゴリズムでは、 ピボットの選び方にあいまいさがあります。 (自由度といったほうがいいかも。) ここでは、ソート範囲の最後の要素をピボットとして 説明します。 実際に、 プログラミングするときは、 もっといろんな状況を考えましょう。

クイックソートの動き前半(分割1) 1 2 3 4 5 6 7 13 A 5 9 8 1 4 3 2 ピボットより大きい値を探す 13 A 5 9 8 1 4 3 2 ピボットより小さい値を探す 1 13 A 9 8 5 4 3 2 交換 探索の継続

1 13 A 9 8 5 4 3 2 探索が交差したら分割終了。 1 A 2 8 5 4 13 3 9 ピボットと前半最後の要素を交換し、 あとは再帰呼び出し。 1 A 2 8 5 4 13 3 9 ピボットは位置確定

クイックソートの動き後半(再帰) 1 2 3 4 5 6 7 1 A 2 8 5 4 13 3 9 partition(0,7) 1 2 7 1 A 2 8 5 4 13 3 9 partition(0,7) 1 2 7 1 A 2 8 5 4 13 3 9 q_sort(0,0) A[2]からA[7]までを ソートして 位置確定 q_sort(2,7) A[0]からA[0]までをソートして 8 5 4 13 3 9 1 partition(2,7) 位置確定 3 13 8 5 4 9 位置確定 q_sort(2,5) q_sort(7,7) 以下省略

練習 次の配列を、クイックソートでソートするとき、 前のスライドに対応する図を作成せよ。 5 11 25 21 1 8 3 16

クイックソートの実現1(分割) /*概略です。細かい部分は省略*/ int partition(int left,int right) { double int i,j; /*カウンタ*/ i=left; j=right-1; while(TRUE){ while(A[i]<pivot){i++;} while(A[j]>pivot){j--;} if(i>=j){break;} swap(&A[i],&A[j]); } swap(&A[i],&A[right]); return(i);

クイックソートの実現2(再帰) /*概略です。細かい部分は省略*/ void q_sort(int left,int right) { int pos; /*分割位置 */ if(left>=right) return; } else pos=partition(left,right); q_sort(left,pos-1); q_sort(pos+1,right);

このときは、明らかにステップ6により終了する。 命題Q1(クイックソートの停止性) q_sort(left,right)は必ず停止する。 証明 が常に成り立つことに注意する。 に関する帰納法で証明する。 基礎: のとき。 このときは、明らかにステップ6により終了する。 帰納: のとき。         なる全ての整数に対して、q_sort(left,left+k’)が 終了すると仮定する。(帰納法の仮定。)

q_sort(left,left+k)の停止性を考える。 このとき、else節(10-13)が実行される。 10で得られる pos の値に対して、  が成り立つ。 11で呼び出すq(left,pos-1)において、 その適用される列の長さは である。 したがって、帰納法の仮定より、 q(left,pos-1)は停止する。

12で呼び出すq(pos+1,left+k)において、 その適用される列の長さは である。 したがって、帰納法の仮定より、 q(pos+1,left+k)は停止する。 以上より、10-13の全ての行において、 かく再帰式は停止する。 したがって、アルゴリズムq_sort(left,right)は停止する。

停止しないクイックソート 例えば、次のようなクイックソート(?)は、 停止するとは限らない。 if(left>=right) { return; } else pos=partition(left,right); q_sort(left,pos); q_sort(pos,right); サイズが小さくなるとは限らない。

命題Q2(クイックソートのの正当性1) ピボットに選択された値は、partition実行により、 ソート済みの順列と同じ位置に設定される。 証明 ソート済みの順列を  とし、 アルゴリズムの途中の順列を  とする。 また、ピボット   の各順列における順位をそれぞれ、     、     と表すものとする。 このとき、   において、   未満の要素数は      であり、   より大きい要素数は        である。 一方、    における  未満の要素数は       であるが、 これは        と同じはずである。 したがって、

命題Q3(クイックソートのの正当性2) 全ての要素はピボットに選択されるか、あるいは 列の長さ1の再帰呼び出しにより位置が決定される。 証明 再帰呼び出しにおいて、サイズが減少することに注意すると、ピボットとして選ばれるか、サイズが1の再帰呼び出しされる。

クイックソートの計算量 クイックソートは、 最悪時の計算量と平均の計算量が異なります。 これらは、 ピボットの選び方にもよりますが、 どんな選び方によっても最悪のデータ初期配置があります。 ここでは、最悪計算量と、平均計算量の両方を考えます。

クイックソートの最悪計算量 まず、関数partition(i,j)の1回の時間量は、 j-i+1に比例した時間量です。 再帰の同じ深さで、parttition()の時間量を 総計すると になります。 いつも0個、ピボット、残りのように 分割されるのが最悪の場合です。 つまり、ピボットとしていつも最小値が選択されたりするのが最悪です。 (他にも最悪の場合はあります。) このときでも、partition(i,j)の実行には、j-i+1回の演算が必要です。 これは、結局選択ソートの実行と同じようになり、 最悪時間量 のアルゴリズムです。

クイックソートの平均時間計算量 クイックソートの平均時間の解析は、  複雑である。 順を追って解析する。

漸化式の導出 初期状態として、 通りの並びが すべて等確率だとしましょう。 クイックソートの時間量 を とします。 初期状態として、 通りの並びが すべて等確率だとしましょう。 クイックソートの時間量 を とします。 ピボットが 番目のときには、 以下の漸化式を満たす。 小さい方の分割を 再帰的にソートする分 大きい方の分割を 再帰的にソートする分 partition()分 ピボットの順位は、n通り全て均等におこるので、 それらを総和して、nで割ったものが平均時間量

したがって、入力順列がすべて均等に起こるという仮定では、 クイックソートの平均時間計算量は、次の漸化式を満たす。

漸化式における再帰式を個々に分解して調べる。 漸化式の解法 漸化式における再帰式を個々に分解して調べる。 まず、

次に、 したがって、 に    を代入して、

両辺の差をとる。 両辺を     で割る。 この式を辺々加える。

ここで、 調和級数 (Harmonic Series)

調和級数の見積もり

以上より、クイックソートの平均計算時間量は、 である。

マージソート

マージソートの方針 方針 問題を小分けにして、あとで組み合わせる。(分割統治法) 小分けした問題は、再帰的にソートする。 もしソートされた2つの配列があれば、 それらのそれらを組み合わせて、 大きいソートの列をつくる。(マージ操作) 1要素だけの列はソート済みとみなせる。 B 1 3 5 8 3 8 A 1 2 4 5 9 13 C 2 4 9 13

マージの動き B 1 3 5 8 A C 2 4 9 13 B 1 3 5 8 A 1 C 2 4 9 13 ソート済み B 1 3 5 8 A 1 2 C 2 4 9 13

分割 もし2つのソート列があったら、 マージ操作によって、長いソート列がえられることが わかった。 どうやって、2つのソート列を作るのか? おなじ問題で、 問題のサイズが小さくなっていることに 注意する。 列を二等分にして、再帰的にソートする。

マージソート動き前半(分割) 3 1 2 4 5 6 7 13 A 5 3 8 1 4 9 2 A[0]からA[3]まで ソートして。 13 A 5 3 8 1 4 9 2 A[0]からA[3]まで ソートして。 A[4]からA[7]まで ソートして。 1 2 3 4 5 6 7 13 5 3 8 1 4 9 2 m_sort(0,1,A) m_sort(2,3,A) 1 2 3 6 7 4 5 5 3 13 9 2 8 1 4 6 1 3 2 5 7 4 13 5 3 8 1 4 9 2

マージソート動き後半(マージ) 1 2 3 4 5 7 6 13 5 3 8 1 4 9 2 marge 6 4 5 7 2 3 1 6 7 5 7 6 13 5 3 8 1 4 9 2 marge 6 4 5 7 2 3 1 6 7 13 2 9 4 1 8 3 5 1 2 3 4 5 6 7 8 1 3 5 2 4 9 13 5 1 2 3 4 6 7 A 9 1 2 3 4 5 8 13

練習 次の配列を、マージソートでソートするとき、 前のスライドに対応する図を作成せよ。 5 11 25 21 1 8 3 16

マージに関する注意 マージでは、配列の無いようをいったん別の作業用 配列に蓄える必要がある。 作業用の配列が必要 A 退避 tmp 作業用配列 マージ A

データ退避の実現 /* A[left]-A[right]をtmp[left]-tmp[right]に書き出す。*/ void write(int left,int right) { int i; for(i=left;i<=right;i++){ tmp[i]=a[i]; } return;

マージの実現 /* tmp[left]-tmp[mid]とtmp[mid+1]-tmp[right]を A[left]-A[right]にマージする。(細かい部分は省略)*/ void marge(int) { int l=left,r=mid+1;/*tmp走査用*/ int i=left;/*A走査用*/ for(i=left;i<=right;i++){ if(tmp[l]<=tmp[r ] && l<=mid){ A[i]=tmp[l];l++; }else if(tmp[r]<tmp[l] && r<= right){ A[i]=tmp[r];r++; }else if(l>mid){ }else if(r>right){ } return;

マージソートの実現 /*概略です。細かい部分は省略*/ void merge_sort(int left,int right) { int mid; /*中央*/ if(left>=right){ return; }else{ mid=(left+right)/2; merge_sort(left,mid); merge_sort(mid+1,right); write(left,right); merge(left,mid,right); }

命題M1(マージの正当性) マージにより、2つの短いソート列から、 一つの長いソート列が得られる。 証明 配列Aの走査用のカウンタに関する帰納法で 証明することができる。(厳密な証明は省略)

命題M2(マージソートの正当性) マージソートにより、配列が昇順にソートされる。 証明 再帰の深さに関する帰納法や、 あるいはソートされている部分列の長さに関する帰納法 で証明できる。(厳密な証明は省略。)

命題M3(マージソートの停止性) マージソートは停止する。 証明 再帰呼び出しにおいて、必ずサイズが小さくなる(約半分) ことに注意する。 また、要素数が1以下の時には、停止することにも注意する。 これらの考察から、帰納法で証明できる。 (厳密な証明は省略。)

マージソートの計算量 まず、マージの計算量 を考えます。 明らかに、出来上がるソート列の長さに比例した時間量です。 マージソートの時間量を まず、マージの計算量 を考えます。 明らかに、出来上がるソート列の長さに比例した時間量です。 マージソートの時間量を とします。 以下の再帰式を満たします。

解析を簡単にするため、データを 個あると仮定します。

任意の に対して、 を満たす が必ず存在する。         であるような一般の入力サイズに対しては、 もう一段階解析の途中を考察する。 任意の に対して、        を満たす  が必ず存在する。 よって、 一方 したがって、

結局、どのような入力に対しても、マージソートの 最悪時間計算量は、 である。

分割統治法について

分割統治法とは 元の問題をサイズの小さいいくつかの部分問題に分割し、 個々の部分問題を何らかの方法で解決し、 それらの解を統合することによって、元の問題を解決する方法のことである。 (分割統治法に基づくアルゴリズムは、再帰を用いると比較的容易に記述することができる。)

分割統治法のイメージ 問題 分割 部分問題1 部分問題2 この部分で再帰がもちいられることが多い。 解1 解2 統治 (全体の)解

ここでは、より一般的な分割統治法における計算量を考察する。 分割統治法の時間計算量 ここでは、より一般的な分割統治法における計算量を考察する。 サイズ 個々の要素数 分割数 基礎 個 統治部分は線形時間で行えると仮定する。

一般的な分割統治法における時間計算量   は、次の漸化式で表されることが多い。 この漸化式を解く。 を代入して次式を得る。 この式を上式に代入する。

  と   の大小関係で式が異なる。 等比級数の和 ここで、       と仮定する。 (一般のnでもほぼ同様に求めることができる。)

場合1: すなわち      のとき この場合は線形時間アルゴリズムが得られる。

場合2: すなわち      のとき この場合は、典型的な           時間の アルゴリズムが得られる。

場合3: すなわち      のとき ここで、         とおく。 この場合は指数時間アルゴリズムになってしまう。

分割統治法の計算時間のまとめ 分割数(a)がサイズ縮小(b)より小さい場合には、線形時間アルゴリズム  (マージソートがこの場合に相当する。) 分割数(a)がサイズ縮小(b)より大きい場合  指数時間アルゴリズムになってしまう。