導航:首頁 > 源碼編譯 > 證明洗牌演算法是隨機的

證明洗牌演算法是隨機的

發布時間:2022-09-26 10:01:17

❶ VBA洗牌法原理誰能文字闡釋一下

我找了此資料,一起共享


下面直接介紹【經典數組洗牌法】的演算法原理:

假如你有一個布袋或者抽屜,裡面有m=10個不同號碼的球,

你要隨機抽取,並保證不重復……

那麼正確的做法是:

1.每次從布袋中隨機抽取一個球;注意到rnd()函數的正確抽取目數應該是=m

2.抽取出來的這一個球要另外放置開;

【如果不另外放置,而只是記下號碼後再把球返回布袋,接下來就無法保證這個已經被抽到過的球又被重復抽到。】

而這個,就是1樓代碼中沒有考慮到而產生的重大bug

3.繼續從布袋中隨機抽取另一個球;

注意到此時布袋中剩餘球的數量少了一個是m-1了,因此rnd()函數的正確抽取目數應該是=m-1

4.抽取出來的這第2個球和已經抽取出來的第1個球放置在一齊,並且按新的序列排放。

5.重復以上隨機抽取過程,注意到關鍵是:

a.每次抽取的母數即剩餘球數要遞減1個

b.每次抽取出來的新球要分開放置,不能放回布袋!

c.新抽取出來的球,要和前面已經取出的球按新的序列整齊排放。

d.剩下最最重要一點,但是看到這里好多人都可能不會意識到的一個問題:

布袋中剩餘球如何放置?

即,假定布袋中球也是像放置在抽屜中那樣,有序地排放著的,

那麼每次抽走一個球,必然留下一個空格……【這就很麻煩了!】

因為大家知道,實際上數組中用rnd()函數只能是返回一個一定區間內的值及數組位置,

而如果留有空位的話,隨機性就無法保證高效……萬一抽到空格怎麼辦?難道重新再抽一次?

如果抽到只剩最後一個求時,則原先的布袋/抽屜中,將留下9個空格,則每次隨機函數的計算結果,將有90%的概率仍舊抽到空格……

這就完蛋了。


【經典數組洗牌法】的真正原理是:

1.從m個值中【隨機確定一個位置r】(利用Rnd()隨機函數計算,具體演算法是【以剩餘數m為母數】區間進行隨機值計算並取整返回位置)

2.把這個位置即要被抽取的元素(球)先取出拿在手中【存入臨時變數t】,【騰出一個空位】。

3.把數組的【第1位置】(Lbound)元素拿出來,【放入剛才騰出的r空位】。並隨即【騰出】了數組第一位置作為【新的空位】

(也可以以數組的最末位置(UBound)作為開始位置進行處理,具體演算法代碼就不太一樣了)

4.把上述第2步驟取出的、存入了臨時變數t的元素(球),准確地放入【新的空位】,即數組第一位置。

這個數組第一位置中的【新元素】,就是已經被有效抽取的第1個不重復值。

然後,繼續

1.抽第2個數時,以剩餘母數m-1作為隨機計算區間而返回一個隨機值並計算取整返回第2個不重復的隨機位置r

2.把這個位置r即要被抽取的第2個元素(球)先取出拿在手中【存入臨時變數t】,【騰出一個空位】。

3.把數組的【第2位置】元素拿出來,【放入剛才騰出的r空位】。並隨即【騰出】了數組第2位置作為【新的空位】

(也可以以數組的最末倒數第2位置進行處理,具體演算法代碼就不太一樣了)

4.把上述第2步驟取出的、存入了臨時變數t的元素(球),准確地放入【新的空位】,即數組第2位置。

這個數組第2位置中的【新元素】,就是已經被有效抽取的第2個不重復值。

以上述方式反復進行,抽取、置換,存放,直到最後一個,也不會產生重復抽取了。


下面是【經典數組洗牌法】實際代碼中最簡單的代碼例子:

