论坛首页 Java企业应用论坛

由新闻引出的计算概率方法题

浏览 7999 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (1)
作者 正文
   发表时间:2010-06-03   最后修改:2010-06-11
http://news.163.com/10/0603/04/687PSPBB00011229.html
新闻大意:浙江省青田县进行的经济适用房摇号中,有786人报名参与摇号,要摇出203人,摇出了“五连号”。记者请教了数学老师,从786个号码中摇出203个号码,203个号码能产生五连号的概率接近于零。
好久没看过排列组合计算概率的知识了,今天看了这个新闻发现很多网友提出了千奇百怪的算法,你还会算这个概率吗?

花了点时间整理后大致思路如下:
设:总计球all个,取出get个,相连con个球
1.首先总数量a中取出某个数量g的球的所有组合数量有数学公式可得出a*(a-1)*……*(a-g+1)/g!
2.求有con个连续球号总数.
假设5个球中取3个球,2个球相连的组合如下:
1 1 1 0 0
1 1 0 1 0
1 1 0 0 1
1 0 1 1 0
1 0 1 0 1
1 0 0 1 1
0 1 1 1 0
0 1 1 0 1
0 1 0 1 1
0 0 1 1 1
将问题分解为[5个球取3个(首球必取),2球连续的总数]+[4个球取3个(首球必取),2球连续的总数]+[3个球取3个(首球必取),2球连续的总数]
推出:[all个球取get个(首球必取),con球连续的总数]+[all-1个球取get个(首球必取),con球连续的总数]+……+[get个球取get个(首球必取),con球连续的总数]
简化:  当all==get时总数为1;  当get==con时总数为all-con+1;

3.那么2的结果除以1的结果可得概率

public static void main(String[] args) {
		getGL(786, 203,5);
	}

	/**
	 * 计算从all个球中取出get个球,有con个球相连的概率
	 * 
	 * @param all
	 *            球总数
	 * @param get
	 *            取出球数
	 * @param con
	 *            相连球数
	 * @return
	 */
	public static BigDecimal getGL(long all, long get, long con) {
		BigDecimal result = new BigDecimal(0);
		if (all < get) {
			return result;
		}
		BigDecimal total = getTotalNumber(all, get); // all个数取出get个数的组合总数
		System.out.println("--------" + total + "--------");
		BigDecimal tim = getTOGLNumber(all, get, con); // all个数取出get个数有con个数相连的总数
		System.out.println(tim);
		result = tim.divide(total, 200, BigDecimal.ROUND_HALF_EVEN);
		// result = result.multiply(new BigDecimal(100));
		System.out.println(result);
		return result;
	}

	/**
	 * 递归计算从all个球中取出get个球,有con个球相连的组合总数
	 * 
	 * @param thisAll
	 * @param get
	 * @param con
	 * @return
	 */
	public static BigDecimal getTOGLNumber(long thisAll, long get, long con) {
		BigDecimal result = new BigDecimal(0);
		if (get == thisAll || get == 0) {
			result = result.add(new BigDecimal(1));
		} else if (get == con) {
			result = result.add(new BigDecimal(thisAll - con + 1));
		} else if (get > con) {
			result = result.add(getTotalNumber(thisAll - con, get - con)); // 开始con个数相连的组合总数
			for(long i=con;i>=2;i--){
				if ((thisAll - i) >= con && get - i+1 >= con) { // 首数到i-1数选中,第i个数不选,con个数相连的组合总数
					result = result.add(getTOGLNumber(thisAll - i, get - i+1, con));
				}
			}
			result = result.add(getTOGLNumber(thisAll - 1, get, con)); // (递归)首数不选,con个数相连的组合总数
		}
		// System.out.println(thisAll + ":" + get + ":" + con + ":" + result);
		return result;
	}

	/**
	 * 计算从all个球中取出get个球的组合总数
	 * 
	 * @param all
	 *            球总数
	 * @param get
	 *            取出球数
	 * @return
	 */
	public static BigDecimal getTotalNumber(long all, long get) {
		BigDecimal max = new BigDecimal(1);
		BigDecimal sub = new BigDecimal(1);
		for (long i = 1; i <= get; i++) {
			max = max.multiply(new BigDecimal(all - i + 1));
			sub = sub.multiply(new BigDecimal(get - i + 1));
		}
		max = max.divide(sub);
		return max;
	}

以上方法效率太低,不知道有没有更好的方法,请高手 指教
   发表时间:2010-06-03  
其实我真不会!
0 请登录后投票
   发表时间:2010-06-04  
sjynt131 写道
http://news.163.com/10/0603/04/687PSPBB00011229.html
新闻大意:浙江省青田县进行的经济适用房摇号中,有786人报名参与摇号,要摇出203人,摇出了“五连号”。记者请教了数学老师,从786个号码中摇出203个号码,203个号码能产生五连号的概率接近于零。
好久没看过排列组合计算概率的知识了,今天看了这个新闻发现很多网友提出了千奇百怪的算法,你还会算这个概率吗?


和你摇出几个特定号的概率是一样的。


0 请登录后投票
   发表时间:2010-06-04  
mathfox 写道
sjynt131 写道
http://news.163.com/10/0603/04/687PSPBB00011229.html
新闻大意:浙江省青田县进行的经济适用房摇号中,有786人报名参与摇号,要摇出203人,摇出了“五连号”。记者请教了数学老师,从786个号码中摇出203个号码,203个号码能产生五连号的概率接近于零。
好久没看过排列组合计算概率的知识了,今天看了这个新闻发现很多网友提出了千奇百怪的算法,你还会算这个概率吗?


和你摇出几个特定号的概率是一样的。



关键是这个概率的算法,该如何计算,并保证结果正确。我到现在还没有思路
0 请登录后投票
   发表时间:2010-06-04  
我也不会~
0 请登录后投票
   发表时间:2010-06-04  
召唤数学帝
0 请登录后投票
   发表时间:2010-06-04  
1)先计算在786出现一个5连号的总数有多少: 768-5+1 = 764

2)在计算在203里一个5连号出现的位置总数: 203-5+1 = 199

3)计算符合要求所有出现5连号的总数: 764*199

4)计算768个人选出203人的所有可能总数: 768*767*766* ... *(768-203+1)

步骤3得出的总数除以步骤4得出的总数就是那个概率了,这也太小了,几乎为0
0 请登录后投票
   发表时间:2010-06-04  
潜意识中可能性不是那么低应该也就是千分之一吧.
0 请登录后投票
   发表时间:2010-06-04   最后修改:2010-06-04
Mark_Lee 写道
1)先计算在786出现一个5连号的总数有多少: 768-5+1 = 764

2)在计算在203里一个5连号出现的位置总数: 203-5+1 = 199

3)计算符合要求所有出现5连号的总数: 764*199

4)计算768个人选出203人的所有可能总数: 768*767*766* ... *(768-203+1)

步骤3得出的总数除以步骤4得出的总数就是那个概率了,这也太小了,几乎为0


1和4是没问题,但2不对吧,有什么根据?
照你这么算6个球中取3个球,2个连续的概率是:
6-2+1=5
3-2+1=2
2*5/(6*5*4/3/2)=10/20
但实际上是:16/20
1 2 3
1 2 4
1 2 5
1 2 6
1 3 4
1 3 5
1 3 6
1 4 5
1 4 6
1 5 6
2 3 4
2 3 5
2 3 6
2 4 5
2 4 6
2 5 6
3 4 5
3 4 6
3 5 6
4 5 6

0 请登录后投票
   发表时间:2010-06-04  
我用程序模拟了一下,竟然有48%的概率,附程序,看看是不是我哪里搞错了
    public static void main(String[] args) {
        int rc = 1000000;
        int mc = 0;
        for (int i = 0; i < rc; i++) {
            List<Integer> ai = genRank();
            int ri = isMatch(ai);
            if (ri > 0) {
                mc ++;
//                System.out.println(ai);
//                System.out.println(ri);
            }
        }
        System.out.println(mc);
    }

    public static List<Integer> genRank() {
        Set<Integer> ai = new HashSet<Integer>();
        Random r = new Random();
        while (ai.size() < 203) {
            ai.add(r.nextInt(786) + 1);
        }
        List<Integer> ri = new ArrayList<Integer>();
        ri.addAll(ai);
        Collections.sort(ri);
        return ri;
    }

    public static int isMatch(List<Integer> ai) {
        for (int i = 0; i < ai.size() - 4; i ++) {
            int ac = ai.get(i) + ai.get(i+1) + ai.get(i+2) + ai.get(i+3) + ai.get(i+4);
            if (ac == ai.get(i) * 5 + 10) {
                return ai.get(i);
            }
        }
        return 0;
    }
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics