1

最近、アンケートを使用して、さまざまなソフトウェアコンポーネントの重要性に関する一連の意見を収集しました。何らかの形のコンドルセット投票方法が全体的なランクを取得するための最良の方法であると考えて、私はそれを分析するためにOpenSTVを使用することを選択しました。


私のデータは表形式で、スペースで区切られ、多かれ少なかれ次のように見えます。

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形式には、各投票用紙の終わりを示す先頭の重みと後続のゼロも含まれていますが、これについてはあまり気にしません。


私の質問は、最初の形式から(数値の)2番目の形式に変換する最もエレガントな方法は何ですか?

4

1 に答える 1

0

これがPythonでの私の解決策であり、問​​題なく動作しますが、少し不器用に感じます。よりクリーンな方法があると確信しています(おそらく別の言語で?)

これは、昨日の午後に頭を包む必要があるよりも時間がかかったので、他の誰かがこれを使用できるかもしれません。

与えられた:

ballot = '5 2 4 3 7 6 1'

Python one(ish)-変換するライナー:

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)])
于 2010-06-03T00:59:49.820 に答える