Articles

Timsortを理解する

ソートアルゴリズムは、基本的に必要であり、深く論争の厄介な組み合わせです。 インタビューで印象づけるために見ている新しいエンジニアから急速に規模のデータベースに解決を捜している古いエンジニアに考慮に入れるべき無数の要因がある。 二つのオブジェクト間の比較の速度は何ですか? スワップの時間は何ですか? データベースの大きさはどのくらいですか? それにはどのような種類のオブジェクトが含まれていますか? それはすでに半ソートされていますか? 結果は安定する必要がありますか?

これらの質問のそれぞれは、あるアルゴリズムまたは別のアルゴリズムに有利な引数を引き出すことができます。 ソースデータは大規模で複雑ですか? ほとんどの言語は、O(n log n)時間の複雑さを持つ標準のクイックソートにデフォルト設定されています。 それは小さいですか? 挿入の並べ替えはそれらの驚異を働かせる。 主にソート? ヘック、バブルソートはほとんどそのために働くかもしれません。 それぞれのメリットを読んだり視覚化したりしたい場合は、この比較を次のようにしてチェックしてくださいtoptal.com…..

そのサイトでは見つからないソートアルゴリズムの1つ、または他のほとんどのものはTim Sortです。 このあいまいなソートは現在Pythonに固有のもので、デフォルトのソートアルゴリズムとして使用されています。 Pythonでarray.sortを呼び出すと、Tim Sortが実行されます。 それにもかかわらず、Tim Sortを知り、理解しているエンジニアを見つけることはまれです。 だから:それは何ですか?

図1: Tim Peters、Timsortの発明者

Tim Sortは、Pythonで使用するためにTim Petersによって2002年に最初に実装されました。 これは、ほとんどのソートアルゴリズムが学校の部屋で生まれ、現実世界のデータで実用的に使用するために設計されていないという理解から来たと Tim Sortは、データの一般的なパターンを利用し、マージソートと挿入ソートの組み合わせといくつかの内部ロジックを利用して、大規模データの操作を最適化します。Div>

図2:様々なソートアルゴリズムの複雑さの比較(礼儀

http://bigocheatsheet.com/

)

なぜtimソート?

図2を見ると、すぐに興味深いものが見えます。 最高の状態では、Tim SortはMerge SortとQuick Sortより優れています。 最悪の場合、それは同等の速度でマージソートで実行され、実際にはクイックソートよりも優れています。 言い換えれば、それは予想外に速いです。

スペースの面では、Tim Sortはスペクトルの悪い終わりにありますが、ほとんどのソートアルゴリズムのスペースの考慮事項はかなりまばらです。 可能性のある欠点として注目する価値があり、Quick SortがTim Sortよりも優れている1つの場所です。

ソートアルゴリズムがしばしば判断される最終的な項目は安定性です。 安定性とは、ソートされたときに、等しい値のオブジェクトが元の順序を維持するという概念です。 なぜ私たちがそれを気にしているのか疑問に思うかもしれません。 アイテムは同じ価値があります—なぜ彼らがどのように注文されているのか気にしますか?簡単な答えは、積み重ねられたソートの安定性が重要であるということです。

つまり、最初に1つの基準に基づいてソートし、次に2つ目の基準に基づいてソートします。 不安定なアルゴリズムでこれを行うと、2番目の並べ替えを実行すると、最初の並べ替えからの信頼性が即座に失われます。 参考までに、Quick Sortは不安定で、Merge Sortは安定しています。

Tim Sortも安定していますが、わずかに重い場合は高速です(クイックソートのみと比較して)。 ソートアルゴリズムは他の考慮事項で判断することができます(そしてすべきです)が、これらは大きな三つです。

三つのステップでの実装

Tim Sortは、アルゴリズムの標準であっても複雑です。 実装は、部分に分割するのが最善です。Timソートを実装するために最初に必要なのは、バイナリ検索メソッドです。 これは、後で挿入ソートを実装するために使用されます。

参考のために:バイナリ検索アルゴリズム

挿入ソート&マージソート

第二に、挿入ソートとマージソートをコード化する必要があります。 これらはよく知られたアルゴリズムであり、ほとんどのエンジニアの後ろポケットにあるはずですが、彼らがどのように機能するのか、なぜここで私たDiv>

)

