Skip to content

Instantly share code, notes, and snippets.

@xvedejas
Created January 17, 2015 05:42
Show Gist options
  • Save xvedejas/b19650bdc6f829d64b51 to your computer and use it in GitHub Desktop.
Save xvedejas/b19650bdc6f829d64b51 to your computer and use it in GitHub Desktop.
#!/usr/bin/python
import numpy as np
# Schulze Condorcet voting method:
# http://en.wikipedia.org/wiki/Schulze_method
def schulze(votes):
"""Input: An array of votes. In each row are the candidates' rankings. The
index of each entry in the row corresponds to a single candidate.
Only the relative rankings of candidates matter.
Lower numbers are better."""
voter_count, candidate_count = votes.shape
preferences = np.zeros((candidate_count, candidate_count))
for vote in votes:
for i, candidate1 in enumerate(vote):
for j, candidate2 in enumerate(vote):
if i <= j:
continue
if candidate1 > candidate2: # c2 preferred to c1
preferences[j, i] += 1
elif candidate2 > candidate1:
preferences[i, j] += 1
strengths = np.zeros((candidate_count, candidate_count))
for (i, j), voter_count in np.ndenumerate(preferences):
if i == j:
continue
strengths[i, j] = voter_count if voter_count > preferences[j, i] else 0
for (i, j), voter_count in np.ndenumerate(preferences):
if i == j:
continue
for k in range(candidate_count):
if i != k and j != k:
strengths[j, k] = max(strengths[j, k],
min(strengths[j, i],
strengths[i, k]))
# Condorcet winners are those candidates who are preferred to all others.
winners = []
for i, row in enumerate(strengths):
column = strengths[:,i]
if (row >= column).all():
winners.append(i)
return winners
with open('votes.txt', 'r') as f:
rankings = []
candidates = 'ABCDEFGHIJ'
for vote in f:
ranking = []
for candidate in candidates:
ranking.append(vote.index(candidate))
rankings.append(ranking)
print(rankings)
print("Winner:", candidates[schulze(np.array(rankings))[0]])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment