java隨機(jī)數(shù)生成具體實現(xiàn)代碼
更新時間:2016年04月26日 16:27:24 作者:賣蠟筆的小新
這篇文章主要為大家分享了java隨機(jī)數(shù)生成具體實現(xiàn)代碼,具有一定的參考價值,感興趣的小伙伴們可以參考一下
本文實例為大家分享了java隨機(jī)數(shù)生成代碼,供大家參考,具體內(nèi)容如下
package com.gonvan.common.utils;
import java.util.*;
/**
* 隨機(jī)數(shù)工具
*
* @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];
}
}
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助。
相關(guān)文章
詳解基于MybatisPlus兩步實現(xiàn)多租戶方案
這篇文章主要介紹了詳解基于MybatisPlus兩步實現(xiàn)多租戶方案,本文分兩步,通過實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-04-04
Spring?data?jpa緩存機(jī)制使用總結(jié)
這篇文章主要介紹了Spring?data?jpa緩存機(jī)制使用總結(jié),具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-12-12
Java中的SimpleDateFormat的線程安全問題詳解
這篇文章主要介紹了Java中的SimpleDateFormat的線程安全問題詳解,sonar 是一個代碼質(zhì)量管理工具,SonarQube是一個用于代碼質(zhì)量管理的開放平臺,為項目提供可視化報告, 連續(xù)追蹤項目質(zhì)量演化過程,需要的朋友可以參考下2024-01-01
跟我學(xué)Java Swing之游戲設(shè)計(1)
跟我學(xué)Java Swing之游戲設(shè)計(1)...2006-12-12
IntelliJ Plugin 開發(fā)之添加第三方j(luò)ar的示例代碼
這篇文章主要介紹了IntelliJ Plugin 開發(fā)之添加第三方j(luò)ar的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-09-09
JAVA實現(xiàn)空間索引編碼——GeoHash的示例
本篇文章主要介紹了JAVA實現(xiàn)空間索引編碼——GeoHash的示例,如何從眾多的位置信息中查找到離自己最近的位置,有興趣的朋友可以了解一下2016-10-10

