私は非常に好奇心旺盛ですが、なぜソートアルゴリズムでは安定性が重要であるか重要ではないのですか?
IBM (Insertion, Bubble, Merge)
私は非常に好奇心旺盛ですが、なぜソートアルゴリズムでは安定性が重要であるか重要ではないのですか?
IBM (Insertion, Bubble, Merge)
回答:
並べ替えアルゴリズムは、キーが等しい2つのオブジェクトが、並べ替えられる入力配列に表示されるのと同じ順序で並べ替えられた出力に表示される場合、安定していると言います。挿入ソート、マージソート、バブルソートなど、一部のソートアルゴリズムは本質的に安定しています。ヒープソート、クイックソートなど、一部のソートアルゴリズムは安定していません。
背景:「安定した」ソートアルゴリズムは、同じソートキーを持つアイテムを順番に保持します。5文字の単語のリストがあるとします。
peach
straw
apple
spork
各単語の最初の文字だけでリストを並べ替えると、安定した並べ替えは次のようになります。
apple
peach
straw
spork
不安定なソートアルゴリズム、straw
またはspork
交換することができるが、(以降、安定なの一つに、それらが同じ相対位置にとどまるstraw
前に表示されるspork
入力で、それはまた、前に表示されるspork
出力で)。
このアルゴリズムを使用して単語のリストを並べ替えることができます。5列目、4列目、3列目、2列目、1列の順に並べ替えます。最後に、正しく並べ替えられます。それを納得してください。(ちなみに、そのアルゴリズムは基数ソートと呼ばれています)
次に、質問に答えるために、姓名のリストがあるとします。「姓、次に名順」でソートするように求められます。最初にファーストネームで(安定または不安定)ソートし、次にラストネームで安定ソートすることができます。これらのソート後、リストは主に姓でソートされます。ただし、姓が同じ場合は、名がソートされます。
不安定なソートを同じ方法でスタックすることはできません。
straw
、spork
等しいと比較してください。安定したソートは入力の順序を保持しますが、不安定なソートはその保証をしません。「正しい」は、アプリケーションによって異なります。ほとんどのプログラミング言語の並べ替え関数では、ユーザーがカスタムの順序付け関数を指定できます。ユーザーの関数が異なる項目を同じものとして扱う場合(たとえば、同じ姓、異なる姓)、元の順序が保持されるかどうかを知るのに役立ちます。実際の例については、OCamlの配列ソート関数を参照してください。
安定したソートアルゴリズムは、入力に現れるのと同じ順序で同じ要素をソートするアルゴリズムですが、不安定なソートはケースを満たさない場合があります。- 私はアルゴリズムの講師であるDidem Gozupekにアルゴリズムへの洞察を提供してくれたことに感謝します。
安定した並べ替えアルゴリズム:
不安定な並べ替えアルゴリズム:
ソートの安定性とは、同じキーを持つレコードがソート前後の相対的な順序を保持することを意味します。
したがって、解決している問題がその相対的な順序の保持を必要とする場合にのみ、安定性が重要です。
安定性が必要ない場合は、ヒープソートやクイックソートなど、ライブラリの高速メモリアルゴリズムを使用して、それを忘れることができます。
安定性が必要な場合は、さらに複雑です。安定したアルゴリズムは、不安定なアルゴリズムよりもbig-O CPUやメモリの使用率が高くなります。したがって、大きなデータセットがある場合は、CPUとメモリのどちらを破壊するかを選択する必要があります。CPUとメモリの両方に制約がある場合は、問題があります。優れた妥協安定アルゴリズムは、バイナリツリーソートです。Wikipediaの記事は、 STLに基づいて哀れ簡単にC ++の実装を持っています。
各レコードの最後のキーとして元のレコード番号を追加することにより、不安定なアルゴリズムを安定したものにすることができます。
安定性が重要になる理由はいくつかあります。1つは、2つのレコードを交換することによって交換する必要がない場合、メモリ更新を引き起こす可能性があり、ページがダーティとマークされ、ディスク(または別の低速なメディア)に再書き込みする必要があることです。
並べ替えアルゴリズムは、等しいキーを持つ2つのオブジェクトが、並べ替えられた出力で、並べ替えられていない入力配列に表示されるのと同じ順序で表示される場合、安定していると言います。挿入ソート、マージソート、バブルソートなど、一部のソートアルゴリズムは本質的に安定しています。ヒープソート、クイックソートなど、一部のソートアルゴリズムは安定していません。
ただし、安定していない任意の特定のソーティングアルゴは、安定するように変更できます。ソートアルゴ固有の方法で安定させることができますが、一般に、本質的に安定していない比較ベースのソートアルゴリズムは、2つのキーの比較で位置が等しいキーを持つオブジェクトの係数。
参照:http : //www.math.uic.edu/~leon/cs-mcs401-s08/handouts/stability.pdf http://en.wikipedia.org/wiki/Sorting_algorithm#Stability
これには多くの答えがあることは知っていますが、私にとっては、この答えはRobert Harveyにより、より明確に要約されています。
安定したソートとは、入力セットの元の順序を維持するソートであり、[unstable]アルゴリズムは2つ以上のアイテムを区別しません。
並べ替える対象が単なる数値であり、それらの値のみがそれらを識別/識別している(たとえば、同じ値を持つ要素は同一である)と仮定すると、並べ替えの安定性の問題は意味がありません。
ただし、並べ替えの優先順位が同じオブジェクトは異なる場合があり、それらの相対的な順序が意味のある情報になる場合があります。この場合、ソートが不安定になると問題が発生します。
たとえば、ゲーム内のレベル[L]の迷路を掃除するためにすべてのプレーヤーの時間コスト[T]を含むデータのリストがあるとします。迷路を掃除する速さでプレイヤーをランク付けする必要があるとします。ただし、追加のルールが適用されます。時間のコストがどれだけ長くても、より高いレベルで迷路を掃除するプレイヤーは常により高いランクになります。
もちろん、ルールに従ったアルゴリズムを使用してペア値[T、L]を実数[R]にマッピングし、[R]値ですべてのプレーヤーをランク付けすることもできます。
ただし、安定した並べ替えが可能な場合は、リスト全体を[T](最初に速いプレイヤー)で並べ替え、次に[L]で並べ替えることができます。この場合、プレイヤーをクリーンアップした迷路のレベルでグループ化した後、(時間コストによる)プレイヤーの相対的な順序は変更されません。
PS:もちろん、2回並べ替えるアプローチは特定の問題に対する最善の解決策ではありませんが、投稿者の質問を説明するにはそれで十分です。
安定したソートは、常に同じ入力で同じ解(順列)を返します。
たとえば、[2,1,2]は順列[2,1,3]として安定したソートを使用してソートされます(最初はインデックス2、次にインデックス1、次にソートされた出力のインデックス3)つまり、出力は常に同じ方法でシャッフルされます。その他の非安定ですが、まだ正しい順列は[2,3,1]です。
クイックソートは安定したソートではなく、同じ要素間の置換の違いはピボットを選択するアルゴリズムに依存します。一部の実装はランダムに取得し、同じアルゴリズムを使用して同じ入力で異なる並べ替えをすばやくソートすることができます。
安定したソートアルゴリズムは決定論的に必要です。
sort([(5,3),(1,5),(3,3),(1,3)], x) => [(1,5),(1,3),(3,3),(5,3)]
。常に(確定的に)出力する確定的なソートを作成できます[(1,3),(1,5),(3,3),(5,3)]
が、これは安定したソートではありません。
安定したソートが必要な理由のいくつかの例。データベースは一般的な例です。取引データベースの場合は、姓、名、購入日時、アイテム番号、価格が含まれます。データベースは通常、日付|時刻でソートされているとしましょう。次に、クエリはデータベースの姓と名で並べ替えられたコピーを作成します。安定した並べ替えでは元の順序が保持されるため、照会の比較には姓と名のみが含まれますが、各姓と名のトランザクションはデータ|時間順になります。
同様の例は、一度に3列にソートを制限する従来のExcelです。6列を並べ替えるには、最下位の3列で並べ替えを行い、その後に最上位の3列で並べ替えを行います。
安定した基数ソートの古典的な例は、基数10の数値列のフィールドでソートするために使用されるカードソーターです。カードは、最下位桁から最上位桁に並べ替えられます。各パスで、カードのデッキが読み取られ、その列の数字に従って10の異なるビンに分けられます。次に、カードの10ビンが順番に入力ホッパーに戻されます(最初に「0」カード、最後に「9」カード)。次に、すべての列がソートされるまで、次の列で別のパスが実行されます。カードには12のゾーンがあるため、実際のカードソーターには10を超えるビンがあり、列が空白になる可能性があり、ビンの読み取りに誤りがあります。文字を並べ替えるには、列ごとに2つのパスが必要です。1番目のパスは数字、2番目のパスは12 11ゾーンです。
後で(1937年)、フィールドを比較することによって2組のカードをマージできるカード照合(マージ)マシンがありました。入力は、マスターデッキとアップデートデッキの2つのソート済みカードデッキでした。コレーターは、2つのデッキを新しいマスタービンとアーカイブビンにマージしました。これらは、オプションでマスターの複製に使用され、複製の場合に新しいマスタービンには更新カードしかありません。これはおそらく、元の(ボトムアップ)マージソートの背後にあるアイデアの基礎でした。