重複の可能性:
シードを設定すると、Javaランダムは常に同じ番号を返しますか?
JavaのRandomクラスとnextInt()
メソッドを使用して乱数を取得しています。しかし、数字は常に同じ順序になっているようです。これを修正する方法はありますか?いくつかのランダムジェネレーターがシード値を取り込むことを知っています。次に、シードにシステムタイマーを使用します。
コード:
重複の可能性:
シードを設定すると、Javaランダムは常に同じ番号を返しますか?
JavaのRandomクラスとnextInt()
メソッドを使用して乱数を取得しています。しかし、数字は常に同じ順序になっているようです。これを修正する方法はありますか?いくつかのランダムジェネレーターがシード値を取り込むことを知っています。次に、シードにシステムタイマーを使用します。
コード:
これにより、乱数のevry時間が得られます。
Time t = new Time();
t.setToNow();
mRandom = new Random(t.toMillis(false));
int rand = mRandom.nextInt(10);
Randomオブジェクトを1回だけ作成し(たとえば、アプリケーションのonCreateで)、アプリを起動するたびに比較的ランダムな結果が得られるはずです。
これは、 https://stackoverflow.com/a/11705615/1143977を実際に参照する必要があるものです。参照リンクから私の答えを引用します。
あなたが見るものを引き起こす2つの問題があります。1つ目は、コードがRandomインスタンスのシード値を設定することです。2つ目は、インスタンスメソッドが新しいRandomオブジェクトを「ランダム」にインスタンス化し、そのシードを毎回同じシードですぐに設定することです。これら2つの組み合わせにより、iの値が同じ場合、メソッド「random」は常に同じ値を返し、シードが常に生成するシーケンスの最初になります。
シードの設定が必須であると仮定すると、毎回シーケンスの同じ最初の値ではなく、シーケンスの次の値を取得するために、Randomのrandnumインスタンスは、次のメソッドが呼び出される直前に毎回シードを設定することはできません。これを修正するには、Randomのrandnumローカル変数インスタンスをrandominstanceメソッドのスコープからクラススコープに移動します。次に、ランダムにランダムインスタンスが割り当てられている場合にのみ、またはシードから同じシーケンスの結果を取得して最初からやり直す場合にのみ、シードを設定します。クラスRandomのsetSeed(long seed)インスタンスメソッドはクラススコープで実行できないため、コンストラクターは、longseedパラメーターを指定したRandomコンストラクターを使用して設定する必要があります。次のコードは変更を示しています。
public class RandomDemo { // arbitrary example class name
// lots of class related stuff may be here...
// still inside the class scope...
// private is a good idea unless an external method needs to change it
private Random randnum = new Random(123456789L);
// the seed guarantees it will always produce the same sequence
// of pseudo-random values when the next methods get called
// for unpredicable sequences, use the following constructor instead:
// private Random randnum = new Random();
// lots of code may be here...
// publicly exposed instance method for getting random number
// from a sequence determined by seed 123456789L
// in the range from 0 through i-1
public int randnum(int i) {
// don't set the seed in here, or randnum will return the exact same integer
// for the same value of i on every method call
// nextInt(i) will give the next value from randnum conforming to range i
return randnum.nextInt(i);
} // end randnum
// lots of more code may be here...
} // end class RandDemo
上記は、述べたように、あなたの正確な問題に対する正確な解決策をあなたに与えるでしょう。ただし、必須シードを使用することは、それが何をするかを考えると、珍しいようです。
以下では、ランダム、ランダムのシード、およびシードを提供するための規定がある理由について詳しく説明します。
ランダムには2つのコンストラクタがあります。
Random()
と
Random(long seed)
およびインスタンスメソッド
setSeed(long seed)
これらはすべて、ランダムインスタンスから取得される数列に影響します。インスタンスメソッド、
setSeed(long seed)
Randomオブジェクトを、コンストラクター引数と同じシードでインスタンス化された場合と同じ状態に設定します。シード値の下位48ビットのみが使用されます。
ランダムオブジェクトがシードなしでインスタンス化されている場合、シードはミリ秒単位のシステム時間と同じになります。これにより、2つのランダムオブジェクトが同じミリ秒でインスタンス化されない限り、それらは異なる疑似ランダムシーケンスを生成することが保証されます。シード値の下位48ビットのみが使用されます。これにより、予測できない疑似ランダムシーケンスが発生します。次のメソッドを呼び出すたびにRandomの新しいインスタンスを取得する必要はなく、コンピューティングリソースを無駄にしません。
ランダムのシードパラメータは、繰り返し可能なシーケンスを生成するランダムオブジェクトをインスタンス化できるように提供されています。特定のシードについて、次のメソッドの値のシーケンスは、そのシードが使用されるときは常に同じシーケンスであることが保証されます。これは、結果が予測可能で再現可能でなければならない疑似ランダムシーケンスを使用するソフトウェアをテストする場合に役立ちます。動作中に異なる予測不可能な疑似ランダムシーケンスを作成する場合には役立ちません。
Androidで乱数を生成するには、クラスjava.util.Random
を使用できます。
このクラスjava.util.Random
は、int、long、double、floatなどのさまざまなタイプの疑似乱数を生成するメソッドを提供します。
2つのパブリックコンストラクターをサポートします。
Random()
-初期状態としてミリ秒単位の現在の時刻を使用してランダムジェネレーターを構築します。
Random(long seed)
-指定されたシードを初期状態としてランダムジェネレーターを構築します。
詳細については、次のリンクを参照してください。