From 85b695c1336588ef2214421193c8d74cbd8f54ef Mon Sep 17 00:00:00 2001 From: RunasSudo Date: Thu, 19 Aug 2021 18:08:24 +1000 Subject: [PATCH] Improve performance of Scottish STV Remove reliance on normalising ballot papers --- docs/options.md | 2 +- html/index.js | 2 +- src/stv/gregory.rs | 8 ++++++-- tests/scotland.rs | 4 ++-- 4 files changed, 10 insertions(+), 6 deletions(-) diff --git a/docs/options.md b/docs/options.md index 3155102..27d78fe 100644 --- a/docs/options.md +++ b/docs/options.md @@ -196,7 +196,7 @@ In the BLT file format, each set of preferences can have a specified weight – When ballots are not normalised (default), a set of preferences with weight *n* > 1 is represented as a single ballot with value *n*. This is known as [list-packed ballots](http://www.votingmatters.org.uk/ISSUE21/I21P1.pdf). -When ballots are normalised, a set of preferences with weight *n* > 1 is instead converted to *n* ballots each with value 1. This is generally required only when the rules directly deal with individual ballot values, such as when *Sum surplus transfers* is set to *Per ballot*. +When ballots are normalised, a set of preferences with weight *n* > 1 is instead converted to *n* ballots each with value 1. ## Count optimisations diff --git a/html/index.js b/html/index.js index 8a3b94a..32433a4 100644 --- a/html/index.js +++ b/html/index.js @@ -438,7 +438,7 @@ function changePreset() { document.getElementById('selNumbers').value = 'fixed'; document.getElementById('txtDP').value = '5'; document.getElementById('txtPPDP').value = '5'; - document.getElementById('chkNormaliseBallots').checked = true; + document.getElementById('chkNormaliseBallots').checked = false; document.getElementById('chkRoundQuota').checked = true; document.getElementById('txtRoundQuota').value = '0'; document.getElementById('chkRoundVotes').checked = false; diff --git a/src/stv/gregory.rs b/src/stv/gregory.rs index f55405a..e5cd8fd 100644 --- a/src/stv/gregory.rs +++ b/src/stv/gregory.rs @@ -226,15 +226,19 @@ where SumSurplusTransfersMode::PerBallot => { // Sum transfer per each individual ballot // TODO: This could be moved to distribute_surplus to avoid looping over the votes and calculating transfer values twice + let mut new_value_fraction = reweight_value_fraction(orig_value_fraction, surplus, is_weighted, surplus_fraction, surplus_denom, opts.round_surplus_fractions); + if let Some(dps) = opts.round_votes { + new_value_fraction.floor_mut(dps); + } + let mut result = N::new(); for vote in entry.votes.iter() { - let mut vote_value = &vote.ballot.orig_value * &reweight_value_fraction(orig_value_fraction, surplus, is_weighted, surplus_fraction, surplus_denom, opts.round_surplus_fractions); + let mut vote_value = &new_value_fraction * &vote.ballot.orig_value; if let Some(dps) = opts.round_votes { vote_value.floor_mut(dps); } result += vote_value; } - //state.logger.log_literal(format!("Transferring {:.0} ballot papers, totalling {:.dps$} votes.", entry.num_ballots, entry.num_votes, dps=opts.pp_decimals)); return result; } } diff --git a/tests/scotland.rs b/tests/scotland.rs index 9ce0541..915e06c 100644 --- a/tests/scotland.rs +++ b/tests/scotland.rs @@ -32,7 +32,7 @@ fn scotland_linn07_fixed5() { //.round_votes(Some(5)) .round_quota(Some(0)) .sum_surplus_transfers(stv::SumSurplusTransfersMode::PerBallot) - .normalise_ballots(true) + //.normalise_ballots(true) .quota_criterion(stv::QuotaCriterion::GreaterOrEqual) .early_bulk_elect(false) .pp_decimals(5) @@ -50,7 +50,7 @@ fn scotland_linn07_gfixed5() { .round_votes(Some(5)) .round_quota(Some(0)) .sum_surplus_transfers(stv::SumSurplusTransfersMode::PerBallot) - .normalise_ballots(true) + //.normalise_ballots(true) .quota_criterion(stv::QuotaCriterion::GreaterOrEqual) .early_bulk_elect(false) .pp_decimals(5)