4.ソート 4-1.ソート問題について 4-2.簡単なソートアルゴリズム 4-3.高度なソートアルゴリズム

Slides:



Advertisements
Similar presentations
逐次ソート 2011/05/16. ソート(sort) 順序集合の要素a 1 … a n の上下関係を整 える 一般的には、整数の集合 N を考えればよ い ソートの計算量が問題となる どのような入力に対し、どのようなアル ゴリズムが最適か?
Advertisements

4.ソート問題とアルゴリズム 4-1.ソート問題について 4-2.簡単なソートアルゴリズム 4-3.高度なソートアルゴリズム
離散システム特論 整列(sorting)アルゴリズム 2.
データ構造とアルゴリズム論 第5章 整列(ソート)のアルゴリズム
アルゴリズムイントロダクション第2章 主にソートに関して
アルゴリズムとデータ構造 2012年6月27日
第12回 ソート(3): シェルソート、クイックソート
アルゴリズムとデータ構造 第8回 ソート(3).
第10回 整列 ~ バブルソート,挿入ソート,選択ソート~
近似アルゴリズム 第10章 終了時刻最小化スケジューリング
第11回 整列 ~ シェルソート,クイックソート ~
データ構造とアルゴリズム論 第5章 整列(ソート)のアルゴリズム
第11回 整列 ~ バケットソート,基数ソート,ヒープソート~
2009/10/30 整列アルゴリズム (2) 第5講: 平成21年10月30日 (金) 4限 E252教室 コンピュータアルゴリズム.
データ構造とアルゴリズム論 第6章 探索のアルゴリズム
ファーストイヤー・セミナーⅡ 第8回 データの入力.
4-3:高度なソートアルゴリズム① (分割統治法にもとづくソート)
2009/10/9 良いアルゴリズムとは 第2講: 平成21年10月9日 (金) 4限 E252教室 コンピュータアルゴリズム.
4.整列のアルゴリズム.
アルゴリズムとデータ構造 --- 理論編 --- 山本 真基
第10回 ソート(1):単純なソートアルゴリズム
データ構造と アルゴリズム 第二回 知能情報学部 新田直也.
担当:青木義満 情報工学科 3年生対象 専門科目 システムプログラミング システムプログラミング プロセス間通信(パイプ) 担当:青木義満
アルゴリズムとデータ構造 補足資料7-3 「単純選択ソートselsort.c」
データ構造とアルゴリズム 分割統治 ~ マージソート~.
岩井 儀雄 コンピュータ基礎演習  ー探索、整列ー 岩井 儀雄
データ構造と アルゴリズム 第八回 知能情報学部 新田直也.
データ構造とアルゴリズム論 第2章 配列(構造)を使った処理
データ構造と アルゴリズム 第四回 知能情報学部 新田直也.
アルゴリズム入門.
アルゴリズムとデータ構造 第7回探索のためのデータ構造(1) 2015/11/18 アルゴリズムとデータ構造 2015.
第11回 整列 ~ シェルソート,クイックソート ~
プログラミング基礎a 第8回 プログラムの設計 アルゴリズムとデータ構造
7-3.高度な木 (平衡木) AVL木 平衡2分木。回転操作に基づくバランス回復機構により平衡を保つ。 B木
2009/11/6 整列アルゴリズムの復習 第6講: 平成21年11月6日 (金) 4限 E252教室 コンピュータアルゴリズム.
情報工学概論 (アルゴリズムとデータ構造)
アルゴリズムとデータ構造1 2005年7月15日
ソートアルゴリズムの種類 選択ソート (selection sort) バブルソート (bubble sort)
情報工学概論 (アルゴリズムとデータ構造)
わんくま同盟茶藝部顧問 Microsoft MVP for VC episthmh
データ構造とアルゴリズム論 第6章 整列(ソート)のアルゴリズム
大岩 元 慶応大学環境情報学部 再帰 データ構造とプログラミング(8) 大岩 元 慶応大学環境情報学部
アルゴリズムとプログラミング (Algorithms and Programming)
先進的計算基盤システムシンポジウム SACSIS2007併設企画 マルチコアプログラミングコンテスト 「Cellスピードチャレンジ2007」
プログラミング基礎a 第8回 プログラムの設計 アルゴリズムとデータ構造
データ構造とアルゴリズム論 第5章 整列(ソート)のアルゴリズム
データ構造とアルゴリズム論 第5章 整列(ソート)のアルゴリズム
プログラミング 4 整列アルゴリズム.
アルゴリズムとデータ構造1 2005年6月24日
2009/10/23 整列アルゴリズム (1) 第4講: 平成21年10月23日 (金) 4限 E252教室 コンピュータアルゴリズム.
プログラミング 4 探索と計算量.
データ構造とアルゴリズム論 第5章 整列(ソート)のアルゴリズム
アルゴリズムとデータ構造1 2006年7月11日
アルゴリズムとデータ構造 2011年6月23日
プログラミング演習Ⅲ- Sorting Quick Sort and Merge Sort
5.サーチ 5-1.線形探索 5-2.2分探索 5-3.ハッシュ.
アルゴリズムとデータ構造 --- 理論編 --- 山本 真基
データ構造とアルゴリズム (第5回) 静岡大学工学部 安藤和敏
アルゴリズムとデータ構造 2012年7月2日
アルゴリズムとプログラミング (Algorithms and Programming)
情報工学概論 (アルゴリズムとデータ構造)
アルゴリズムとデータ構造 2013年7月2日
ソートのプログラムの流れ 配列の中身を小さい順に並び替える a[1],a[2],…a[n]の値を順に出力する
精密工学科プログラミング基礎 第7回資料 (11/27実施)
アルゴリズムとデータ構造 2012年6月25日
プログラミング入門2 第6回 関数 情報工学科 篠埜 功.
参考:大きい要素の処理.
精密工学科プログラミング基礎Ⅱ 第2回資料 今回の授業で習得してほしいこと: 配列の使い方 (今回は1次元,次回は2次元をやります.)
7.木構造 7-1.データ構造としての木 7-2.2分探索木 7-3.高度な木.
プログラミング論 バイナリーサーチ 1.
Presentation transcript:

