• 検索結果がありません。

第9回 並び替えアルゴリズ ム

N/A
N/A
Protected

Academic year: 2021

シェア "第9回 並び替えアルゴリズ ム"

Copied!
41
0
0

読み込み中.... (全文を見る)

全文

(1)

第9回 並び替えアルゴリズ ム

~さまざまなアルゴリズムを比較しよ

う~

(2)

学習目標

適切なアルゴリズムを用いたプログラ ムが書ける

並び替え(ソート)アルゴリズムの性能に ついて比較検討し、説明できる

Java でソートのプログラムが書ける

問題が与えられたとき、適切なアルゴリズ

ムでプログラムを書ける

(3)

9.1 並び替えの

性能比較プログラム

9.1.1 今回扱うアルゴリズム

9.1.2 実験環境の構築

① ソート性能比較プログラムの設計

② ランダムな数値を発生させる

(4)

9.1.1 今回扱うアルゴリズム

リニアサーチを使えるのは次の場合に限ら れる

要素が少ない時 ( 数十個程度 )

ソートされていないデータに対する時

バイナリサーチを使うには、ソート済み

(順番に並んでいる状態)である必要あり

今回は、ソートを考えましょう

(5)

今回は簡単なソートをやりま す

ソートは重要で時間のかかる処理なので、これまでに も多くのコンピュータ科学者が研究に取り組み、いく つかの高度な方法も発明されています

今回はその中で比較的簡単な 3 つの方法を紹介します

バブルソート

選択ソート

挿入ソート

これらのテクニックは素朴で、遅いアルゴリズムですが、やってみる価値はあります 単に分かりやすいだけでなく、データの並び方や数によって、これらの方法のほうが 速い場合もあるからです

(6)

9.1.2 実験環境の構築

① クラス設計

② ランダムに数値を発生させる

(7)

I t emTypeLi st + add( )

+ i sSor t ( ) + sort ( )

① クラス設計

ItemTypeList にメソッドを追加します

•sort() メソッド - ソートする

•isSort() メソッド - ソート済みか調べる

(8)

クラス設計 (2)

アルゴリズムをクラスに、ポリモー フィズムで設計します

Bubbl eSor t + sort ( )

Sel ect i onSor t + sort ( )

I nsert i onSor t + sort ( )

I t emTypeLi st + add( )

+ i sSor t ( ) + sort ( )

Sor t Al gor i sm + sort ( )

(9)

② ランダムに数値を発生させ る

Math.random() メソッドを使います

double randomId = Math.random();

メソッドの返り値は double 型で、

0 ~ 1 の間のランダムな数を返します

(10)

1 ~ N までの

ランダムな数を発生させる

double 型を int 型に

変換 ( キャスト ) します

int randomRange = 1000000;// ランダムの範囲

( 100 万なら 1 ~ 100 万の範囲のランダムな数字を生成する)

double randomNo = Math.random();

int randomInt = (int)(randomNo*randomRange);

ランダム生成した 0 以上~ 1 未満

の少数を N 倍して 0 ~ (N-1) にします

(11)

9.2 ソートのアルゴリズム

9.2.1 バブルソート

① コンピュータでの「入れ替え」 (Swap)

9.2.2 選択ソート

9.2.3 挿入ソート

9.2.4 挿入ソートの効率化

(12)

9.2.1 バブルソート

アルゴリズム

1. 2 つの商品番号を比較する

2. 左側の方の番号が大きければ商品種類を入れ替え る。

3. 右へ一つ移動する

4. ソートの終ってない部分 ( 毎回小さくなる ) に対 して上のステップを繰り返す

※ 配列の一番左の箱の中の番号が最小になるように並 べ替える場合です

(13)

[0] [1] [2] [3] [4] [5] [6] [7] [8] [9]

103 22 51 3 64 18

※ 実際にはオブジェクトが入りますが、今日は見やすいように番号 だけが入っているように見せます

バブルソート

比較する 22 103 入れ替える

一つ移動する 比較する

51 103 入れ替える

一つ移動する 比較する

3 103 入れ替える

一つ移動する 比較する

64 103 入れ替える

一つ移動する 比較する

18 103 入れ替える

一つ移動する もう一度始めから

比較する 22 51 そのまま

一つ移動する 比較する

3 51 入れ替える

一つ移動する 比較する

51 64 そのまま

一つ移動する 比較する

18 64 入れ替える

一つ移動する

ソート済み ソート済み

とやっていくと、最後に ソートされます

(14)

① コンピュータでの

「入れ替え」 (Swap)

前ページの例では、「入れ替え」を一 瞬で行っていましたが、実はコン

ピュータはそのような操作はできませ ん

[0] [1]

513 513 入れ替える

(15)

コンピュータでの「入れ替 え」 (Swap) やり方

一時的に箱を用意します

[0] [1] tmp

51 3 3

コピー 51

コピー 3

コピー

入れ替え完了!

これを何回もやるのは 結構時間かかります

