I understand how to make a random number which is between two numbers:
1 + (int)(Math.random() * ((10 - 1) + 1))
or
min + (int)(Math.random() * ((max - min) + 1))
But how do I go about generating a random number which falls into multiple ranges?
For example: number can be between 1 to 10 or between 50 to 60
6 Answers 6
I'd go with something like this, to allow you to do it with as many ranges as you like:
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
class RandomInRanges
{
private final List<Integer> range = new ArrayList<>();
RandomInRanges(int min, int max)
{
this.addRange(min, max);
}
final void addRange(int min, int max)
{
for(int i = min; i <= max; i++)
{
this.range.add(i);
}
}
int getRandom()
{
return this.range.get(new Random().nextInt(this.range.size()));
}
public static void main(String[] args)
{
RandomInRanges rir = new RandomInRanges(1, 10);
rir.addRange(50, 60);
System.out.println(rir.getRandom());
}
}
3 Comments
First generate an integer between 1 and 20. Then if the value is above 10, map to the second interval.
Random random = new Random();
for (int i=0;i<100;i++) {
int r = 1 + random.nextInt(60-50+10-1);
if (r>10) r+=(50-10);
System.out.println(r);
}
Comments
First, you need to know how many numbers are in each range. (I'm assuming you are choosing integers from a discrete range, not real values from a continuous range.) In your example, there are 10 integers in the first range, and 11 in the second. This means that 10/21 times, you should choose from the first range, and 11/21 times choose from the second. In pseudo-code
x = random(1,21)
if x in 1..10
return random(1,10)
else
return random(50,60)
1 Comment
if the list is known I think you can use something like this.
public class Test
{
public static void main(String[] args)
{
int a;
for(int i=0;i<10;i++)
{
a=(int) (Math.random()*((10-0)+(60-50)));
if(a<=10)
{
}
else if(a>(60-50))
{
a=a+50;
}
System.out.println(a);
}
}
}
Comments
How about the following approach: randomize picking a range an use that range to generage your random number, for that you'll have to put your ranges in some list or array
public class RandomRangeGenerator {
class Range {
public int min, max;
public Range(int min, int max) { this.min = min; this.max = max; }
}
@Test
public void generate() {
List<Range> ranges = new ArrayList<>();
ranges.add(new Range(1, 10));
ranges.add(new Range(50, 60));
List<Integer> randomNumbers = generateRandomNumbers(ranges, 10);
System.out.println(randomNumbers.toString());
for(Integer i : randomNumbers) {
Assert.assertTrue((i >= 1 && i <= 10) || (i >= 50 && i <= 60));
}
}
private List<Integer> generateRandomNumbers(List<Range> ranges, int numberOfNumbers) {
List<Integer> randomNumbers = new ArrayList<>(numberOfNumbers+1);
while(numberOfNumbers-- > 0) {
Range range = ranges.get(new Random().nextInt(ranges.size()));
randomNumbers.add(range.min + (int)(Math.random() * ((range.max - range.min) + 1)));
}
return randomNumbers;
}
}
Comments
To generate numbers between two ranges add up the total number of possibilities. 1 - 10 gives us 10 and 50 - 60 gives us another 11, so 21 total. Then, generate a random number between 1 - 21.
int rn = (int)(1 + (Math.random() * 21));
If the random number is between 1 and 10, that is easy, you have your number. If it is between 11 - 21, then you have to do some work. First, you can use modulus to get the index of the number between 50 - 60. Since you have 11 possible values in that range, then mod the random number by 11 and add 50.
if (rn > 10) {
rn %= 11;
rn += 50;
}
System.out.println(rn);
This will print values between 1 - 10 and 50 - 60 inclusive.