Python会の正式名称最終投票のために作成した、簡易選挙ツールです。
単記移譲式反復投票を行います。
- 毎回の投票では、自分以下の全てを足しても上の候補に及ばない候補と、それ以下の全候補が落選します。
- 最下位が同数で落選候補を決められない場合、「当該候補以外の同率最下位を全て落選させた場合に、当選の可能性がある」候補のみが残ります。
- それでも落選が決まらない場合は、ランダムに落選させるシミュレーションを繰り返して当選回数を表示する機能があります。 この場合、反復回数をコマンドライン引数として10進非負整数で指定します。
フルスクラッチ実装のため、特にパッケージは必要ありません。
Schulze法による当選候補決定を行います。
こちらはパッケージ python3-vote-core のインストールが必要です。
pipでインストールすることができます。
使い方は election.py, election_schulze.py どちらも同じです。
1人の投票は、候補の記号を選好順に1以上の任意個数並べたものとします。
(Schulze法で許容されている同順位は、ここでは採用していません。)
それらを並べて1人1行のテキストファイルとします。
それを標準入力にリダイレクトしてスクリプトを実行します。
$ python election.py < votes.txt
BACD
EBDACFG
BCAD
B
FBDACG
DBAC
BCAFDEG
BC
BCDAF
DBACFEG
BDACFE
DFBEACG
DABCFEG
DBFACE
DBA
DACBF
BFEDGAC
DBCA
DBA
CDABFE
BADE
BDFA
The 1-th vote: [('B', 10), ('D', 9), ('E', 1), ('F', 1), ('C', 1)]
Candidates ['B', 'D'] survived.
The 2-th vote: [('B', 12), ('D', 10)]
---
The candidate 'B' is the Final Winner !!!
candidates: {'C', 'B', 'D', 'G', 'A', 'E', 'F'}
winner: B
pairs: {('C', 'B'): 2, ('C', 'D'): 6, ('C', 'G'): 16, ('C', 'A'): 6, ('C', 'E'): 14, ('C', 'F'): 13, ('B', 'C'): 20, ('B', 'D'): 12, ('B', 'G'): 22, ('B', 'A'): 19, ('B', 'E'): 21, ('B', 'F'): 20, ('D', 'C'): 15, ('D', 'B'): 10, ('D', 'G'): 20, ('D', 'A'): 16, ('D', 'E'): 18, ('D', 'F'): 17, ('G', 'C'): 1, ('G', 'B'): 0, ('G', 'D'): 0, ('G', 'A'): 1, ('G', 'E'): 1, ('G', 'F'): 0, ('A', 'C'): 15, ('A', 'B'): 3, ('A', 'D'): 4, ('A', 'G'): 19, ('A', 'E'): 17, ('A', 'F'): 15, ('E', 'C'): 4, ('E', 'B'): 1, ('E', 'D'): 2, ('E', 'G'): 10, ('E', 'A'): 3, ('E', 'F'): 2, ('F', 'C'): 5, ('F', 'B'): 2, ('F', 'D'): 3, ('F', 'G'): 13, ('F', 'A'): 5, ('F', 'E'): 12}
strong_pairs: {('C', 'G'): 16, ('C', 'E'): 14, ('C', 'F'): 13, ('B', 'C'): 20, ('B', 'D'): 12, ('B', 'G'): 22, ('B', 'A'): 19, ('B', 'E'): 21, ('B', 'F'): 20, ('D', 'C'): 15, ('D', 'G'): 20, ('D', 'A'): 16, ('D', 'E'): 18, ('D', 'F'): 17, ('A', 'C'): 15, ('A', 'G'): 19, ('A', 'E'): 17, ('A', 'F'): 15, ('E', 'G'): 10, ('F', 'G'): 13, ('F', 'E'): 12}
---
The candidate 'B' is the Final Winner !!!