Skip to content
Snippets Groups Projects
Commit 6e52f54a authored by Millian Poquet's avatar Millian Poquet
Browse files

code: condorcet/schulze implem + tests

parent b15768fd
Branches
No related tags found
No related merge requests found
__pycache__
elect.py 0 → 100755
#!/usr/bin/env python3
import argparse
import json
import numpy as np
# N[a,b] is the number of voters who prefer candidate a to candidate b
def load_pairwise_preferences_matrix(file):
list_of_lists = json.load(file)
n = np.stack([np.asarray(l, dtype=np.int8) for l in list_of_lists])
return n
# As defined in section 4.12.1 https://arxiv.org/pdf/1804.02973.pdf,
# A Condorcet winner is an alternative a ∈ A that wins every head-to-head
# contest with some other alternative b ∈ A \ {a}.
def condorcet_winner(n, candidates):
nb_candidates = len(candidates)
for potential_winner in range(nb_candidates):
won_all_contests = True
for opponent in range(nb_candidates):
if n[opponent][potential_winner] > n[potential_winner][opponent]:
won_all_contests = False
if won_all_contests:
return candidates[potential_winner]
return None
# As defined in section 4.12.1 https://arxiv.org/pdf/1804.02973.pdf,
# A weak Condorcet winner is an alternative a ∈ A that doesn’t lose any
# head-to-head contest with some other alternative b ∈ A \ {a}
def weak_condorcet_winners(n, candidates):
weak_winners = []
nb_candidates = len(candidates)
for potential_winner in range(nb_candidates):
lost_a_contest = False
for opponent in range(nb_candidates):
if n[opponent][potential_winner] > n[potential_winner][opponent]:
lost_a_contest = True
if not lost_a_contest:
weak_winners.append(candidates[potential_winner])
return weak_winners
# As defined in section 4 https://citizensassembly.arts.ubc.ca/resources/submissions/csharman-10_0409201706-143.pdf
def schulze_winners(n, candidates):
nb_candidates = len(candidates)
p = np.zeros((nb_candidates, nb_candidates), dtype=np.int8)
for i in range(nb_candidates):
for j in range(nb_candidates):
if i != j:
p[i][j] = n[i][j] - n[j][i]
for i in range(nb_candidates):
for j in range(nb_candidates):
if i != j:
for k in range(nb_candidates):
if i != k and j != k:
s = min(p[j][i], p[i][k])
if p[j][k] < s:
p[j][k] = s
winners = []
for i in range(nb_candidates):
has_lost_directly_or_indirectly = False
for j in range(nb_candidates):
if i != j:
if p[j][i] > p[i][j]:
has_lost_directly_or_indirectly = True
if not has_lost_directly_or_indirectly:
winners.append(candidates[i])
return winners
if __name__ == '__main__':
parser = argparse.ArgumentParser(description='Computes winners of the election')
parser.add_argument('-c', '--candidates-file', help='candidates JSON file', type=argparse.FileType('r', encoding='utf-8'), required=True)
parser.add_argument('matrix_file', help="pairwise preference matric JSON file", type=argparse.FileType('r', encoding='utf-8'))
args = parser.parse_args()
n = load_pairwise_preferences_matrix(args.matrix_file)
assert(n.shape[0] > 0)
assert(n.shape[0] == n.shape[1])
candidates = json.load(args.candidates_file)
assert(len(candidates) == n.shape[0])
# Condorcet winner (win every head-to-head contest)
c_winner = condorcet_winner(n, candidates)
if c_winner is None:
print('There is no Condorcet winner')
else:
print(f'Condorcet winner: {c_winner}')
# Condorcet weak winner (do not lose any head-to-head contest)
weak_c_winners = weak_condorcet_winners(n, candidates)
if len(weak_c_winners) == 0:
print('There are no weak Condorcet winners')
else:
print(f'Weak Condorcet winners: {weak_c_winners}')
# Schulze winners (win every head-to-head contest, directly or indirectly)
schulze_winners = schulze_winners(n, candidates)
assert(len(schulze_winners) > 0)
print(f'Schulze winners: {schulze_winners}')
#!/usr/bin/env python3
import argparse
import json
import numpy as np
import pygraphviz as pgv
from itertools import groupby
def all_equal(iterable):
g = groupby(iterable)
return next(g, True) and not next(g, False)
def is_blank(ballot, unranked_value):
for x in ballot:
if x != 0 and x != unranked_value:
return False
return True
# ballot values should be consistent (unranked value should be the greatest)
# N[a,b] is the number of voters who prefer candidate a to candidate b
def pairwise_preferences(ballot, nb_candidates):
n = np.zeros((nb_candidates, nb_candidates), dtype=np.int8)
for a in range(nb_candidates):
for b in range(a, nb_candidates):
if ballot[a] < ballot[b]:
n[a][b] = 1
elif ballot[a] > ballot[b]:
n[b][a] = 1
return n
def pairwise_preferences_matrix(belenios_raw_data):
# traverse data to compute some stuff and check some assumptions
max_observed_value = -1
nb_blank = 0
min_nb_candidates = 1000
max_nb_candidates = -1
for ballot in belenios_raw_data:
max_observed_value = max(max_observed_value, max(ballot))
nb_candidates = len(ballot)
min_nb_candidates = min(min_nb_candidates, nb_candidates)
max_nb_candidates = max(max_nb_candidates, nb_candidates)
assert(max_observed_value > -1)
assert(min_nb_candidates == max_nb_candidates)
nb_candidates = min_nb_candidates
unranked_value = max_observed_value + 1
# put a consistent value for unranked candidates
fix_unranked_value = lambda x: unranked_value if x == 0 else x
data = [ list(map(fix_unranked_value, ballot)) for ballot in belenios_raw_data ]
# compute some stats
nb_voters = len(data)
nb_blank = sum([int(is_blank(ballot, unranked_value)) for ballot in data])
# compute N, the matrix of pairwise preferences
# N[a,b] is the number of voters who prefer candidate a to candidate b
n = np.zeros((nb_candidates, nb_candidates), dtype=np.int8)
for ballot in data:
n += pairwise_preferences(ballot, nb_candidates)
return (n, nb_candidates, nb_voters, nb_blank)
# compute graph of pairwise preferences
# When N[i,j] > N[j,i], then there is a link from candidate i to candidate j of strength N[i,j] – N[j,i]
def pairwise_preferences_graph(n, candidates):
graph = pgv.AGraph(strict=True, directed=True)
graph.add_nodes_from(candidates)
assert n.shape[0] == n.shape[1]
assert n.shape[0] == len(candidates)
nb_candidates = len(candidates)
for a in range(nb_candidates):
for b in range(a, nb_candidates):
margin = n[a][b] - n[b][a]
if margin != 0:
(x, y) = (a, b) if margin > 0 else (b, a)
margin = abs(margin)
cx = candidates[x]
cy = candidates[y]
text_fr = f"{cx} domine {cy} par {margin} votants\n{n[x][y]} votants préfèrent {cx} à {cy}\n{n[y][x]} votants préfèrent {cy} à {cx}"
text_en = f"{cx} dominates {cy} by a margin of {margin} voters\n{n[x][y]} voters prefer {cx} over {cy}\n{n[y][x]} voters prefer {cy} over {cx}"
graph.add_edge(cx, cy, label=f"{margin}", tooltip=f"{text_fr}\n\n{text_en}")
return graph
if __name__ == '__main__':
parser = argparse.ArgumentParser(description='Computes pairwise preferences matrix and graph from belenios ballot files')
parser.add_argument('-om', '--output-matrix-file', required=True)
parser.add_argument('-og', '--output-graph-file', required=True)
parser.add_argument('-c', '--candidates-file', help='candidates JSON file', type=argparse.FileType('r', encoding='utf-8'), required=True)
parser.add_argument('ballot_file', nargs='+', help="belenios ballot JSON file", type=argparse.FileType('r', encoding='utf-8'))
args = parser.parse_args()
# compute the pairwise preference matrix from all belenios ballot files
ballot_data = []
for file in args.ballot_file:
raw_data = json.load(file)
(n, nb_candidates, nb_voters, nb_blank) = pairwise_preferences_matrix(raw_data)
#print(n)
ballot_data.append((n, nb_candidates, nb_voters, nb_blank))
# make sure that the ballot fires are consistent with each other
nb_candidates = [b[1] for b in ballot_data]
assert(all_equal(nb_candidates))
# aggregate values
nb_voters = sum([b[2] for b in ballot_data])
nb_blank = sum([b[3] for b in ballot_data])
n = sum([b[0] for b in ballot_data])
print(n)
with open(args.output_matrix_file, 'w') as matrix_file:
json.dump(n.tolist(), matrix_file)
candidates = json.load(args.candidates_file)
g = pairwise_preferences_graph(n, candidates)
with open(args.output_graph_file, 'w') as graph_file:
graph_file.write(g.to_string())
#print(args)
#raw_data = [[0,0,0,0,0,0],[1,2,3,4,5,5],[1,2,3,0,0,0],[0,0,0,0,0,0],[1,2,3,4,5,5]]
#(n, nb_candidates, nb_voters, nb_blank) = pairwise_preferences_matrix(raw_data)
#!/usr/bin/env python3
import numpy as np
import preference_counter
import elect
# all examples are from Section 3 of Markus Schulze's "The Schulze Method of Voting",
# version 13 (latest as I write these lines: 2023-07-14). https://arxiv.org/pdf/1804.02973.pdf
def test_example1():
candidates = ['a', 'b', 'c', 'd']
ballots = [[ 1, 4, 2, 3]] * 8 + \
[[ 2, 1, 4, 3]] * 2 + \
[[ 4, 3, 1, 2]] * 4 + \
[[ 3, 2, 4, 1]] * 4 + \
[[ 4, 3, 2, 1]] * 3
(n, nb_candidates, nb_voters, nb_blank) = preference_counter.pairwise_preferences_matrix(ballots)
expected_n = np.array([[ 0, 8, 14, 10],
[13, 0, 6, 2],
[ 7, 15, 0, 12],
[11, 19, 9, 0]], dtype=np.int8)
assert nb_candidates == len(candidates)
assert nb_voters == 8+2+4+4+3
assert nb_blank == 0
assert np.array_equal(n, expected_n)
assert elect.condorcet_winner(n, candidates) is None
assert len(elect.weak_condorcet_winners(n, candidates)) == 0
assert elect.schulze_winners(n, candidates) == ['d']
def test_example2():
candidates = ['a', 'b', 'c', 'd']
ballots = [[ 1, 4, 2, 3]] * 3 + \
[[ 2, 1, 3, 4]] * 9 + \
[[ 3, 4, 1, 2]] * 8 + \
[[ 2, 3, 4, 1]] * 5 + \
[[ 4, 2, 3, 1]] * 5
(n, nb_candidates, nb_voters, nb_blank) = preference_counter.pairwise_preferences_matrix(ballots)
expected_n = np.array([[ 0, 16, 17, 12],
[14, 0, 19, 9],
[13, 11, 0, 20],
[18, 21, 10, 0]], dtype=np.int8)
assert nb_candidates == len(candidates)
assert nb_voters == 3+9+8+5+5
assert nb_blank == 0
assert np.array_equal(n, expected_n)
assert elect.condorcet_winner(n, candidates) is None
assert len(elect.weak_condorcet_winners(n, candidates)) == 0
assert elect.schulze_winners(n, candidates) == ['c']
def test_example3():
candidates = ['a', 'b', 'c', 'd', 'e']
ballots = [[ 1, 3, 2, 5, 4]] * 5 + \
[[ 1, 5, 4, 2, 3]] * 5 + \
[[ 4, 1, 5, 3, 2]] * 8 + \
[[ 2, 3, 1, 5, 4]] * 3 + \
[[ 2, 4, 1, 5, 3]] * 7 + \
[[ 3, 2, 1, 4, 5]] * 2 + \
[[ 5, 4, 2, 1, 3]] * 7 + \
[[ 3, 2, 5, 4, 1]] * 8
(n, nb_candidates, nb_voters, nb_blank) = preference_counter.pairwise_preferences_matrix(ballots)
expected_n = np.array([[ 0, 20, 26, 30, 22],
[25, 0, 16, 33, 18],
[19, 29, 0, 17, 24],
[15, 12, 28, 0, 14],
[23, 27, 21, 31, 0]], dtype=np.int8)
assert nb_candidates == len(candidates)
assert nb_voters == 5+5+8+3+7+2+7+8
assert nb_blank == 0
assert np.array_equal(n, expected_n)
assert elect.condorcet_winner(n, candidates) is None
assert len(elect.weak_condorcet_winners(n, candidates)) == 0
assert elect.schulze_winners(n, candidates) == ['e']
def test_example4():
candidates = ['a', 'b', 'c', 'd']
ballots = [[ 1, 2, 3, 4]] * 3 + \
[[ 4, 2, 1, 3]] * 2 + \
[[ 2, 3, 4, 1]] * 2 + \
[[ 4, 2, 3, 1]] * 2
(n, nb_candidates, nb_voters, nb_blank) = preference_counter.pairwise_preferences_matrix(ballots)
expected_n = np.array([[ 0, 5, 5, 3],
[ 4, 0, 7, 5],
[ 4, 2, 0, 5],
[ 6, 4, 4, 0]], dtype=np.int8)
assert nb_candidates == len(candidates)
assert nb_voters == 3+2+2+2
assert nb_blank == 0
assert np.array_equal(n, expected_n)
assert elect.condorcet_winner(n, candidates) is None
assert len(elect.weak_condorcet_winners(n, candidates)) == 0
assert elect.schulze_winners(n, candidates) == ['b', 'd']
def test_example5():
candidates = ['a', 'b', 'c', 'd']
ballots = [[ 1, 2, 3, 4]] * 12 + \
[[ 1, 3, 4, 2]] * 6 + \
[[ 4, 1, 2, 3]] * 9 + \
[[ 3, 4, 1, 2]] * 15 + \
[[ 3, 2, 4, 1]] * 21
(n, nb_candidates, nb_voters, nb_blank) = preference_counter.pairwise_preferences_matrix(ballots)
expected_n = np.array([[ 0, 33, 39, 18],
[30, 0, 48, 21],
[24, 15, 0, 36],
[45, 42, 27, 0]], dtype=np.int8)
assert nb_candidates == len(candidates)
assert nb_voters == 12+6+9+15+21
assert nb_blank == 0
assert np.array_equal(n, expected_n)
assert elect.condorcet_winner(n, candidates) is None
assert len(elect.weak_condorcet_winners(n, candidates)) == 0
assert elect.schulze_winners(n, candidates) == ['d']
def test_example6():
candidates = ['a', 'b', 'c', 'd']
ballots = [[ 1, 4, 2, 3]] * 8 + \
[[ 4, 1, 2, 3]] * 2 + \
[[ 3, 1, 4, 2]] * 3 + \
[[ 4, 2, 1, 3]] * 5 + \
[[ 4, 3, 1, 2]] * 1 + \
[[ 2, 3, 4, 1]] * 3 + \
[[ 3, 2, 4, 1]] * 1
(n, nb_candidates, nb_voters, nb_blank) = preference_counter.pairwise_preferences_matrix(ballots)
expected_n = np.array([[ 0, 11, 15, 8],
[12, 0, 9, 10],
[ 8, 14, 0, 16],
[15, 13, 7, 0]], dtype=np.int8)
assert nb_candidates == len(candidates)
assert nb_voters == 8+2+3+5+1+3+1
assert nb_blank == 0
assert np.array_equal(n, expected_n)
assert elect.condorcet_winner(n, candidates) is None
assert len(elect.weak_condorcet_winners(n, candidates)) == 0
assert elect.schulze_winners(n, candidates) == ['a', 'c']
def test_example7():
# situation 1
candidates = ['a', 'b', 'c', 'd', 'e', 'f']
ballots = [[ 1, 4, 5, 2, 3, 6]] * 3 + \
[[ 6, 1, 4, 5, 3, 2]] * 3 + \
[[ 2, 3, 1, 5, 6, 4]] * 4 + \
[[ 6, 2, 3, 1, 4, 5]] * 1 + \
[[ 4, 5, 6, 1, 2, 3]] * 4 + \
[[ 6, 3, 2, 4, 1, 5]] * 2 + \
[[ 2, 5, 3, 4, 6, 1]] * 2
(n, nb_candidates, nb_voters, nb_blank) = preference_counter.pairwise_preferences_matrix(ballots)
expected_n = np.array([[ 0, 13, 9, 9, 9, 7],
[ 6, 0, 11, 9, 10, 13],
[10, 8, 0, 11, 7, 10],
[10, 10, 8, 0, 14, 10],
[10, 9, 12, 5, 0, 10],
[12, 6, 9, 9, 9, 0]], dtype=np.int8)
assert nb_candidates == len(candidates)
assert nb_voters == 3+3+4+1+4+2+2
assert nb_blank == 0
assert np.array_equal(n, expected_n)
assert elect.condorcet_winner(n, candidates) is None
assert len(elect.weak_condorcet_winners(n, candidates)) == 0
assert elect.schulze_winners(n, candidates) == ['a']
# situation 2
candidates = ['a', 'b', 'c', 'd', 'e', 'f']
ballots2 = [[ 1, 5, 4, 6, 2, 3]] * 2
new_ballots = ballots + ballots2
(n, nb_candidates, nb_voters, nb_blank) = preference_counter.pairwise_preferences_matrix(new_ballots)
expected_n = np.array([[ 0, 15, 11, 11, 11, 9],
[ 6, 0, 11, 11, 10, 13],
[10, 10, 0, 13, 7, 10],
[10, 10, 8, 0, 14, 10],
[10, 11, 14, 7, 0, 12],
[12, 8, 11, 11, 9, 0]], dtype=np.int8)
assert nb_candidates == len(candidates)
assert nb_voters == 3+3+4+1+4+2+2+2
assert nb_blank == 0
assert np.array_equal(n, expected_n)
assert elect.condorcet_winner(n, candidates) is None
assert len(elect.weak_condorcet_winners(n, candidates)) == 0
assert elect.schulze_winners(n, candidates) == ['d']
def test_example8():
# situation 1
candidates = ['a', 'b', 'c', 'd']
ballots = [[ 1, 2, 4, 3]] * 3 + \
[[ 1, 3, 4, 2]] * 5 + \
[[ 1, 4, 3, 2]] * 1 + \
[[ 2, 1, 4, 3]] * 2 + \
[[ 4, 1, 3, 2]] * 2 + \
[[ 2, 3, 1, 4]] * 4 + \
[[ 3, 2, 1, 4]] * 6 + \
[[ 4, 2, 3, 1]] * 2 + \
[[ 3, 4, 2, 1]] * 5
(n, nb_candidates, nb_voters, nb_blank) = preference_counter.pairwise_preferences_matrix(ballots)
expected_n = np.array([[ 0, 18, 11, 21],
[12, 0, 14, 17],
[19, 16, 0, 10],
[ 9, 13, 20, 0]], dtype=np.int8)
assert nb_candidates == len(candidates)
assert nb_voters == 3+5+1+2+2+4+6+2+5
assert nb_blank == 0
assert np.array_equal(n, expected_n)
assert elect.condorcet_winner(n, candidates) is None
assert len(elect.weak_condorcet_winners(n, candidates)) == 0
assert elect.schulze_winners(n, candidates) == ['a']
# situation 2
candidates = ['a', 'b', 'c', 'd', 'e']
ballots = [[ 1, 2, 5, 3, 4]] * 3 + \
[[ 1, 4, 5, 2, 3]] * 5 + \
[[ 1, 5, 4, 2, 3]] * 1 + \
[[ 2, 1, 5, 3, 4]] * 2 + \
[[ 5, 1, 4, 2, 3]] * 2 + \
[[ 2, 3, 1, 4, 5]] * 4 + \
[[ 3, 2, 1, 4, 5]] * 6 + \
[[ 5, 2, 4, 1, 3]] * 2 + \
[[ 4, 5, 3, 1, 2]] * 5
(n, nb_candidates, nb_voters, nb_blank) = preference_counter.pairwise_preferences_matrix(ballots)
expected_n = np.array([[ 0, 18, 11, 21, 21],
[12, 0, 14, 17, 19],
[19, 16, 0, 10, 10],
[ 9, 13, 20, 0, 30],
[ 9, 11, 20, 0, 0]], dtype=np.int8)
assert nb_candidates == len(candidates)
assert nb_voters == 3+5+1+2+2+4+6+2+5
assert nb_blank == 0
assert np.array_equal(n, expected_n)
assert elect.condorcet_winner(n, candidates) is None
assert len(elect.weak_condorcet_winners(n, candidates)) == 0
assert elect.schulze_winners(n, candidates) == ['b']
def test_example9():
# situation 1
candidates = ['a', 'b', 'c', 'd']
ballots = [[ 1, 4, 2, 3]] * 5 + \
[[ 4, 1, 2, 3]] * 2 + \
[[ 3, 1, 4, 2]] * 4 + \
[[ 3, 4, 1, 2]] * 2
(n, nb_candidates, nb_voters, nb_blank) = preference_counter.pairwise_preferences_matrix(ballots)
expected_n = np.array([[ 0, 7, 9, 5],
[ 6, 0, 6, 6],
[ 4, 7, 0, 9],
[ 8, 7, 4, 0]], dtype=np.int8)
assert nb_candidates == len(candidates)
assert nb_voters == 5+2+4+2
assert nb_blank == 0
assert np.array_equal(n, expected_n)
assert elect.condorcet_winner(n, candidates) is None
assert len(elect.weak_condorcet_winners(n, candidates)) == 0
assert elect.schulze_winners(n, candidates) == ['a']
# situation 2
candidates = ['a', 'b', 'c', 'd', 'e']
ballots = [[ 1, 5, 3, 4, 2]] * 5 + \
[[ 4, 1, 2, 3, 5]] * 2 + \
[[ 3, 1, 5, 2, 4]] * 4 + \
[[ 3, 4, 1, 2, 5]] * 2
(n, nb_candidates, nb_voters, nb_blank) = preference_counter.pairwise_preferences_matrix(ballots)
expected_n = np.array([[ 0, 7, 9, 5, 13],
[ 6, 0, 6, 6, 8],
[ 4, 7, 0, 9, 4],
[ 8, 7, 4, 0, 8],
[ 0, 5, 9, 5, 0]], dtype=np.int8)
assert nb_candidates == len(candidates)
assert nb_voters == 5+2+4+2
assert nb_blank == 0
assert np.array_equal(n, expected_n)
assert elect.condorcet_winner(n, candidates) is None
assert len(elect.weak_condorcet_winners(n, candidates)) == 0
assert elect.schulze_winners(n, candidates) == ['b']
def test_example10():
candidates = ['a', 'b', 'c', 'd']
ballots = [[ 1, 2, 3, 4]] * 6 + \
[[ 1, 1, 2, 2]] * 8 + \
[[ 1, 2, 1, 2]] * 8 + \
[[ 1, 3, 1, 2]] * 18 + \
[[ 1, 2, 1, 1]] * 8 + \
[[ 2, 1, 2, 2]] * 40 + \
[[ 4, 2, 1, 3]] * 4 + \
[[ 3, 4, 1, 2]] * 9 + \
[[ 2, 2, 1, 1]] * 8 + \
[[ 2, 3, 4, 1]] * 14 + \
[[ 4, 2, 3, 1]] * 11 + \
[[ 3, 4, 2, 1]] * 4
(n, nb_candidates, nb_voters, nb_blank) = preference_counter.pairwise_preferences_matrix(ballots)
expected_n = np.array([[ 0, 67, 28, 40],
[55, 0, 79, 58],
[36, 59, 0, 45],
[50, 72, 29, 0]], dtype=np.int8)
assert nb_candidates == len(candidates)
assert nb_voters == 6+8+8+18+8+40+4+9+8+14+11+4
assert nb_blank == 0
assert np.array_equal(n, expected_n)
assert elect.condorcet_winner(n, candidates) is None
assert len(elect.weak_condorcet_winners(n, candidates)) == 0
assert elect.schulze_winners(n, candidates) == ['a']
#assert False, "TODO: implement other methods to compute strength of link"
def test_example11():
candidates = ['a', 'b', 'c', 'd', 'e']
ballots = [[ 1, 3, 5, 2, 4]] * 9 + \
[[ 3, 1, 2, 4, 5]] * 6 + \
[[ 5, 1, 2, 3, 4]] * 5 + \
[[ 5, 3, 1, 2, 4]] * 2 + \
[[ 5, 4, 3, 1, 2]] * 6 + \
[[ 2, 4, 3, 5, 1]] * 14 + \
[[ 3, 4, 2, 5, 1]] * 2 + \
[[ 3, 5, 4, 2, 1]] * 1
(n, nb_candidates, nb_voters, nb_blank) = preference_counter.pairwise_preferences_matrix(ballots)
expected_n = np.array([[ 0, 26, 24, 31, 15],
[19, 0, 20, 27, 22],
[21, 25, 0, 29, 13],
[14, 18, 16, 0, 28],
[30, 23, 32, 17, 0]], dtype=np.int8)
assert nb_candidates == len(candidates)
assert nb_voters == 9+6+5+2+6+14+2+1
assert nb_blank == 0
assert np.array_equal(n, expected_n)
assert elect.condorcet_winner(n, candidates) is None
assert len(elect.weak_condorcet_winners(n, candidates)) == 0
assert elect.schulze_winners(n, candidates) == ['b']
def test_example12():
candidates = ['a', 'b', 'c', 'd', 'e']
ballots = [[ 1, 3, 5, 2, 4]] * 9 + \
[[ 2, 1, 3, 5, 4]] * 1 + \
[[ 3, 2, 1, 4, 5]] * 6 + \
[[ 5, 3, 1, 2, 4]] * 2 + \
[[ 4, 5, 1, 2, 3]] * 5 + \
[[ 4, 5, 3, 1, 2]] * 6 + \
[[ 3, 2, 4, 5, 1]] * 14 + \
[[ 4, 2, 3, 5, 1]] * 2
(n, nb_candidates, nb_voters, nb_blank) = preference_counter.pairwise_preferences_matrix(ballots)
expected_n = np.array([[ 0, 20, 24, 32, 16],
[25, 0, 26, 23, 18],
[21, 19, 0, 30, 14],
[13, 22, 15, 0, 28],
[29, 27, 31, 17, 0]], dtype=np.int8)
assert nb_candidates == len(candidates)
assert nb_voters == 9+1+6+2+5+6+14+2
assert nb_blank == 0
assert np.array_equal(n, expected_n)
assert elect.condorcet_winner(n, candidates) is None
assert len(elect.weak_condorcet_winners(n, candidates)) == 0
assert elect.schulze_winners(n, candidates) == ['e']
def test_example13():
candidates = ['a', 'b', 'c']
ballots = [[ 1, 2, 3]] * 2 + \
[[ 3, 1, 2]] * 2 + \
[[ 2, 3, 1]] * 1
(n, nb_candidates, nb_voters, nb_blank) = preference_counter.pairwise_preferences_matrix(ballots)
expected_n = np.array([[0, 3, 2],
[2, 0, 4],
[3, 1, 0]], dtype=np.int8)
assert nb_candidates == len(candidates)
assert nb_voters == 2+2+1
assert nb_blank == 0
assert np.array_equal(n, expected_n)
assert elect.condorcet_winner(n, candidates) is None
assert len(elect.weak_condorcet_winners(n, candidates)) == 0
assert elect.schulze_winners(n, candidates) == ['a', 'b']
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment