C#實現的洗牌演算法

來源:互聯網
上載者:User

我們先看一下紙牌遊戲。一幅紙牌由 52 張不同的紙牌組成,發牌時必須產生不重複的紙牌,而且洗牌過程必須公平,即 52! 中紙牌順序應該等機率出現。很明顯這種隨機排列所產生的隨機數必須均勻分布且獨立。由此代碼如下:

  1. using System;
  2. using System.Diagnostics;
  3. namespace Lucifer.CSharp.Sample
  4. {
  5.     class Program
  6.     {
  7.         static void Main(string[] args)
  8.         {
  9.             //初始化牌局
  10.             int[] array = new int[52];
  11.             for (int i = 0; i < array.Length; i++)
  12.             {
  13.                 array = i;
  14.             }
  15.             //洗牌
  16.             Permute<int>(array);
  17.             //驗證牌局
  18.             for (int i = 0; i < array.Length; i++)
  19.             {
  20.                 var value = array;
  21.                 for (int j = 0; j < array.Length; j++)
  22.                 {
  23.                     if (j == i) continue;
  24.                     Debug.Assert(array[j] != value);
  25.                 }
  26.             }
  27.         }
  28.         static void Permute<T>(T[] array)
  29.         {
  30.             Random random = new Random();
  31.             for (int i = 1; i < array.Length; i++)
  32.             {
  33.                 Swap<T>(array, i, random.Next(0, i));
  34.             }
  35.         }
  36.         static void Swap<T>(T[] array, int indexA, int indexB)
  37.         {
  38.             T temp = array[indexA];
  39.             array[indexA] = array[indexB];
  40.             array[indexB] = temp;
  41.         }
  42.     }
  43. }

複製代碼

程式碼範例中的 Permute<T>(T[] array) 方法產生一個隨機序列。第一個迴圈用 1, 2, 3, …, N 初始化該序列。第二個迴圈完成一次隨機洗牌。在該迴圈的每次迭代中,我們講 array[j] 的值於數組位置在區間[0, j)之間的某個元素相交換(也可能不交換)。

然而,我們要問的是 Permute<T>(T[] array) 方法產生的所有排列等機率嗎?

若根據該演算法,答案為是。因為一共有 N! 種可能的排列,而 Swap<T>(array, i, random.Next(0, i)); 這一句 N-1 次調用 Next 方法出現的不同結果也是 N! 種。但是,事實上答案為否,並非所有排列都是等機率。問題就出在可愛的偽隨機數數產生器(Pseudo-Random Number Generator)上。PRNG 的隨機性很大程度上限制了隨機序列的隨機性。所以,上述代碼需要一個更好的偽隨機數數產生器以使實際與理論更加相符。但是好的 PRNG 往往伴隨著效能的下降,比如 Mt19937 隨機化演算法。


















相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.