首页 > 编程 > Java > 正文

java随机数生成具体实现代码

2019-11-26 14:25:12
字体:
来源:转载
供稿:网友

本文实例为大家分享了java随机数生成代码,供大家参考,具体内容如下

package com.gonvan.common.utils; import java.util.*; /** * 随机数工具 * * @author yuerzm *    */public final class LotteryAliasMethod {   /**   * The random number generator used to sample from the distribution.   */  private final Random  random;   /**   * The alias tables.   */  private final int[]   alias;   /**   * The probability tables.   */  private final double[] probability;   /**   * Constructs a new AliasMethod to sample from a discrete distribution and   * hand back outcomes based on the probability distribution.   * <p/>   * Given as input a list of probabilities corresponding to outcomes 0, 1,   * ..., n - 1, this constructor creates the probability and alias tables   * needed to efficiently sample from this distribution.   *   * @param probabilities   *      The list of probabilities.   */  public LotteryAliasMethod(List<Double> probabilities) {    this(probabilities, new Random());  }   /**   * Constructs a new AliasMethod to sample from a discrete distribution and   * hand back outcomes based on the probability distribution.   * <p/>   * Given as input a list of probabilities corresponding to outcomes 0, 1,   * ..., n - 1, along with the random number generator that should be used as   * the underlying generator, this constructor creates the probability and   * alias tables needed to efficiently sample from this distribution.   *   * @param probabilities   *      The list of probabilities.   * @param random   *      The random number generator   */  public LotteryAliasMethod(List<Double> probabilities, Random random) {    /* Begin by doing basic structural checks on the inputs. */    if (probabilities == null || random == null)      throw new NullPointerException();    if (probabilities.size() == 0)      throw new IllegalArgumentException("Probability vector must be nonempty.");     /* Allocate space for the probability and alias tables. */    probability = new double[probabilities.size()];    alias = new int[probabilities.size()];     /* Store the underlying generator. */    this.random = random;     /* Compute the average probability and cache it for later use. */    final double average = 1.0 / probabilities.size();     /*     * Make a copy of the probabilities list, since we will be making     * changes to it.     */    probabilities = new ArrayList<Double>(probabilities);     /* Create two stacks to act as worklists as we populate the tables. */    Deque<Integer> small = new ArrayDeque<Integer>();    Deque<Integer> large = new ArrayDeque<Integer>();     /* Populate the stacks with the input probabilities. */    for (int i = 0; i < probabilities.size(); ++i) {      /*       * If the probability is below the average probability, then we add       * it to the small list; otherwise we add it to the large list.       */      if (probabilities.get(i) >= average)        large.add(i);      else        small.add(i);    }     /*     * As a note: in the mathematical specification of the algorithm, we     * will always exhaust the small list before the big list. However,     * due to floating point inaccuracies, this is not necessarily true.     * Consequently, this inner loop (which tries to pair small and large     * elements) will have to check that both lists aren't empty.     */    while (!small.isEmpty() && !large.isEmpty()) {      /* Get the index of the small and the large probabilities. */      int less = small.removeLast();      int more = large.removeLast();       /*       * These probabilities have not yet been scaled up to be such that       * 1/n is given weight 1.0. We do this here instead.       */      probability[less] = probabilities.get(less) * probabilities.size();      alias[less] = more;       /*       * Decrease the probability of the larger one by the appropriate       * amount.       */      probabilities.set(more, (probabilities.get(more) + probabilities.get(less)) - average);       /*       * If the new probability is less than the average, add it into the       * small list; otherwise add it to the large list.       */      if (probabilities.get(more) >= 1.0 / probabilities.size())        large.add(more);      else        small.add(more);    }     /*     * At this point, everything is in one list, which means that the     * remaining probabilities should all be 1/n. Based on this, set them     * appropriately. Due to numerical issues, we can't be sure which     * stack will hold the entries, so we empty both.     */    while (!small.isEmpty())      probability[small.removeLast()] = 1.0;    while (!large.isEmpty())      probability[large.removeLast()] = 1.0;  }   /**   * Samples a value from the underlying distribution.   *   * @return A random value sampled from the underlying distribution.   */  public int next() {    /* Generate a fair die roll to determine which column to inspect. */    int column = random.nextInt(probability.length);     /* Generate a biased coin toss to determine which option to pick. */    boolean coinToss = random.nextDouble() < probability[column];     /* Based on the outcome, return either the column or its alias. */    return coinToss ? column : alias[column];  } }

以上就是本文的全部内容,希望对大家的学习有所帮助。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表