Prolog: how to non-uniformly randomly select a element from a list?

佐手、 提交于 2021-01-28 05:53:53

问题


Does anyone have any Prolog code to non-uniformly select a random element from a list?

I want to replicate the functionality of numpy.random.choice when given the probabilities associated with each entry in the input list.


回答1:


I found nothing useful in library(random).

Here's my implementation 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).

It works by recursively building the cumulative probability distribution from the probabilities given in Ps, and checking if the random number R is below that.

Note: to function correctly the probabilities Ps must sum to 1, no check is made to warn you if that is not the case.

Example:

?- 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 .

...


来源:https://stackoverflow.com/questions/50250234/prolog-how-to-non-uniformly-randomly-select-a-element-from-a-list

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!