對於一個下標1開始的一維數組,從中隨機抽取n個元素返回。

SubGetRnd(arr,n)
Randomize
Fori=1Ton'正序洗牌1ton簡化代碼
r=Int(Rnd()*(n-i+1))+i
t=arr(r):arr(r)=arr(i):arr(i)=t'下標1開始一維代碼
Next
EndSub

'正序洗牌1ton簡化代碼詳解:

SubGetRnd(arr,n)

Randomize'隨機種子初始化,保證每次代碼運行或打開文件時出現的隨機序列是和上次文件保存/運行時不同的序列。

Fori=1Ton'遍歷1ton

r=Int(Rnd()*(n-i+1))+i、

'按每次剩餘母數(n-i+1)作為隨機計算區間,計算Rnd()*(n-i+1)然後用int()函數去整,得到剩餘數中的隨機位置。

'緊接著,這個隨機位置後面【+i】處理,轉化成從新的起點i開始的隨機位置r。即不再包括已經抽取出的結果,避免重復。

t=arr(r)'把這個隨機位置r中的元素取出,存入臨時變數t

arr(r)=arr(i)'把【第i個】位置中的元素【放入剛才騰出的r空位】(實際數據操作時並沒有騰出,而只是用新的值直接覆蓋掉。)

arr(i)=t'把上面剛剛【騰出的i空位】放入剛才存放在臨時變數t中的當前最新抽取元素,完成一次抽取過程。

Next'循環抽取、置換、存貯抽取結果

EndSub

❷ 幾種撲克牌洗牌演算法

洗牌的

幾種話先設定好洗牌方式幾種比方對分上下交l以及交織洗牌然撲克牌後用隨機數生成函數確定單步洗牌作牌的數量多反復幾遍即可。

  1. 的一個合理的定義就是演算法

  2. 一副撲克張牌有種陳列方式。

這樣做的好處:

給出的洗牌算演算法應該可以等概率地生成這種結果中的一種

❸ 隨機洗牌:哪一種演算法是正確的

幾乎所有的程序員都寫過類似於「洗牌」的演算法,也就是將一個數組隨機打亂後輸出,雖然很簡單,但是深入研究起來,這個小小的演算法也是大有講究。我在面試程序員的時候,就會經常讓他們當場寫一個洗牌的函數,從中可以觀察到他們對於這個問題的理解和寫程序的基本功。 在深入討論之前,必須先定義出一個基本概念:究竟洗牌演算法的本質是什麼?也就是說,什麼樣的洗牌結果是「正確」的? 雲風曾經有一篇博文,專門討論了這個問題,他也給出了一個比較確切的定義,在經過洗牌函數後,如果能夠保證每一個數據出現在所有位置的概率是相等的,那麼這種演算法是符合要求的。在這個前提下,盡量降低時間復雜度和空間復雜度就能得到好的演算法。 第一個洗牌演算法:隨機抽出一張牌,檢查這張牌是否被抽取過,如果已經被抽取過,則重新抽取,直到找到沒被抽出過的牌,然後把這張牌放入洗好的隊列中,重復該過程,直到所有的牌被抽出。 大概是比較符合大腦對於洗牌的直觀思維,這個演算法經常出現在我遇到的面試結果中,雖然它符合我們對於洗牌演算法的基本要求,但這個演算法並不好,首先它的復雜度為O(N2),而且需要額外的內存空間保存已經被抽出的牌的索引。所以當數據量比較大時,會極大降低效率。

❹ 網易雲音樂隨機播放經常重復

因為隨機播放採用的是洗牌演算法。
是因為洗牌演算法中生成的序列是隨機的,在用戶播放完一個隨機播放的歌單後,系統會再次將雖有歌曲進行隨機排序,重新生成另一個隨機播放歌單,那麼這兩個歌單之間必然會有歌曲重復出現。
我們可以通過降低已聽過的歌曲被選中的幾率,或者在選中同一首歌曲的時候重新進行洗牌排序來降低此類問題出現的頻率。

