Я не нашел ничего полезного в library(random)
.
Вот моя реализация choice(Xs, Ps, Y)
:
choice([X|_], [P|_], Cumul, Rand, X) :-
Rand < Cumul + P.
choice([_|Xs], [P|Ps], Cumul, Rand, Y) :-
Cumul1 is Cumul + P,
Rand >= Cumul1,
choice(Xs, Ps, Cumul1, Rand, Y).
choice([X], [P], Cumul, Rand, X) :-
Rand < Cumul + P.
choice(Xs, Ps, Y) :- random(R), choice(Xs, Ps, 0, R, Y).
Он работает путем рекурсивного построения совокупного распределения вероятностей из вероятностей, указанных в Ps
, и проверки, находится ли случайное число R
ниже этого значения.
Примечание: для правильного функционирования вероятности Ps
должно составлять 1, проверка не делается, чтобы предупредить вас, если это не так.
Пример:
?- choice([1,2,3], [0.1,0.2,0.7], Y).
Y = 3 .
?- choice([1,2,3], [0.1,0.2,0.7], Y).
Y = 1 .
?- choice([1,2,3], [0.1,0.2,0.7], Y).
Y = 2 .
?- choice([1,2,3], [0.1,0.2,0.7], Y).
Y = 3 .
?- choice([1,2,3], [0.1,0.2,0.7], Y).
Y = 2 .
?- choice([1,2,3], [0.1,0.2,0.7], Y).
Y = 3 .
?- choice([1,2,3], [0.1,0.2,0.7], Y).
Y = 3 .
?- choice([1,2,3], [0.1,0.2,0.7], Y).
Y = 3 .
?- choice([1,2,3], [0.1,0.2,0.7], Y).
Y = 3 .
?- choice([1,2,3], [0.1,0.2,0.7], Y).
Y = 3 .
?- choice([1,2,3], [0.1,0.2,0.7], Y).
Y = 3 .
...