def test_basic(tiebreaker): utilities = np.array([ [0.0, 0.5, 1.0], [1.0, 0.5, 1.0], [0.0, 0.2, 0.0], [0.0, 1.0, 0.7], [0.3, 0.4, 0.5], ]) assert utility_winner(utilities, tiebreaker) == 2
def test_ties(): # Ties are very unlikely because of float equality # Two-way tie between candidates 1 and 2 utilities = np.array([ [0.0, 0.5, 1.0], [1.0, 0.5, 0.0], [0.0, 0.5, 0.0], [0.0, 1.0, 1.0], [0.2, 0.0, 0.5], ]) # No tiebreaker: assert utility_winner(utilities, tiebreaker=None) is None # Mode 'order' should always prefer lowest candidate ID assert utility_winner(utilities, tiebreaker='order') == 1 # Mode 'random' should choose all tied candidates at random assert collect_random_results(utility_winner, utilities) == {1, 2} # Three-way tie between 0, 1, and 2 utilities = np.array([ [0.0, 0.5, 1.0], [1.0, 0.5, 0.0], [0.0, 1.0, 0.5], [1.0, 0.0, 0.5], [0.5, 0.5, 0.5], ]) # No tiebreaker: assert utility_winner(utilities, tiebreaker=None) is None # Mode 'order' should always prefer lowest candidate ID assert utility_winner(utilities, tiebreaker='order') == 0 # Mode 'random' should choose all tied candidates at random assert collect_random_results(utility_winner, utilities) == {0, 1, 2}
def func(): count = defaultdict(dict) for n_cands in n_cands_list: utilities = random_utilities(n_voters, n_cands) # Find the social utility winner and accumulate utilities UW = utility_winner(utilities) count['UW'][n_cands] = utilities.sum(axis=0)[UW] for name, method in rated_methods.items(): try: winner = method(utilities, tiebreaker='random') count[name][n_cands] = utilities.sum(axis=0)[winner] except ValueError: # Skip junk cases like vote-for-2 with 2 candidates count[name][n_cands] = np.nan rankings = honest_rankings(utilities) for name, method in ranked_methods.items(): winner = method(rankings, tiebreaker='random') count[name][n_cands] = utilities.sum(axis=0)[winner] return count
ranked_methods = {'Standard': fptp, 'Borda': borda} rated_methods = {'Vote-for-half': lambda utilities, tiebreaker: approval(vote_for_k(utilities, 'half'), tiebreaker)} count = {key: Counter() for key in (ranked_methods.keys() | rated_methods.keys() | {'UW'})} start_time = time.monotonic() for iteration in range(n): for n_cands in n_cands_list: utilities = random_utilities(n_voters, n_cands) # Find the social utility winner and accumulate utilities UW = utility_winner(utilities) count['UW'][n_cands] += utilities.sum(axis=0)[UW] for name, method in rated_methods.items(): winner = method(utilities, tiebreaker='random') count[name][n_cands] += utilities.sum(axis=0)[winner] rankings = honest_rankings(utilities) for name, method in ranked_methods.items(): winner = method(rankings, tiebreaker='random') count[name][n_cands] += utilities.sum(axis=0)[winner] elapsed_time = time.monotonic() - start_time print('Elapsed:', time.strftime("%H:%M:%S", time.gmtime(elapsed_time)), '\n') plt.figure(f'Effectiveness, {n_voters} voters, {n} iterations')
def test_legit_winner(election, tiebreaker): election = np.asarray(election) n_cands = election.shape[1] winner = utility_winner(election, tiebreaker) assert isinstance(winner, int) assert winner in range(n_cands)
def test_legit_winner_no_tiebreaker(election): election = np.asarray(election) n_cands = election.shape[1] winner = utility_winner(election) assert isinstance(winner, (int, type(None))) assert winner in set(range(n_cands)) | {None}