-
Notifications
You must be signed in to change notification settings - Fork 0
/
SchulzeVoting.py
101 lines (86 loc) · 2.56 KB
/
SchulzeVoting.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
#!/usr/bin/env python
# Licence: LGPL - by Thomas Hirsch 2009
class SchulzeVoting:
def __init__(self):
self.reset()
def reset(self):
self.ballots = []
self.candidates = []
def addVote(self, ballot):
self.ballots.append(ballot)
for candidate in ballot:
if not candidate in self.candidates:
self.candidates.append(candidate)
def getPaths(self):
defeats = {}
paths = {}
for c1 in self.candidates:
for c2 in self.candidates:
if not c1 in defeats:
defeats[c1]={}
if not c1 in paths:
paths[c1]={}
defeats[c1][c2] = 0
paths[c1][c2] = 0
for ballot in self.ballots:
for i, choice in enumerate(ballot):
for candidate in self.candidates:
place = ballot.index(candidate)
if place and place>i:
defeats[choice][candidate] += 1
for c1 in self.candidates:
for c2 in self.candidates:
if (c1 != c2):
if defeats[c1][c2]>defeats[c2][c1]:
paths[c1][c2]=defeats[c1][c2]
for c1 in self.candidates:
for c2 in self.candidates:
if (c1 != c2):
for c3 in self.candidates:
if (c1 != c3) and (c2 != c3):
paths[c2][c3] = max(paths[c2][c3], min(paths[c2][c1], paths[c1][c3]))
return paths
def getWinners(self):
paths = self.getPaths()
winners = self.candidates[:]
for c1 in self.candidates:
for c2 in self.candidates:
if (c1 != c2):
if paths[c2][c1]>paths[c1][c2]:
winners.remove[c1]
return winners
def getRanks(self):
paths = self.getPaths()
ranks = []
remaining = self.candidates[:]
while remaining:
winners = remaining[:]
for c1 in remaining:
for c2 in remaining:
if (c1 != c2):
if paths[c2][c1]>paths[c1][c2]:
if c1 in winners:
winners.remove(c1)
ranks.append(winners)
for winner in winners:
remaining.remove(winner)
return ranks
def countVotes(self):
return len(self.ballots)
if __name__=="__main__":
v = SchulzeVoting()
ballot = ["Correct"]
v.addVote(ballot)
print("Tests:")
print("Single vote, single candidate: "+str(v.getRanks()))
v.reset()
ballot.extend(["Second","Third"])
v.addVote(ballot)
print("Single vote, three candidates: "+str(v.getRanks()))
v.reset();
ballot2 = ["Third","Correct","Second"]
ballot3 = ["Second","Correct","Third"]
v.addVote(ballot);
v.addVote(ballot2);
v.addVote(ballot3);
print("Three votes, three candidates: "+str(v.getRanks()))