Генерация случайных чисел с вектором целых чисел в качестве семени в Java - PullRequest
2 голосов
/ 08 мая 2011

Я хочу сгенерировать воспроизводимые случайные числа, представляющие величины в разных точках трехмерного пространства, например,

double draw = rand(int seed, int x, int y, int z)

Я хочу, чтобы одни и те же входные данные всегда давали одно и то же дро. Я не хочу генерировать все значения заранее, так как их будет слишком много.

Я хочу, чтобы ничьи на разных позициях были независимыми. Я также хочу, чтобы ничьи на одной позиции с разными семенами были независимыми. Это исключает возможность взять сумму или произведение четырех аргументов и использовать это в качестве начального числа.

Ответы [ 4 ]

0 голосов
/ 21 сентября 2014

Класс Случайный использует 48-битное начальное число, которое удобно разделить на три части по 16 бит в каждом, вот так.

0 голосов
/ 08 мая 2011

В Java есть Случайный (long seed) конструктор, но он принимает только одно длинное значение.

Но вам не стоит сильно волноваться, так как вы можете применить (математическую) функцию к вашемувектор и ваше семя, чтобы произвести одно число.Версия для бедняков будет просто добавлять числа:

 Random rand = new Random(seed+x+y+z);

Но, как вы, вероятно, заметили, это не лучший вариант, поскольку он дает одинаковый результат для (1,0,0) и (0,1,0) и (0,0,1).Я уверен, что вместо этого вы можете придумать лучшую функцию, например seed + 31*31*x + 31*y + z или аналогичную.

0 голосов
/ 08 мая 2011

Как отмечено в API setSeed(), java.util.Random использует 48-битовое начальное число. Ваша модель может предложить определение подходящей функции для хэширования ваших трех целых чисел. Кроме того, вы можете расширить java.util.Random с помощью пользовательской реализации.

0 голосов
/ 08 мая 2011

Как насчет

return new Random(seed ^ x ^ y ^ z).nextDouble();

(поскольку аргумент seed для конструктора на самом деле 64-битный, вы могли бы получить лучший «разброс», скажем, сдвигая вверх два ваших целых на 32 бита до xor: ing)


Еще одним простым решением было бы сделать что-то вроде

Random rnd = new Random(seed);
rnd.setSeed(rnd.nextLong() ^ x);
rnd.setSeed(rnd.nextLong() ^ y);
rnd.setSeed(rnd.nextLong() ^ z);
return rnd.nextDouble();
...