Javaの特定の範囲内の乱数を生成するにはどうすればよいですか?


Answers

このアプローチは、 nextIntアプローチ( https://stackoverflow.com/a/738651/360211よりも偏っており効率が低いことに注意してhttps://stackoverflow.com/a/738651/360211

これを達成するための1つの標準パターンは次のとおりです。

Min + (int)(Math.random() * ((Max - Min) + 1))

Java Mathライブラリ関数Math.random()は、 [0,1)の範囲でdouble値を生成します。 この範囲には1が含まれていないことに注意してください。

最初に特定の範囲の値を取得するには、対象とする値の範囲の大きさを掛ける必要があります。

Math.random() * ( Max - Min )

これは[0,Max-Min)の範囲の値を返します。ここで 'Max-Min'は含まれません。

たとえば、 [5,10]が必要な場合は、5つの整数値をカバーする必要があります

Math.random() * 5

これは、範囲が[0,5)値を返します。ここでは5は含まれません。

今度は、この範囲をあなたが目標とする範囲にシフトする必要があります。 これを行うには、最小値を追加します。

Min + (Math.random() * (Max - Min))

[Min,Max)の範囲の値が得られます。 私たちの例に従えば、それは[5,10)を意味します:

5 + (Math.random() * (10 - 5))

しかし、これはまだMaxを含んでおらず、あなたは二重価値を得ています。 Max値を取得するには、範囲パラメータ(Max - Min) 1を加え、intにキャストして小数部分を切り捨てる必要があります。 これは次の方法で達成されます。

Min + (int)(Math.random() * ((Max - Min) + 1))

そしてそこにあなたはそれを持っています。 [Min,Max] 、または例[5,10]の範囲のランダムな整数値です。

5 + (int)(Math.random() * ((10 - 5) + 1))
Question

特定の範囲でランダムなint値を生成するにはどうすればよいですか?

私は以下を試しましたが、それらはうまくいきません:

試行1:

randomNum = minimum + (int)(Math.random() * maximum);
// Bug: `randomNum` can be bigger than `maximum`.

試行2:

Random rn = new Random();
int n = maximum - minimum + 1;
int i = rn.nextInt() % n;
randomNum =  minimum + i;
// Bug: `randomNum` can be smaller than `minimum`.



ランダムではなくSecureRandomを使用する方が良いでしょう。

public static int generateRandomInteger(int min, int max) {
    SecureRandom rand = new SecureRandom();
    rand.setSeed(new Date().getTime());
    int randomNum = rand.nextInt((max - min) + 1) + min;
    return randomNum;
}



私が慎重であることを許してください。しかし、大多数が提案した解決策、すなわちmin + rng.nextInt(max - min + 1))

  • rng.nextInt(n)Integer.MAX_VALUE到達できません。
  • (max - min)は、 minが負の場合にオーバーフローを引き起こす可能性があります。

簡単な解決法は、[ Integer.MIN_VALUEInteger.MAX_VALUE ]内の任意のmin <= maxに対して正しい結果を返すでしょう。 以下の単純な実装を考えてみましょう。

int nextIntInRange(int min, int max, Random rng) {
   if (min > max) {
      throw new IllegalArgumentException("Cannot draw random int from invalid range [" + min + ", " + max + "].");
   }
   int diff = max - min;
   if (diff >= 0 && diff != Integer.MAX_VALUE) {
      return (min + rng.nextInt(diff + 1));
   }
   int i;
   do {
      i = rng.nextInt();
   } while (i < min || i > max);
   return i;
}

非効率的ですが、 whileループの成功確率は常に50%以上になることに注意してください。




ただRandomクラスを使用してください:

Random ran = new Random();
// Assumes max and min are non-negative.
int randomInt = min + ran.nextInt(max - min + 1);



import java.util.Random; 

public class RandomUtil {
    // Declare as class variable so that it is not re-seeded every call
    private static Random random = new Random();

    /**
     * Returns a psuedo-random number between min and max (both inclusive)
     * @param min Minimim value
     * @param max Maximim value. Must be greater than min.
     * @return Integer between min and max (both inclusive)
     * @see java.util.Random#nextInt(int)
     */
    public static int nextInt(int min, int max) {
        // nextInt is normally exclusive of the top value,
        // so add 1 to make it inclusive
        return random.nextInt((max - min) + 1) + min;
    }
}



マルチスレッド環境の場合はjava.util.Randomクラスに相当するThreadLocalRandom 乱数の生成は、各スレッドでローカルに実行されます。 だから私たちは競合を減らしてより良いパフォーマンスを得ています。

int rand = ThreadLocalRandom.current().nextInt(x,y);

x、y - 間隔(例えば、1,10)




このメソッドは便利です:

このメソッドは、指定さた最小値と最大値のの乱数を返します。

public static int getRandomNumberBetween(int min, int max) {
    Random foo = new Random();
    int randomNumber = foo.nextInt(max - min) + min;
    if (randomNumber == min) {
        // Since the random number is between the min and max values, simply add 1
        return min + 1;
    } else {
        return randomNumber;
    }
}

このメソッドは指定さた最小値と最大値から乱数を返します(生成された数値も最小値または最大値になる可能性があります)。

public static int getRandomNumberFrom(int min, int max) {
    Random foo = new Random();
    int randomNumber = foo.nextInt((max + 1) - min) + min;

    return randomNumber;
}



nextint(n)メソッドを使用してminとmaxの差の乱数を生成し、minの数値を結果に追加します。

Random rn = new Random();
int result = rn.nextInt(max - min + 1) + min;
System.out.println(result);



つかいます:

minimum + rn.nextInt(maxValue - minvalue + 1)



あなたはJava 8でそれを簡潔に達成することができます:

Random random = new Random();

int max = 10;
int min = 5;
int totalNumber = 10;

IntStream stream = random.ints(totalNumber, min, max);
stream.forEach(System.out::println);



2番目のコード例は、次のように編集できます。

Random rn = new Random();
int range = maximum - minimum + 1;
int randomNum =  rn.nextInt(range) + minimum;



public static Random RANDOM = new Random(System.nanoTime());

public static final float random(final float pMin, final float pMax) {
    return pMin + RANDOM.nextFloat() * (pMax - pMin);
}



int random = minimum + Double.valueOf(Math.random()*(maximum-minimun)).intValue();

あるいは、 Apache Commonsの RandomUtilsを見てください。




rand.nextInt((max+1) - min) + min;

これはうまくいきます。




 rand.nextInt((max+1) - min) + min;



Links