读书人

一个骰子有6面概率均匀,小弟我怎么选

发布时间: 2012-04-13 13:50:24 作者: rapoo

一个骰子有6面,概率均匀,我如何选择7件事?
一个骰子有6面,概率均匀,我有7件事要随机均匀选择,如何扔?

如果我有4件事,5件事,8件事,9件事,10件事,
...n件事要选择,那

么我如何用最少的扔掷次数,来做到均匀分布?

[解决办法]
java代码,思路是上面几位提到的6进制。测试结果呈均匀分布。

Java code
import java.util.ArrayList;import java.util.HashMap;import java.util.Iterator;import java.util.Random;public class TestN {    public static void main(String[] args) {        int things = 1600;//事件数        HashMap<Integer,Integer> map = new HashMap<Integer,Integer>();        int whatTodo = whatShouldIDo(things);                //Begin:以10万次为统计结果,发现是均匀分布的//        for(int t =0;t<100000;t++){//            int whatTodo = whatShouldIDo(things);//            map.put(whatTodo, map.get(whatTodo)==null?1:map.get(whatTodo)+1);//        }//        Iterator<Integer> iterator = map.keySet().iterator();//        while(iterator.hasNext()){//            Object key =iterator.next();//            System.out.println(key+"->"+map.get(key));//        }        //End    }    private static int whatShouldIDo(int things) {        float percent = 0.9f;//精度         int tongSize = 0;        int MaxTime = 10;        int j = 0;        int times=0;//需要扔色子次数        int total=0; //扔出来N次的色子总和        for(int i=1;i<MaxTime+1;i++){            tongSize =  (int) Math.pow(6, i);            times++;            j = tongSize/things*things;            System.out.println("查看"+times+":"+tongSize+"->"+j);            if(j>=tongSize*percent){                System.out.println("有合理的桶存在!需要扔色子次数为"+times);                break;            }        }                System.out.println("桶的大小:"+tongSize);        System.out.println("输入为"+things+"的任务离桶最近的数:"+j);        System.out.println("舍弃数为:"+(tongSize-j));        System.out.println();                Random r = new Random();        StringBuffer sb = new StringBuffer();        ArrayList shanZi = new ArrayList() ;        while(true){            total = 0;            shanZi.clear();            for(int time=0;time<times;time++){                int now=r.nextInt(6);                total=total*6+now;//                System.out.println("第"+(time+1)+"次:"+now+"->"+total);                System.out.println("第"+(time+1)+"次,你扔的骰子为:"+(now+1));                shanZi.add(now);            }            if(total<=j){                break;            }else{                System.out.println(total+"不在有效范围内,作废!重新开始扔");            }        }        //输出计算结果        //现实中的色子数为[1,6],计算时用[0,5]表示        for(int index=0;index<shanZi.size();index++){            int pow = shanZi.size()-index-1;            sb.append(shanZi.get(index)+"*power(6,"+pow+")");            if(pow!=0){                sb.append("+");            }        }        System.out.println(sb.append("=").append(total));        System.out.println("取模:"+(total%things));        if(total%things==0){            System.out.println("色子决定人生:你要做的是第"+things+"件事");        }else{            System.out.println("色子决定人生:你要做的是第"+(total%things)+"件事");        }//        //生成模板图形//        for(int i=1;i<tongSize+1;i++){//            System.out.print(i+"\t" );//            if(i%things==0){//                System.out.println();//            }//        }        return (total%things);    }}
[解决办法]
C/C++ code
#include <stdio.h>#include <stdarg.h>#include <stdlib.h>#include <dirent.h>#include <sys/stat.h>#include <string.h>#define EVENT_MAX        100static int dice_radix; /* 基数,比如7件事色子有6面,则基数为9 */static int event_count; /* 事件数目,比如这里的7、4、5、8、9、10 */static int throw_times; /* 所需要掷色子次数,比如此题事件7次则需要掷2次 */static int dice_max; /* 色子的面数,比如6 */int init_rand(int event_count, int dice_max_count);int get_rand(void);int main(int argc, char *argv[]){    int i;    int ret[EVENT_MAX];    memset(ret, 0, sizeof(ret));    init_rand(7, 6);    printf("%d, %d, %d, %d...\n", dice_radix, event_count, throw_times, dice_max);    for(i=0; i<10000; ++i) {        ret[get_rand()]++;    }    int total = 0;    for(i=0; i<event_count; ++i) {        total += ret[i];        printf("event[%2d]=%4d...\n", i, ret[i]);    }    printf("\ntotal=%d...\n", total);    return 0;}static time_t rand_pip;int init_rand(int count, int dice_max_count){    dice_radix = dice_max_count;    event_count = count;    throw_times = 1;    dice_max = dice_max_count;    if(count<=0) {        return -1;    }    while(dice_radix < count) {        ++throw_times;        dice_radix *= dice_max_count;    }    while(dice_radix%count!=0) {        ++count;    }    dice_radix = count;    rand_pip = time(NULL);    return 0;}int get_rand(void){    int ret;    int i;    do {        rand_pip += 100;        srand(rand_pip);        ret = 0;        for(i=0; i<throw_times; ++i) {            ret *= dice_max;            ret += rand()%dice_max;        }        ret = rand()%dice_radix;    } while(ret>=event_count);    return ret;} 


[解决办法]

探讨
[color=#FF0000]
扔多个股子吧!然后你自己看要多少个能够满足你的N件事的需求![/color]

[解决办法]
也可以不舍弃。
可以第一次扔骰子以后,继续扔,但是对于以后:
偶数次,如果得到非6的数,即终止,选择第一个骰子得到的值对应的事件
奇数次(至少第三次),如果得到6,终止,选择第7个事件。

读书人网 >软件架构设计

热点推荐