2010-06-03 20 views
0

我最近收集了一系列關於各種軟件組件重要性的意見。考慮到某種形式的Condorcet投票方式是獲得總體排名的最佳方式,我選擇使用OpenSTV進行分析。將每位候選人格式轉換爲OpenSTV BLT格式


我的數據以表格形式,分隔空間,看上去或多或少是:

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 

在這種格式,數字表示的等級和序列順序顯示的候選人。 每個「候選人」的排名(必填)從​​1到7,其中1表示最重要,7表示最不重要。不允許重複。

這種格式讓我覺得這是表示輸出的最自然的方式,直接表示選票格式。


的OpenSTV/BLT格式使用表示相同信息的一種不同的方法,在概念如下:

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 

實際數字文件格式使用候選的(基於1的)索引,而不是標籤,因此更像是:

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

在這種格式,數字表示的候選人,以及序列順序表示秩。實際的,真實的BLT格式還包括領先權重和接下來的零,以表示每次投票的結束,我不太在意這一點。


我的問題是,什麼是從第一格式轉換爲(數字)第二最優雅的方式?

回答

0

這是我在Python中的解決方案,它工作正常,但感覺有點笨拙。我敢肯定,有一種更清潔的方式(可能是另一種語言?)

這讓我花了比昨天下午應該圍繞我的頭腦更長的時間,所以也許別人也可以使用它。

考慮:

ballot = '5 2 4 3 7 6 1' 

Python的一個(ISH)-liner將它轉換:

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

或者,在一個稍微更容易理解的形式:

# 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)]) 
相關問題