`

从n个对象中随机取出m个

 
阅读更多

很多类似的这种问题,都有两种方案,一种以时间换空间,一种以空间换时间。

 对于方法一:这里可以计算一下其每次循环的概率是否都相同,

假设i=0,随机到元素的概率为m/n;

假设i=1,随机到元素的概率为m/n*((m-1)/(n-1))+(1-m/n)*(m/(n-1))=m/n(分别假设i=0时没有随机到和有随机到)

...

所以每次循环所随机到元素的概率都相同。

//此方法摘录于其他网站,是一种省空间省时间的方案。注意,这里返回数值是坐标,即n=3,m=1,则返回值为0~2的一个数
	public static Integer[] way1(int n, int m) {
		Integer[] output = new Integer[m];
		for (int i = 0; i < n; i++) {
			// if (m > 0 && new Random().nextInt(n - i) % (n - i) < m) {//这个也可以
			if (m > 0 && random(1, n-i) % (n - i) < m) {
				int index = output.length - m;
				output[index] = i;
				m--;
			}
		}
		return output;
	}

	public static List<String> way1(List<String> names, int m) {
		List<String> output = new ArrayList<>(m);
		int n = names.size();
		for (int i = 0; i < n; i++) {
			if (m > 0 && random(1, n - i) % (n - i) < m) {
				output.add(names.get(i));
				m--;
			}
		}
		return output;
	}

	public static final int random(int begin, int end) {
		if (begin > end) {
			throw new RuntimeException("随机开始值大于结束值");
		}

		if (begin == end) {
			return begin;
		}

		int dec = begin - 0;
		Random r = new Random();
		// nextInt(n)随机的结果为0~n-1,所以加1效果是end这个值也可以随机到
		int random = r.nextInt(end - dec + 1);// 保证开始值为0,且结束值>0,即begin-dec=0
		return random + dec;
	}

	//线程安全的随机类
	public static final int random2(int begin, int end){
		if (begin > end) {
			throw new RuntimeException("随机开始值大于结束值");
		}

		if (begin == end) {
			return begin;
		}
		return ThreadLocalRandom.current().nextInt(begin, end+1);
	}

	// 此方法以空间换时间,只需循环n次即可
	public static int[] way2(int n, int m){
		int[] sequence = new int[n];
        int[] output = new int[m];
        Random r = new Random();
        for (int i = 0; i < n; i++)
        {
            sequence[i] = i;
        }

        int end = n - 1;
        for (int i = 0; i < m; i++)
        {
            int num = r.nextInt(n);
            output[i] = sequence[num];
            sequence[num] = sequence[end];
            end--;
        }
        return output;
	}

 

另外,摘录了几个算法题,总觉得答案需要仔细琢磨一下,仅供参考:

题目2

假设你参加了一个游戏节目,现在要从三个密封的箱子中选择一个。其中两个箱子是空的,另一个箱子里面有大奖。你并不知道奖在哪一个箱子里,但主持人知道。游戏节目的主持人先要你选择一个箱子,接着他把你没有选的空箱子打开,以证明它是空的。最后主持人给你换箱子的机会,你可以把你所选择的箱子换成另一个没有打开的箱子。此时你该不该换箱子?

 

分析:

要相信直觉。你当然应该换箱子!我们把三个箱子编号A,B,C,并假设你选的是A箱。显然奖品在A里的概率是1/3,在B或C里的概率是2/3。B和C可能有一个是空的,也可能两个都是空的。因此,当你选择了A箱后,主持人很可能会打开B箱或C箱,以显示里面是空的。在这种情况下,主持人的举动并不会影响奖品在A箱里面的机会。我们假设主持人打开了B箱,以告诉你它是空的。现在A箱有奖品的概率还是1/3,B箱里面有奖品的概率是0,因此C箱里面有奖品的概率是2/3。在这种情况下,你应该换到C箱,因为它使你赢的机会提高了1倍!

 

题目3

有一对夫妇,先后生了两个孩子,其中一个孩子是女孩,问另一个孩子是男孩的概率是多大?

 

答案是2/3.两个孩子的性别有以下四种可能:(男男)(男女)(女男)(女女),其中一个是女孩,就排除了(男男),还剩三种情况。其中另一个是男孩的占了两种,2/3. 之所以答案不是1/2是因为女孩到底是第一个生的还是第二个生的是不确定的。

分享到:
评论

相关推荐

    随机森林的训练

    2. 当每个样本有 M 个属性时,在决策树的每个节点需要分裂时,随机从这 M 个属性中选取出 m 个属性,满足条件 m &lt;&lt; M。然后从这 m 个属性中采用某种策略(比如说信息增益)来选择 1 个属性作为该节点的分裂属性。 3....

    部编6 第6讲 离散型随机变量及其分布列 新题培优练.doc

    这里的P(X=k)的概率公式为P(X=k)=C(m,k) * C(n-m,M-k) / C(n,M),其中m是总体中成功类别的对象数,n是总体大小,M是样本大小,k是成功事件在样本中的数目。 2. 离散均匀分布:问题2中随机变量X的每个值出现的概率...

    2016年高考数学(理)二轮复习精品资料(新课标版)专题07 排列组合、二项式定理,概率与统计(教学案) 含解析.doc

    组合则是无序的,是从n个不同元素中取出m个元素组成一组的方法数,记作Cn,m。排列和组合在解决实际问题时经常被用到,例如在计算可能性或者选择对象的方案数时。 【二项式定理】二项式定理是指数学中的一个基本定理...

    组合数学基本原理(陈景润)

    其中,排列指的是从n个不同元素中取出m个元素按照一定顺序排列的方式总数;组合则是不考虑顺序的情况下,从n个不同元素中取出m个元素的方式总数。组合数学还包括二项式系数、多面体数、递推关系、母函数、生成函数等...

    排列与组合.doc

    2. 组合:从n个不同元素中取出m个元素,只考虑哪几个元素被选中,而不考虑它们的顺序,称为组合。组合的总数记为C(n, m),计算公式为C(n, m) = n! / [m!(n-m)!]。 3. 素数:在大于1的自然数中,除了1和它本身外,不...

    组合数学基本原理

    排列是指从n个不同元素中取出m(m≤n)个元素,按照一定的顺序排列起来的方法总数。排列强调的是顺序性,即不同的顺序视为不同的结果。排列的数量可以通过公式P(n,m)=n*(n-1)*...*(n-m+1)计算得出。 #### 组合 组合是...

    组合数学_Introductory Combinatorics

    - **排列**:从n个不同元素中取出m(m≤n)个元素按照一定的顺序排成一列的方式,称为排列。 - **组合**:从n个不同元素中取出m(m≤n)个元素,不考虑顺序的取法,称为组合。排列与组合的区别在于是否考虑顺序。 #### ...

    组合数学简介(陈景润)

    - 排列是指从n个不同元素中取出m(m≤n)个元素,按照一定的顺序排成一列的方式。 - 组合是指从n个不同元素中取出m(m≤n)个元素,不管其顺序如何,作为一组的方式。 - **二项式系数**:在组合数学中,二项式系数表示...

    抽屉原理高一数学讲座.doc

    通过将整数按照除以某个自然数m的余数分成m类,即m的剩余类,可以证明任意n+1个自然数中,总存在两个数的差是n的倍数。例如,证明任取8个自然数,必有两个数的差是7的倍数,可以通过将自然数按被7除的余数分成7类,...

    必学算法 抽屉原理

    - 手套配对:从5双不同手套中随机抽取6只,至少有两只手套可以配成一对。 - 数字奇偶性:从1到10中选取6个数字,至少有2个数字奇偶性不同。 **整除问题与抽屉原理:** 在整除问题中,我们可以将所有整数根据除以...

    程序设计中的组合数学

    排列是指从n个不同元素中取出m个元素,并按照一定的顺序排列。排列的数量可以用阶乘表示,即nPr=n!/(n-m)!。组合则是不考虑顺序的选择,公式为nCr=n!/m!(n-m)!。这两个概念在处理如任务分配、调度问题或选择最佳方案...

    2004~2015年程序员软考考试上午真题合集.pdf

    在数组和矩阵中,一维数组T[0...m*n-1]可以通过每隔n个元素取出一个元素依次存入数组B[1...m]中。 * question 14: A.T[(k-1)*n] B.T[k*n] C.T[(k-1)*m] D.T[k*m] 回答:A.T[(k-1)*n] 7.递归函数 在递归函数...

    组合数学简介

    集合是指具有某种共同属性的对象的总体,子集是集合的一部分,排列是指从n个不同元素中取出m个元素按照一定顺序排列的方式,组合则是不考虑顺序的选取。 2. **帕斯卡定律**:在组合计算中,帕斯卡定律(Pascal's ...

    Richard A.Brualdi 组合数学习题解答

    4. **二项式系数**: 记作\(C^n_m\)或\(\binom{n}{m}\),表示从n个不同元素中取出m个元素的方法数。 5. **组合恒等式**: 描述了不同的组合方式之间的关系,例如杨辉三角中的恒等式。 #### 题目解析 ##### 题目2.9 ...

    河北省邯郸市第一中学高中数学3.2.1古典概率同步测试新人教A版必修3

    例如,第1题,从三件正品、一件次品中随机取出两件,全是正品的概率是C(2,3) / C(2,4),其中C(n,k)表示组合数,表示从n个不同的元素中取k个元素的组合数。 3. 古典概型的应用:第3题,连掷一枚质地均匀的硬币4次,...

    随机产生验证码代码块

    // 随机产出一个下标,通过下标取出字符数组中的对应字符 char c = codeSequence[random.nextInt(codeSequence.length)]; // 假设取出来的字符在动态字符串中不存在代表没有重复的 if (sb.indexOf(c + "") == -...

    Redis入门 (脑图)

    * srandmember key n:随机从集合中取出 n 个元素 * smove source destination value:将一个集合中的值移动到另一个集合中 * sinter key1 key2:返回两个集合的交集元素 * sunion key1 key2:返回两个集合的元素的...

    (完整版)概率论与数理统计公式整理(超全版).pdf

    1. 组合公式:在概率论中,从n个不同元素中取出m个元素的组合数表示为C(n, m)或写作nCm,并遵循数学表达式: nCm = n! / [m! * (n-m)!] 其中n!表示n的阶乘,即n! = n * (n-1) * (n-2) * ... * 1。 2. 事件的加法...

    组合数学完整版(原书第4版,作者Brualdi)

    - **组合**:从n个不同元素中取出m(m≤n)个元素组成一组的方式称为组合,记作C(n,m)或C(m,n)。 #### 知识点三:鸽巢原理 **原理简介** - **经典鸽巢原理**:如果有n+1只鸽子飞进n个鸽舍中,至少有一个鸽舍里有两...

Global site tag (gtag.js) - Google Analytics