Я думаю, что обсуждение в комментариях приняло менее чем полезный оборот. Дэвид прав в том, что невозможно получить целое число uniform без верхней границы, но неясно, хотите ли вы этого. Существуют абсолютно разные способы получения неограниченных случайных целых чисел из асимметричного распределения, где числа ближе к 0 будут более вероятными, чем числа дальше от 0, но никаких целых чисел, даже один с 10000 триллионов цифр, невозможен. (Пока вы не превышаете память Пролога.)
Вот простой генератор. Во-первых, списки случайной длины:
random_length(List) :-
random(P),
( P > 0.25
-> List = [_ | Tail],
random_length(Tail)
; List = [] ).
Примеры:
?- random_length(List).
List = [].
?- random_length(List).
List = [_2004, _2022, _2040, _2058, _2076].
?- random_length(List).
List = [].
?- random_length(List).
List = [_2004, _2022, _2040, _2058].
Далее, списки случайных битов произвольной длины:
random_bit(Bit) :-
random(P),
( P > 0.5
-> Bit = 1
; Bit = 0 ).
random_bits(Bits) :-
random_length(Bits),
maplist(random_bit, Bits).
Примеры:
?- random_bits(Bits).
Bits = [0].
?- random_bits(Bits).
Bits = [1, 0, 1, 1, 0, 0].
?- random_bits(Bits).
Bits = [].
?- random_bits(Bits).
Bits = [0, 0, 0].
И тогда мы можем оценить эти списки битов как число, скажем, используя этот подход:
bits_value([], 0).
bits_value([Bit | Bits], Value) :-
bits_value(Bits, TailValue),
Value is TailValue * 2 + Bit.
Примеры:
?- random_bits(Bits), bits_value(Bits, Value).
Bits = [1, 1, 0],
Value = 3.
?- random_bits(Bits), bits_value(Bits, Value).
Bits = [0, 1, 0],
Value = 2.
?- random_bits(Bits), bits_value(Bits, Value).
Bits = [0, 0, 0, 1, 1, 0],
Value = 24.
?- random_bits(Bits), bits_value(Bits, Value).
Bits = [0, 1],
Value = 2.
?- random_bits(Bits), bits_value(Bits, Value).
Bits = [],
Value = 0.
Эти списки не ограничены по длине, но имеют тенденцию быть короткими, поэтому значения довольно низкие. Мы можем изменить коэффициент 0,25 в random_length
, чтобы сделать более длинные списки более вероятными. Например, с 0,01:
?- random_bits(Bits), bits_value(Bits, Value).
Bits = [0, 0, 0, 0, 0, 0, 1, 0],
Value = 64.
?- random_bits(Bits), bits_value(Bits, Value).
Bits = [0, 1, 0, 1, 1, 1, 0, 0, 0|...],
Value = 137345267061686159418.
?- random_bits(Bits), bits_value(Bits, Value).
Bits = [1, 1, 0, 1, 1, 0, 0, 1, 0|...],
Value = 105607189397659.
?- random_bits(Bits), bits_value(Bits, Value).
Bits = [0, 0, 0, 1, 0, 1, 1],
Value = 104.
Есть много вещей, которые можно изменить в этом, например, списки, содержащие только нули, не очень полезны. Вы можете добавить неявный элемент 1 в такие списки. Вы также можете рассматривать один из битов как бит знака, чтобы разрешить генерацию отрицательных чисел. Вы можете сгенерировать случайные, полностью неограниченные рациональные числа, сгенерировав два случайных целых числа P
и Q
и используя P/Q
в качестве случайного значения. И так далее.
person
Isabelle Newbie
schedule
23.12.2020
random/3
... как сгенерировать равномерно случайное число от 0 до бесконечности? С другой стороны, дляbetween/3
это имеет смысл... этоinf
(но это зависит только от предиката) - person David Tonhofer   schedule 22.12.2020float
) между 0 и 1,0). Вы можете выбрать только до некоторого максимума. - person David Tonhofer   schedule 22.12.2020random/1
, где вы получаете случайное число с плавающей запятой между 0,0 и 1.0 (вероятно, генерируется путем случайной установки битов мантиссы и экспоненты) - person David Tonhofer   schedule 22.12.2020random_real_0_1([X|XS]):- freeze(XS, (random(0,2,X), random_real_0_1(XS))).
является настоящим числом, не так ли? Тогда я могrandom_real_0_1_to_prec(N,Y):- random_real_0_1(X), length(Y,N),append(Y,[_|_],X).
@DavidTonhofer - person Will Ness   schedule 22.12.2020N
бит. Вероятность получения любой из возможных битовых строк N битов подбрасывания честной монеты четко определена (2 ^ -N), но выбор случайного числа от 0 до бесконечности не таков - это выбор любого бесконечного числа битов из этого потока . Мало того, что это запрещено в этой вселенной, вероятность получения любого точного числа равна 0. Может быть, вам очень повезет, и вы нажмете число, которое имеет только 0 с после конечной позиции K. :-) См. также: Книга песка - person David Tonhofer   schedule 22.12.20200
иinf
, но если вы просто не хотите указывать верхний предел, вы можете просто передать случайный интервал через функцию, которая охватывает бесконечный интервал на интервале. Он будет _not_ распределен равномерно. Не очень хороший пример -1/x
, если вы сделаетеrandom(X), Y is floor(1/X).
, большинство чисел будет близко к 1, но без верхнего предела как такового. - person rajashekar   schedule 22.12.2020