• 编程珠玑:取样问题



    1.问题描述

    程序的输入包含两个整数m和n,其中m<n。输出是0~n-1范围内m个随机整数的有序列表,不允许重复。从概率的角度说,我们希望得到没有重复的有序选择,其中每个选择出现的概率相等。

    2.解决思路与代码实现

    编程珠玑上给出了四个函数

    1).genknuth():算法依次考虑整数0,1,2,...,n-1,并通过一个适当的随机测试对每个整数进行选择。通过按序访问整数,可以保证输出结果是有序的

    代码C++实现:

    void genknuth(int m, int n) 
    {
         for(int i = 0;i < 0;i++) 
         {
                 if((bigrand() % (n-i)) < m)
                 {
                        cout << i << "\n";
                        m--;
                 }
         }
    }

    2).gensets():一种解决方案是在一个初始为空的集合里面插入随机整数,直到个数足够,这里利用C++ set容器

    void gensets(int m, int n)
    {
         set<int> S;
         
         while(S.size() < m)
               S.insert(bigrand() % n);
         set<int>::iterator i;
         
         for(i = S.begin(); i != S.end(); ++i)
               cout << *i << endl;
    }

    3).genshuffle():生成随机整数的有序子集的另一种方法是把包含整数0~n-1的数组的前m个元素打乱,然后把前m个元素排序输出。

    void genshuf(int m, int n)
    {
         int i,j;
         int *x = new int[n];
         
         for(i = 0; i < n; i++)
                x[i] = i;
         for(i = 0; i < m; i++)
         {
                j = randint(i, n-1);
                int t = x[i];
                x[i] = x[j];
                x[j] = t;
         }
         
         sort(x , x+m);
         for(i = 0; i < m; i++)
                cout << x[i] << endl;
    }

    4).genfloyd():m和n接近的时候,基于2)的改进,并能在m个步骤之内就可以按要求等概率地生成有序随机数

    void genfloyd(int m, int n)
    {
         set<int> S;
         set<int>::iterator i;
         
         for(int j = n-m; j < n; j++)
         {
                 int t = bigrand() % (j+1);
                 if(S.find(t) == S.end())
                     S.insert(t);            //t not in S 
                 else
                     S.insert(j);            //t in S
         }
         
         for(i = S.begin(); i != S.end(); ++i)
                 cout << *i << endl;
    }
  • 相关阅读:
    POJ 2251 Dungeon Master
    HDU 3085 Nightmare Ⅱ
    CodeForces 1060 B Maximum Sum of Digits
    HDU 1166 敌兵布阵(树状数组)
    HDOJ 2050 折线分割平面
    HDU 5879 Cure
    HDU 1878 欧拉回路
    HDU 6225 Little Boxes
    ZOJ 2971 Give Me the Number
    HDU 2680 Choose the best route
  • 原文地址:https://www.cnblogs.com/biyeymyhjob/p/2640251.html
Copyright © 2020-2023  润新知