7

How to generate an odd Random number between a given range..

For Eg: For range between 1 to 6 .. Random No is 3 or 1 or 5

Method for Generating Random No :

    Random_No = Min + (int)(Math.Random()*((Max-Min)+1))

Refer How do I generate random integers within a specific range in Java?

Method For Generating Odd Random No :

    Random_No = Min + (int)(Math.Random()*((Max-Min)+1))
    if(Random_No%2 ==0)
    {
          if((Max%2)==0)&&Random_No==Max)
          {
              Random_No = Random_No - 1;  
          }
          else{
              Random_No = Random_No +1;
          }
    }

This Function will always convert 2 into 3 and not 1 Can we make this a more random function which can convert 2 sometimes into 3 and sometimes into 1 ??

Community
  • 1
  • 1
Sanket
  • 393
  • 1
  • 3
  • 12

10 Answers10

7

Assuming max is inclusive, I'd suggest the following:

if (Max % 2 == 0) --Max;
if (Min % 2 == 0) ++Min;
Random_No = Min + 2*(int)(Math.random()*((Max-Min)/2+1));

It results in even distribution among all the odd numbers.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
CrazyCasta
  • 26,917
  • 4
  • 45
  • 72
  • 2
    Actually, [romedius](http://stackoverflow.com/users/1637543/romedius) did the clever stuff; I just cleaned up the edit a bit, accidentally but unavoidably getting undue credit. You can see the details of who did what in the revision history (click on the time by the 'edited' label). – Jonathan Leffler Sep 26 '12 at 05:51
  • @CrazyCasta, you do not need the first line where you decrement Max. – rouble Mar 31 '17 at 05:12
  • @CrazyCasta. Great solution. But why we need "if (Min % 2 == 0) ++Min". ? I think we do not need to change the value of Min? – user3369592 Apr 19 '17 at 04:27
2

If you want to include randomness in the direction as well use random number for the same.

  int  randomDirection = Min + (int)(Math.Random()*((Max-Min)+1));
  if(randomDirection%2==0) {  // any condition to switch the direction 
      Random_No = Random_No + 1;  
  } else {
      Random_No = Random_No - 1;  
  }
Bharat Sinha
  • 13,973
  • 6
  • 39
  • 63
1

Instead of generating a random number between 0 and 6, generate one between 0 and 5 and round up to the nearest odd number, that way you'll have a perfect distribution (33% for each possibility (1, 3, 5))

Jonathon Ashworth
  • 1,182
  • 10
  • 20
1

To do so you need to generate a second pseudo-random number to add or substract 1

Random_No = Min + (int)(Math.Random()*((Max-Min)+1))
repartitionNumber =(int)(Math.Random()*((2)) // between 0 and 1
if(Random_No%2 ==0)
{
      if(Random_No+1<=Max && Random_No-1>=Min)
      {
          if(repartitionNumber==0)
              Random_No = Random_No + 1; 
          else
              Random_No = Random_No - 1;  
      }
      else if(Random_No+1<=Max)
          Random_No = Random_No + 1;
      else if (Random_No-1>=Min)
          Random_No = Random_No - 1;
}
Morendo
  • 752
  • 1
  • 4
  • 23
1

I wonder why other answers all use the int cast to generate the random number. Why not generate random integer directly, which is more accurate than real number way?

Random rn = new Random();
if(maximum % 2 == 1) maximum = maximum + 1; // turn right bound to even
if(minimum % 2 == 0) minimum = minimum - 1; // turn left bound to odd
int range = (maximum - minimum + 1) / 2;
int randomNum =  rn.nextInt(range) * 2 + minimum;
chyx
  • 501
  • 2
  • 10
1

To generate an odd number from a integer you can use n * 2 + 1 Really you are generating random numbers and applying a transformation afterwards

int num = min / 2 + random.nextInt((max + 1) / 2 - min / 2);
num = num * 2 + 1;

This will work even if the range is [1,5] [2,5] [2,6] [1,6]

Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
0

Mathematically the numbers will not gain anything by rounding up or down in the last step. Instead the first and the last number have a 50% lower chance to get picked over all the other numbers.

Stick with CrazyCasta's or J.A's solution.

romedius
  • 775
  • 6
  • 20
0

How about checking the return from Math.random() as a floating number. If its int part is an even number, then convert up/down based on its floating part. Like:

assume Math.random() returned x.y; if x is even, return (y>=0.5)?(x+1):(x-1)

Will this randomized a little?

Michael Chen
  • 5,438
  • 3
  • 15
  • 9
  • I guess thats what my question is... I want equal probability for all the numbers ranging from x to y – Sanket Sep 26 '12 at 06:00
0

Let the rouding above or below depend on a random epsilon.

    Random_No = Min + (int)(Math.Random()*((Max-Min)+1))
    if(Random_No%2 ==0)
    {

          if((Max%2)==0)&&Random_No==Max)
          {
              Random_No = Random_No - 1;  
          }
          else{
              epsilon = Math.Random();
              if(epsilon > 0.5)
                  Random_No = Random_No + 1;
              else
                  Random_No = Random_No - 1;
          }
    }
kiriloff
  • 25,609
  • 37
  • 148
  • 229
0

In Java 1.7 or later, I would use ThreadLocalRandom:

import java.util.concurrent.ThreadLocalRandom;

// Get odd random number within range [min, max]
// Start with an odd minimum and add random even number from the remaining range
public static int randOddInt(int min, int max) {
    if (min % 2 == 0) ++min;
    return min + 2*ThreadLocalRandom.current().nextInt((max-min)/2+1);
}

// Get even random number within range [min, max]
// Start with an even minimum and add random even number from the remaining range
public static int randEvenInt(int min, int max) {
    if (min % 2 != 0) ++min;
    return min + 2*ThreadLocalRandom.current().nextInt((max-min)/2+1);
}

The reason to use ThreadLocalRandom is explained here. Also note that the reason we +1 to the input to ThreadLocalRandom.nextInt() is to make sure the max is included in the range.

Community
  • 1
  • 1
rouble
  • 16,364
  • 16
  • 107
  • 102