❺ c++編程,撲克牌洗牌,將一副撲克牌隨機洗好,順序輸出54張撲克牌,求完整代碼註:用C++寫

#include <iostream>
#include <cstdlib>
#include <algorithm>
#include <time.h>
using namespace std;

// 輸出輔助
const string strtype[6] = {"方塊", "梅花", "紅心", "黑桃", "小王", "大王"};
const string strnum[14] = {"", "A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K"};

struct Card
{
// type是花色,0~3分別表示不同的花色,4是小王,5是大王
// num是牌上的數字
int type, num;
}dat[54];

int main()
{
// 時間隨機函數
srand((unsigned)time(NULL));

int cnt = 0;
for (int i = 0; i < 4; i ++)
for (int j = 1; j <= 13; j ++)
{
dat[cnt].type = i;
dat[cnt ++].num = j;
}

dat[cnt ++].type = 4;
dat[cnt ++].type = 5;

for (int i = 1; i < 54; i ++)
// 交換函數,可以證明這樣交換出來的數列是隨機的
// 這里就不展開了
swap(dat[i], dat[rand() % i]);

// 輸出
for (int i = 0; i < 54; i ++)
{
cout << strtype[dat[i].type];
if (dat[i].type < 4) cout << strnum[dat[i].num];
cout << ' ';
}

cout << endl;

system("pause");
}

我測試過啦,運行的一次結果如下(當然是隨機的):

方塊10 黑桃6 梅花9 紅心6 方塊J 黑桃A 方塊4 梅花3 黑桃K 梅花4 方塊K 方塊5 方塊2
黑桃Q 方塊A 紅心K 梅花K 黑桃10 紅心10 紅心3 黑桃2 紅心2 黑桃8 小王 方塊Q 紅心J
梅花6 梅花Q 紅心9 方塊7 梅花7 方塊9 梅花J 紅心A 紅心4 大王 紅心Q 紅心8 方塊6 黑
桃J 方塊8 梅花A 方塊3 紅心7 黑桃7 梅花10 梅花2 黑桃5 紅心5 黑桃3 黑桃9 黑桃4 梅
花5 梅花8
請按任意鍵繼續. . .

希望能夠幫到你!

❻ 什麼是「隨機」教你分清「偽隨機」和「真隨機」

​很久以前流傳著這樣一則笑話:一個身患重病的人決定去動手術。在手術之前,他問醫生:「這起手術的成功率是多少?」醫生回答他:「只有1%。」他很驚慌,但是醫生說:「沒事的,在你之前我已經治死過99個人了。」

這是一則嘲笑那些不懂「概率」的人的笑話,卻講出了「真隨機」和「偽隨機」之間的區別。

在四月末的時候,我曾寫過一篇 《你打 游戲 靠的是技術,還是運氣?》 ,其中就提及了「偽隨機」這個概念。當時受限於篇幅,沒有詳細展開解釋「偽隨機」的概念。前不久,在因國際邀請賽而備受關注的Dota2在最近一次的更新中,有這么一條更新內容: 「落空的負面效果和下坡攻擊的落空效果現在都採用偽隨機觸發」

那麼到底什麼是 「偽隨機」 呢?以及和「偽隨機」對應的 「真隨機」 又是什麼概念?

贗隨機數演算法(Pseudo-Random Number Generator,簡稱PRNG) 是計算機的一個術語——當然,它也可以被叫做「偽隨機數演算法」,只是為了方便與 游戲 中的「偽隨機數」進行區分,本文中統一稱作「贗隨機數演算法」。

眾所周知,計算機程序是由無數「0」和「1」兩種狀態構成的,如果一個狀態不是「0」,那就必定是「1」,頗有種非黑即白的味道。

因此,在計算機程序中,不存在「不確定」的數字,只有確定的「1」和「0」。基於這種特性,計算機無法生成「真正的(不確定的)隨機數」。

