码迷,mamicode.com
首页 > 编程语言 > 详细

随机洗牌算法Knuth Shuffle和错排公式

时间:2018-08-16 21:39:28      阅读:163      评论:0      收藏:0      [点我收藏+]

标签:span   基础   方法   rand   多少   自己   color   相互   出现   

Knuth随机洗牌算法:譬如现在有54张牌,如何洗牌才能保证随机性。可以这么考虑,从最末尾一张牌开始洗,对于每一张牌,编号在该牌前面的牌中任意一张选一张和当前牌进行交换,直至洗到第一张牌为止。参考代码如下:

void knuth() {
        for (int i = 54; i > 1; i--) {
            int id = rand() % (i - 1) + 1;
            swap(a[i], a[id]);
        }
    }

由上述方法可知,每一张牌经过洗牌之后一定不会出现在原来位置,那么一共会有多少情况呢,这其实就是错排的定义,n个数的错排数有如下递推公式:

f(n)=(n-1)(f(n-1)+f(n-2))

公式的推导:首先让我们假设已知n-1个数和n-2个数的错排数,这时又在原来基础上加了一个数字,那么如果这n个数要构成错排,新加入的数字一定不能出现在自己的位置上,所以它只能选择其余的n-1个位置,不妨设选择了第k个位置,那么原本在第k个位置上的数又会跑到哪里去呢,这里有两种情况,原本的第k个数跑到第n个数的位置上去了,这时这两个数只是相互交换了位置,其余的n-2个数怎么排列完全不受影响,故此时有f(n-2)种情况;再考虑原本第k个数不在第n个数的位置上,那么除去第n个数,其余的n-1个数任然构成错排,错排数为f(n-1)。至此就可得递推式f(n)=(n-1)(f(n-1)+f(n-2));

 

随机洗牌算法Knuth Shuffle和错排公式

标签:span   基础   方法   rand   多少   自己   color   相互   出现   

原文地址:https://www.cnblogs.com/ZefengYao/p/9490061.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!