分割統治アルゴリズム– 2つ以上の部分に分割してみませんか?


33

クイックソートやマージソートなどの分割統治アルゴリズムでは、入力は通常(少なくとも入門テキストでは)2つに分割され、2つの小さなデータセットは再帰的に処理されます。データセット全体を処理する作業が半分以下で済む場合、これにより問題の解決が速くなるというのは理にかなっています。しかし、データセットを3つの部分に分割してみませんか?四?n

データを多くの多くのサブセットに分割する作業は価値がないと思いますが、2つのサブセットで停止する必要があるという直感が欠けています。

また、3ウェイクイックソートへの多くの参照を見てきました。これはいつ高速ですか?実際には何が使用されていますか?


配列を3つの部分に分割するクイックソートに似たアルゴリズムを作成してみてください。
gnasher729

回答:


49

データセット全体を処理する作業が半分以下で済む場合、これにより問題の解決が速くなるというのは理にかなっています。

それは、分割統治アルゴリズムの本質ではありません。通常、ポイントは、アルゴリズムが「データセット全体を扱う」ことができないということです。代わりに、簡単に解決できる部分に分割され(2つの数値を並べ替えるなど)、それらが簡単に解決され、結果が完全なデータセットの解を生成する方法で再結合されます。

しかし、データセットを3つの部分に分割してみませんか?四??

主に、3つ以上の部分に分割し、2つ以上の結果を再結合すると、実装がより複雑になりますが、アルゴリズムの基本的な(ビッグO)特性は変更されないため、差は一定の要因であり、スローダウンを引き起こす可能性があります3つ以上のサブセットの分割と再結合により追加のオーバーヘッドが生じる場合。

たとえば、3方向のマージソートを行う場合、再結合フェーズでは、すべての要素に対して3つの要素のうち最大のものを見つける必要があります。1ではなく2つの比較が必要なので、全体で2倍の比較を行います。 。代わりに、再帰深度をln(2)/ ln(3)== 0.63の係数で減らすため、スワップは37%少なくなりますが、2 * 0.63 == 26%の比較(およびメモリアクセス)が増えます。それが良いか悪いかは、ハードウェアのどちらがより高価かによります。

また、3ウェイクイックソートへの多くの参照を見てきました。これはいつ高速ですか?

どうやらクイックソートのデュアルピボット変異体は、比較の同じ数を必要とするように証明することができますが、平均20%少ないスワップに、それは純利益です。

実際には何が使用されていますか?

最近では、独自のソートアルゴリズムをプログラムする人はほとんどいません。ライブラリが提供するものを使用します。たとえば、Java 7 APIは実際にデュアルピボットクイックソートを使用します

何らかの理由で実際に独自のソートアルゴリズムをプログラミングする人は、ほとんどの場合、エラーの可能性が20%向上するため、単純な2ウェイバリアントに固執する傾向があります。覚えておいてください。パフォーマンスの最も重要な改善は、コードが「機能しない」状態から「機能する」状態になるときです。


1
小さな注意:Java 7は、プリミティブをソートするときにのみデュアルピボットクイックソートを使用します。オブジェクトをソートするには、Timsortを使用します。
バクリウ

1
「最近では、だれも独自のソートアルゴリズムをプログラムすることはほとんどありません」と(さらに重要なことです)「最も重要なパフォーマンスの改善は、コードが「機能しない」から「機能する」に移行することです。ただし、たとえば、データセットを多くの多くの部分に分割する場合、そのオーバーヘッドがまだ些細なものかどうかを知りたいと思います。それはとても偶然にも、そう他の人々を持っている: bealto.com/gpu-sorting_intro.html stackoverflow.com/questions/1415679/... devgurus.amd.com/thread/157159
AndrewJacksonZA

私は、少し遅いです。なぜ2 * 0.69の比較が必要なのか誰にも説明できますか?0.69がどこから来たのかわからない。
-jeebface

@jeebfaceおっと、それはタイプミスでした(現在修正済み)。それは0.63(再帰の深さの減少)であり、26%の結果もうまくいきます。
マイケルボルグワード

30

