diff --git a/elections/templates/elections/results/rank.html b/elections/templates/elections/results/rank.html
index 073cfda..3e9cfc4 100644
--- a/elections/templates/elections/results/rank.html
+++ b/elections/templates/elections/results/rank.html
@@ -32,7 +32,7 @@
{% for cell in line %}
-
{{ cell }} |
+ {{ cell }} |
{% endfor %}
{% endwith %}
diff --git a/elections/utils.py b/elections/utils.py
index f8ed5db..5b0ec03 100644
--- a/elections/utils.py
+++ b/elections/utils.py
@@ -99,13 +99,8 @@ class TallyFunctions:
"""On dépouille un vote par classement et on crée la matrice des duels"""
from .models import Duel, Option, Rank
- def duel(a, b):
- # Renvoie 1 si a est classé avant b, -1 si c'est l'inverse et
- # 0 si a et b ont le même rang, ce qui permet d'avoir directement
- # le graphe des duels en faisant le max avec la matrice nulle
- return (a.rank < b.rank) - (a.rank > b.rank)
-
options = list(question.options.all())
+ nb_options = len(options)
ranks = Rank.objects.select_related("vote").filter(vote__option__in=options)
ranks_by_user = {}
@@ -121,12 +116,19 @@ class TallyFunctions:
# Pour chaque votant·e, on regarde son classement
for user in ranks_by_user:
votes = ranks_by_user[user]
- ballots.append(np.array([[duel(x, y) for x in votes] for y in votes]))
+ ballot = np.zeros((nb_options, nb_options))
+
+ for i in range(nb_options):
+ for j in range(i):
+ ballot[i, j] = int(votes[i].rank < votes[j].rank)
+ ballot[j, i] = int(votes[j].rank < votes[i].rank)
+
+ ballots.append(ballot)
if ballots != []:
# On additionne les classements de tout le monde pour avoir la matrice
# des duels
- duels = np.maximum(sum(ballots), 0)
+ duels = sum(ballots)
# Configuration du graphe
graph = nx.DiGraph()
@@ -136,21 +138,25 @@ class TallyFunctions:
cells = []
# On enregistre la matrice
- for i, line in enumerate(duels):
- for j, cell in enumerate(line):
- if cell > 0:
- graph.add_edge(options[j], options[i], weight=cell)
+ for i in range(nb_options):
+ for j in range(nb_options):
+ if duels[i, j] > duels[j, i]:
+ graph.add_edge(
+ options[i], options[j], weight=(duels[i, j] - duels[j, i])
+ )
+
+ if duels[i, j] > 0:
cells.append(
Duel(
question=question,
- winner=options[j],
- loser=options[i],
- amount=cell,
+ winner=options[i],
+ loser=options[j],
+ amount=duels[i, j],
)
)
Duel.objects.bulk_create(cells)
- # On utilise la méthode de schwartz pour trouver les options gagnantes
+ # On utilise la méthode de Schwartz pour trouver les options gagnantes
while graph.edges():
losers = set() # Les options qui se font battre strictement
for n in graph.nodes():