4.ソート 4-1.ソート問題について 4-2.簡単なソートアルゴリズム 4-3.高度なソートアルゴリズム 4-4.比較によらないソートアルゴリズム 4-5.ソート問題の下界(高速化の限界)

4-1:ソート問題 入力:データ数nとn個の数 出力: (ここで、入力サイズは、 とします。) を小さい順にならべたもの ここで、 は、 (ここで、入力サイズは、   とします。) 出力:                   を小さい順にならべたもの ここで、               は、                   の置換

整列(ソート) データ データ k,a,l,c,d,s 5,3,8,1,6,21,11 ソートアルゴリズム ソートアルゴリズム 1,3,5,6,8,11,21 a,c,d,k,l.s

内部整列と外部整列 CPU CPU 高速アクセス 高速アクセス データの一部 全データ メモリ メモリ 低速アクセス 全データ ディスク

仮定と要求 内部整列 どのデータにも均等な時間でアクセスできる。 できるだけ高速に整列したい。 (理想的な計算機上のアルゴリズムではこっち) 外部整列 CPU-メモリ間のデータ転送速度より、 ディスク-メモリ間のデータ転送速度が極端に遅い。 全体の整列をできるだけ高速にしたい。 (ディスクーメモリ間のデータ転送をあまり行わないように する。現実的な問題だが、より複雑な解析が必要である。)

ソート問題の重要性 実際に頻繁に利用される。 アルゴリズム開発の縮図 十分な理論解析が可能。 豊富なアィディア 繰り返しアルゴリズム(バブルソート、挿入ソート等) アルゴリズムの組み合わせ(選択ソート、マージソート等) 分割統治法(マージソート、クイックソート等) データ構造の利用(ヒープソート、2分探索木等) 十分な理論解析が可能。 最悪計算量と平均計算量の違い(クイックソート) 豊富なアィディア

