2010-06-03 7 views
0

J'ai récemment recueilli, à l'aide d'un questionnaire, un ensemble d'opinions sur l'importance de divers composants logiciels. Considérant qu'une certaine forme de méthode de vote Condorcet serait le meilleur moyen d'obtenir un classement général, j'ai choisi d'utiliser OpenSTV pour l'analyser.Conversion format par candidat au format OpenSTV BLT


Mes données est sous forme de tableau, espace délimité, et ressemble plus ou moins comme:

A B C D E F G # Candidates 
5 2 4 3 7 6 1 # First ballot. G is ranked first, and E is ranked 7th 
4 2 6 5 1 7 3 # Second ballot 
etc 

Dans ce format, le nombre indique le rang et l'ordre de séquence indique le candidat. Chaque «candidat» a un rang (requis) de 1 à 7, où 1 signifie le plus important et 7 signifie le moins important. Aucun doublon n'est autorisé.

Ce format m'a semblé le moyen le plus naturel de représenter la sortie, étant une représentation directe du format de vote.


Le format OpenSTV/BLT utilise une méthode différente de représenter la même information, sur le plan conceptuel comme suit:

G B D C A F E # Again, G is ranked first and E is ranked 7th 
E B G A D C F # 
etc 

Le format de fichier numérique réelle utilise l'index du candidat (base 1), plutôt que l'étiquette, et est donc plus comme:

7 2 4 3 1 6 5 # Same ballots as before. 
5 2 7 1 4 3 6 # A -> 1, G -> 7 

Dans ce format, le nombre indique le candidat, et l'ordre de séquence indique le rang. Le format réel, réel, BLT comprend également un poids initial et un zéro suivant pour indiquer la fin de chaque bulletin de vote, dont je ne me soucie pas trop pour cela.


Ma question est, quelle est la manière la plus élégante pour convertir du premier format à la (numérique) secondes?

Répondre

0

Voici ma solution en Python, et ça marche bien mais ça me semble un peu maladroit. Je suis sûr qu'il y a une façon plus propre (peut-être dans une autre langue?)

Cela m'a pris plus de temps qu'il aurait fallu pour faire le tour hier après-midi, alors peut-être que quelqu'un d'autre peut l'utiliser aussi.

Donné:

ballot = '5 2 4 3 7 6 1' 

une python (ish) -liner pour le convertir:

rank = [i for r,i in sorted((int(r),i+1) for i,r in enumerate(ballot.split())] 
rank = " ".join(rank) 

En variante, sous une forme légèrement plus compréhensible:

# Split into a list and convert to integers 
int_ballot = [int(x) for x in ballot.split()] 

# This is the important bit. 
# enumerate(int_ballot) yields pairs of (zero-based-candidate-index, rank) 
# Use a list comprehension to swap to (rank, one-based-candidate-index) 
ranked_ballot = [(rank,index+1) for index,rank in enumerate(int_ballot)] 

# Sort by the ranking. Python sorts tuples in lexicographic order 
# (ie sorts on first element) 
# Use a comprehension to extract the candidate from each pair 
rank = " ".join([candidate for rank,candidate in sorted(ranked_ballot)]) 
Questions connexes