(I don't know Scala so the following code is in Java)
MersenneTwister rng = new MersenneTwister();
rng.setSeed(new int[] {
1234567890
});
System.out.println(rng.nextInt(Integer.MAX_VALUE)); // 1977150888
Note: If you seed with a string, random.seed()
changed between Python 2 and 3. The pythonStringHash
function here is compatible with the Python 2 version, or in Python 3, random.seed(s, version=1)
.
private static long pythonStringHash(String s) {
char[] chars = s.toCharArray();
long x;
if (s.isEmpty()) {
x = 0;
} else {
x = chars[0] << 7;
}
for (char c: chars) {
x = ((1000003 * x) ^ c);
}
x ^= chars.length;
if (x == -1) {
return -2;
}
return x;
}
private static void pythonSeed(MersenneTwister random, long seed) {
int[] intArray;
if (Long.numberOfLeadingZeros(seed) >= 32) {
intArray = new int[] {
(int) seed
};
} else {
intArray = new int[] {
(int) seed, (int)(seed >> 32)
};
}
random.setSeed(intArray);
}
public static RandomGenerator pythonSeededRandom(String seed) {
MersenneTwister random = new MersenneTwister();
pythonSeed(random, pythonStringHash(seed));
return random;
}
This generator is described in a paper by Makoto Matsumoto and Takuji Nishimura in 1998: Mersenne Twister: A 623-Dimensionally Equidistributed Uniform Pseudo-Random Number Generator, ACM Transactions on Modeling and Computer Simulation, Vol. 8, No. 1, January 1998, pp 3--30,This class is mainly a Java port of the 2002-01-26 version of the generator written in C by Makoto Matsumoto and Takuji Nishimura. Here is their original copyright:,This generator features an extremely long period (219937-1) and 623-dimensional equidistribution up to 32 bits accuracy. The home page for this generator is located at http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html.,Loader (org.hibernate.loader)Abstract superclass of object loading (and querying) strategies. This class implements useful common
/**
* Create an object that will use a default RNG ({@link MersenneTwister}),
* in order to generate the individual components.
*
* @param dimension Space dimension.
*/
public UnitSphereRandomVectorGenerator(final int dimension) {
this(dimension, new MersenneTwister());
}
@Override
public MersenneTwister generator() {
MersenneTwister random = new MersenneTwister();
random.setSeed(seed);
return random;
}
}
public void randomize () {
for (TIntObjectIterator<int[]> it = offsets.iterator(); it.hasNext();) {
it.advance();
int[] newVal = new int[it.value().length];
RaptorWorkerTimetable tt = data.timetablesForPattern.get(it.key());
for (int i = 0; i < newVal.length; i++) {
newVal[i] = mt.nextInt(tt.headwaySecs[i]);
}
it.setValue(newVal);
}
}
}
setSeed(System.currentTimeMillis() + System.identityHashCode(this));
return;
setSeed(19650218);
int i = 1;
int j = 0;
clear(); // Clear normal deviate cache
public static void main(String...args) {
System.out.println("Testing histogram store with normal distribution, mean 0");
Histogram h = new Histogram("Normal");
MersenneTwister mt = new MersenneTwister();
IntStream.range(0, 1000000).map(i - > (int) Math.round(mt.nextGaussian() * 20 + 2.5)).forEach(h::add);
h.displayHorizontal();
System.out.println("mean: " + h.mean());
}
}
@Override
public RandomGenerator sharedInstance(Class < ? > clazz) {
stateCheck();
if (!classRngMap.containsKey(clazz)) {
final RandomGenerator rng = new UnmodifiableRandomGenerator(
new MersenneTwister(masterRandomGenerator.nextLong()));
classRngMap.put(clazz, rng);
return rng;
}
return classRngMap.get(clazz);
}
}
Let’s use MT both in Java and python, and compare the results. First, take a look at the Java example code:,However, It seems that the number representation in NumPy and Java are different, therefore it is not enough to get the same random bits.,Is there any option to generate identical random numbers in Java like in Numpy random, when using same seed (e.g. 12345).,I am comparing outputs of some methods in SciKit learn and my own library in Java. In order to generate same outputs I need to generate same randoms like Numpy does (SciKit learn uses Numpy random).
from numpy.random
import RandomState
rs = RandomState(12345)
rs.random()
import java.util.Random;
Random random = new Random(12345);
System.out.println(random.nextDouble());
import org.apache.commons.math3.random.RandomGenerator;
import org.apache.commons.math3.random.MersenneTwister;
class QuickStart {
public static void main(String[] args) {
RandomGenerator prng = new MersenneTwister(0);
for (int i = 0; i < 3; ++i) {
long num = prng.nextLong();
System.out.println(Long.toString(num) + "t" + Long.toBinaryString(num));
}
System.out.println();
for (int i = 0; i < 3; ++i) {
int num = prng.nextInt();
System.out.println(Integer.toString(num) + "t" + Integer.toBinaryString(num));
}
System.out.println();
for (int i = 0; i < 3; ++i) {
double num = prng.nextDouble();
System.out.println(Double.toString(num) + "t" + Long.toBinaryString(Double.doubleToRawLongBits(num)));
}
}
}
-8322921849960486353 1000110001111111000010101010110010010111110001001010101000101111 - 5253828890213626688 1011011100010110101001100111010111011000001000011100110011000000 - 7327722439656189189 1001101001001110101100110100001111011011101000100101001011111011 - 1954711869 10001011011111010111011011000011 - 656048793 11011000111001010111110101100111 1819583497 1101100011101001010010000001001 0.6235637015982585 11111111100011111101000011101111011101001010101100101010001000 0.38438170310239794 11111111011000100110011011010110110111000000000101101101110000 0.2975346131886989 11111111010011000010101100111010011110010001001011001111000100
import numpy
import bitstring
numpy.random.seed(0)
for i in range(3):
state = numpy.random.get_state()
num = numpy.random.randint(0, 2 ** 64, dtype = numpy.uint64)
print(num, bin(num), sep = "t")
print()
for i in range(3):
state = numpy.random.get_state()
num = numpy.random.randint(0, 2 ** 32, dtype = numpy.uint32)
print(num, bin(num), sep = "t")
print()
for i in range(3):
state = numpy.random.get_state()
num = numpy.random.random()
f1 = bitstring.BitArray(float = num, length = 64)
print(num, f1.bin, sep = "t")
10123822223749065263 0b1000110001111111000010101010110010010111110001001010101000101111 13192915183495924928 0b1011011100010110101001100111010111011000001000011100110011000000 11119021634053362427 0b1001101001001110101100110100001111011011101000100101001011111011 2340255427 0b10001011011111010111011011000011 3638918503 0b11011000111001010111110101100111 1819583497 0b1101100011101001010010000001001 0.6235636967859723 0011111111100011111101000011101111011010100101010110010101000100 0.3843817072926998 0011111111011000100110011011010110111011100000000010110110111000 0.2975346065444723 0011111111010011000010101100111010010111001000100101100111100010
Как я уже писал в комментариях, основной алгоритм для получения следующего целого числа между Python и Apache Math (исходный код здесь, здесь, и здесь). Трассировка через код кажется, что основное различие заключается в том, как две версии засевают генератор. Версия Python преобразует данное семя в массив и семя из массива, в то время как версия Apache Math имеет отдельный алгоритм для посева из одного числа. Таким образом, чтобы метод Apache Math nextInt(...) действовал в качестве метода Python randrange(...), вы должны использовать версию Apache Math с массивом.,Apache Commons Math, по-видимому, использует целое число как базовый источник случайности, хотя я не совсем уверен, как он его извлекает, а Python использует double, сгенерированный версией C алгоритма., 1 Вы также пробовали Кольт, чтобы увидеть разницу между этими реализациями? Кроме того, поскольку это генератор случайных чисел (если я не понял неправильно), почему значения не должны отличаться? user3813256 04 авг. 2014, в 21:04 , На случай, если кому-то понадобится это сделать, я разработал рабочую версию, основанную на реализации CPython.
В Python:
SEED = 1234567890 PRIMARY_RNG = random.Random() PRIMARY_RNG.seed(SEED) n = PRIMARY_RNG.randrange((2 ** 31) - 1) #1977150888
В Scala:
val Seed = 1234567890
val PrimaryRNG = new MersenneTwister(Seed)
val n = PrimaryRNG.nextInt(Int.MaxValue) //1328851649
MersenneTwister rng = new MersenneTwister();
rng.setSeed(new int[] {
1234567890
});
System.out.println(rng.nextInt(Integer.MAX_VALUE)); // 1977150888
Примечание: если вы random.seed()
строку, random.seed()
изменяется между Python 2 и 3. pythonStringHash
функция pythonStringHash
совместима с версией Python 2, или в Python 3 - random.seed(s, version=1)
.
private static long pythonStringHash(String s) {
char[] chars = s.toCharArray();
long x;
if (s.isEmpty()) {
x = 0;
} else {
x = chars[0] << 7;
}
for (char c: chars) {
x = ((1000003 * x) ^ c);
}
x ^= chars.length;
if (x == -1) {
return -2;
}
return x;
}
private static void pythonSeed(MersenneTwister random, long seed) {
int[] intArray;
if (Long.numberOfLeadingZeros(seed) >= 32) {
intArray = new int[] {
(int) seed
};
} else {
intArray = new int[] {
(int) seed, (int)(seed >> 32)
};
}
random.setSeed(intArray);
}
public static RandomGenerator pythonSeededRandom(String seed) {
MersenneTwister random = new MersenneTwister();
pythonSeed(random, pythonStringHash(seed));
return random;
}
Let's use MT both in Java and python, anycodings_numpy and compare the results. First, take a anycodings_numpy look at the Java example code:,Is there any option to generate identical anycodings_numpy random numbers in Java like in Numpy random, anycodings_numpy when using same seed (e.g. 12345).,However, It seems that the number anycodings_numpy representation in NumPy and Java are anycodings_numpy different, therefore it is not enough to anycodings_numpy get the same random bits.,I am comparing outputs of some methods in anycodings_numpy SciKit learn and my own library in Java. In anycodings_numpy order to generate same outputs I need to anycodings_numpy generate same randoms like Numpy does anycodings_numpy (SciKit learn uses Numpy random).
In Numpy I get for code below output: anycodings_numpy 0.9296160928171479
from numpy.random
import RandomState
rs = RandomState(12345)
rs.random()
In Java I get for code below output: anycodings_numpy 0.3618031071604718
import java.util.Random;
Random random = new Random(12345);
System.out.println(random.nextDouble());
Let's use MT both in Java and python, anycodings_numpy and compare the results. First, take a anycodings_numpy look at the Java example code:
import org.apache.commons.math3.random.RandomGenerator;
import org.apache.commons.math3.random.MersenneTwister;
class QuickStart {
public static void main(String[] args) {
RandomGenerator prng = new MersenneTwister(0);
for (int i = 0; i < 3; ++i) {
long num = prng.nextLong();
System.out.println(Long.toString(num) + "\t" + Long.toBinaryString(num));
}
System.out.println();
for (int i = 0; i < 3; ++i) {
int num = prng.nextInt();
System.out.println(Integer.toString(num) + "\t" + Integer.toBinaryString(num));
}
System.out.println();
for (int i = 0; i < 3; ++i) {
double num = prng.nextDouble();
System.out.println(Double.toString(num) + "\t" + Long.toBinaryString(Double.doubleToRawLongBits(num)));
}
}
}
This produces the output
-8322921849960486353 1000110001111111000010101010110010010111110001001010101000101111 - 5253828890213626688 1011011100010110101001100111010111011000001000011100110011000000 - 7327722439656189189 1001101001001110101100110100001111011011101000100101001011111011 - 1954711869 10001011011111010111011011000011 - 656048793 11011000111001010111110101100111 1819583497 1101100011101001010010000001001 0.6235637015982585 11111111100011111101000011101111011101001010101100101010001000 0.38438170310239794 11111111011000100110011011010110110111000000000101101101110000 0.2975346131886989 11111111010011000010101100111010011110010001001011001111000100
Whereas the python example is:
import numpy
import bitstring
numpy.random.seed(0)
for i in range(3):
state = numpy.random.get_state()
num = numpy.random.randint(0, 2 ** 64, dtype = numpy.uint64)
print(num, bin(num), sep = "\t")
print()
for i in range(3):
state = numpy.random.get_state()
num = numpy.random.randint(0, 2 ** 32, dtype = numpy.uint32)
print(num, bin(num), sep = "\t")
print()
for i in range(3):
state = numpy.random.get_state()
num = numpy.random.random()
f1 = bitstring.BitArray(float = num, length = 64)
print(num, f1.bin, sep = "\t")