如何在java中获得不同范围内具有不同概率的随机数?

时间:2018-06-17 11:07:03

标签: java random

我想得到一个0到100之间的整数随机数,不同范围内的概率不同。

例如,我希望0到20之间的值的概率为0.5,并且21到80之间的值概率为0.4,值为81到100之间的概率为{ {1}}。

Java中是否有任何方法或类或Java的任何库可以执行此操作?如果没有,我怎么能自己做?

4 个答案:

答案 0 :(得分:2)

你只需要一个额外的随机数来确定它应该产生的范围:

int getRandomNumberWithRangeProbability() {
    double range = Math.random();

    if (range < 0.5) {
        return randomWithRange(0, 20);
    } else if (range < 0.9) {
        return randomWithRange(21, 80);
    } else {
        return randomWithRange(81, 100);
    }
}

int randomWithRange(int min, int max) {
    int range = (max - min) + 1;
    return (int) (Math.random() * range) + min;
}

可以找到一个小测试here

AusCBloke方法对randomWithRange()的信用。

答案 1 :(得分:1)

你应该在每个范围内随机,然后在0和1之间获得另一个随机,并根据你的兴趣对待 祝好运 ETG

答案 2 :(得分:0)

我可以这样想,不知道是否有任何内置功能可以做到这一点

  1. 因此,创建一个将在两个整数之间随机返回的函数。
  2. 使变量可能具有1-10
  3. 的随机值
  4. 满足这些条件
  5. if(probable>=0 &&  probable<=5){
              random = getUniqueRandom(0, 20);
    
          }
          else if(probable>=6 &&  probable<=9) {
              random = getUniqueRandom(21, 80);
    
          }
          else if (probable == 10) {
              random = getUniqueRandom(81, 100);
    
          }
    

    以下是工作实施

    import java.util.Random;
    
    
    public class Solution  {
        private static Random r = new Random();
        public static void main(String[] args) {
            int pro1 = 0, pro2 =0, pro3 =0;
            for(int i=0; i<10000; i++) {
            int probable = getUniqueRandom(0, 10);
            int random = 0;
    
            if(probable>=0 &&  probable<=5){
                random = getUniqueRandom(0, 20);
                pro1++;
            }
            else if(probable>=6 &&  probable<=9) {
                random = getUniqueRandom(21, 80);
                pro2++;
            }
            else if (probable == 10) {
                random = getUniqueRandom(81, 100);
                pro3++;
            }
    
            //System.out.println(random);
        }
            System.out.println("Checked 10000 Times.\n0-20 Found: "+pro1);
            System.out.println("21-80 Found: "+pro2);
            System.out.println("81-100 Found: "+pro3);
        }
        static int getUniqueRandom(int min, int max){
            int num = r.nextInt(max-min+1) + min;
            return num;
        }
    }
    

答案 3 :(得分:0)

您可以从统一分布中提取随机数(区间中的每个数字具有“相同”概率;使用Math.random()),然后使用“逆累积分布函数”映射这些数字。见CumulativeDistribution

考虑下面的图表,它是您案例的累积分配函数。 随机数r=Math.random()是介于0和1之间的数字,并且是下图中某点的y坐标。您从图表中返回相应的x坐标。

Comulative distribution

可以通过添加更多点或更改概率权重来推广以下示例代码。

package stackOv;   
public class RandomNum {

  public static void main(String[] args) {
    RandomNum rn = new RandomNum();
    for (int i=0;i<10;i++) {
      // random number extracted from an uniform distribution
      double u = Math.random();
      // random number extracted from the custom distribution
      double r = rn.myCustomInverse(u);
      System.out.println(String.format("u=%.4f r=%.4f", u, r) );
    }
  }

  double xPoints[]= new double[] {0, 20,  80,  100};
  double yPoints[]= new double[] {0, 0.5, 0.9, 1};

  /**
   * y is a number between 0 and 1
   * returns the x coordinate from the probability distribution
   */
  double myCustomInverse(double y) {
    if (y<0 || y>1) throw new IllegalArgumentException();

    if (y==0) return 0;
    if (y==1) return 1;

    // find the region y belongs to
    // (we want to find i, such that yPoints[i-1]<y<yPoints[i] )
    int i=0;
    while (y>yPoints[i]) {
      i++;
    }
    // compute m
    double m = (xPoints[i]-xPoints[i-1])/(yPoints[i]-yPoints[i-1]);
    // compute x0 = m*(y-y0)+q
    double x = xPoints[i-1] + m * (y-yPoints[i-1]);
    return x;
  }

}