シャッフルアルゴリズムの2つの実装の比較

シャッフルアルゴリズムの2つの実装の比較

方法1: ランダム生成

まず、非常に一般的な方法であるランダム生成法(私が名付けました)を紹介します。私はこの方法を使用して、マインスイーパ ゲームで地雷の位置をランダムに分散させました(考え方は同じです)。この方法の重要なポイントは、最初から指定された領域に 1 つずつ数字をランダムに生成することです。新しく生成された乱数が以前に生成された場合、その数字は保存されません。新しく生成された乱数が以前に生成されていない場合、その数字は保存されます。生成された数字の数が必要な数に達するまで保存されます。

実装コードは次のとおりです。

  1. size_tシャッフル( char s[], int n)
  2. {
  3. size_t t=0; //ループ回数を計算する 
  4. 整数c = 0;
  5. (c<n)の場合
  6. {
  7. t++;
  8. int num = rand()%n;
  9. (memchr(s,num,c) == NULL)の場合
  10. {
  11. s[c++] = static_cast < char >(num);
  12. }
  13. }
  14. tを返します
  15. }
  16.  
  17.  
  18. void printCards( char s[], int n)
  19. {
  20. ( int i=0; i<n; i++)の場合
  21. {
  22. cout << static_cast < int >(s[i]) << " " ;
  23. }
  24. cout << 終了;
  25. }

コードでは、memchr 関数を使用しています (時間計算量は O(n) かもしれませんが、証拠は見つかりませんでした)。たとえ O(1) であっても、乱数を生成するためにループする回数は固定ではありません (生成する必要がある数以上)。

方法2: ポジション交換法

この方法は、昨日テンセントの筆記試験を受けているときに思いつきました。今日学校に戻って寮で試してみました。基本的な考え方は、まず分散した数字の列を初期化し、次にランダムな位置を生成して、各位置と順番に交換します。生成されたランダムな位置がそれ自身でない場合は、交換操作を実行します。

実装コード:

  1. void swap( int & a, int & b)
  2. {
  3. ;
  4. ;
  5. ;
  6. }
  7.  
  8. size_t shuffle2( int s[], int n)
  9. {
  10. size_t t=0; //ループ回数を計算する 
  11. ( int i=0; i<n; i++)の場合
  12. {
  13. t++;
  14. s[i] = i;
  15. }
  16. ( int i=0; i<n; i++)の場合
  17. {
  18. t++;
  19. int num = rand()%n;
  20. (数値!= i)の場合
  21. {
  22. swap(s[num],s[i]);
  23. }
  24. }
  25. tを返します
  26. }
  27.  
  28. void printCards2( int s[], int n)
  29. {
  30. ( int i=0; i<n; i++)の場合
  31. {
  32. cout << s[i] << " " ;
  33. }
  34. cout << 終了;
  35. }

比較: 方法 2 は、スワップ位置の最大数が制限されている (生成される乱数の数が固定されている) ため、新しく生成された数が生成された数の中にあるかどうかを調べる時間が節約されるため、時間の点で方法 1 よりもはるかに高速です。方法 1 では、新たに生成された数字が既に生成された数字の中にある場合、新しい乱数を生成する必要があるため、乱数として生成される数字の数は固定ではありません (最小値があります)。

テストコード:

結果:

2 番目の方法が優れているかどうかはまだわかりません。これは私自身のアイデアであり、検証が完全ではないためです。他の欠点 (弱いランダム性など) がある可能性があります。他の本では見たことがありません。ネットユーザーがどこかで見たことがある場合は、教えてください。方法 1 は、中国語版の「The Essentials of C and C++ Code」P97 で見つかりました。

後続の補足:

chncwang さんの返信ありがとうございます。方法 2 は完全にランダムではありません。完全にランダムな変更は次のとおりです。

  1. size_t shuffle22( int s[], int n)
  2. {
  3. size_t t=0; //ループ回数を計算する 
  4. ( int i=0; i<n; i++)の場合
  5. {
  6. t++;
  7. s[i] = i;
  8. }
  9. ( int i=n-1; i>0; --i)の場合
  10. {
  11. t++;
  12. 整数= rand()%(i+1);
  13. (数値!= i)の場合
  14. {
  15. swap(s[num],s[i]);
  16. }
  17. }
  18. tを返します
  19. }
