How to change probability of random numbers - java

First of all, I did a search on this topic but I could not found anything similar to what I'm trying to accomplished, so this could be a duplicate question.
I would like to have a function that returns a number (1 or 2) with a probability of 0.8% for the number one and 0.2% for the number two.
How can I do it?

Generate a random number between 0 and 1. If the number is between 0 and 0.8, return 1. else, return 2:
return rnd.nextFloat() < 0.8 ? 1 : 2;

You just make intervals, and if your random number fits in the interval, you have a hit. In this most simple example, you make intervals 1-4 and 5. So you fetch random number from 1 to 5. if it's a 1-4 (80% probability) you act as it's 1, and if it's 5 (20% probability) you act as it's 2.

For example, make an array of 100 numbers. 20 numbers with number two, and 80 numbers with number one.
Use the Random class to generate a number between 0 and 100. Then you use that number to get the result from the array.
This is just an example, you can use another values in the array.

Related

About getting random values between fixed range in java

the thing I wanted to know is that. Example: I want range of number from 1 to 10. and how to call a random number between the range from 1 to 10 automatically. Not using switches cases or if else statements. Any Idea ?

java.util.Random digging a bit deep

I was reading Data Structures and Algorithms in Java book and I came across the following question that I would like to get help with:
Suppose you are given an array, A, containing 100 integers that were generated using the method r.nextInt(10), where r is an object of type java.util.Random. Let x denote the product of the integers in A. There is a single number that x will equal with probability at least 0.99. What is that number and what is a formula describing the probability that x is equal to that number?
I think x is equal to zero; as most probably 0 will be generated. However, that's just a guess. I wasn't able to find the formula. The java documentation doesn't specify the randomization equation and I wasn't able to find any related topics either here or after searching using Google.
I would like to get some help with the probability formula please. Thanks in advance.
The possible values for the array elements are 0 .. 9, each with probability 1/10. If one of the elements is 0, the product will be 0 as well. So we calculate the probability that at least one element is 0.
It turns out, this is the opposite of all elements being greater than zero. The probability for an element to be greater than 0 is 9/10, and the probability that all elements are greater than zero is therefore (9/10)^100.
The probability that at least one element is 0 is therefore 1 - (9/10)^100 which is approximately 0.9999734.
Regarding nextInt: The javadoc specifies:
uniformly distributed int value between 0 (inclusive) and the
specified value (exclusive)
a "uniform distribution" is a distribution where each outcome is equally likely.
hence the chances for a particular outcome are "1/[number of possible outcomes]" (so they all add up to 1).
Regarding the array:
Filling the array can be regarded as observing 100 statistically independent events.
You should read up, on how the maths work when combining multiple independent events.
https://docs.oracle.com/javase/7/docs/api/java/util/Random.html#nextInt(int)
As you already expect, it will of be 0
r.nextInt(10)
will return numbers from 0 to 9
The product of any 0 * 1-9 will be 0, therefore for 100 random numbers, the chance that no 0 will be returned from this function is pretty low.

Weighed Number Generator

I've been searching for, and found similar topics, but cannot understand them or work out how to apply them.
Simple: all I want is to generate a number between 1 and 100:
Numbers 1 to 30 should have a 60% probability.
Numbers 31 to 60 should have a 35% probability.
Numbers 61 to 100 should have a 5% probability.
Get numbers in your ranges
First generate 3 random numbers in your 3 intervals.
1: 1-30
2: 31-60
3: 61-100
Generate the probability number
Next, generate a number 1-100. If the number is 1-60 choose the first random number from the first step if it is 61-95 do the second option and if it is 96-100 chose the third.
This sounds like a homework problem so I will not provide the code, but here is a description of a simple algorithm:
Generate a random number between 1 and 100. Lets call this X. X will be used to determine how to generate your final result:
If X is between 1 and 60, generate a random number between 1 and 30 to be your final result.
If X is between 61 and 95, generate a random number between 31 and 60 to be your final result.
If X is between 96 and 100, generate a random number between 61 and 100 to be your final result.
You can see that this requires two random number generations for every weighted number that you want. It can actually be simplified into a single random number generation, and that is left as an exercise for you.
FYI, how to generate a random number within a range is found here: How do I generate random integers within a specific range in Java?
Simplest way for me would be to generate four randoms. The first would be a number 1-100. The second would be a number 1-30, the third would be a number 31-60, and the fourth would be a number 61-100. Think of the first random as a percent. If it is 1-60 you then move on to run the second random, if it is 60-95 run the third random, and if it is 95-100 run the fourth random. There are other ways to make it shorter, but in my opinion this is easiest to comprehend.
Create random number 1-100 with this: (int)(Math.random()*100)+1
The rest should just be conditionals.

