一个骰子有6面,概率均匀,小弟我怎么选择7件事
一个骰子有6面,概率均匀,我如何选择7件事?
一个骰子有6面,概率均匀,我有7件事要随机均匀选择,如何扔?
如果我有4件事,5件事,8件事,9件事,10件事,
...n件事要选择,那
么我如何用最少的扔掷次数,来做到均匀分布?
------解决方案--------------------
java代码,思路是上面几位提到的6进制。测试结果呈均匀分布。
一个骰子有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 100 static 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; }