なぜなら、「最初の移動後、最初の数字がまだ最初の位置にある確率は 1/n であり、その後の移動ではこの確率が下がるだけです。したがって、このアルゴリズムは完全にランダムではありません。」変更されたアルゴリズムは、実際には C++ の STL<algorithm> ライブラリの random_shuffle() 関数の実装方法です。 i が変化するたびに乱数の範囲が変更されるため、前の位置の数字が元の数字のままである確率は低下しません (つまり、後続のスワップ操作は、すでにスワップされた位置に影響を与えません)。

実装は標準ライブラリ <algorithm> の random_shuffle() 関数を使用すると簡単です。コードは次のとおりです。

  1. intメイン()
  2. {
  3. ベクトル< int > s_stl;
  4. ( int i=0; i<CARDS_COUNT; ++i)の場合、 s_stl.push_back(i);
  5. ランダムシャッフル(s_stl.begin(),s_stl.end());
  6. cout << "C++ アルゴリズム ライブラリの使用:" ;
  7. (ベクトル< int >::iterator it=s_stl.begin(); it!=s_stl.end(); ++it)
  8. cout << " " << *it;
  9. 0を返します
  10. }

オリジナルリンク: http://www.cnblogs.com/hanxi/archive/2012/10/15/2725047.html

【編集者のおすすめ】

  1. 3つの興味深い写真: 負荷分散アルゴリズムの改善が必要
  2. プログラマーの芸術: ソートアルゴリズムのダンス
  3. 私が純粋アルゴリズムの面接の質問に反対する理由
  4. 趙傑:面接では(純粋な)アルゴリズムの質問が見られる
  5. アリの採餌とインターネットアルゴリズム

<<:  基本的なアルゴリズムについての簡単な説明: AVL ツリーとスプレイ ツリー (パート 3)

>>:  大規模ウェブサイトのアルゴリズムとアーキテクチャについての簡単な説明(パート 2)

ブログ    
ブログ    
ブログ    

推薦する

生成 AI とデータ品質は共存できますか?

このハイテク時代では、生成型人工知能については誰もが知っているか、少なくとも聞いたことがあると思いま...

...

GPT-3 に匹敵するものでしょうか? EleutherAIがGPT-Jをオープンソース化

2020年、マイクロソフトはOpenAIと合意に達し、MicrosoftはGPT-3のソースコードに...

量子コンピュータ、モノのインターネット、サイバーセキュリティの相互作用

量子コンピュータは多くの産業の運営方法を変えるでしょう。量子コンピューティングは社会に大きな影響を与...

人類はまたもやAIに敗北:ドローンレースの世界チャンピオンが人工知能に敗北

8月31日、人工知能(AI)がチェスやビデオゲームなどの分野で人間に勝利した。そして今回初めて、人間...

TPCアライアンス設立:科学的発見の推進に向け、1兆以上のパラメータを持つAIモデルを目指す

11月16日、業界をリードする科学研究機関、米国国立スーパーコンピューティングセンター、そしてAI分...

面白いですね!プログラマーが AI を使って双子の息子を認識するんです! 「この Raspberry Pi の顔認識システムは私のものほど正確ではありません」

2021年までに、学習アルゴリズムと人工知能の研究を通じて、機械は多くの面で人間よりも優れていると...

インテル、IoTとエッジ向け第10世代プロセッサーを発表

Intel は最近、第 10 世代 Core プロセッサが、スループット、LGA ソケットのスケーラ...

Daguan Data: ナレッジグラフと Neo4j の簡単な分析

現在のビッグデータ業界では、アルゴリズムのアップグレード、特に機械学習の導入により、「パターン発見」...

Google が Mirasol をリリース: 30 億のパラメータで、マルチモーダル理解を長時間動画にまで拡張

11月16日、Googleは、動画に関する質問に答えたり、新たな記録を樹立したりできる小型人工知能モ...

アナリスト:Appleは早ければ来年末にも生成AIをiPhoneとiPadに統合する予定

10月22日、海通国際証券のアナリストであるPu Deyu氏が最近、Appleが早ければ2024年末...

Transformerは画像を生成することも可能で、新しいViTGANのパフォーマンスはCNNベースのGANに匹敵する。

[[412196]]トランスフォーマーはさまざまな自然言語タスクに急速な進歩をもたらし、最近ではコ...

ブロックチェーンのいくつかのコンセンサスアルゴリズム

まず、一般的なビザンチン将軍問題からコンセンサスとは何かを理解しましょう。ビザンチン将軍問題ビザンチ...

教師あり学習、教師なし学習、強化学習とは何ですか?ついに誰かが明らかにした

01 用語このセクションでは、機械学習の概要とその 3 つの分類 (教師あり学習、教師なし学習、強化...