Skip to content

Commit

Permalink
UWIs must always be eliminated first
Browse files Browse the repository at this point in the history
  • Loading branch information
artoonie committed Jan 23, 2024
1 parent 7b45e7e commit 02f4e60
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 19 deletions.
21 changes: 19 additions & 2 deletions src/main/java/network/brightspots/rcv/Tabulator.java
Original file line number Diff line number Diff line change
Expand Up @@ -509,6 +509,11 @@ private List<String> identifyWinners(
throws TabulationAbortedException {
List<String> selectedWinners = new LinkedList<>();

if (getCandidateSignum(UNDECLARED_WRITE_IN_OUTPUT_LABEL, currentRoundTally) != 0) {
// No winners can be selected while undeclared candidates are live
return selectedWinners;
}

if (config.isMultiSeatBottomsUpWithThresholdEnabled()) {
// if everyone meets the threshold, select them all as winners
boolean allMeet =
Expand Down Expand Up @@ -636,8 +641,7 @@ private void selectWinners(
private List<String> dropUndeclaredWriteIns(RoundTally currentRoundTally) {
List<String> eliminated = new LinkedList<>();
String label = UNDECLARED_WRITE_IN_OUTPUT_LABEL;
if (currentRoundTally.getCandidateTally(label) != null
&& currentRoundTally.getCandidateTally(label).signum() == 1) {
if (getCandidateSignum(label, currentRoundTally) == 1) {
eliminated.add(label);
Logger.info(
"Eliminated candidate \"%s\" in round %d because it represents undeclared write-ins. It "
Expand All @@ -647,6 +651,19 @@ private List<String> dropUndeclaredWriteIns(RoundTally currentRoundTally) {
return eliminated;
}

// Returns the signum of the tally for a given label, or 0 if the label is not
// in the current round
// param: label candidate ID
// param: currentRoundTally map of candidate IDs to their tally for a given round
// returns: signum of the candidate tally
private int getCandidateSignum(String label, RoundTally currentRoundTally) {
BigDecimal tally = currentRoundTally.getCandidateTally(label);
if (tally == null) {
return 0;
}
return tally.signum();
}

// eliminate all candidates below a certain tally threshold
// param: currentRoundTallyToCandidates map of tally to candidate IDs for a given round
// returns: eliminated candidates
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,16 @@ Total Number of Ballots,15
Number of Undervotes,0

Rounds,Round 1 Votes,% of vote,transfer,Round 2 Votes,% of vote,transfer,Round 3 Votes,% of vote,transfer,Round 4 Votes,% of vote,transfer,Round 5 Votes,% of vote,transfer
Eliminated,,,,Undeclared Write-ins,,,C,,,,,,,,
Elected,A,,,,,,,,,B,,,,,
A,6,40.0%,0.0000,6.0000,66.66%,0.0000,6.0000,120.0%,0.0000,6.0000,200.0%,0.0000,6.0000,,0
B,3,20.0%,0,3,33.33%,0,3,60.0%,0,3,100.0%,0.0000,3.0000,,0
C,2,13.33%,0,2,22.22%,0,2,40.0%,-2,0,0.0%,0,0,,0
Undeclared Write-ins,4,26.66%,0,4,44.44%,-4,0,0.0%,0,0,0.0%,0,0,,0
Active Ballots,15,,,9,,,5,,,3,,,0,,
Eliminated,Undeclared Write-ins,,,,,,C,,,,,,,,
Elected,,,,A,,,,,,B,,,,,
A,6,40.0%,0,6,54.54%,0.0000,6.0000,120.0%,0.0000,6.0000,200.0%,0.0000,6.0000,,0
B,3,20.0%,0,3,27.27%,0,3,60.0%,0,3,100.0%,0.0000,3.0000,,0
C,2,13.33%,0,2,18.18%,0,2,40.0%,-2,0,0.0%,0,0,,0
Undeclared Write-ins,4,26.66%,-4,0,0.0%,0,0,0.0%,0,0,0.0%,0,0,,0
Active Ballots,15,,,11,,,5,,,3,,,0,,
Current Round Threshold,6,,,6,,,6,,,6,,,6,,
Inactive Ballots by Overvotes,0,,0,0,,0,0,,0,0,,0,0,,0
Inactive Ballots by Skipped Rankings,0,,0,0,,0,0,,0,0,,0,0,,0
Inactive Ballots by Exhausted Choices,0,,0,0,,0,0,,0,0,,0,0,,0
Inactive Ballots by Repeated Rankings,0,,0,0,,0,0,,0,0,,0,0,,0
Inactive Ballots Total,0,,0.0000,0.0000,,4.0000,4.0000,,2.0000,6.0000,,0.0000,6.0000,,0
Inactive Ballots Total,0,,4,4,,0.0000,4.0000,,2.0000,6.0000,,0.0000,6.0000,,0
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,10 @@
"Undeclared Write-ins" : "4"
},
"tallyResults" : [ {
"elected" : "A",
"transfers" : { }
"eliminated" : "Undeclared Write-ins",
"transfers" : {
"exhausted" : "4"
}
} ],
"threshold" : "6"
}, {
Expand All @@ -35,16 +37,13 @@
},
"round" : 2,
"tally" : {
"A" : "6.0000",
"A" : "6",
"B" : "3",
"C" : "2",
"Undeclared Write-ins" : "4"
"C" : "2"
},
"tallyResults" : [ {
"eliminated" : "Undeclared Write-ins",
"transfers" : {
"exhausted" : "4"
}
"elected" : "A",
"transfers" : { }
} ],
"threshold" : "6"
}, {
Expand Down

0 comments on commit 02f4e60

Please sign in to comment.