Neffarion
Neffarion

Reputation: 59

Fair non-binary random item

Is it possible to get an item of a list of tuples randomly regarding its own random value with a fair share?

For example:

X = [(0.60, test1),  (0.20, test2),  (0.20, test3)]

In this case test1 has a 60% probability of getting chosen over the other ones.
I tried using maybe/1 but that gives me a "binary chance" over each one whereas I want a fair chance for each member of the list if that makes sense.

Upvotes: 1

Views: 32

Answers (1)

damianodamiano
damianodamiano

Reputation: 2662

You can easily adapt the solution from this answer (from which i copied the predicates choice/3 and choice/4), in this way:

solve:-
    X = [(0.60, test1),  (0.20, test2),  (0.20, test3)],
    findall(P,member((P,_),X),LP),
    findall(T,member((_,T),X),LT),
    choice(LT,LP,V),
    writeln(V).

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), !.

And then call ?- solve. This is a basic solution, it can be improved, for instance without calling findall/2 two times... An interesting alternative is to use probabilistic logic programming, check it out.

Upvotes: 3

Related Questions