Update quota/VRE in certain rare cases
This commit is contained in:
parent
de19324d2c
commit
c9b189fefe
@ -840,6 +840,44 @@ fn update_vre_ers<N: Number>(state: &mut CountState<N>, opts: &STVOptions) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Update vote required for election if only one candidate remains, used in early bulk election
|
||||||
|
///
|
||||||
|
/// Assumes early bulk election is enabled.
|
||||||
|
fn update_vre_bulk<N: Number>(state: &mut CountState<N>, _opts: &STVOptions) {
|
||||||
|
// If --early-bulk-elect and one candidate remains, VRE is half of the active vote
|
||||||
|
// For display purposes only
|
||||||
|
|
||||||
|
if state.election.seats - state.num_elected == 1 {
|
||||||
|
//let mut log = String::new();
|
||||||
|
|
||||||
|
// Calculate active vote
|
||||||
|
let active_vote = state.candidates.values().fold(N::zero(), |acc, cc| {
|
||||||
|
match cc.state {
|
||||||
|
CandidateState::Elected => { if !cc.finalised && &cc.votes > state.quota.as_ref().unwrap() { acc + &cc.votes - state.quota.as_ref().unwrap() } else { acc } }
|
||||||
|
_ => { acc + &cc.votes }
|
||||||
|
}
|
||||||
|
});
|
||||||
|
//log.push_str(format!("Active vote is {:.dps$}, so the vote required for election is ", active_vote, dps=opts.pp_decimals).as_str());
|
||||||
|
|
||||||
|
let vote_req = active_vote / N::from(state.election.seats - state.num_elected + 1);
|
||||||
|
|
||||||
|
if &vote_req < state.quota.as_ref().unwrap() {
|
||||||
|
// VRE is less than the quota
|
||||||
|
//if let Some(v) = &state.vote_required_election {
|
||||||
|
// if &vote_req != v {
|
||||||
|
//log.push_str(format!("{:.dps$}.", vote_req, dps=opts.pp_decimals).as_str());
|
||||||
|
state.vote_required_election = Some(vote_req);
|
||||||
|
//state.logger.log_literal(log);
|
||||||
|
// }
|
||||||
|
//} else {
|
||||||
|
//log.push_str(format!("{:.dps$}.", vote_req, dps=opts.pp_decimals).as_str());
|
||||||
|
// state.vote_required_election = Some(vote_req);
|
||||||
|
//state.logger.log_literal(log);
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Calculate the quota according to [STVOptions::quota]
|
/// Calculate the quota according to [STVOptions::quota]
|
||||||
fn calculate_quota<N: Number>(state: &mut CountState<N>, opts: &STVOptions) {
|
fn calculate_quota<N: Number>(state: &mut CountState<N>, opts: &STVOptions) {
|
||||||
if state.quota.is_none() || opts.quota_mode == QuotaMode::DynamicByTotal {
|
if state.quota.is_none() || opts.quota_mode == QuotaMode::DynamicByTotal {
|
||||||
@ -910,36 +948,8 @@ fn calculate_quota<N: Number>(state: &mut CountState<N>, opts: &STVOptions) {
|
|||||||
} else {
|
} else {
|
||||||
// No ERS97/ERS76 rules
|
// No ERS97/ERS76 rules
|
||||||
|
|
||||||
// If --early-bulk-elect and one candidate remains, VRE is half of the active vote
|
if opts.early_bulk_elect {
|
||||||
// For display purposes only
|
update_vre_bulk(state, opts);
|
||||||
if opts.early_bulk_elect && (state.election.seats - state.num_elected) == 1 {
|
|
||||||
//let mut log = String::new();
|
|
||||||
|
|
||||||
// Calculate active vote
|
|
||||||
let active_vote = state.candidates.values().fold(N::zero(), |acc, cc| {
|
|
||||||
match cc.state {
|
|
||||||
CandidateState::Elected => { if !cc.finalised && &cc.votes > state.quota.as_ref().unwrap() { acc + &cc.votes - state.quota.as_ref().unwrap() } else { acc } }
|
|
||||||
_ => { acc + &cc.votes }
|
|
||||||
}
|
|
||||||
});
|
|
||||||
//log.push_str(format!("Active vote is {:.dps$}, so the vote required for election is ", active_vote, dps=opts.pp_decimals).as_str());
|
|
||||||
|
|
||||||
let vote_req = active_vote / N::from(state.election.seats - state.num_elected + 1);
|
|
||||||
|
|
||||||
if &vote_req < state.quota.as_ref().unwrap() {
|
|
||||||
// VRE is less than the quota
|
|
||||||
//if let Some(v) = &state.vote_required_election {
|
|
||||||
// if &vote_req != v {
|
|
||||||
//log.push_str(format!("{:.dps$}.", vote_req, dps=opts.pp_decimals).as_str());
|
|
||||||
state.vote_required_election = Some(vote_req);
|
|
||||||
//state.logger.log_literal(log);
|
|
||||||
// }
|
|
||||||
//} else {
|
|
||||||
//log.push_str(format!("{:.dps$}.", vote_req, dps=opts.pp_decimals).as_str());
|
|
||||||
// state.vote_required_election = Some(vote_req);
|
|
||||||
//state.logger.log_literal(log);
|
|
||||||
//}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1119,17 +1129,22 @@ fn elect_hopefuls<'a, N: Number>(state: &mut CountState<'a, N>, opts: &STVOption
|
|||||||
cands_meeting_quota.remove(cands_meeting_quota.iter().position(|c| *c == candidate).unwrap());
|
cands_meeting_quota.remove(cands_meeting_quota.iter().position(|c| *c == candidate).unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
if opts.quota_mode == QuotaMode::ERS97 || (opts.quota_mode == QuotaMode::ERS76 && elected_on_quota) {
|
if opts.quota_mode == QuotaMode::ERS97 || opts.quota_mode == QuotaMode::ERS76 || opts.quota_mode == QuotaMode::DynamicByActive {
|
||||||
// Vote required for election may have changed
|
// Vote required for election may have changed
|
||||||
// ERS97: Check this after every elected candidate (cf. model election)
|
// ERS97: Check this after every elected candidate (cf. model election)
|
||||||
// ERS76: Check this after every candidate elected on a quota, but all at once for candidates elected on VRE (cf. model election)
|
// ERS76: Check this after every candidate elected on a quota, but all at once for candidates elected on VRE (cf. model election)
|
||||||
calculate_quota(state, opts);
|
if opts.quota_mode == QuotaMode::ERS97 || (opts.quota_mode == QuotaMode::ERS76 && elected_on_quota) || opts.quota_mode == QuotaMode::DynamicByActive {
|
||||||
|
calculate_quota(state, opts);
|
||||||
// Repeat in case vote required for election has changed
|
|
||||||
match elect_hopefuls(state, opts, true) {
|
// Repeat in case vote required for election has changed
|
||||||
Ok(_) => { break; }
|
match elect_hopefuls(state, opts, true) {
|
||||||
Err(e) => { return Err(e); }
|
Ok(_) => { break; }
|
||||||
|
Err(e) => { return Err(e); }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} else if opts.early_bulk_elect {
|
||||||
|
// Vote required for election may have changed for display purposes
|
||||||
|
update_vre_bulk(state, opts);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user