假设有100个数字 代表100种不同的物品 每次随机取其中一个使用  使用频率越高的  下次循环取用的时候 随机到这个数的机率就更大。。 
反之随机到的机率就越小。。 比如  1234567890   9号在10次随机取中 被抽到 5次  3被抽到3次 7被抽1次  4=1   1=1  他们在第11次随机抽取的 概率 大概为  93“741”25680  大概是这么个排位。 
求这个解决思路。。 741是同概率级别的 都被抽过1次 有限概率比后面5位高。。 

解决方案 »

  1.   

    思路有点同1L
    就是每个数有个权值,比如用抽取次数+1作为权值(考虑到0权值的概率分布),这样,下次随机的时候,按权值分布随机比如说
    9 的权值是 5+1=6
    3 的权值是 3+1=4
    741 的权值是 1+1=2
    25680的权值是 0+1=1下次随机的时候按权值分布随机,也就是把权值求总和 6+4+2+1=13, 
    取[0,13)之间的随机数,如果该随机数<6则取9,如果6<=该随机数<10则取3,如果<=10该随机数<12则741随机取一个,如果该随机数==12,则25680随机取一个,然后重新刷新权值
    权值可以用Map来管理
    Map<Integer, List<Integer>>, key是权值,value是数字列表
      

  2.   


    List<Integer> list = new ArrayList<Integer>();
    for(int i=0;i<10;i++){
    list.add(i);
    }
    Random rd = new Random();
    //随机20次,每次随机结果在下一次随机时概率增加1/list.size()
    for(int i=0;i<20;i++){
    int rdIndex = rd.nextInt(list.size());

    int rdInt = list.get(rdIndex);
    System.out.print(rdInt+",");
    //将当前随机结果加入下次随机集合,增加该随机结果在下次随机时的概率
    list.add(rdInt);
    }
      

  3.   


    先感谢。。但是这种操作的话 不是很适合 降低概率这一说。。  每次出现后增加数组的量,反之 如果减少的话
    按照这个思路 就是增加 除出现的数 其他所有数字的量  次数少 还行,如果字数多的话  这个LIST的SIZE 估计会非常非常大  如果默认SIZE是10000的话  做减少概率这个方式。。
      

  4.   


    先感谢。。但是这种操作的话 不是很适合 降低概率这一说。。  每次出现后增加数组的量,反之 如果减少的话
    按照这个思路 就是增加 除出现的数 其他所有数字的量  次数少 还行,如果字数多的话  这个LIST的SIZE 估计会非常非常大  如果默认SIZE是10000的话  做减少概率这个方式。。
      

  5.   


    先感谢。。但是这种操作的话 不是很适合 降低概率这一说。。  每次出现后增加数组的量,反之 如果减少的话
    按照这个思路 就是增加 除出现的数 其他所有数字的量  次数少 还行,如果字数多的话  这个LIST的SIZE 估计会非常非常大  如果默认SIZE是10000的话  做减少概率这个方式。。
      

  6.   

    package com;import java.util.Random;public class Demo {

    public static void main(String[] args) {
    long r = 100; //随机数的跟
    long[] arr = new long[100];
    for(int i = 0; i < 100; i++) {
    arr[i] = 1;
    }
    Random random = new Random();
    while(true) {
    long randomNum = random.nextLong();
    randomNum = randomNum % r + 1;
    if(randomNum <= 0) {
    randomNum += r;
    }
    System.out.print("随机数为" + randomNum + "。");
    long total = 0;
    for(int i = 0; i < 100; i++) {
    total += arr[i];
    if(randomNum <= total) {
    arr[i]++;
    r++;
    System.out.println("选择的数字为" + (i + 1) + "。");
    break;
    }
    }
    if(r == 10000) {
    break;
    }
    }
    for(int i = 0; i < 100; i++) {
    System.out.println(arr[i]);
    }
    }}我的一个简单的思路,可能不是很好,仅供lz参考
      

  7.   


    5L 刚刚思路大概就是这样。。  不过这个对减少出现概率的话 不是很实用呢  对数组长度增加太大了。
    如果起始的集合 SIZE很大的话。
      

  8.   


    XD  没接触过权值  我在琢磨4L的提议
      

  9.   


    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);
    }
      

  10.   

    5L和10L思路一样,线性分布会影响性能,随着随机次数的增加,list的size就会越来越大,最后会耗尽内存的,所以不可取,4L说的权值管理,实际上就是概率区间分布管理,实现起来也很简单
    //初始化处理
    int[] num = {...}; //100个数字
    TreeMap<Integer, List<Integer>> prob = new TreeMap<Integer, List<Integer>>(); //权值管理表
    prob.put(1, new ArraysList()); //初始化权值为1
    for (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所在区间的权值管理表的key
    List<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); //把随机数放到权值增加的数字列表中
      

  11.   

    午休
        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);
        }
      

  12.   

    可以创建一个冗余容器,比如大小为N*C,每取一个元素与最后一个元素对调,当容器大小为N*(C-1)时填充N个数。
    C取值到比log(N)大一点点就差不多了。
      

  13.   


    int pow_rand= sqrt(rand()% (array_size*array_size) );
    int ret= array[pow_rand];
    array.erase(array.begin()+pow_rand);
    array.push_back(ret);
    return ret;
    sqrt之后分布是不平均的
    用这样的方法试试
      

  14.   

      List<Integer> list = new ArrayList<Integer>();
            for(int i=0;i<10;i++){
                list.add(i);
            }
            Random rd = new Random();
            //随机20次,每次随机结果在下一次随机时概率增加1/list.size()
            for(int i=0;i<20;i++){
                int rdIndex = rd.nextInt(list.size());
                
                int rdInt = list.get(rdIndex);
                System.out.print(rdInt+",");
                //将当前随机结果加入下次随机集合,增加该随机结果在下次随机时的概率
                list.add(rdInt);
            }