漸近的に言えば、それは問題ではありません。たとえば、バイナリ検索ではおよそlog 2  n個の比較が行われ、三値検索ではおよそlog 3  n個の比較が行われます。対数がわかっていれば、log a  x = log b  x / log b aで  あることがわかるので、バイナリ検索では約1 / log 3しか作成されません。 2≈3項検索の1.5倍の比較。これは、だれも大きな対数表記法で対数の底を指定しない理由でもあります。実際の底が何であっても、それは与えられた底の対数から常に一定の因子です。したがって、問題をより多くのサブセットに分割しても、時間の複雑さは改善されず、実際には、より複雑なロジックを上回るには不十分です。実際、その複雑さは実際のパフォーマンスに悪影響を及ぼし、キャッシュのプレッシャーを増大させたり、マイクロ最適化を実行不可能にする可能性があります。

一方、ツリーのようなデータ構造では、通常他の理由で、高い分岐係数(3よりもはるかに大きい、多くの場合32以上)を使用します。これにより、メモリ階層の利用率が向上します。RAMに格納されたデータ構造はキャッシュをより有効に活用し、ディスクに格納されたデータ構造はHDD-> RAMの読み取りが少なくて済みます。


はい、バイナリツリー構造以上の特定のアプリケーションのoctreeを検索します。
daaxix

@daaxix btreeはおそらくより一般的です。
ジュール

4

2つではなくNで細分する検索/ソートアルゴリズムがあります。

簡単な例は、O(1)時間かかるハッシュコーディングによる検索です。

ハッシュ関数が順序を保持している場合、それを使用してO(N)ソートアルゴリズムを作成できます。(ソートアルゴリズムは、結果内の数字の位置をN回検索するだけと考えることができます。)

基本的な問題は、プログラムがいくつかのデータを調べてからいくつかの後続の状態に入るとき、いくつの後続の状態があり、それらの確率がどれくらい等しいかということです。

たとえば、コンピューターが2つの数値を比較し、ジャンプするかしないか、両方のパスが等しくなる可能性がある場合、プログラムカウンターは各パスの情報をもう1ビット「認識」するため、平均して「学習」しますビット。問題がMビットの学習を必要とする場合、バイナリ決定を使用すると、Mより少ない決定で答えを得ることができません。したがって、たとえば、サイズが1024のソートされたテーブルで数値を検索することは、10未満のバイナリ決定では実行できません。それより少ない数では十分な結果が得られないからです。

コンピューターが1つの数値を取得し、それを配列のインデックスに変換すると、配列内の要素数の2を底とするまで「学習」され、一定の時間で実行されます。たとえば、1024エントリのジャンプテーブルが存在する場合、ほぼ同じ確率で、そのテーブルをジャンプして10ビットを「学習」します。それがハッシュコーディングの基本的なトリックです。この並べ替えの例は、カードのデッキを並べ替える方法です。カードごとに1つずつ、52個のビンがあります。各カードをビンに入れて、すくい上げます。細分化は不要です。


1

これはソートだけでなく、一般的な分割と征服に関する質問なので、誰もマスター定理を持ち出していないことに驚いています

簡単に言えば、分割統治アルゴリズムの実行時間は、2つのカウンターベイルの力によって決まります。大きな問題を小さな問題に変えることで得られる利点と、より多くの問題を解決するために支払う価格です。アルゴリズムの詳細に応じて、問題を3つ以上の部分に分割するのにお金を払う場合と払わない場合があります。各ステップで同じ数のサブ問題に分割し、各ステップで結果を結合する時間の複雑さを知っている場合、マスター定理はアルゴリズム全体の時間の複雑さを示します。

乗算のKaratsubaアルゴリズムは、3方向の除算と征服を使用して、O(3 n ^ log_2 3)の実行時間を実現します。これは、通常の乗算​​アルゴリズム(nは、数字)。


マスター定理では、作成する副問題の数だけが要因ではありません。Karatsubaとその従兄弟のStrassenでは、実際にはいくつかのサブ問題のソリューションをスマートにマージすることで改善がもたらされるため、サブ問題の再帰呼び出しの数を減らすことができます。要するに、bマスターの定理が上昇するaためには、さらに分裂を改善するためにゆっくりと上昇することが必要です。
情報14

-4

そのバイナリの性質のため、コンピューターは物事を2に分割するのに非常に効率的であり、3ではそれほど効率的ではありません。 3部門を得るために2で割ると、2で割ることもできます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.