/* Multinomial voting in Picat. From Mathematica MultinomialDistribution """ There are two candidates in an election where the winner is chosen based on a simple majority. Each of n voters votes for candidate 1 with probability p1 and for candidate 2 with probability p2, where p1+p2<1, so that a voter may choose not to vote for either candidate. When n=100, p1=p2=0.4, the probability of one swing vote is: D = MultinomialDistribution(100 - 1, (0.4, 0.4, 1 - 0.4 - 0.4)); Probability(x == y, (x, y, z) -> D) -> 0.0447288 Probability that a winner won by one vote: Probability( Abs(x - y) == 1, (x, y, z) -> D) -> 0.0888996 Probability that candidate 1 wins the election: Probability(x > y, (x, y, z) -> D) -> 0.477636 """ Cf my Gamble model gamble_multinomial_voting2.rkt This program was created by Hakan Kjellerstrand, hakank@gmail.com See also my Picat page: http://www.hakank.org/picat/ */ import ppl_distributions, ppl_utils. import util. % import ordset. main => go. /* var : x mean = 39.6598 HPD intervals: HPD interval (0.84): 33.00000000000000..46.00000000000000 var : y mean = 39.5486 HPD intervals: HPD interval (0.84): 33.00000000000000..46.00000000000000 var : z mean = 19.7916 HPD intervals: HPD interval (0.84): 15.00000000000000..25.00000000000000 var : p swing vote mean = 0.0449 var : p won by one vote mean = 0.0842 var : p candidate 1 wins mean = 0.4678 */ go ?=> reset_store, run_model(10_000,$model,[mean, show_hpd_intervals,hpd_intervals=[0.84] ]), nl, % show_store_lengths,nl, % fail, nl. go => true. model() => [X,Y,Z] = multinomial_dist(99,[0.4,0.4,0.2]), PSwingVote = check(X == Y), PWonByOneVote = check(abs(X-Y) == 1), PCandidate1Wins = check(X > Y), % add("V",[X,Y,Z]), add("x",X), add("y",Y), add("z",Z), add("p swing vote",PSwingVote), add("p won by one vote",PWonByOneVote), add("p candidate 1 wins",PCandidate1Wins).