陣列中隨機抽取 演算法 撲克隨機洗牌演算法分析

2021-10-14 17:41:57 字數 1035 閱讀 3459

洗牌演算法實際上就是常見的隨機問題。我們可以抽象理解為:得到乙個m以內的所有自然數的隨機順序陣列。

然而怎麼樣操作才是好的洗牌演算法呢?我們通常認為得保證概率相等。即洗牌之後,如果能夠保證每乙個數出現在所有位置上的概率是相等的。

① 隨機抽出一張牌

② 檢查這種牌是否被抽取過,如果已經被抽取過,則重新抽取,直到找到沒有被抽取的牌;

③ 重複上述過程,直到所有的牌都被抽取到。

這種演算法是比較符合大腦的直觀思維,這種演算法有兩種形式:

每次隨機抽取後,將抽取的牌拿出來,則此時剩餘的牌為(n-1),這種演算法避免了重複抽取,但是每次抽取一張牌後,都有乙個刪除操作,需要在原始陣列中刪除隨機選中的牌(可使用hashtable實現)。

每次隨機抽取後,將抽取的符合要求的牌做好標記,但並不刪除;與1相比,省去了刪除的操作,但增加了額外的儲存標誌為的空間,同時導致可每次可能會抽取之前抽過的牌。

每次隨機抽出兩張牌交換,交換一定次數後結束。

void shuffle(int* array, int len)    }
這是乙個常見的洗牌演算法。 但是如何確定乙個合適的交換次數?

假設交換了m此,則某張牌始終沒有被交換的概率為 (n-2)/n * (n-2)/n, … …* (n-2)/n = ((n-2)/n)^m;我們希望其概率小於摸個值,求出m的解.假設概率小於1/1000,對於n=52,m大概為176,實際上遠遠大於陣列的長度.

每次隨機選取乙個數,然後將該數與陣列中最後(或最前)的元素相交換(如果隨機選中的是最後/最前的元素,則相當於沒有發生交換);然後縮小選取陣列的範圍,去掉最後的元素,即之前隨機抽取出的數。重複上面的過程,直到剩餘陣列的大小為1,即只有乙個元素時結束。

void shuffle(int* array, int len)        while (--i)        }

隨機洗牌演算法

問題 給定乙個有序序列1 n,要你將其完全打亂,要求每個元素在任何乙個位置出現的概率均為1 n。解決方案 依次遍歷陣列,對第n個元素,以1 n的概率與前n個元素中的某個元素互換位置,最後生成的序列即滿足要求,1 n的概率可通過rand n實現。見如下程式 void swap int p,int q ...

隨機洗牌演算法

先看看肖舸老師的文章 隨機洗牌演算法複雜度的比較例項 其實我最初想到的也是那3個方法 1判斷生成的隨機數有沒有重複,2.生成一張布林表,3.雙隨機數。下面給出我的演算法 include include include using namespace std void randcard vector,...

隨機演算法入門 洗牌演算法

洗牌演算法是什麼?其實就理解為生成乙個隨機數列的乙個簡單操作而已。怎麼生成?我們先講下一般我們會想到的乙個解法 標記。怎麼標記呢?假設我們的陣列為a,ai 代表陣列a第i個數。乙個布林陣列b 其他型別的陣列也行 然後把a陣列下標作為狀態空間進行隨機生成,接著把生成過的數下標 i 用 bi 1表示為已...