ソートアルゴリズムの種類 バブルソート 選択ソート 挿入ソート クイックソート マージソート ヒープソート バケットソート 基数ソート

ソートアルゴリズムの分類 原理 比較による 比較によらない バブルソート 選択ソート バケットソート 時間量(速度) 挿入ソート 基数ソート クイックソート 計算量は      ヒープソート だけど条件付き マージソート

入出力形態 5 3 8 1 4 13 9 2 入力: 配列A A[0] A[1] A[i] A[n-1] n 個 2 3 4 5 8 9 (終了状態): 配列A A[n-1] A[0] A[1] n 個 入力は配列で与えられるとする。

交換関数(準備) 参照渡しにする必要があることに注意すること。 /* 交換用の関数。 swap(&a,&b)で呼び出す。 */ /* 交換用の関数。 swap(&a,&b)で呼び出す。 */ void swap(double *a,double *b) { double tmp; /* データの一次保存用*/ tmp=*a; *a=*b; *b=tmp; return; }

4-2:簡単なソートアルゴリズム

バブルソート 方針 隣同士比べて、小さいほうを上(添字の小さい方)に 順にもっていく。 先頭の方は、ソートされている状態にしておく。 これらを繰り返して、全体をソートする。

バブルソートの動き1 1 2 3 4 5 6 7 5 3 8 1 2 4 13 9 A 5 3 8 1 4 13 9 2 交換 交換 5 3 8 1 4 13 2 9 5 3 1 8 2 4 13 9 交換 交換 5 3 8 1 4 2 13 9 5 1 3 8 2 4 13 9 交換 交換 1 5 3 8 2 4 13 9 5 3 8 1 2 4 13 9 この一連の動作をバブルソートの 「パス」といいます。 非交換

バブルソートの動き2 1 2 3 4 5 6 7 1 2 3 4 5 8 9 A 5 3 8 1 4 13 9 2 13 パス5 パス1 1 5 3 8 2 4 13 9 1 2 3 4 5 8 9 13 未ソート ソート 済み パス2 パス6 1 2 5 3 8 4 13 1 2 3 4 5 8 9 9 13 パス3 パス7 1 2 3 4 5 8 9 1 2 3 5 4 8 9 13 13 パス4    パスでソートできる。

練習 次の配列を、バブルソートでソートするとき、 全てのパスの結果を示せ。 11 25 21 1 8 3 16 5

