Last active
August 29, 2015 14:01
-
-
Save efruchter/876dd07a14354b269973 to your computer and use it in GitHub Desktop.
An implementation of weighted random selection in python. O(n*log(n))
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import random | |
| # This method randomly picks a single choice from a collection of choices. | |
| # freq_tuples: List of tuples of the form: (choice, count) | |
| # Returns a choice, or None if empty list. | |
| def weighted_random_selection(freq_tuples): | |
| if len(freq_tuples) == 1: | |
| return freq_tuples[0][0] | |
| sorted_freq_tuples = sorted(freq_tuples, key = lambda tup : tup[1], reverse=True) | |
| total = sum([count for gram, count in freq_tuples]) * random.random() | |
| for gram, count in sorted_freq_tuples: | |
| total -= count | |
| if (total < 0): | |
| return gram | |
| return None |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # sample | |
| choices = [('x', 1), ('y', 1), ('z', 2), ('a', 0)] | |
| pick_counts = {'x': 0, 'y': 0, 'z': 0, 'a': 0} | |
| trials = 100000 | |
| for i in range(trials): | |
| choice = weighted_random_selection(choices) | |
| pick_counts[choice] += 1 | |
| for pick in sorted(pick_counts.keys()): | |
| print (pick, 1.0 * pick_counts[pick] / trials) |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
note for me: Might this work without the sorting? Can this be brought down to O(n)?