挿入ソートは非常に基本的なソートアルゴリズムです。 配列を実行し、順不同の項目(厳密には前の項目よりも少ない/多い)に遭遇すると、既にソートされた配列内の適切な位置に移動します。 挿入ソートは、すでにソートされている配列や小さな配列で非常に迅速に動作することで有名です。 実際、図2から、挿入ソートにはO(n)の印象的な最良のケース実行時間があることがわかります。 挿入ソートの最良のケースは、すでにソートされた配列です。 それは愚かに聞こえるかもしれませんが、それは関連性があります。Div>

図4:マージソート(礼儀
図4:マージソート(礼儀https://commons.wikimedia.org/wiki/File:Merge_sort_algorithm_diagram.svg)

マージソートは、一方、基本的な原則によって動作します:すでにソートされた配列をマージすることは非常に簡単です。 したがって、単一の要素になるまで、開始配列を何度も半分に分割します。 次に、それらの要素をソートされた順序で一緒にマージすることによって、メイン配列をゆっくりと再構築します。 私たちはサイズ1のブロックを構築することから始めたので、最初のソートされた配列を構築するのは非常に簡単でした。 その後、それらをマージするのは簡単です。 最後に、私たちはO(n log n)時間を費やし、(重要なことに)安定していることが保証されている方法でそうします。

マージソート:https://www.geeksforgeeks.org/merge-sort/

挿入ソート:https://www.geeksforgeeks.org/insertion-sort/

Timソートの実装

Timソートの実装を理解するための鍵は、実行の使用を理解することです。 Tim Sortは、自然に発生する事前ソートされたデータを活用しています。 事前ソートされていることは、単に順次要素がすべて増加または減少していることを意味します(どちらを気にしません)。まず、minrunサイズを設定します。 これが意味することは、すべての実行が少なくとも一定の長さであることを確認したいということです。 このサイズのランが見つかることを保証するものではないことに注意してください—私たちは後でこれに入るでしょう。 私たちは、単に実行が少なくとも一定の長さでなければならないと言っています。

実行に遭遇したとき、私たちはそれを脇に置きます。 minrunminrun長さであれば、huzzah! 私たちは前進してもいいです。 そうでない場合は、挿入ソートを遊びに入れます。上から、挿入ソートは、小さな配列とすでにソートされている配列の2つのタイプで特に効果的であることを覚えているかもしれません。 私たちが作ったのは、小さなソートされた配列です。 少なくともminrunの長さでない場合は、先に到達して実行を完了するのに十分な他の要素を取得し、挿入ソートを使用してソートされた配列に 明らかに、実行が配列の終わりに遭遇した場合、それを少し短くすることができます。

すべての実行(つまり、ソートされたサブアレイ)を作成したら、マージソートを使用してそれらを結合します。 最良のケースのシナリオでは、配列全体がすでにソートされており、Tim Sortは他に何もする必要がないことを知るのに十分スマートです。 他の回は、それだけで非常に効率的になる傾向があります。 追加の利点として、挿入ソートとマージソートの両方が安定しているため、結果の配列は安定しています。弾丸を好む人のために

:

  1. データの最初のminrunサイズが2の累乗(通常は32、64を超えることはありません)
  2. 最初のminrunで実行を見つけます。
  3. 実行が少なくともminrun長さでない場合は、挿入ソートを使用して後続または前の項目を取得し、正しい最小サイズになるまで実行に挿入
  4. 配列全体がソートされたサブセクションに分割されるまで繰り返します。
  5. Merge Sortの後半を使用して、順序付けられた配列を結合します。

結論

Tim Sortは強力です。 それは高速で安定していますが、おそらく最も重要なのは、現実世界のパターンを利用し、最終製品を構築するためにそれらを利用します。 それはすべての状況のためですか? そうじゃないかもしれませんね。 幸運はインタビューの間にwhiteboardのそれをプログラミングし、ちょうどピンチの速く簡単な分類のアルゴリズムを必要とすればおそらく何かをこの複 しかし、数値を計算するデータ科学者にとっては、一見の価値があります。好奇心のために、あなたはgithubの上で全体のTimソートコードをチェックアウトすることができます。

ありがとう

私の読者に一つとすべてに感謝します。 私はあなたの時間に感謝し、心からあなたが有益なコンテンツを発見したことを願っています。 ご質問や返信がある場合は、以下のいずれかをドロップすること自由に感じます。