【问题标题】:Generating an Odd Random Number between a given Range在给定范围之间生成奇数随机数
【发布时间】:2026-01-17 03:45:01
【问题描述】:

如何在给定范围内生成奇数随机数..

例如:对于 1 到 6 之间的范围 .. 随机数是 3 或 1 或 5

随机数生成方法:

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

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

奇随机数生成方法:

    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;
          }
    }

此函数将始终将 2 转换为 3 而不是 1 我们能不能把它变成一个更随机的函数,它可以将 2 有时转换为 3,有时转换为 1 ??

【问题讨论】:

  • 另一种方法是生成一个从 0 到 2 ((6-1)/2) 的数字,然后加倍然后递增结果。很容易将其推广到以任何数字开头的范围。

标签: java math random


【解决方案1】:

假设 max 包含在内,我建议如下:

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

它导致所有奇数之间的分布均匀。

【讨论】:

  • 实际上,romedius 做得很聪明;我只是稍微清理了一下编辑,意外但不可避免地获得了不应有的荣誉。您可以在修订历史记录中查看谁做了什么的详细信息(单击“已编辑”标签旁的时间)。
  • @CrazyCasta,你不需要减少 Max 的第一行。
  • @CrazyCasta。很好的解决方案。但是为什么我们需要“if (Min % 2 == 0) ++Min”。 ?我认为我们不需要更改 Min 的值?
【解决方案2】:

如果您还想在方向中包含随机性,请使用随机数。

  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;  
  }

【讨论】:

    【解决方案3】:

    生成一个介于 0 和 6 之间的随机数,而不是生成一个介于 0 和 5 之间的随机数,然后四舍五入到最接近的奇数,这样您将获得一个完美的分布(每种可能性 33%(1、3、5 ))

    【讨论】:

      【解决方案4】:

      为此,您需要生成第二个伪随机数来加或减 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;
      }
      

      【讨论】:

        【解决方案5】:

        我想知道为什么其他答案都使用 int cast 来生成随机数。为什么不直接生成随机整数,比实数方式更准确?

        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;
        

        【讨论】:

          【解决方案6】:

          要从整数生成奇数,您可以使用 n * 2 + 1 实际上,您正在生成随机数并在之后应用转换

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

          即使范围是 [1,5] [2,5] [2,6] [1,6] 也可以使用

          【讨论】:

            【解决方案7】:

            从数学上讲,在最后一步中,通过向上或向下舍入,数字不会获得任何收益。取而代之的是,第一个和最后一个数字被选中的几率比其他所有数字低 50%。

            坚持使用 CrazyCasta 或 J.A 的解决方案。

            【讨论】:

              【解决方案8】:

              如何将 Math.random() 的返回值检查为浮点数。如果它的 int 部分是偶数,则根据它的浮动部分向上/向下转换。喜欢:

              假设 Math.random() 返回 x.y;如果 x 是偶数,则返回 (y>=0.5)?(x+1):(x-1)

              这会随机一些吗?

              【讨论】:

              • 我想这就是我的问题...我希望从 x 到 y 的所有数字的概率相等
              【解决方案9】:

              让上面或下面的路由取决于一个随机的 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;
                        }
                  }
              

              【讨论】:

                【解决方案10】:

                在 Java 1.7 或更高版本中,我会使用 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);
                }
                

                here 解释了使用 ThreadLocalRandom 的原因。另请注意,我们对 ThreadLocalRandom.nextInt() 的输入 +1 的原因是确保最大值包含在范围内。

                【讨论】: