I am kind of learning concepts of Random number generation & Multithreading in java.
The idea is to not generating a repeated random number of range 1000 in a particular millisecond (Considering, not more than 50 data, in a multithreaded way will be processed in a millisecond). So that list of generated random number at the specific time is unique. Can you give me any idea as i am ending up generating couple of repeated random numbers (also, there is a considerable probability) in a particular milli second.
I have tried the following things where i failed.
Random random = new Random(System.nanoTime());
double randomNum = random.nextInt(999);
//
int min=1; int max=999;
double randomId = (int)Math.abs(math.Random()* (max - min + 1) + min);
//
Random random = new Random(System.nanoTime()); // also tried new Random();
double randomId = (int)Math.abs(random.nextDouble()* (max - min + 1) + min);
As I am appending the timestamp that is being generated, in a multithreaded environment i see the same ids (around 8-10) that is being generated (2-4 times) for 5000+ unique data.
First, you should use new Random(), since it looks like this (details depend on Java version):
public Random() { this(++seedUniquifier + System.nanoTime()); }
private static volatile long seedUniquifier = 8682522807148012L;
I.e. it already makes use of nanoTime() and makes sure different threads with the same nanoTime() result get different seeds, which new Random(System.nanoTime()) doesn't.
(EDIT: Pyranja pointed out this is a bug in Java 6, but it's fixed in Java 7:
public Random() {
this(seedUniquifier() ^ System.nanoTime());
}
private static long seedUniquifier() {
// L'Ecuyer, "Tables of Linear Congruential Generators of
// Different Sizes and Good Lattice Structure", 1999
for (;;) {
long current = seedUniquifier.get();
long next = current * 181783497276652981L;
if (seedUniquifier.compareAndSet(current, next))
return next;
}
}
private static final AtomicLong seedUniquifier
= new AtomicLong(8682522807148012L);
)
Second, if you generate 50 random numbers from 1 to 1000, the probability some numbers will be the same is quite high thanks to the birthday paradox.
Third, if you just want unique ids, you could just use AtomicInteger counter instead of random numbers. Or if you want a random part to start with, append a counter as well to guarantee uniqueness.
This class will allow you to get nonrepeating values from a certain range until the whole range has been used. Once the range is used, it will be reinitialized.
Class comes along with a simple test.
If you want to make the class thread safe, just add synchronized to nextInt() declaration.
Then you can use the singleton pattern or just a static variable to access the generator from multiple threads. That way all your threads will use the same object and the same unique id pool.
public class NotRepeatingRandom {
int size;
int index;
List<Integer> vals;
Random gen = new Random();
public NotRepeatingRandom(int rangeMax) {
size = rangeMax;
index = rangeMax; // to force initial shuffle
vals = new ArrayList<Integer>(size);
fillBaseList();
}
private void fillBaseList() {
for (int a=0; a<size; a++) {
vals.add(a);
}
}
public int nextInt() {
if (index == vals.size()) {
Collections.shuffle(vals);
index = 0;
}
int val = vals.get(index);
index++;
return val;
}
public static void main(String[] args) {
NotRepeatingRandom gen = new NotRepeatingRandom(10);
for (int a=0; a<30; a++) {
System.out.println(gen.nextInt());
}
}
}
If I understand your question correctly, multiple threads are creating their own instances of Random class at the same time and all threads generate the same random number?
Same number is generated, because all random instances where created at the same time, i.e. with the same seed.
To fix this, create only one instance of Random class, which is shared by all threads so that all your threads call nextDouble() on the same instance. Random.nextDouble() class is thread safe and will implicitly update its seed with every call.
//create only one Random instance, seed is based on current time
public static final Random generator= new Random();
Now all threads should use the same instance:
double random=generator.nextDouble()
Related
My question is how I would implement multithreading to this task correctly.
I have a program that takes quite a long time to finish executing. About an hour and a half. I need to generate about 10,000 random and unique number codes. The code below is how I first implemented it and have it right now.
import java.util.Random;
import java.util.ArrayList;
public class Main
{
public static void main(String[] args) {
Random random = new Random();
// This holds all the codes
ArrayList<String> database = new ArrayList<>();
int counter = 0;
while(counter < 10000){
// Generate a 10 digit long code and append to sb
StringBuilder sb = new StringBuilder();
for(int i = 0; i < 10; i++){
sb.append(random.nextInt(10));
}
String code = String.valueOf(sb);
sb.setLength(0);
// Check if this code already exists in the database
// If not, then add the code and update counter
if(!database.contains(code)){
database.add(code);
counter++;
}
}
System.out.println("Done");
}
}
This of course is incredibly inefficient. So my question is: Is there is a way to implement multithreading that can work on this single piece of code? Best way I can word it is to give two cores/ threads the same code but have them both check the a single ArrayList? Both cores/ threads will generate codes but check to make sure the code it just made doesn't already exist either from the other core/ thread or from itself. I drew a rough diagram below. Any insight, advice, or pointers is greatly appreciated.
Using a more appropriate data structure and a more appropriate representation of the data, this should be a lot faster and easier to read, too:
Set<Long> database = new HashSet<>(10000);
while(database.size() < 10000){
database.add(ThreadLocalRandom.current().nextLong(10_000_000_000L);
}
Start with more obvious optimizations:
Do not use ArrayList, use HashSet. ArrayList contains() time complexity is O(n), while HashSet is O(1). Read this question about Big O summary for java collections framework. Read about Big O notation.
Initialize your collection with appropriate initial capacity. For your case that would be:
new HashSet<>(10000);
Like this underlying arrays won't be copied to increase their capacity. I would suggest to look/debug implementations of java collections to better understand how they work under the hood. Even try to implement them on your own.
Before you delve into complex multithreading optimizations, fix the simple problems - like bad collection choices.
Edit: As per suggestion from #Thomas in comments, you can directly generate a number(long) in the range you need - 0 to 9_999_999_999. You can see in this question how to do it. Stringify the resulting number and if length is less than 10, pad with leading zeroes.
Example:
(use ConcurrentHashMap, use threads, use random.nextLong())
public class Main {
static Map<String,Object> hashMapCache = new ConcurrentHashMap<String,Object>();
public static void main(String[] args) {
Random random = new Random();
// This holds all the codes
ArrayList<String> database = new ArrayList<>();
int counter = 0;
int NumOfThreads = 20;
int total = 10000;
int numberOfCreationsForThread = total/NumOfThreads;
int leftOver = total%NumOfThreads;
List<Thread> threadList = new ArrayList<>();
for(int i=0;i<NumOfThreads;i++){
if(i==0){
threadList.add(new Thread(new OneThread(numberOfCreationsForThread+leftOver,hashMapCache)));
}else {
threadList.add(new Thread(new OneThread(numberOfCreationsForThread,hashMapCache)));
}
}
for(int i=0;i<NumOfThreads;i++){
threadList.get(i).start();;
}
for(int i=0;i<NumOfThreads;i++){
try {
threadList.get(i).join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
for(String key : hashMapCache.keySet()){
database.add(key);
}
System.out.println("Done");
}}
OneThread:
public class OneThread implements Runnable{
int numberOfCreations;
Map<String,Object> hashMapCache;
public OneThread(int numberOfCreations,Map<String,Object> hashMapCache){
this.numberOfCreations = numberOfCreations;
this.hashMapCache = hashMapCache;
}
#Override
public void run() {
int counter = 0;
Random random = new Random();
System.out.println("thread "+ Thread.currentThread().getId() + " Start with " +numberOfCreations);
while(counter < numberOfCreations){
String code = generateRandom(random);
while (code.length()!=10){
code = generateRandom(random);
}
// Check if this code already exists in the database
// If not, then add the code and update counter
if(hashMapCache.get(code)==null){
hashMapCache.put(code,new Object());
counter++;
}
}
System.out.println("thread "+ Thread.currentThread().getId() + " end with " +numberOfCreations);
}
private static String generateRandom(Random random){
return String.valueOf(digits(random.nextLong(),10));
}
/** Returns val represented by the specified number of hex digits. */
private static String digits(long val, int digits) {
val = val > 0 ? val : val*-1;
return Long.toString(val).substring(0,digits);
}
}
I am new in Java and for the moment basic with methods, classes and constructors. For practice I am trying to write a basic game (safecracker). So my logic is get a 3 digit random number and try to guess it.
private static int takeRandomSafeCode(int min, int max) {
Random random = new Random();
int result = random.nextInt(max - min) + min;
return result;
private static void playGame() {
int safeCode = takeRandomSafeCode(100, 999);
int guess = takeGuess();
These are my random number methods. But if player guess a number and first digit is correct but on a wrong place I want to say "1 digit is correct but on a wrong position" or if one digit is correct "1 digit is correct and correct position"
I need to use here if-else statement i guess but I get my numbers int variable. What is the way of checking numbers one by one? Do I need to use a String? I am a little bit lost at this point. I would appreciate with your help.
It may be preferable - and result in simpler code - if you generate an integer array with three elements. Logically, the safe code 1-2-3 is not one hundred and twenty three but actually 1 followed by 2 followed by 3.
private static int takeRandomDigit() {
Random random = new Random();
int result = random.nextInt(10);
return result;
}
private static void playGame() {
int[] safeCode = {takeRandomDigit(), takeRandomDigit(), takeRandomDigit()};
int guess = takeGuess();
for (int safeDigit : safeCode) // for each digit in the safe code
{
// if the digit matches the guess, do something
}
}
You can use some math to take the numbers for example if your number is:
d=253
d % 10 -> gives you 3
d / 10 % 10 -> gives you 5
d / 100 -> gives you 2
Changing it to string is also an option because you can then access the different characters using the string functions like charAt etc.
But if you want to make it the Java and OOP way in order to learn you can make an object and add the 3 numbers as properties of that object and input some of the logic for checking there instead of doing some magic tricks like the above. For example:
class Combination {
private int firstPos;
private int secondPos;
private int thirdPos;
public Combination(){
firstPos=random.nextInt(10);
secondPos=random.nextInt(10);
thirdPos=random.nextInt(10);
}
public boolean checkCombination(Combination testedCombination){
.............
}
some methods, getter, setters etc
}
I have the following uni assignment that's been puzzling me. I have to implement a genetic algorithm that allocates processes into processors. More specifically the problem is the following:
"You have a program that is computed in parallel processor system. The program is made up of a N number of processes that need to be allocated on a n number of processors (where n is way smaller than N). The communication of processes during this whole process can be quite time consuming, so the best practice would be to assign processes that need intercommunication with one another to same processor.
In order to reduce the communication time between processes you could allocate of these processes to the same processor but this would negate the parallel processing idea that every processor needs to contribute to the whole process.
Consider the following: Let's say that Cij is the total amount of communication between process i and process j. Assume that every process needs the same amount of computing power so that the limitations of the processing process can be handled by assigning the same amount of processes to a processor. Use a genetic algorithm to assign N processes to n processors."
The above is roughly translated the description of the problem. Now I have the following question that puzzle me.
1) What would be the best viable solution in order to for the genetic algorithm to run. I have the theory behind them and I have deduced that you need a best possible solution in order to check each generation of the produced population.
2) How can I properly design the whole problem in order to be handled by a program.
I am planning to implement this in Java but any other recommendations for other programming languages would be welcome.
The Dude abides. Or El Duderino if you're not into the whole brevity thing.
What you're asking is really a two part question, but the Genetic Algorithm part can be easily illustrated in concept. I find that giving a basic start can be helpful, but this problem as a "whole" is too complicated to address here.
Genetic Algorithms (GA) can be used as an optimizer, as you note. In order to apply a GA to a process execution plan, you need to be able to score an execution plan, then clone and mutate the best plans. A GA works by running several plans, cloning the best, and then mutating some of them slightly to see if the offspring (cloned) plans are improved or worsened.
In this example, I created a array of 100 random Integers. Each Integer is a "process" to be run and the value of the Integer is the "cost" of running that individual process.
List<Integer> processes = new ArrayList<Integer>();
The processes are then added to an ExecutionPlan, which is a List<List<Integer>>. This List of List of Integers will be used to represent 4 processors doing 25 rounds of processing:
class ExecutionPlan implements Comparable<ExecutionPlan> {
List<List<Integer>> plan;
int cost;
The total cost of an execution plan will be computed by taking the highest process cost per round (the greatest Integer) and summing the costs of all the rounds. Thus, the goal of the optimizer is to distribute the initial 100 integers (processes) into 25 rounds of "processing" on 4 "processors" such that total cost is as low as possible.
// make 10 execution plans of 25 execution rounds running on 4 processors;
List<ExecutionPlan> executionPlans = createAndIntializePlans(processes);
// Loop on generationCount
for ( int generation = 0; generation < GENERATIONCOUNT; ++generation) {
computeCostOfPlans(executionPlans);
// sort plans by cost
Collections.sort(executionPlans);
// print execution plan costs
System.out.println(generation + " = " + executionPlans);
// clone 5 better plans over 5 worse plans
// i.e., kill off the least fit and reproduce the best fit.
cloneBetterPlansOverWorsePlans(executionPlans);
// mutate 5 cloned plans
mutateClones(executionPlans);
}
When the program is run, the cost is initially randomly determined, but with each generation it improves. If you run it for 1000 generations and plot the results, a typical run will look like this:
The purpose of the GA is to Optimize or attempt to determine the best possible solution. The reason it can be applied to you problem is that your ExecutionPlan can be scored, cloned and mutated. The path to success, therefore, is to separate the problems in your mind. First, figure out how you can make an execution plan that can be scored as to what the cost will be to actually run it on an assumed set of hardware. Add rountines to clone and mutate an ExecutionPlan. Once you have that plug it into this GA example. Good luck and stay cool dude.
public class Optimize {
private static int GENERATIONCOUNT = 1000;
private static int PROCESSCOUNT = 100;
private static int MUTATIONCOUNT = PROCESSCOUNT/10;
public static void main(String...strings) {
new Optimize().run();
}
// define an execution plan as 25 runs on 4 processors
class ExecutionPlan implements Comparable<ExecutionPlan> {
List<List<Integer>> plan;
int cost;
public ExecutionPlan(List<List<Integer>> plan) {
this.plan = plan;
}
#Override
public int compareTo(ExecutionPlan o) {
return cost-o.cost;
}
#Override
public String toString() {
return Integer.toString(cost);
}
}
private void run() {
// make 100 processes to be completed
List<Integer> processes = new ArrayList<Integer>();
// assign them a random cost between 1 and 100;
for ( int index = 0; index < PROCESSCOUNT; ++index) {
processes.add( new Integer((int)(Math.random() * 99.0)+1));
}
// make 10 execution plans of 25 execution rounds running on 4 processors;
List<ExecutionPlan> executionPlans = createAndIntializePlans(processes);
// Loop on generationCount
for ( int generation = 0; generation < GENERATIONCOUNT; ++generation) {
computeCostOfPlans(executionPlans);
// sort plans by cost
Collections.sort(executionPlans);
// print execution plan costs
System.out.println(generation + " = " + executionPlans);
// clone 5 better plans over 5 worse plans
cloneBetterPlansOverWorsePlans(executionPlans);
// mutate 5 cloned plans
mutateClones(executionPlans);
}
}
private void mutateClones(List<ExecutionPlan> executionPlans) {
for ( int index = 0; index < executionPlans.size()/2; ++index) {
ExecutionPlan execution = executionPlans.get(index);
// mutate 10 different location swaps, maybe the plan improves
for ( int mutationCount = 0; mutationCount < MUTATIONCOUNT ; ++mutationCount) {
int location1 = (int)(Math.random() * 100.0);
int location2 = (int)(Math.random() * 100.0);
// swap two locations
Integer processCostTemp = execution.plan.get(location1/4).get(location1%4);
execution.plan.get(location1/4).set(location1%4, execution.plan.get(location2/4).get(location2%4));
execution.plan.get(location2/4).set(location2%4, processCostTemp);
}
}
}
private void cloneBetterPlansOverWorsePlans(List<ExecutionPlan> executionPlans) {
for ( int index = 0; index < executionPlans.size()/2; ++index) {
ExecutionPlan execution = executionPlans.get(index);
List<List<Integer>> clonePlan = new ArrayList<List<Integer>>();
for ( int roundNumber = 0; roundNumber < 25; ++roundNumber) {
clonePlan.add( new ArrayList<Integer>(execution.plan.get(roundNumber)) );
}
executionPlans.set( index + executionPlans.size()/2, new ExecutionPlan(clonePlan) );
}
}
private void computeCostOfPlans(List<ExecutionPlan> executionPlans) {
for ( ExecutionPlan execution: executionPlans) {
execution.cost = 0;
for ( int roundNumber = 0; roundNumber < 25; ++roundNumber) {
// cost of a round is greatest "communication time".
List<Integer> round = execution.plan.get(roundNumber);
int roundCost = round.get(0)>round.get(1)?round.get(0):round.get(1);
roundCost = execution.cost>round.get(2)?roundCost:round.get(2);
roundCost = execution.cost>round.get(3)?roundCost:round.get(3);
// add all the round costs' to determine total plan cost
execution.cost += roundCost;
}
}
}
private List<ExecutionPlan> createAndIntializePlans(List<Integer> processes) {
List<ExecutionPlan> executionPlans = new ArrayList<ExecutionPlan>();
for ( int planNumber = 0; planNumber < 10; ++planNumber) {
// randomize the processes for this plan
Collections.shuffle(processes);
// and make the plan
List<List<Integer>> currentPlan = new ArrayList<List<Integer>>();
for ( int roundNumber = 0; roundNumber < 25; ++roundNumber) {
List<Integer> round = new ArrayList<Integer>();
round.add(processes.get(4*roundNumber+0));
round.add(processes.get(4*roundNumber+1));
round.add(processes.get(4*roundNumber+2));
round.add(processes.get(4*roundNumber+3));
currentPlan.add(round);
}
executionPlans.add(new ExecutionPlan(currentPlan));
}
return executionPlans;
}
}
Okay, I implemented this SO question to my code: Return True or False Randomly
But, I have strange behavior: I need to run ten instances simultaneously, where every instance returns true or false just once per run. And surprisingly, no matter what I do, every time i get just false
Is there something to improve the method so I can have at least roughly 50% chance to get true?
To make it more understandable: I have my application builded to JAR file which is then run via batch command
java -jar my-program.jar
pause
Content of the program - to make it as simple as possible:
public class myProgram{
public static boolean getRandomBoolean() {
return Math.random() < 0.5;
// I tried another approaches here, still the same result
}
public static void main(String[] args) {
System.out.println(getRandomBoolean());
}
}
If I open 10 command lines and run it, I get false as result every time...
I recommend using Random.nextBoolean()
That being said, Math.random() < 0.5 as you have used works too. Here's the behavior on my machine:
$ cat myProgram.java
public class myProgram{
public static boolean getRandomBoolean() {
return Math.random() < 0.5;
//I tried another approaches here, still the same result
}
public static void main(String[] args) {
System.out.println(getRandomBoolean());
}
}
$ javac myProgram.java
$ java myProgram ; java myProgram; java myProgram; java myProgram
true
false
false
true
Needless to say, there are no guarantees for getting different values each time. In your case however, I suspect that
A) you're not working with the code you think you are, (like editing the wrong file)
B) you havn't compiled your different attempts when testing, or
C) you're working with some non-standard broken implementation.
Have you tried looking at the Java Documentation?
Returns the next pseudorandom, uniformly distributed boolean value from this random number generator's sequence ... the values true and false are produced with (approximately) equal probability.
For example:
import java.util.Random;
Random random = new Random();
random.nextBoolean();
You could also try nextBoolean()-Method
Here is an example: http://www.tutorialspoint.com/java/util/random_nextboolean.htm
Java 8: Use random generator isolated to the current thread: ThreadLocalRandom nextBoolean()
Like the global Random generator used by the Math class, a ThreadLocalRandom is initialized with an internally generated seed that may not otherwise be modified. When applicable, use of ThreadLocalRandom rather than shared Random objects in concurrent programs will typically encounter much less overhead and contention.
java.util.concurrent.ThreadLocalRandom.current().nextBoolean();
Why not use the Random class, which has a method nextBoolean:
import java.util.Random;
/** Generate 10 random booleans. */
public final class MyProgram {
public static final void main(String... args){
Random randomGenerator = new Random();
for (int idx = 1; idx <= 10; ++idx){
boolean randomBool = randomGenerator.nextBoolean();
System.out.println("Generated : " + randomBool);
}
}
}
You can use the following for an unbiased result:
Random random = new Random();
//For 50% chance of true
boolean chance50oftrue = (random.nextInt(2) == 0) ? true : false;
Note: random.nextInt(2) means that the number 2 is the bound. the counting starts at 0. So we have 2 possible numbers (0 and 1) and hence the probability is 50%!
If you want to give more probability to your result to be true (or false) you can adjust the above as following!
Random random = new Random();
//For 50% chance of true
boolean chance50oftrue = (random.nextInt(2) == 0) ? true : false;
//For 25% chance of true
boolean chance25oftrue = (random.nextInt(4) == 0) ? true : false;
//For 40% chance of true
boolean chance40oftrue = (random.nextInt(5) < 2) ? true : false;
The easiest way to initialize a random number generator is to use the parameterless constructor, for example
Random generator = new Random();
However, in using this constructor you should recognize that algorithmic random number generators are not truly random, they are really algorithms that generate a fixed but random-looking sequence of numbers.
You can make it appear more 'random' by giving the Random constructor the 'seed' parameter, which you can dynamically built by for example using system time in milliseconds (which will always be different)
you could get your clock() value and check if it is odd or even. I dont know if it is %50 of true
And you can custom-create your random function:
static double s=System.nanoTime();//in the instantiating of main applet
public static double randoom()
{
s=(double)(((555555555* s+ 444444)%100000)/(double)100000);
return s;
}
numbers 55555.. and 444.. are the big numbers to get a wide range function
please ignore that skype icon :D
You can also make two random integers and verify if they are the same, this gives you more control over the probabilities.
Random rand = new Random();
Declare a range to manage random probability.
In this example, there is a 50% chance of being true.
int range = 2;
Generate 2 random integers.
int a = rand.nextInt(range);
int b = rand.nextInt(range);
Then simply compare return the value.
return a == b;
I also have a class you can use.
RandomRange.java
Words in a text are always a source of randomness. Given a certain word, nothing can be inferred about the next word. For each word, we can take the ASCII codes of its letters, add those codes to form a number. The parity of this number is a good candidate for a random boolean.
Possible drawbacks:
this strategy is based upon using a text file as a source for the words. At some point,
the end of the file will be reached. However, you can estimate how many times you are expected to call the randomBoolean()
function from your app. If you will need to call it about 1 million times, then a text file with 1 million words will be enough.
As a correction, you can use a stream of data from a live source like an online newspaper.
using some statistical analysis of the common phrases and idioms in a language, one can estimate the next word in a phrase,
given the first words of the phrase, with some degree of accuracy. But statistically, these cases are rare, when we can accuratelly
predict the next word. So, in most cases, the next word is independent on the previous words.
package p01;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
public class Main {
String words[];
int currentIndex=0;
public static String readFileAsString()throws Exception
{
String data = "";
File file = new File("the_comedy_of_errors");
//System.out.println(file.exists());
data = new String(Files.readAllBytes(Paths.get(file.getName())));
return data;
}
public void init() throws Exception
{
String data = readFileAsString();
words = data.split("\\t| |,|\\.|'|\\r|\\n|:");
}
public String getNextWord() throws Exception
{
if(currentIndex>words.length-1)
throw new Exception("out of words; reached end of file");
String currentWord = words[currentIndex];
currentIndex++;
while(currentWord.isEmpty())
{
currentWord = words[currentIndex];
currentIndex++;
}
return currentWord;
}
public boolean getNextRandom() throws Exception
{
String nextWord = getNextWord();
int asciiSum = 0;
for (int i = 0; i < nextWord.length(); i++){
char c = nextWord.charAt(i);
asciiSum = asciiSum + (int) c;
}
System.out.println(nextWord+"-"+asciiSum);
return (asciiSum%2==1) ;
}
public static void main(String args[]) throws Exception
{
Main m = new Main();
m.init();
while(true)
{
System.out.println(m.getNextRandom());
Thread.sleep(100);
}
}
}
In Eclipse, in the root of my project, there is a file called 'the_comedy_of_errors' (no extension) - created with File> New > File , where I pasted some content from here: http://shakespeare.mit.edu/comedy_errors/comedy_errors.1.1.html
For a flexible boolean randomizer:
public static rbin(bias){
bias = bias || 50;
return(Math.random() * 100 <= bias);
/*The bias argument is optional but will allow you to put some weight
on the TRUE side. The higher the bias number, the more likely it is
true.*/
}
Make sure to use numbers 0 - 100 or you might lower the bias and get more common false values.
PS: I do not know anything about Java other than it has a few features in common with JavaScript. I used my JavaScript knowledge plus my inferring power to construct this code. Expect my answer to not be functional. Y'all can edit this answer to fix any issues I am not aware of.
I have a set of over 100 different probabilities ranging from 0.007379 all the way to 0.913855 (These probabilities were collected from an actuary table http://www.ssa.gov/oact/STATS/table4c6.html). In Java, how can I use these probabilities to determine whether something will happen or not? Something along these lines...
public boolean prob(double probability){
if (you get lucky)
return true;
return false;
}
The Random class allows you to create a consistent set of random numbers so that every time you run the program, the same sequence of values is generated. You can also generate normally distributed random values with the Random class. I doubt you need any of that.
For what you describe, I would just use Math.random. So, given the age of a man we could write something like:
double prob = manDeathTable[age];
if( Math.random() < prob )
virtualManDiesThisYear();
First you need to create an instance of Random somewhere sensible in your program - for example when your program starts.
Random random = new Random();
Use this code to see whether an event happens:
boolean happens = random.NextDouble() < prob;
I'm not sure where that range came from. If you have a distribution in mind, I'd recommend using a Random to generate a value and get on with it.
public ProbabilityGenerator {
private double [] yourValuesHere = { 0.007379, 0.5, 0.913855 };
private Random random = new Random(System.currentTimeMillis());
public synchronized double getProbability() {
return this.yourValuesHere[this.random.nextInt(yourValuesHere.length));
}
}