随机取数使概率相等

导读:本篇文章讲解 随机取数使概率相等,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

题目:随机地从大小为n个数中选取m个数。要求每个元素被选中的概率相等?

分析:这道题目和随机洗牌算法类似,只需要随机选取1个元素, 然后在剩下的元素里面随机选取下一个元素,不断这样操作即可。

这样做能保证每个元素选中的概率一样吗?也就是选中每个元素的概率都是1/n? 答案是YES,让我们来做一下简单的计算。

选第1个元素:在n个中随机选,因此概率为1/n

选第2个元素:在剩下的n-1个中随机选:1/(n-1),由于第1次没有选中它, 而是在另外n-1个中选:(n-1)/n,因此概率为:(n-1)/n * 1/(n-1) = 1/n

选第3个元素:同上:(n-1)/n * (n-2)/(n-1) * 1/(n-2) = 1/n

。。。。。

思路
由于Random的nextInt(x) 方法是从 0 到 x-1 随机取数,所以使random的数视为从数组从后往前倒着数的索引;
第一次 i=0 ,首先在索引0 到 n-1 共n个数之间取一个数,即 j= nextInt(n),抽出来的数的索引是 n-1-j, 然后将这个下标对应的数和数组的i=0 处数交换位置;
然后i=1时,从1到n-1共n-1个数之间用nextInt() 方法随机取一个数,nextInt()是从0到n-2取 所以是nextInt(n-1),然后将下标对应的数和数组的第二个数交换位置。依次这样下去,知道找出m个数。

注意
Random对象的 nextInt(x) 方法,随机从0到x-1 之间取数,不包括 x !

public class test02 {
    static List<Integer> r=new ArrayList<>();
    public static void main(String[] args) throws IOException {
        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
        String s1 = in.readLine();
        String s2 = in.readLine();
        int n = Integer.parseInt(s1);
        int m = Integer.parseInt(s2);
        int[] nums = new int[n];
        for (int i = 0; i < n; i++) {
            nums[i] = i;
        }
        select(nums, m);
        for(int k:r){
            System.out.println(k);
        }

    }

    static void select(int[] nums, int m) {
        int n=nums.length;
        for (int i = 0; i < m; i++) {
            // Random.nextInt(x) 随机筛选0到x-1之间的数 !
            // 每次筛选以i为起点,所以实际筛出来的数的索引是  n-1-筛的索引
            int randomindex=n-1-new Random().nextInt(n-i);
            r.add(nums[randomindex]);
            //交换
            int temp=nums[i];
            nums[i]=nums[randomindex];
            nums[randomindex]=temp;
        }
    }
}

参考:https://blog.csdn.net/m0_46450708/article/details/121067627

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/89190.html

(0)
小半的头像小半

相关推荐

极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!