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));
}
}
Related
I've never written a single line of Java in my life and I'm trying to help my son return a random number between 0-100. I figured out how to write it to the console but not how to return the actual value out of his method so he can use it. I think it has something to do with the crazy void, static, or ways ya'll write your functions. That's all Greek to me (er, java to me). Coming from Javascript I fixed that up for him in 10 secs but this has now really stumped me since I know nothing about Java.
The code is below and I want to give him some kind of return so he can use the number in the program he's writing.
import java.util.Random;
public class generateRandom{
public static void main(String args[]){
// create instance of Random class
Random rand = new Random();
// Generate random integer in range 0 to 100
int rand_int1 = rand.nextInt(101);
// Print random integers
System.out.println("Random Integer: "+rand_int1);
}
}
You can start by adding a static method like:
public static int computeRandom() {
Random rand = new Random();
return rand.nextInt(101);
}
and then invoke that method from your main().
But thing is: there are no detours in life. The real answer is: even if you just want "some small thing", you will have to invest the time and energy to learn enough to make that happen.
You need to create a separate method here return the random value and pass it around or you can just pass the rand_int variable as a argument to the function you want to use.
I have a method that return a number:
public String getNum()
{
Random random = new Random();
return random.nextInt(1000) + "";
}
And I have this method that stores an object
public void store(User user)
{
String str = getNum();
user.setIdCode(str);
for (User users: userList)
{
if(users.getId() == user.getId())
{
user.setIdCode(getNum);
}
}
}
if Id is excited than re-set the id. This is for sure checks if the id exists the first time but how about the second time that id is set. there would be a possibility of repeating the same number. At the same time we cant go in infinite loop.
What you can try is add a few random numbers in a Set and then use them separately whenever you want.
What I mean by it is that if you're trying to get a random number every time, you can just store some random numbers at once and then retrieve them one by one when you need them.
In code, put this in some method called storeRandomNumbers() and call it in the beginning of your program. Also, declare the Set as a global variable.
You can also make a separate variable to keep track of how many random numbers have been used up and use it to retrieve the next random number from the Set.
The code would look something like this (makes changes according to your needs):
Random rand = new Random();
Set<Integer> uniqueRandoms = new HashSet<>();
while (uniqueRandoms.size()<10){
uniqueRandoms.add(rand.nextInt(11));
}
for (Integer i : uniqueRandoms){
// System.out.print(i+" ");
// retrieve them from here and use them whenever you want
}
Edit:
Yes as #Andreas gave the link to suggest, you don't compare Strings with ==, rather you use the equals() method.
This question already has answers here:
Java random numbers using a seed
(7 answers)
Closed 5 years ago.
Given the function:
static boolean chance(int percentage) {
return percentage != 0 && random.nextInt(101) <= percentage;
}
and a test for that function:
#Test
public void chance_AlwaysFalse_Percentage0() {
assertFalse(chance(0));
}
The test does not provide with certainty that chance will always return true. I could change the change function to the following:
static boolean chance(int percentage) {
return random.nextInt(101) <= percentage;
}
and the test would still pass. However, there is a very small chance that random.nextInt(100) will return 0, which would make the function return true, making the test fail.
I could execute this test a billion times as well, but given the nature of random numbers, there is still a minimal chance of failure.
How should I go about testing a function like this? Should it be tested at all? What is a better approach to this problem?
There are some functionalities in java that may serve for repeatable unit tests:
Random numbers: the Random constructor with a seed, for instance new Random(13) will always give the same sequence of random numbers. This already has been exploited to find a random sequence starting with 1, 2, 3, ..., 10. Or the alphabetic letters of someones name.
Time: the new java time functions allow for a faked clock, so "now" is always at a given time. Clock.fixed
And then there are mocking frameworks, that instrument the byte code of arbitrary calls so the return a provided result. Also useful for blending out more complex contexts.
Automated tests can't catch everything. In fact, the first example of your function might also have a bug, in that chance(1) will have a 2% chance instead of a 1% chance of returning true (since it would return true if the random number was either 0 or 1). But if you only test 0 and 100, it would pass those tests 100% of the time. (In fact, 0 and 100 are the only values that will return true the correct percentage of the time; everything else will be off by 1%. The effects of that bug are subtle enough that you may or may not ever notice it, depending on how the function is used.)
You could put your tests in a loop, if you really wanted to. If you ran the chance_AlwaysFalse_Percentage0 test 10,000 times, the odds would be very much in favor of any particular random number being hit. (No, it's not technically guaranteed, but if you calculate the odds, I think you'd be satisfied.) I'm not sure if that's worth doing.
Software random number generators are not random
They are deterministic if they are seeded with the same seed.
I also corrected the comparison logic to be correct in the range check.
Testable Implementation
import javax.annotation.ParametersAreNonnullByDefault;
import java.util.Random;
#ParametersAreNonnullByDefault
public class Q47336122
{
private final Random random;
public Q47336122(final long seed)
{
this.random = new Random(seed);
}
public boolean chance(final int percentage)
{
if (percentage <= 0) { return false; }
else if (percentage >= 100) { return true; }
else
{
final int r = this.random.nextInt(100);
return r > 0 && r <= percentage;
}
}
}
Deterministic Test
import org.junit.Test;
import javax.annotation.ParametersAreNonnullByDefault;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
#ParametersAreNonnullByDefault
public class Q47336122Test
{
#Test
public void testChance()
{
final Q47336122 q = new Q47336122(1000L);
/* poor man's code generator */
// for (int i=0; i <= 100; i++) {
// System.out.println(String.format("assertThat(q.chance(%d),is(%s));", i, q.chance(i)));
// }
assertThat(q.chance(0),is(false));
assertThat(q.chance(1),is(false));
assertThat(q.chance(2),is(false));
assertThat(q.chance(3),is(false));
assertThat(q.chance(4),is(false));
assertThat(q.chance(5),is(false));
assertThat(q.chance(6),is(false));
assertThat(q.chance(7),is(false));
assertThat(q.chance(8),is(false));
assertThat(q.chance(9),is(false));
assertThat(q.chance(10),is(false));
assertThat(q.chance(11),is(false));
assertThat(q.chance(12),is(false));
assertThat(q.chance(13),is(false));
assertThat(q.chance(14),is(false));
assertThat(q.chance(15),is(false));
assertThat(q.chance(16),is(false));
assertThat(q.chance(17),is(false));
assertThat(q.chance(18),is(true));
assertThat(q.chance(19),is(false));
assertThat(q.chance(20),is(false));
assertThat(q.chance(21),is(false));
assertThat(q.chance(22),is(false));
assertThat(q.chance(23),is(false));
assertThat(q.chance(24),is(true));
assertThat(q.chance(25),is(false));
assertThat(q.chance(26),is(false));
assertThat(q.chance(27),is(false));
assertThat(q.chance(28),is(false));
assertThat(q.chance(29),is(false));
assertThat(q.chance(30),is(false));
assertThat(q.chance(31),is(false));
assertThat(q.chance(32),is(false));
assertThat(q.chance(33),is(false));
assertThat(q.chance(34),is(false));
assertThat(q.chance(35),is(false));
assertThat(q.chance(36),is(true));
assertThat(q.chance(37),is(false));
assertThat(q.chance(38),is(true));
assertThat(q.chance(39),is(false));
assertThat(q.chance(40),is(true));
assertThat(q.chance(41),is(false));
assertThat(q.chance(42),is(true));
assertThat(q.chance(43),is(false));
assertThat(q.chance(44),is(false));
assertThat(q.chance(45),is(false));
assertThat(q.chance(46),is(false));
assertThat(q.chance(47),is(false));
assertThat(q.chance(48),is(false));
assertThat(q.chance(49),is(false));
assertThat(q.chance(50),is(true));
assertThat(q.chance(51),is(true));
assertThat(q.chance(52),is(false));
assertThat(q.chance(53),is(true));
assertThat(q.chance(54),is(false));
assertThat(q.chance(55),is(true));
assertThat(q.chance(56),is(false));
assertThat(q.chance(57),is(true));
assertThat(q.chance(58),is(false));
assertThat(q.chance(59),is(false));
assertThat(q.chance(60),is(true));
assertThat(q.chance(61),is(false));
assertThat(q.chance(62),is(false));
assertThat(q.chance(63),is(true));
assertThat(q.chance(64),is(true));
assertThat(q.chance(65),is(true));
assertThat(q.chance(66),is(true));
assertThat(q.chance(67),is(true));
assertThat(q.chance(68),is(true));
assertThat(q.chance(69),is(false));
assertThat(q.chance(70),is(false));
assertThat(q.chance(71),is(true));
assertThat(q.chance(72),is(true));
assertThat(q.chance(73),is(true));
assertThat(q.chance(74),is(true));
assertThat(q.chance(75),is(false));
assertThat(q.chance(76),is(true));
assertThat(q.chance(77),is(true));
assertThat(q.chance(78),is(true));
assertThat(q.chance(79),is(false));
assertThat(q.chance(80),is(true));
assertThat(q.chance(81),is(false));
assertThat(q.chance(82),is(true));
assertThat(q.chance(83),is(true));
assertThat(q.chance(84),is(true));
assertThat(q.chance(85),is(true));
assertThat(q.chance(86),is(true));
assertThat(q.chance(87),is(true));
assertThat(q.chance(88),is(true));
assertThat(q.chance(89),is(true));
assertThat(q.chance(90),is(true));
assertThat(q.chance(91),is(true));
assertThat(q.chance(92),is(true));
assertThat(q.chance(93),is(true));
assertThat(q.chance(94),is(true));
assertThat(q.chance(95),is(true));
assertThat(q.chance(96),is(true));
assertThat(q.chance(97),is(true));
assertThat(q.chance(98),is(true));
assertThat(q.chance(99),is(true));
assertThat(q.chance(100),is(true));
}
}
No matter how many times you run this test it will always pass.
It is a trivial exercise for the reader to expand this to test for thousands or millions of inputs. As long as the seed is the same as when the test data is generated, it will pass when tested.
An injectable random number generator instance would be a better design and would make testing even easier in cases where the random number source is actually not deterministic.
static methods are an anti-pattern and is the crux of your problem with testing as it stands, there is nothing here that can not be fixed with some simple refactoring to get rid of the static stuff and make it deterministic and testable as my code shows.
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()
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.