那麼在計算機中,需要生成或是使用到隨機數的時候怎麼辦呢? 通常是利用計算機抓取一些數值,然後將這些數值輸入至一個復雜演算法 (常用的演算法是同餘法和梅森旋轉演算法,有興趣的讀者可以自行查詢,這里就不展開講了) 當中,通過一系列運算得出一個數字,這就是平常說的贗隨機數了。

只要最初輸入的數值(初值)不變,那麼輸出的值都會是同一個值,這就證明了這個數並不隨機,只是看起來隨機而已。

換句話說,只要這個隨機數是由確定演算法生成的,那就是贗隨機數。

所以下一次在和朋友聊天時提到真隨機數、偽隨機數時,如果有人插嘴:「計算機只能生成偽隨機數,所以根本沒有什麼真隨機」,那你就可以霸氣側漏地說他是 「雲玩家」 了。

我們通常說的 真隨機 又名 「純隨機」(True Random Distribution) ,就是我們平常一直說的那種、一般意義上的「隨機」。

在真隨機中, 每一個事件都是相互獨立、服從真隨機分布的,不受其他事件的發生而改變 。比方說某款 游戲 為了吸引用戶,擁有這么一個隨機抽卡系統:每次抽卡時,都有1%的幾率抽出SSR卡片,這個概率服從真隨機分布。

回到我們最開始說的那個「治死99個」的笑話:我們一眼就能看出這個笑話的不合理性。但在抽卡 游戲 中,我們的大腦瞬間失去理智。有相當一部分玩家認為: 我連抽100次,總能抽到這張卡吧!

實際上,連抽100次卻抽不出1%的SSR卡的幾率是為(1-0.01)^100=36.6%,甚至還稍稍超過了1/3。將連抽數字上升至300,也仍有4.9%的幾率。

換句話說,假設有10000個玩家連抽100次,就有約3660個玩家抽不出這張SSR;10000個玩家連抽300次,也仍有約490個玩家抽不出這張SSR ——這對玩家的 游戲 體驗來說可以說是毀滅性的打擊。

盡管純隨機在數學上是無罪的,在代碼中更是明明白白、清清楚楚,但玩家抽不出卡可不會回想到初高中的數學課本, 而是首先懷疑幾率是否被策劃運營篡改、這背後又是否有骯臟的PY交易……

當然不僅僅是在抽卡系統當中如此。在一些競技性比較強的 游戲 中(比如War3、Dota2之中——英雄聯盟幾乎完全摘除了隨機系統,不在此列),連續數次的「走運」極大影響 游戲 的競技性和觀賞性。

比方說Dota中最著名的概率英雄虛空假面的技能「回到過去」: 使虛空假面有25%幾率完全躲避一次傷害。 受限於War3引擎,這個技能採用的是真隨機概率,在某個極端情況下(通常見於精彩集錦中),虛空假面能夠保持很低的血量承受多次傷害卻不死、最終反殺對手。這種帶給敵方極差 游戲 體驗的系統,因此也進入了計師們「整治范圍」之中。

為了避免極差的 游戲 體驗帶來的玩家數量流失,設計者們提出了「偽隨機」的概念: 在不確定性的隨機事件當中,通過一系列演算法使隨機事件均勻分布在多次事件當中,盡可能減少或消除極端情況的發生,以提高玩家的 游戲 體驗。

在設計師們的努力下,「偽隨機」應運而生,這里的偽隨機就和上文的贗隨機數演算法(PRNG)意義不同了。

製造「偽隨機」的方法有很多,在War3、Dota2這類 游戲 當中普遍使用的是 「偽隨機分布」(Pseudo Random Distribution,簡稱PRD) 處理概率。

就拿Dota2中最強大的暴擊技能「恩賜解脫」來舉例: 幻影刺客有15%的幾率造成200%/325%/450%致命一擊傷害 。在PRD機制下,幻影刺客的攻擊實際上 並不是 每一刀都有15%的暴擊率。

