尤拉計劃595題:增量隨機排序
隨機洗一副從 1 到 n編號的牌,使得每種排列都有相同的概率。
這些牌要使用以下技術排為升序︰
1.看牌的初始順序。如果它已經排好序,那麼就不需要採取進一步行動。否則,如果牌的任何子序列碰巧相對於彼此是在正確的位置 (升序且沒有縫隙),然後通過把牌連線在一起固定這些子序列。例如,對於 7張 牌,最初順序 4123756,標記 1,2 和 3 的牌將被連線在一起, 標記5 和 6的牌也是。
2.把牌拋向空中,'洗牌',但注意任何正確順序的牌都將保持連線,因此維持它們的順序。然後隨機挑選牌(或成捆的連線牌)。你應假定此隨機化是無偏的,儘管一些牌是單張的,而其他的是連線在一起的。
3.重複步驟 1 和 2,直到整副牌有序。
設 S(n) 是將牌片排序所需的洗牌次數的期望。因為在第一次洗牌前要檢查順序,S(1) = 0。已知 S(2) = 1 和 S(5) = 4213/871。
求 S(52),並把給你的答案四捨五入到小數點後 8位。
分析
如果是3張牌,洗一次出來的可能性有下面6種,每種的概率都是1/6.
1 2 3 =>已有序
1 3 2
2 1 3
2 3 1 ->[2 3] 1
3 1 2 ->3 [1 2]
3 2 1
上述未排好序的5種中,有2種發生了合併,下次洗牌都有1/2的概率排好序。其餘3種相當於初始值。
如果是4張牌,相當於在上述3張牌的基礎上,把4號牌插入4個可能的位置,其中每種3的排列都對應一種可以合併的情況,而第1種還是直接排序完成。
一個模擬程式,但每次執行差距有點大。
#include <cstdio> #include <ctime> #include <cstdlib> #define d_p if(debug)printf const int debug=0; int blk_sort(const int NN) { struct st { int h; int l; }; st a[NN+1]; st tmp[NN+1]; int b[NN+1]; for(int i=0; i<=NN; i++) b[i]=i; //init srand(time(0)); for(int i=1; i<=NN; i++) { int t=rand()%(NN+1-i)+1; a[i].h=b[t]; a[i].l=b[t]; b[t]=b[NN+1-i]; // swap with last unused one } for(int i=1; i<=NN; i++) { d_p("[%d,%d] ",a[i].l,a[i].h); } int shuf_cnt=0; int blkno=NN; while(blkno>1) { for(int i=1; i<blkno; i++) if(a[i].h==a[i+1].l-1) { a[i].h=a[i+1].h; for(int j=i+1; j<blkno; j++) { a[j].l=a[j+1].l; a[j].h=a[j+1].h; } blkno--; i--; //continue merge next block } d_p("\n---->"); for(int i=1; i<=blkno; i++) { d_p("[%d,%d] ",a[i].l,a[i].h); tmp[i].l=a[i].l;//copy to tmp tmp[i].h=a[i].h; a[i].l=a[i].h=0; } //shuffle tmp to new a for(int i=1; i<=blkno; i++) { int t=rand()%(blkno+1-i)+1; a[i].h=tmp[t].h; a[i].l=tmp[t].l; tmp[t].h=tmp[blkno+1-i].h; // swap with last unused one tmp[t].l=tmp[blkno+1-i].l; } shuf_cnt++; d_p("\nshff %d\n",shuf_cnt); for(int i=1; i<=blkno; i++) { d_p("[%d,%d] ",a[i].l,a[i].h); } } d_p("%d",shuf_cnt); return shuf_cnt; } int main() { double test_cnt=1e5; int sum=0; for(int tm=1; tm<=test_cnt; tm++) sum+=blk_sort(52); printf("%lf",sum/test_cnt); }
輸出
D:\>a 60.225190 D:\>a 51.528500 D:\>a 44.021820 D:\>a 56.847820 D:\>a 57.052220 D:\>a 59.092310 D:\>a 56.555870
相關文章
- 尤拉計劃695:隨機長方形隨機
- 尤拉計劃697:隨機衰減序列隨機
- 尤拉計劃701:隨機連線區域隨機
- 尤拉計劃512題(冪的尤拉總計函式和)函式
- 尤拉計劃425題:質數連線
- 尤拉計劃605題:結對投幣遊戲遊戲
- 尤拉計劃463題:奇怪的遞迴關係遞迴
- 用尤拉計劃題目來學q語法
- 隨機排序隨機排序
- 尤拉計劃533題:卡邁克爾函式函式
- 000. 尤拉計劃簡介
- 尤拉計劃717:取模公式之和公式
- 尤拉計劃433題:歐幾里德演算法的步數演算法
- 對尤拉計劃427題(n-序列) 的一些分析
- 尤拉計劃713:圖蘭熱水系統
- 透過Treeset解決隨機數排序問題隨機排序
- 實踐中的增量計劃 (轉)
- 生成隨機字串並排序隨機字串排序
- 隨機字串生成與排序隨機字串排序
- JavaScript陣列隨機排序JavaScript陣列隨機排序
- 尤拉計劃711:二進位制黑板
- javaScript隨機排序演算法JavaScript隨機排序演算法
- 隨機題隨機
- 利用容斥原理求尤拉計劃565題的S(1E9,2017)
- python:numpy陣列運算、排序、統計、隨機數生成Python陣列排序隨機
- 隨機快速排序Java程式碼實現隨機排序Java
- 隨機錯亂排序(sort的應用)隨機排序
- 尤拉計劃386題(反鏈的最大長度) 論壇python解法學習筆記Python筆記
- 尤拉計劃386題(反鏈的最大長度) 論壇c++解法學習筆記C++筆記
- 尤拉計劃287題:四分樹編碼(一個簡單的壓縮演算法)演算法
- JavaScript 陣列中元素隨機打亂排序JavaScript陣列隨機排序
- JS陣列隨機排序的三種方法JS陣列隨機排序
- 8i下sort*排序大小以及執行計劃的問題?排序
- UA MATH567 高維統計II 隨機向量6 亞高斯隨機向量的應用: 半正定規劃H5隨機
- 初識隨機規劃:一個小小例子隨機
- 氣泡排序(機試題)排序
- 快速排序(java機試題)排序Java
- random隨機生成10個數,然後氣泡排序random隨機排序