diff --git a/src/perl/prefvote/README.md b/src/perl/prefvote/README.md index f20908e..9aee356 100644 --- a/src/perl/prefvote/README.md +++ b/src/perl/prefvote/README.md @@ -219,9 +219,8 @@ It only makes sense for tie-breaking, where becomes meaningful if everything els For high-stakes elections, a runoff may be a more appropriate action. For polls on approval of a proposal or measure, a tie should mean failure to achieve a majority. - _PrefVote::Core_ makes average choice rank (ACR) data available to subclasses which must use it for tie-breaking, - except when the _no-tiebreak_ configuration flag is set. - Ties should be extremely unlikely with ACR tie-breaking enabled. + _PrefVote::Core_ makes average choice rank (ACR) data available to subclasses which must use it for tie-breaking. + Ties are less likely due to ACR tie-breaking, but cannot be made impossible. - result\_yaml() diff --git a/src/perl/prefvote/bin/vote-count b/src/perl/prefvote/bin/vote-count index 3a8615d..367c155 100755 --- a/src/perl/prefvote/bin/vote-count +++ b/src/perl/prefvote/bin/vote-count @@ -266,14 +266,6 @@ Supported configuration settings: =over 1 -=item no-tiebreak - -takes a boolean value, 1 for true or 0 for false. -This indicating PrefVote voting methods should disable the -normal tie-breaking by Average Choice Rank (ACR). -The default is false, which allows tie-breaking with ACR. -This setting is used by the STV, Schulze and RankedPairs voting methods. - =item input-ties (for use in testing only) diff --git a/src/perl/prefvote/lib/PrefVote/Config.pm b/src/perl/prefvote/lib/PrefVote/Config.pm index 24f4c21..21140e1 100644 --- a/src/perl/prefvote/lib/PrefVote/Config.pm +++ b/src/perl/prefvote/lib/PrefVote/Config.pm @@ -68,12 +68,6 @@ All configuration entries default to non-existent and undefined. =over 1 -=item no-tiebreak - -If defined, this contains a boolean flag that inhibits the PrefVote system's use of L -"average choice rank" (ACR) data for tie-breaking. This is recognized by L, L and -L. - =item input-ties (experimental) diff --git a/src/perl/prefvote/lib/PrefVote/Core.pm b/src/perl/prefvote/lib/PrefVote/Core.pm index a74f4cb..f8cf157 100644 --- a/src/perl/prefvote/lib/PrefVote/Core.pm +++ b/src/perl/prefvote/lib/PrefVote/Core.pm @@ -1103,9 +1103,8 @@ For low-stakes polls, such as where to meet for dinner, a random selection such For high-stakes elections, a runoff may be a more appropriate action. For polls on approval of a proposal or measure, a tie should mean failure to achieve a majority. -I makes average choice rank (ACR) data available to subclasses which must use it for tie-breaking, -except when the I configuration flag is set. -Ties should be extremely unlikely with ACR tie-breaking enabled. +I makes average choice rank (ACR) data available to subclasses which must use it for tie-breaking. +Ties are less likely with ACR tie-breaking, but cannot be made impossible. =item result_yaml() diff --git a/src/perl/rankedpairs/lib/PrefVote/RankedPairs.pm b/src/perl/rankedpairs/lib/PrefVote/RankedPairs.pm index dc405b5..705e7a2 100644 --- a/src/perl/rankedpairs/lib/PrefVote/RankedPairs.pm +++ b/src/perl/rankedpairs/lib/PrefVote/RankedPairs.pm @@ -408,13 +408,10 @@ sub cmp_choice } # 2nd comparison: choice/candidate's average ballot placement in ascending order - my $tiebreak_disabled = $self->config("no-tiebreak") // 0; # config flag to disable tie-breaking by avg rank - if ( not $tiebreak_disabled ) { - my $place1 = $self->average_ranking($cand1); - my $place2 = $self->average_ranking($cand2); - if ( not fp_equal( $place1, $place2 ) ) { - return fp_cmp( $place1, $place2 ); - } + my $place1 = $self->average_ranking($cand1); + my $place2 = $self->average_ranking($cand2); + if ( not fp_equal( $place1, $place2 ) ) { + return fp_cmp( $place1, $place2 ); } return 0; diff --git a/src/perl/schulze/lib/PrefVote/Schulze/Round.pm b/src/perl/schulze/lib/PrefVote/Schulze/Round.pm index edb8684..cc7e358 100644 --- a/src/perl/schulze/lib/PrefVote/Schulze/Round.pm +++ b/src/perl/schulze/lib/PrefVote/Schulze/Round.pm @@ -630,10 +630,6 @@ sub narrow_winners my $self = shift; my $schulze_ref = shift; # ref to PrefVote::Schulze object - # skip step if configuration flag disables PrefVotes's tie-breaking by average rank to strictly follow algorithm - my $tiebreak_disabled = $self->config("no-tiebreak") // 0; # config flag to disable tie-breaking by avg rank - return if $tiebreak_disabled; - # sort winners by average ballot placement order my @winning_group = sort { fp_cmp( $schulze_ref->average_ranking($a), $schulze_ref->average_ranking($b) ) } $self->win_flag_keys(); diff --git a/src/perl/stv/lib/PrefVote/STV.pm b/src/perl/stv/lib/PrefVote/STV.pm index c8a54ea..29495d4 100644 --- a/src/perl/stv/lib/PrefVote/STV.pm +++ b/src/perl/stv/lib/PrefVote/STV.pm @@ -270,14 +270,12 @@ sub process_winners # quota exceeded - we have a winner! my @round_winner; my $place = $self->winners_count() + 1; - my $tiebreak_disabled = $self->config("no-tiebreak") // 0; # config flag to disable tie-breaking by avg rank foreach my $curr_key (@round_candidate) { # mark all the candidates over quota who are tied for first place as winners if ( ( $round->tally_get($curr_key)->votes() == $round->tally_get( $round_candidate[0] )->votes() ) - and ( $tiebreak_disabled - or fp_equal( $self->average_ranking($curr_key), $self->average_ranking( $round_candidate[0] ) ) ) + and fp_equal( $self->average_ranking($curr_key), $self->average_ranking( $round_candidate[0] ) ) ) { my $c_votes = $round->tally_get($curr_key)->votes(); @@ -316,13 +314,11 @@ sub eliminate_losers # mark candidates tied for last as eliminated my @round_eliminated; - my $tiebreak_disabled = $self->config("no-tiebreak") // 0; # config flag to disable tie-breaking by avg rank for ( $i = ( scalar @round_candidate ) - 1 ; $i > 0 ; $i-- ) { my $indexed_cand = $round_candidate[$i]; if ( ( $round->tally_get($last_cand)->votes() == $round->tally_get($indexed_cand)->votes() ) - and ( $tiebreak_disabled - or fp_equal( $self->average_ranking($last_cand), $self->average_ranking($indexed_cand) ) ) + and fp_equal( $self->average_ranking($last_cand), $self->average_ranking($indexed_cand) ) ) { $round->tally_get($indexed_cand)->mark_as_eliminated(); @@ -370,7 +366,6 @@ sub count } # sort in descending order - my $tiebreak_disabled = $self->config("no-tiebreak") // 0; # config flag to disable tie-breaking by avg rank my @round_candidate = $round->sort_candidates( sub { # 1st/primary comparison: votes for candidate in descending order @@ -381,12 +376,10 @@ sub count } # 2nd comparison: average ballot-ranking position in ascending order - if ( not $tiebreak_disabled ) { - my $acr0 = $self->average_ranking( $_[0] ); - my $acr1 = $self->average_ranking( $_[1] ); - if ( not fp_equal( $acr0, $acr1 ) ) { - return fp_cmp( $acr0, $acr1 ); - } + my $acr0 = $self->average_ranking( $_[0] ); + my $acr1 = $self->average_ranking( $_[1] ); + if ( not fp_equal( $acr0, $acr1 ) ) { + return fp_cmp( $acr0, $acr1 ); } # 3rd comparison: alphabetical (so ties in testing keep consistent order)