(16)

練習問題

バブルソートの効率を考えなさい

特に

① 比較の回数

② 入れ替えの回数

を考えなさい

(17)

バブルソートの効率

(考えてみましょう)

① 比較の回数

② 入れ替えの回数

(18)

バブルソートの実装

public class BubbleSort implements SortAlgorithm{

/**

* 並び替え(ソート)をするメソッド

*/ public void sort(ItemType[] itemTypeArray,int size){

for(int i=size-1;i>1;i--){//要素数回始めから作業を繰り返す for(int j=0;j<i;j++){// ソート済みの所まで作業する

if(itemTypeArray[j].getId() > itemTypeArray[j+1].getId()){

swap(itemTypeArray,j,j+1);//もし右側のほうが大きかったら入れ替える }

} } }}

例題9-1 (BubbleSort.java)

(19)

入れ替え (swap) の実装

/** * 要素を入れ替えるメソッド */

private void swap(ItemType[] itemTypeArray,int target1,int target2){

ItemType temp;//temporary の箱を用意する temp = itemTypeArray[target1];

itemTypeArray[target1] = itemTypeArray[target2];

itemTypeArray[target2] = temp;

}

例題9-1 (BubbleSort.java)

(20)

9.2.2 選択ソート

アルゴリズム

1.

全商品番号から、一番小さい番号を探す

2.

見つかったものと、一番左の商品種類を 入れ替える。

ソートの終ってない部分 ( 毎回小さくな

る ) に対して上のステップを繰り返す。

(21)

選択ソート

[0] [1] [2] [3] [4] [5] [6] [7] [8] [9]

103 22 51 3 64 18

最小値の入っている 箱の番号

0 比較する

1

最小値を更新する 比較する比較する比較する比較する

3

最小値を更新する 入れ替える

最小値が見つかった!

3 103

ソート済み

ここからまた同じことをはじめる

1

最小値を更新する 比較する比較する比較する比較する

5

最小値を更新する 最小値がみつかった

入れ替える

18 22

ソート済み

このようにして、ソートが終わるまで 続けます。

(22)

練習問題2

選択ソートの効率を考えなさい

特に

① 比較の回数

② 入れ替えの回数

を考えなさい

(23)

選択ソートの効率

(考えてみましょう)

① 比較の回数

② 入れ替えの回数

(24)

選択ソートの実装