Is the 0/1 knapsack algorithm a suitable candidate here?

I have three categories of input , each with a impact range.
Cat 1 : 20 - 16
Cat 2 : 15 - 5
Cat 3 : 4 -1
I have a file with say N randomly generated categories.
I am trying to take a sum of impact for all the 100 entries through a logic that looks something like this :
// calculate sum of impacts
getSum(){
Generate a random class with seed as current system execution time
for(as many entries in file){
switch(category)
case 1 : i = random input between 20 - 16
case 2 : i = random input between 15 - 5
case 3 : i = random input between 4 - 1
some default case here
sum = sum + i
}
return sum
}
.
.
// loop until you get a desired sum
while(true){
if(Call to getSum() returns value within a desired range){
display some statistics;
break;
}
}
However , i see that the program generally runs infinitely , as the random generation and subsequent summation is giving result beyond the desired range. So , to get things in range , I have to manually tune the max-min ranges for each execution.
Can someone suggest an algorithm that will automatically vary the max min ranges for each category , by learning the trend of obtained sum as the program is running , so as to quickly give a solution ?
Edit : i have just read about the 0/1 knapsack algorithm.. and it seems promising , but unsure if that is the algorithm for this case. Any help would be great.
A couple band-aids:
1) use a long int instead of a regular int t give you a longer range.
2) use an unsigned long, since all of your relevant numbers are positive (then be careful of underflow errors when you subtract.
A couple possible strategies:
1) (This contradicts your question, but it is how things are usually done.) Determine the static maximum for each category, and design to it, using long unsigned int if that is large enough, or some larger data structure as necessary.
2) (This is exactly what you are asking.) Use, and build if necessary, a data structure which expands when an overflow occurs.
Solution for strategy 2:
I will get back to you on this. :)

Generate N random numbers in given ranges that sum up to a given sum

first time here at Stackoverflow. I hope someone can help me with my search of an algorithm.
I need to generate N random numbers in given Ranges that sum up to a given sum!
For example: Generatare 3 Numbers that sum up to 11.
Ranges:
Value between 1 and 3.
Value between 5 and 8.
value between 3 and 7.
The Generated numbers for this examle could be: 2, 5, 4.
I already searched alot and couldnt find the solution i need.
It is possible to generate like N Numbers of a constant sum unsing modulo like this:
generate random numbers of which the sum is constant
But i couldnt get that done with ranges.
Or by generating N random values, sum them up and then divide the constant sum by the random sum and afterwards multiplying each random number with that quotient as proposed here.
Main Problem, why i cant adopt those solution is that every of my random values has different ranges and i need the values to be uniformly distributed withing the ranges (no frequency occurances at min/max for example, which happens if i cut off the values which are less/greater than min/max).
I also thought of an soultion, taking a random number (in that Example, Value 1,2 or 3), generate the value within the range (either between min/max or min and the rest of the sum, depending on which is smaller), substracting that number of my given sum, and keep that going until everything is distributed. But that would be horrible inefficiant. I could really use a way where the runtime of the algorithm is fixed.
I'm trying to get that running in Java. But that Info is not that importend, except if someone already has a solution ready. All i need is a description or and idea of an algorithm.
First, note that the problem is equivalent to:
Generate k numbers that sums to a number y, such that x_1, ..., x_k -
each has a limit.
The second can be achieved by simply reducing the lower bound from the number - so in your example, it is equivalent to:
Generate 3 numbers such that x1 <= 2; x2 <= 3; x3 <= 4; x1+x2+x3 = 2
Note that the 2nd problem can be solved in various ways, one of them is:
Generate a list with h_i repeats per element - where h_i is the limit for element i - shuffle the list, and pick the first elements.
In your example, the list is:[x1,x1,x2,x2,x2,x3,x3,x3,x3] - shuffle it and choose first two elements.
(*) Note that shuffling the list can be done using fisher-yates algorithm. (you can abort the algorithm in the middle after you passed the desired limit).
Add up the minimum values. In this case 1 + 5 + 3 = 9
11 - 9 = 2, so you have to distribute 2 between the three numbers (eg: +2,+0,+0 or +0,+1,+1).
I leave the rest for you, it's relatively easy to create a uniform distribution after this transformation.
This problem is equivalent to randomly distributing an excess of 2 over the minimum of 9 on 3 positions.
So you start with the minima (1/5/3) and then cycle 2 times, generating a (pseudo-)random value of [0-2] (3 positions) and increment the indexed value.
e.g.
Start 1/5/3
1st random=1 ... increment index 1 ... 1/6/3
2nd random=0 ... increment index 0 ... 2/6/3
2+6+3=11
Edit
Reading this a second time, I understand, this is exactly what #KarolyHorvath mentioned.

Categories

Resources