当前位置: 代码迷 >> J2SE >> 求1解决思路。
  详细解决方案

求1解决思路。

热度:92   发布时间:2016-04-24 00:37:05.0
求一解决思路。。
假设有100个数字 代表100种不同的物品 

每次随机取其中一个使用  

使用频率越高的 下次循环取用的时候 随机到这个数的机率就更大。。 
反之随机到的机率就越小。。 

比如 1234567890 9号在10次随机取中 被抽到 5次 3被抽到3次 7被抽1次 4=1 1=1  

他们在第11次随机抽取的 概率 大概为 93“741”25680 大概是这么个排位。 
求这个解决思路。。 

741是同概率级别的 都被抽过1次 有限概率比后面5位高。。 


------解决方案--------------------
Java code
    Map<String, Integer> map = new HashMap<String, Integer>();        List<String> names = new ArrayList<String>() ;        for (int i = 0; i < 10; i++) {//装数据            map.put(""+i, 1) ;            names.add(i+"") ;        }        for (int j = 0; j< 20; j++) {            int i = 0 ;            for (String key : names) {                i =i + map.get(key) ;            }            Random random = new Random() ;            int index = random.nextInt(i) ;            i = 0 ;            String name ="" ;            for (String key : names) {                if(i>=index) {                    name = key ;                    break ;                }                i =i + map.get(key) ;            }            System.out.println("取出的name"+ name);            map.put(name, map.get(name)+1) ;            System.out.println(map);        }
------解决方案--------------------
5L和10L思路一样,线性分布会影响性能,随着随机次数的增加,list的size就会越来越大,最后会耗尽内存的,所以不可取,4L说的权值管理,实际上就是概率区间分布管理,实现起来也很简单

Java code
//初始化处理int[] num = {...}; //100个数字TreeMap<Integer, List<Integer>> prob = new TreeMap<Integer, List<Integer>>(); //权值管理表prob.put(1, new ArraysList()); //初始化权值为1for (int n : num) {    prob.get(1).add(n); //把100个数字加入权值管理表}//取随机数处理TreeMap<Integer, Integer> tmp = new TreeMap<Integer, Integer>(); //权值区间分布整理,用于查找权值(避免遍历)int sum = 0; //权值求和for (int n : map.keySet()) {    tmp.put(sum, n); //权值区间分布    sum += n; //求权值总和}int p = (int)(Math.random()*sum); //取[0,sum)之间的随机数int key = tmp.lowerEntry(p).getValue(); //取随机数p所在区间的权值管理表的keyList<Integer> list = prob.get(key); //key所对应的数字列表信息int index = (int)(Math.random()*list.size()); //随机获取数字列表的一个位置int ran = list.remove(index); //获取随机位置的数字//刷新权值管理表信息if (list.size()==0) {    prob.remove(key); //如果权值对应的数字列表信息没有,则删除权值}if (!prob.containsKey(key+1)) { //权值+1作为key,如果这样的权值不存在    prob.put(key+1, new ArrayList<Integer>()); //则加入权值管理表}prob.get(key+1).add(ran); //把随机数放到权值增加的数字列表中
------解决方案--------------------
午休
Java code
    public static void main(String[] args)   {    //随机数组    int array[]=new int[]{1,2,3,4,5};    //对应权值    int temp[]=new int[] {1,1,1,1,1};    //看看对应的区间    for(int i=0;i<temp.length;i++){        System.out.println(i+1+":  "+(i==0?1:(getEnd(temp,i-1)+1))+"---"+getEnd(temp,i));    }    //随机空间为 1---getEnd(temp,temp.length-1)+1    int randomNum=new Random().nextInt(getEnd(temp,temp.length-1)+1);    int index=getIndex(temp,0,randomNum);//对应索引    System.out.println(randomNum+"---"+array[index]);    //修改权值    temp[index]+=1;    }    //索引对应的区间结尾    private static int getEnd(int[] array,int index){    if(index<=0)         return array[0];    return array[index]+getEnd(array,index-1);    }    //某值随机值对应的索引位置    private static int getIndex(int[] array,int index ,int num){    if((num-=array[index])<=0||index==array.length-1)        return index;    return getIndex(array,++index, num);    }
  相关解决方案