根據PRD機制的公式P(N)=N*C可得出15%幾率的C值為3.22%,即幻影刺客的第一次攻擊暴擊概率為3.22%;如果第一刀沒有暴擊,則第二刀的暴擊率提升至2倍,即6.44%;如果仍舊沒有暴擊,則提升至3倍的9.66%,以此類推。

如果繼續推算,可得在第32刀時暴擊幾率會達到100%,最可能觸發暴擊的次數是第6刀,平均觸發刀數是6.67刀等等……

同樣,在連續觸發暴擊時,下一刀的暴擊幾率會減少。RPD機制使競技 游戲 中連續觸發或不觸發技能的幾率降低,避免了運氣成分過度干擾戰斗結果,大幅提升了玩家的 游戲 體驗,但不影響這些隨機事件的正反饋:TI6決賽的「打我五下暈三下」,可是令全球人民集體沸騰了呢!

除了偽隨機分布RPD之外,還有兩種常見的偽隨機: 洗牌演算法 組合隨機

洗牌演算法 最常見的用法,是在各大音樂播放器中的「隨機播放」之中。在隨機播放時,如果採用真隨機,會導致一首歌無論如何都播放不出,或是同一首歌連續播放數次(有興趣的讀者可以計算一下這些概率)。為了解決這個問題,播放器採用的解決方案即是洗牌演算法:將一個包含所有歌曲的數組像洗牌一樣打亂,然後依次播放這個亂序數組。

至於 組合隨機 ,這是一種廣泛應用於各個 游戲 的做法:在抽獎的時候進行兩次、或是更多次的判斷,一次不隨機,而剩下的判斷則是真隨機。比如說,你會在第X次抽卡時抽到SSR是確定的,但抽中的SSR具體是哪張卡,則是隨機的——這就是廣大手游中的「低保」系統了。

在一堆數據之中想要分清「真隨機」和「偽隨機」似乎並不是那麼容易。那麼接下來為大家介紹兩個例子,有助於更好理解什麼是「真隨機」和「偽隨機」:

真隨機 :有一天,小明在的班級上舉辦了一次抽獎活動。這個班級有40個學生,所以為了公平起見,保證每個學生都有1/40的幾率中獎,老師准備了40個相同的紙盒,每個紙盒中都有40張紙條,有1張紙條是中獎紙條。這樣一來,每個學生都有1/40的幾率中獎,但每個學生是否中獎並不受其他學生的影響。在極端情況下,這個班上可能40個學生都能中獎。這就是真隨機。

偽隨機 :小明班上舉辦了抽獎活動。為了公平起見,老師准備了1個紙盒,紙盒中有40張紙條,只有1張紙條是中獎紙條。這樣一來,每個學生都有1/40的幾率中獎——但是顯而易見,這個班上有且僅有一名學生能夠中獎。一名學生在中獎後,餘下的所有學生中獎幾率都會減少至0。這就是偽隨機。

❼ 為什麼直播時音樂隨意在變換

摘要 您好,我認為,1)播放當前歌曲時才隨機生成下一首,即完全隨機(稱為Random演算法):為了避免某些歌曲經常重復播放或很難被播放到,並非是盲目的完全隨機下一首,而是需要分析用戶的播放歷史,需要比較好的演算法進行支撐,最終始於隨機卻超脫隨機。

❽ 關於牌類游戲洗牌演算法一問:怎樣才算把牌洗

