zoukankan      html  css  js  c++  java
  • 洗牌算法及其证明

    问题定义:

    给定有序序列1-n,要求将其打乱,使得每个元素在任意位置出现的概率均为1/n。

    程序实现:

    void shuffle(int *arr, int n)      // n为序列中元素总数
    {
        int idx;
        for(int i = 0; i < n; i++)
        {
            idx = rand() % (i+1);      // idx在下标[0, i]内
            swap(&arr[idx], &arr[i]);
        }
    }

    数学归纳法证明:

    (1)当n=1时,idx必为0,所以元素arr[0]在任何一个位置的概率为1/1,命题成立。

    (2)假设当n=k时,命题成立,即n=k时,原数组中任何一个元素在任何一个位置的概率为1/k。

     

    (3)则当n=k+1时,由以上假设知,当算法执行完k次时,前k个元素在前k个位置的概率均为1/k;

      当执行最后一步时,前k个元素中任何一个元素被替换到第k+1位置的概率为:(1-1/(k+1)) * 1/k = 1/(k+1); 

      在前面k个位置任何一个位置的概率为(1-1/(k+1)) * 1/k = 1/(k+1);

      故前k个元素在任意位置的的概率都为1/(k+1);

      所以,对于前k个元素,它们在k+1的位置上概率为1/(k+1)。

        对于第k+1个元素,其在原位置的概率为1/k+1,在前k个位置任何一个位置的概率为:(1-1/(k+1)) * (1/k) = 1/(k+1),所以对于第k+1个元

      素,其在整个数组前k+1个位置上的概率也均为1/k+1。

     

    (4)综上所述,对于任意n,只要按照方案中的方法,即可满足每个元素在任何一个位置出现的概率均为1/n。

  • 相关阅读:
    依赖单元测试开发
    今天晚上的遭遇
    设计,UML,测试驱动开发
    我是LIGHT的LP,今天由我代笔
    转贴一篇关于BitVector32的Blog
    看牙记
    调整过的书籍目录
    Queue和Stack的学习代码
    BitVector32结构学习
    Visual Studio 2008 在64位操作系统上调试代码的解决方式
  • 原文地址:https://www.cnblogs.com/1203ljh/p/4734514.html
Copyright © 2011-2022 走看看