バブルソートの実現 /* バブルソート*/ void bubble() { int i,j; /* カウンタ*/ /* バブルソート*/ void bubble() { int i,j; /* カウンタ*/ for(i=0;i<n-1;i++) for(j=n-1;j>i;j--) if(A[j-1]>A[j]) swap(&A[j-1],&A[j]); } return; j>0としてもいいが時間計算量が約2倍になる

命題B1(boubbleの正当性1) 内側のforループ(ステップ6)がk回繰り返されたとき、 A[n-k]からA[n-1]までの最小値が A[n-k]に設定される。 証明 k-1回の繰り返しによって、 A[n-k-1]にA[n-k-1]からA[n-1] までの最小値が 保存されているこのに注意する。 したがって、k回目の繰り返しにより、 がA[n-k]に設定される。 (より厳密な数学的帰納法で証明することもできるが、 ここでは省略する。)

命題B2(boubbleの正当性2) 4.のforループがk回繰り返されたとき、 (すなわち、パスkまで実行されたとき、) 前半のk個(A[0]-A[k-1]) は最小のk個がソートされている。 証明 各パスkにおいては、A[k-1]からA[n-1]の最小値が、 A[k-1]に設定される。(命題B1より) このことに注意すると、数学的帰納法により、 証明できる。(厳密な証明は省略する。)

バブルソートの計算量 パス1で、n-1回の比較と交換 パス2で、n-2 ・ パスn-1で、1回の比較と交換 よって、 時間量 のアルゴリズム

選択ソート 方針 先頭から順に、その位置に入るデータを決める。 (最小値を求める方法で選択する。) その位置のデータと選択されたデータを交換する。 これらを繰り返して、全体をソートする。 ソート済み 残りのデータで最小値を選択

選択ソートの動き1(最小値発見) 1 2 3 4 5 6 7 5 3 8 1 4 13 9 2 A 5 3 8 1 4 13 9 2 min=3 未探索 探索済み 仮の最小値の添え字 min=0 5 3 8 1 4 13 9 2 min=3 5 3 8 1 4 13 9 2 5 3 8 1 4 13 9 2 min=1 最小値発見 min=3 5 3 8 1 4 13 9 2 min=1 1 3 8 5 4 13 9 2 5 3 8 1 4 13 9 2 swap(&A[1],&A[3]) min=3 この一連の動作を選択ソートの 「パス」といいます。 5 3 8 1 4 13 9 2 min=3

選択ソートの動き2 1 2 3 4 5 6 7 1 2 3 4 5 13 9 8 A 5 3 8 1 4 13 9 2 未ソート パス1 min=3 パス5 min=4 1 3 8 5 4 13 9 2 1 2 3 4 5 13 9 8 ソート 済み 未ソート(最小値発見) パス2 min=7 min=7 パス6 1 2 8 5 4 13 9 3 1 2 3 4 5 8 9 13 min=6 パス3 min=7 パス7 1 2 3 5 4 13 9 8 1 2 3 4 5 8 9 13 パス4 min=4    パスでソートできる。

練習 次の配列を、選択ソートでソートするとき、 全てのパスの結果を示せ。 5 11 25 21 1 8 3 16

選択ソートの実現1 (最小値を求めるアルゴリズム) /*選択用の関数、A[left]からA[right] までの最小値を求める*/ int find_min(int left,int right) { int min=left; /* 仮の最小値の添字*/ int j=left; /* カウンタ */ min=left; for(j=left+1;j<=right;j++) if(a[min]>a[j]){min=j;} } return min;

選択ソートの実現2 /* 選択ソート*/ void slection_sort() { int i; /* カウンタ*/ /* 選択ソート*/ void slection_sort() { int i; /* カウンタ*/ int min; /* 最小値の添字*/ for(i=0;i<n-1;i++) min=find_min(i,n-1); swap(&A[i],&A[min]); } return; なお、説明の都合上、関数find_minを作ったが、 関数呼び出しで余分に時間がとられるので、 実際は2重ループにするほうが速いと思われる。 (でも、オーダーでは、同じ。)

命題S1(選択ソートの正当性1) find_min(left,right)は、A[left]-A[right]間の 最小値を添え字を求める。 証明 1回目の資料の命題1と同様に証明される。

命題S2(選択ソートの正当性2) 5.のforループがi+1回繰り返されたとき、 (パスiまで実行されたとき、) A[0]-A[i]には、小さい方からi+1個の要素が ソートされてある。 証明 先の命題S1を繰り返して適用することにより、 この命題S2が成り立つことがわかる。 (厳密には数学的帰納法を用いる。)

選択ソートの計算量 パス1 find_minで、n-1回の比較 パス2 n-2 ・ パスn-1のfind_minで、1回の比較 よって、 交換は、n回 時間量 のアルゴリズム

挿入ソート 方針 先頭の方は、ソート済みの状態にしておく。 未ソートのデータを、ソート済みの列に挿入し、 ソート済みの列を1つ長くする。 これらを繰り返して、全体をソートする。 未ソートデータ ソート済み

挿入ソートの動き1 1 2 3 4 5 6 7 1 3 4 5 8 13 9 2 A 5 3 8 1 4 13 9 2 パス5 未ソート 1 3 4 5 8 13 9 2 ソート済み パス1 パス6 3 5 8 1 4 13 9 2 1 3 4 5 8 9 13 2 パス2 パス7 3 5 8 1 4 13 9 2 1 2 3 4 5 8 9 13 パス3 この各回の挿入操作を、 挿入ソートの「パス」といいます。 n-1パスで挿入ソートが実現できる。 1 3 5 8 4 13 9 2 パス4

挿入ソートの動き2(挿入動作詳細) 1 3 4 5 8 9 13 2 1 3 4 5 8 9 2 13 1 3 4 5 8 2 9 13 1 3 4 5 2 8 9 1 3 4 5 8 9 13 2 13 1 3 4 2 5 8 9 13 1 3 2 4 5 8 9 13 1 2 3 4 5 8 9 13

練習 次の配列を、挿入ソートでソートするとき、 全てのパスの結果を示せ。 5 11 25 21 1 8 3 16

挿入ソートの実現1 (挿入位置を求める) /*挿入位置を見つける関数、 A[left]からA[right]までソート済みのとき、 int find_pos(int left,int right) { int j=left; /* カウンタ */ for(j=left;j<=right;j++) if(A[j]>A[right]){break;} } return j;

挿入ソートの実現2(挿入) /* 挿入(A[right]をA[pos]に挿入する。)*/ void insert(int pos,int right) { int k=right-1; /* カウンタ*/ for(k=right-1;k>=pos;k--) pos=find_pos(i,A); for(j=n-1;j<pos;j--) swap(&A[k],&A[k+1]); } return;

挿入ソートの実現3(繰り返し挿入) /* 挿入ソート*/ void insertion_sort() { /* 挿入ソート*/ void insertion_sort() { int i=0; /* カウンタ(パス回数)*/ int pos=0; /*挿入位置*/ for(i=1;i<n;i++) pos=find_pos(0,i); insert(pos,i); } return;

命題I1(挿入ソートの正当性) 5.のforループがi回繰り返されたとき、 (パスiまで実行されたとき、) A[0]からA[i]はソートされてある。 証明 挿入find_posによって、挿入位置を適切に見つけている また、insertによって、すでにソート済みの列を崩すことなく ソート済みの列を1つ長くしている。 したがって、i回の繰り返しでは、i+1個のソート列が構成される。これらのソート列は、A[0]-A[i]に保持されるので、命題は成り立つ。

命題I2(挿入ソートの停止性) insertion_sortは停止する。 証明 各繰り返しにおいて、ソート列が一つづつ長くなる。 入力データはn個であるので、n-1回の繰り返しにより、必ず停止する。

挿入ソートの最悪計算量 パス1で、1回の比較あるいは交換 パス2で、 2回の ・ パスn-1で、n-1の比較あるいは交換 よって、 比較と交換回数の合計は、 時間量 のアルゴリズム (挿入ソートを元に高速化した、シェルソートっていうものもあるが省略。)

挿入ソートの平均時間計算量の改善 find_posを左からではなくて、右からしらべるようにすることで、平均時間計算量を約半分にすることができる。 i これまで: 比較による探索 挿入のための交換 改善: 比較による探索 挿入のための交換

挿入位置の発見2 /*挿入位置を見つける関数、 A[left]からA[right]までソート済みのとき、 int find_pos(int left,int right) { int j=right; /* カウンタ */ for(j=right-1;j>=left;j--) if(A[j]<A[right]){break;} } return j+1;

挿入ソートの 最悪時間計算量と平均時間計算量 前の解析と同様に求められる。 最悪時間計算量: 平均時間計算量: 各パスiにおいて、位置の発見と、挿入は、 入力がまったく均一だと仮定すると、 平均して     の時間計算量しか必要ないと考え られる。したがって、 高速なソートアルゴリズムがあるので、あまりこだわらなくてもよい。 結局、 時間量 のアルゴリズム