1. 嵌入式洗牌法
把部分的塔羅牌拿在手中,使牌面朝下,將剩下的牌隨意插入手裡的牌,再自手中拿出一些牌,再插進去。重復這個步驟直到你覺得牌洗干凈了為止。不過這種洗牌方式非常容易折損牌的邊緣,要小心喔(有時還會刮傷手…)
2. 推擺洗牌法
將塔羅牌牌面朝下,在桌面上弄混,之後用左手的拇指將最上方的一疊牌推回左手,再用右手拇指推下方的一疊牌到右手,持續重復這個動作,直到所有的牌都被分開,之後重疊再一起並重復這些動作,直到你覺得已經洗干凈為止。不過這個方法不是很容易,你必須常常練習才不會打到手(嘿嘿嘿…)
3. 一般正常洗牌法
將塔羅牌牌面朝下,雙手以順時針或逆時針方向將牌均勻混和即可。以上介紹的三種方式均為一般常見的洗牌方法(尤其是第三項,一般市面上的中文塔羅書籍均是以此法為主,故簡略帶過),在洗牌時一般是建議受占者心中專心默念要問的問題,而占卜師擇是專心洗牌。至於是否要由受占者洗牌則是見仁見智。不過殿主向來是由自己洗牌,有時總會遇到『朋友』想幫『他的朋友』占卜,而『他的朋友』並不在現場的情況,若是非當事者洗牌不可,大概這牌也就不需要算了…
至於是否一定要使用這幾種方法來洗牌,答案是不一定。只要能將牌充分混和均勻,也不致傷到牌面就好了。
此外,在使用第三種洗牌方式時,殿主提供一些經驗分享給大家:
1.轉動時要利用指腹與手腕的力量
2.像寫書法一樣,手腕抬高
3.盡量輕柔地轉動每一張牌
4.每一張牌建議盡量轉三圈半以上(要公轉也要自轉喔)
5.注意上層的牌要與下層的牌混合均勻

❾ 用C++編寫一個洗牌發牌的函數,玩家可能有兩個、三個和四個

幾乎所有的程序員都寫過類似於「洗牌」的演算法,也就是將一個數組隨機打亂後輸出,雖然很簡單,但是深入研究起來,這個小小的演算法也是大有講究。我在面試程序員的時候,就會經常讓他們當場寫一個洗牌的函數,從中可以觀察到他們對於這個問題的理解和寫程序的基本功。

在深入討論之前,必須先定義出一個基本概念:究竟洗牌演算法的本質是什麼?也就是說,什麼樣的洗牌結果是「正確」的?

雲風曾經有一篇博文,專門討論了這個問題,他也給出了一個比較確切的定義,在經過洗牌函數後,如果能夠保證每一個數據出現在所有位置的概率是相等的,那麼這種演算法是符合要求的。在這個前提下,盡量降低時間復雜度和空間復雜度就能得到好的演算法。

第一個洗牌演算法:

隨機抽出一張牌,檢查這張牌是否被抽取過,如果已經被抽取過,則重新抽取,直到找到沒被抽出過的牌,然後把這張牌放入洗好的隊列中,重復該過程,直到所有的牌被抽出。

大概是比較符合大腦對於洗牌的直觀思維,這個演算法經常出現在我遇到的面試結果中,雖然它符合我們對於洗牌演算法的基本要求,但這個演算法並不好,首先它的復雜度為O(N2),而且需要額外的內存空間保存已經被抽出的牌的索引。所以當數據量比較大時,會極大降低效率。

第二個演算法:

設牌的張數為n,首先准備n個不容易碰撞的隨機數,然後進行排序,通過排序可以得到一個打亂次序的序列,按照這個序列將牌打亂。

這也是一個符合要求的演算法,但是同樣需要額外的存儲空間,在復雜度上也會取決於所採用的排序演算法,所以仍然不是一個好的演算法。

第三個演算法:

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

void shuffle(int* data, int length)

{

for(int i=0; i<SWAP_COUNTS; i++)

{

//Rand(min, max)返回[min, max)區間內的隨機數

int index1 = Rand(0, length);

int index2 = Rand(0, length);

std::swap(data[index1], data[index2]);

}

}