public class SelectionSort implements SortAlgorithm{

/**

* 並び替え(ソート)をするメソッド

*/ public void sort(ItemType[] itemTypeArray,int size){

for(int i=0;i<size-1;i++){// 要素数回始めから作業を繰り返す int minimum = i;//最小値の配列番号を保存しておく

for(int j=i+1;j<size;j++){//ソート済み以降を作業する

if(itemTypeArray[j].getId() < itemTypeArray[minimum].getId()){

minimum = j;// 最小値より小さかったら、新しい最小値に }

}

swap(itemTypeArray,i,minimum);//一番左の要素( ソート済み除く )と最小と入れ替える }

}}

例題9-1

(SelectionSort.java)

(25)

9.2.3 挿入ソート

アルゴリズム

1.

途中までソートが終わっているとします

(そのほうが理解しやすいので)

2.

ソートが終わっていない中で、一番左にあ る商品種類をソート済みの商品種類の中で

、あるべき位置に挿入します

ソートの終ってない部分 ( 毎回小さくな

る ) に対して上のステップを繰り返します

(26)

[0] [1] [2] [3] [4] [5] [6] [7] [8] [9]

3 18 22 51 64 18 103

挿入ソート

ソート済み

次に挿入すべき商品種類 入れるところを探すここだ!

22 コピー

3 18 51 64 22 18 103

[0] [1] [2] [3] [4] [5] [6] [7] [8] [9]

3 18 51 64 22 18 103

コピーする 22 51 64

[0] [1] [2] [3] [4] [5] [6] [7] [8] [9]

3 18 22 51 64 18 103 移動

これを繰り返します。

次に挿入する ターゲット ソート済み部分が増えた!

(27)

練習問題3

挿入ソートの効率を考えなさい

特に

① 比較の回数

② 入れ替えの回数

を考えなさい

(28)

挿入ソートの効率

(考えてみましょう)

① 比較回数

② 入れ替え回数

(29)

場合によって効率が変わる!

挿入ソートは、ほとんどソートされて いるときには、とても効率的

逆に、逆順にソートされている場合、

最大の比較回数と移動回数が実行され

てしまい、バブルソートと同じ遅さに

なってしまう

(30)

挿入ソートのアルゴリズム

public class InsertionSort implements SortAlgorithm{

/**

* 並び替え(ソート)をするメソッド

*/ public void sort(ItemType[] itemTypeArray,int size){

int target;// 挿入する対象

for(target = 1;target<size;target++){

ItemType temp = itemTypeArray[target];//対象をコピーする int i=target;

while(i>0 && itemTypeArray[i-1].getId() > temp.getId()){//挿入場所に出会うまで       シフトしつづける

itemTypeArray[i] = itemTypeArray[i-1];//右へシフト i--;

}

itemTypeArray[i] = temp;// 対象を挿入する }

例題9-1

(InsertionSort.java)

(31)

9.2.4 挿入ソートの効率化

挿入ソートをあと少しだけ効率化する

ことを考えましょう

(32)

条件文に注目する

/**

* 並び替え(ソート)をする

*/ public void sort(ItemType[] itemTypeArray,int size){

int target;// 挿入する対象

for(target = 1; target<size; target++){

ItemType temp = itemTypeArray[target];// 対象をコピーする int i=target;

while(i>0 && itemTypeArray[i-1].getId() > temp.getId()){

// 挿入場所に出会うまでシフトしつづける

itemTypeArray[i] = itemTypeArray[i-1];// 右へシフト i--;

}

itemTypeArray[i] = temp;// 対象を挿入する

挿入ソートのプログラム抜粋

(33)

非効率な条件文

while(i>0 && itemTypeArray[i-1].id > temp.id)

i が 0 以上 かつ配列の中の商品番号が、対象商品番号より大きい 間繰り返す

① ②

しかし①の条件は、ほとんど成り立たない(後述)

にもかかわらず、 N^2/4 回行われてしまう

挿入すべき場所を探したい

(34)

条件文を変えられないか

「 i<0 」条件文が何故必要なのか、考

えてみましょう

(35)

「 i<0 」の条件をなくすと

[0] [1] [2] [3] [4] [5] [6] [7] [8] [9]

18 35 2 46 8 ソート済み

挿入対象

i は 0 以下になってしまい、 -1 の配列を アクセスしてしまう

こんなときまずくないですか?

ArrayIndexOutOfBoundsException

(36)

[-1]

条件をなくしても

エラーをなくす方法

[0] [1] [2] [3] [4] [5] [6] [7] [8] [9]

「番兵」という概念

いろんなところで応用が利く重要な概念

18 35 2 46 8 -1

絶対ありえないような小さい商品番号

(商品番号は必ず正だとすると -1 とか -10000000 など)

(37)

配列 [0] は番兵用

0 番目は番兵を常に入れておきます

[0] [1] [2] [3] [4] [5] [6] [7] [8] [9]

18 35 2 46 8 -1

番兵用

(38)

番兵を使うときの注意

番兵を使うと、使える配列は一つ少なくなる

いっぱいにはしないとか、一つ増やした配列を用意す るなどの対応を取るのが一般的

0 番目は番兵用に空けるため、追加アルゴリズ ムにも変更が必要

ソートのときだけずらすやり方でまずはやってみま しょう(ただし効率は少し落ちる)

今回は配列の一番始めに番兵を立てますが、アルゴリ ズムによっては、一番最後に番兵を立てる場合もあり ます。その場合は他のアルゴリズムの変更が不要

(39)

番兵を利用した場合の while 文

while(i>0 && itemTypeArray[i-1].id > temp.id)

while(itemTypeArray[i-1].id > temp.id) 番兵導入前

番兵導入後

(40)

さらにスマートなアルゴリズ ムに

[0] [1] [2] [3] [4] [5] [6] [7] [8] [9]

18-1 3518 352 462 468 8

対象

temp 2

さっきは temp 用の箱を用意 しましたが、、、

(41)

自分自身を番兵とする

[0] [1] [2] [3] [4] [5] [6] [7] [8] [9]

18-1 3518 352 462 468 8

対象 2

自分自身も番兵になります

何故そうなるのか考えてみよう

参照

関連したドキュメント

[r]

Tkachov; Doubly nonlocal Fisher-KPP equation: Speeds and uniqueness of traveling waves.. Tkachov; Doubly nonlocal Fisher-KPP equation:

Joshi; Existence and nonexistence of solutions of sublinear problems with prescribed num- ber of zeros on exterior domains, Electronic Journal of Differential Equations, 2017 No..

Algebraic curvature tensor satisfying the condition of type (1.2) If ∇J ̸= 0, the anti-K¨ ahler condition (1.2) does not hold.. Yet, for any almost anti-Hermitian manifold there

管理画面へのログイン ID について 管理画面のログイン ID について、 希望の ID がある場合は備考欄にご記載下さい。アルファベット小文字、 数字お よび記号 「_ (アンダーライン)

* 本カタログのオーダーはWEB受注「2018年5月展 &gt;&gt; Chou Chou de maman 」 より https://tiara-order.com よりお客様専用の. ID

(4S) Package ID Vendor ID and packing list number (K) Transit ID Customer's purchase order number (P) Customer Prod ID Customer Part Number. (1P)

( ** ) Chemigation: NUDRIN LV INSECTICIDE may be applied via overhead sprinkler irrigation in ID, MT, NV, OR, UT, &amp; WA at the rate of 3 pints of product per acre.. Use of