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

本文实例为大家分享了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.

*

* 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 probabilities) {

this(probabilities, new Random());

}

/**

* Constructs a new AliasMethod to sample from a discrete distribution and

* hand back outcomes based on the probability distribution.

*

* 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 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(probabilities);

/* Create two stacks to act as worklists as we populate the tables. */

Deque small = new ArrayDeque();

Deque large = new ArrayDeque();

/* 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];

}

}

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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值