rejection_sampling.sf 1.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546
  1. #!/usr/bin/ruby
  2. # Rejection sampling algorithm.
  3. # See also:
  4. # https://en.wikipedia.org/wiki/Rejection_sampling
  5. func accept_reject(table) {
  6. var accepted = nil
  7. var max_fitness = table.map{|h| h{:weight} }.max
  8. var prob = max_fitness.rand
  9. loop {
  10. var item = table.rand
  11. if (prob < item{:weight}) {
  12. accepted = item
  13. break
  14. }
  15. }
  16. accepted
  17. }
  18. var table = [
  19. Hash(value => "Sidef", weight => rand(0.5, 1.0)),
  20. Hash(value => "Ruby", weight => 0.5.rand),
  21. Hash(value => "Perl", weight => 0.5.rand),
  22. Hash(value => "Python", weight => 0.5.rand),
  23. Hash(value => "Julia", weight => 0.5.rand),
  24. ]
  25. var picked = accept_reject(table)
  26. say "Picked #{picked{:value}} with a probability of #{picked{:weight}.round(-2)*100}%"
  27. var freq = 100.of { accept_reject(table){:value} }.freq
  28. var max = freq.max_by { |_,v| v }
  29. if (max.key == "Sidef") {
  30. say "On average, Sidef is the winner!"
  31. }
  32. else {
  33. say "On average, #{max.key} is the winner -- that's sad..."
  34. }