這又是一個常見的洗牌方法,比較有意思的問題是其中的「交換次數」,我們該如何確定一個合適的交換次數?簡單的計算,交換m次後,具體某張牌始終沒有被抽到的概率為((n-2)/n)^m,如果我們要求這個概率小於1/1000,那麼 m>-3*ln(10)/ln(1-2/n),對於52張牌,這個數大約是176次,需要注意的是,這是滿足「具體某張牌」始終沒有被抽到的概率,如果需要滿足「任意一張牌」沒被抽到的概率小於1/1000,需要的次數還要大一些,但這個概率計算起來比較復雜,有興趣的朋友可以試一下。

Update: 這個概率是,推算過程可以參考這里,根據這個概率,需要交換280次才能符合要求

第四個演算法:

從第一張牌開始,將每張牌和隨機的一張牌進行交換

void shuffle(int* data, int length)

{

for(int i=0; i<length; i++)

{

int index = Rand(0, length);

std::swap(data[i], data[index]);

}

}

很明顯,這個演算法是符合我們先前的要求的,時間復雜度為O(N),而且也不需要額外的臨時空間,似乎我們找到了最優的演算法,然而事實並非如此,看下一個演算法。

第五個演算法:

void shuffle(int* data, int length)

{

for(int i=1; i<length; i++)

{

int index = Rand(0, i);

std::swap(data[i], data[index]);

}

}

一個有意思的情況出現了,這個演算法和第三種演算法非常相似,從直覺來說,似乎使數據「雜亂」的能力還要弱於第三種,但事實上,這種演算法要強於第三種。要想嚴格的證明這一點並不容易,需要一些數學功底,有興趣的朋友可以參照一下這篇論文,或者matrix67大牛的博文,也可以這樣簡單理解一下,對於n張牌的數據,實際排列的可能情況為n! 種,但第四種演算法能夠產生n^n種排列,遠遠大於實際的排列情況,而且n^n不能被n!整除,所以經過演算法四所定義的牌與牌之間的交換程序,很可能一張牌被換來換去又被換回到原來的位置,所以這個演算法不是最優的。而演算法五輸出的可能組合恰好是n!種,所以這個演算法才是完美的。

事情並沒有結束,如果真的要找一個最優的演算法,還是請出最終的冠軍吧!

第六個演算法:

void shuffle(int* data, int length)

{

std::random_shuffle(data, data+length);

}

沒錯,用c++的標准庫函數才是最優方案,事實上,std::random_shuffle在實現上也是採取了第四種方法,看來還是那句話,「不要重復製造輪子」

不想寫 - -

❿ 怎麼證明這個洗牌演算法是隨機的

有一副牌假設有N張,請設計一個隨機洗牌演算法。
解決方案:
這里只給出一個可以使用數學證明每張牌出現在任何位置概率為1/N的演算法。
Poker[N]
for (i = 0; i < N; ++i)
{
k = rand() % ( i + 1)
if (i != k)
{
switch(Poker[k], Poker[i]);
}

閱讀全文

與證明洗牌演算法是隨機的相關的資料

熱點內容
java極限編程pdf 瀏覽:129
塞葡萄的是哪個小說 瀏覽:821
架設傳奇命令 瀏覽:951
關於醫生的小說 瀏覽:520
愛情動作電影 瀏覽:808
八零電子書txt免費下載網站 瀏覽:509
登陸遼事通顯示伺服器連接錯誤怎麼辦 瀏覽:547
9米高隧道演算法 瀏覽:508
池袋最強作品集txt 瀏覽:784
app專題推薦在哪裡 瀏覽:279
神雲伺服器顯示燈 瀏覽:134
程序員磨合期技巧 瀏覽:849
鬼團六全部電影名稱 瀏覽:864
穿越唯一一個女人世界 瀏覽:645
飛言情小說官網入口 瀏覽:581
pdf壓縮後還清晰嗎 瀏覽:654
得到app的電子書書架在哪裡 瀏覽:151
管道彎頭製作演算法 瀏覽:37
phpmvcsmarty實例 瀏覽:925
spring搭建http伺服器地址 瀏覽:713