この記事では、ハッシュテーブルを使用して重複を排除する通常の方法よりもはるかに高速な、繰り返しのない乱数シーケンスを生成する効率的なアルゴリズムについて説明します。 まず、提案を見てみましょう。 正の整数 n が与えられた場合、長さ n の配列を出力する必要があります。配列の要素は 0 ~ n-1 の範囲の乱数であり、要素を繰り返すことはできません。たとえば、n = 3 の場合、要素の範囲が 0 から 2 までの長さ 3 の配列を取得する必要があります。 たとえば、0、2、1。 この問題の通常の解決方法は、ハッシュテーブルを設計し、ループしてランダムな数字を取得し、ハッシュテーブル内でその数字を探すことです。ハッシュテーブルに数字が存在しない場合は、それを出力します。このアルゴリズムのコードは以下の通りである。
コードは非常にシンプルです。0 から total - 1 までループしてランダムな数字を取得し、ハッシュテーブル内でそれらの数字を一致させようとします。ハッシュテーブルに数字が存在しない場合は、それを出力し、ハッシュテーブルでその数字を 1 に設定します。それ以外の場合は、ハッシュテーブルにない数字が見つかるまでループしてランダムな数字を取得しようとします。このアルゴリズムの問題点は、乱数を取得するために試行し続ける必要があることです。ハッシュテーブルがいっぱいに近づくと、この試行が失敗する確率がどんどん高くなります。 繰り返し試行する必要のないアルゴリズムはありますか?答えはイエスです。 上の図に示すように、n = 4と仮定して順次配列を設計します。 最初のラウンドでは、0から3までの乱数を2として取ります。このとき、配列の2番目の数字を取り出して出力し、この数字を配列から削除します。このとき、配列は次のようになります。 2 回目のラウンドでは、0 から 2 までの乱数を 1 と仮定して、その位置の数字を出力し、配列からこの数字を削除します。これを配列の長さが 0 になるまで繰り返します。すると、ランダムな非繰り返しシーケンスが得られます。 このアルゴリズムの利点は、取得した数値を保存するためのハッシュテーブルを必要とせず、繰り返し試行する必要がないことです。アルゴリズムコードは次のとおりです。
このアルゴリズムは 2 つのループを 1 つのループに変更し、アルゴリズムの複雑さを大幅に軽減します。理論上は、速度は最初のアルゴリズムよりも速くなるはずです。しかし、現実はしばしば私たちの想像を超えています。total = 100000 の場合、テスト後、最初のアルゴリズムは 44 ミリ秒かかり、2 番目のアルゴリズムは 1038 ミリ秒かかり、これははるかに遅いです。これはなぜでしょうか?問題の鍵は input.RemoveAt にあります。配列要素を削除する場合、この配列要素の後のすべての要素を 1 つ前に移動する必要があることはわかっています。この移動操作には非常に時間がかかるため、アルゴリズムが遅くなります。この時点で、配列ではなくリンクリストを使用すれば削除が非常に高速になるのでは、と言う人がいるかもしれません。はい、リンクリストは要素の削除の効率性の問題を解決できますが、検索速度が大幅に低下し、配列のように配列要素の添え字に従って要素を直接見つけることはできません。したがって、リンク リストを使用しても機能しません。ここで行き詰まってしまったようです。ハッシュテーブルを使用して繰り返し試すことは可能でしょうか?以下の内容を読む前に、5分間考えてください。 #p# ...5分考えてみましょう #p# アルゴリズムは窓紙の層のようなものです。窓紙を通しては、中に何が入っているかはわかりませんが、一度突き抜けてしまえば、とても単純なもののように見えます。 n = 4 と仮定して、上記と同じ例を使用しましょう。 最初のラウンドでランダムに 2 を取得した場合、配列から 2 を削除するのではなく、配列の最後の要素を 2 の位置に移動します。 配列は 2 回目のラウンドでは、0 から 2 までの乱数を選択します。この時点で、配列内の最後の使用可能な要素の位置は 3 ではなく 2 になっています。このとき得られた乱数が1であると仮定する。 次に、インデックス2の要素をインデックス1に移動し、配列は次のようになります。 n 個の要素が取り出されるまでこれを繰り返します。 このアルゴリズムの利点は、取得した数値を保存するためのハッシュテーブルが不要で、繰り返し試行する必要がなく、前のアルゴリズムのように配列要素を削除する必要がないことです。配列の有効な位置にある最後の要素を毎回現在の位置に移動するだけで済みます。これにより、アルゴリズムの複雑さが O(n) に軽減され、速度が大幅に向上します。 テストの結果、n=100000 の場合、このアルゴリズムには 7 ミリ秒しかかかりません。 以下はこのアルゴリズムの実装コードである。
オリジナルリンク: http://www.cnblogs.com/eaglet/archive/2011/01/17/1937083.html 【編集者のおすすめ】
|
>>: エントリーレベルのデータベースアルゴリズム [パート 3]
[[251715]]毎年、メディアでは AI の失敗に関する報道が見られます。なぜこのようなばかげ...
これは歴史上最も急速に成長している新技術です。生成 AI は世界を変え、画像、ビデオ、オーディオ、テ...
Google AIの研究者たちは、インド工科大学カラグプル校と協力し、音声コンテンツから話すアバター...
概要分散システムの設計では、通常、サービスはクラスターに展開されます。クラスター内の複数のノードが同...
2021年2月初旬に開催された第35回AAAI人工知能会議で、新しいタイプの人工知能(AI)機械学...
2019年中国人工知能産業年次大会で「2019年人工知能発展報告書」が発表されました。唐潔教授は、関...
シナプスはニューラルネットワークの「橋」です。人間の脳には 860 億個のニューロンがあり、あるニュ...
[[408814]]この記事はAI新メディアQuantum Bit(公開アカウントID:QbitAI...
[[428336]]この記事はAI新メディアQuantum Bit(公開アカウントID:QbitAI...
[元記事は51CTO.comより] 近年、多くのインターネット企業がデータ、テクノロジー、AI、組織...