Struct tallystick::condorcet::CondorcetTally [−][src]
pub struct CondorcetTally<T, C = u64> where
T: Eq + Clone + Hash,
C: Copy + PartialOrd + AddAssign + Num + NumCast, { /* fields omitted */ }
Expand description
A generic condorcet tally.
Generics:
T
: The candidate type.C
: The count type.u64
is recommended, but can be modified to use a different type for counting votes (egf64
for fractional vote weights).
Example:
use tallystick::condorcet::CondorcetTally; // A tally with string candidates, one winner, and `f64` counting. let mut tally = CondorcetTally::<&str, f64>::new(1); tally.add_candidate("Alice"); tally.add_candidate("Bob"); tally.add_candidate("Carlos"); tally.add(&vec!["Alice", "Bob", "Carlos"]); tally.add(&vec!["Bob", "Carlos", "Alice"]); tally.add(&vec!["Alice", "Carlos", "Bob"]); tally.add(&vec!["Alice", "Bob", "Carlos"]); let winners = tally.winners();
Implementations
impl<T, C> CondorcetTally<T, C> where
T: Eq + Clone + Hash,
C: Copy + PartialOrd + AddAssign + Num + NumCast,
impl<T, C> CondorcetTally<T, C> where
T: Eq + Clone + Hash,
C: Copy + PartialOrd + AddAssign + Num + NumCast,
Create a new CondorcetTally
with the given number of winners.
If there is a tie, the number of winners might be more than num_winners
.
(See winners()
for more information on ties.)
Create a new CondorcetTally
with the given number of winners, and the provided candidates
Make this tally an unchecked tally, forgoing vote validity checking
When using an unchecked tally, all vote adding methods will return Ok(), so you may elide checking for errors.
Add a candidate to the tally.
Add some candidates to the tally.
Add a weighted vote.
Add a ranked vote.
A ranked vote is a list of tuples of (candidate, rank), where rank is ascending. Two candidates with the same rank are equal in preference.
Add a ranked vote with a weight.
A ranked vote is a list of tuples of (candidate, rank), where rank is ascending. Two candidates with the same rank are equal in preference.
Get total counts for this tally.
Totals are returned as a list of pairwise comparisons
For a pairwise comparison ((T1, T2), C)
, C
is the number of votes where candidate T1
is preferred over candidate T2
.
Example
use tallystick::condorcet::DefaultCondorcetTally; let mut tally = DefaultCondorcetTally::with_candidates(1, vec!["Alice", "Bob"]); for _ in 0..30 { tally.add(&vec!["Alice", "Bob"]); } for _ in 0..10 { tally.add(&vec!["Bob", "Alice"]); } for ((candidate1, candidate2), num_votes) in tally.totals().iter() { println!("{} is preferred over {} {} times", candidate1, candidate2, num_votes); } // Prints: // Alice is preferred over Bob 30 times // Bob is preferred over Alice 10 times
Get a ranked list of all candidates. Candidates with the same rank are tied.
Candidates are ranked in ascending order. The highest ranked candidate has a rank of 0
.
Example
use tallystick::condorcet::DefaultCondorcetTally; let mut tally = DefaultCondorcetTally::with_candidates(1, vec!["Alice", "Bob", "Carlos"]); for _ in 0..50 { tally.add(&vec!["Alice", "Bob", "Carlos"]); } for _ in 0..40 { tally.add(&vec!["Bob", "Carlos", "Alice"]); } for _ in 0..30 { tally.add(&vec!["Carlos", "Alice", "Bob"]); } for ranked in tally.ranked().iter() { println!("{} has a rank of {}", ranked.candidate, ranked.rank); } // Prints: // Alice has a rank of 0 // Bob has a rank of 1 // Carlos has a rank of 2
Get a ranked list of winners. Winners with the same rank are tied.
The number of winners might be greater than the requested num_winners
if there is a tie.
Example
use tallystick::condorcet::DefaultCondorcetTally; let mut tally = DefaultCondorcetTally::new(2); // We ideally want only 2 winnners tally.add_candidates(vec!["Alice", "Bob", "Carlos", "Dave"]); tally.add_weighted(&vec!["Alice"], 3); tally.add_weighted(&vec!["Bob", "Carlos", "Alice"], 2); tally.add_weighted(&vec!["Carlos", "Alice", "Bob"], 2); tally.add(&vec!["Dave"]); // implicit weight of 1 let winners = tally.winners(); println!("We have {} winners", winners.len()); // Prints: "We have 3 winners" (due to Carlos and Bob being tied) // Check for ties that overflow the wanted number of winners if winners.check_overflow() { println!("There are more winners than seats.") } if let Some(overflow_winners) = winners.overflow() { println!("We need to resolve the following overflowing tie between:"); for overflow_winner in overflow_winners { println!("\t {}", overflow_winner); } } // Print all winners by rank for ranked in winners.iter() { println!("{} has a rank of {}", ranked.candidate, ranked.rank); } // Prints: // Alice has a rank of 0 // Bob has a rank of 1 // Carlos has a rank of 1
Build a graph representing all pairwise competitions between all candidates.
Each candidate is assigned a node, vertexes between nodes contain a tuple of counts. Vertexes are directional, leading from the more preferred candidate to the less prefered candidate. The first element of tuple is the number votes where the first candidate is prefered to the second. The second element of the tuple is the number of votes where the second candidate is prefered to the first. The first element in the tuple is always greater than or equal to the second element in the tuple.
If both candidates are equally prefered, two vertexes are created, one going in each direction.
Image Source: [https://arxiv.org/pdf/1804.02973.pdf](https://arxiv.org/pdf/1804.02973.pdf)Get a list of all candidates seen by this tally. Candidates are returned in no particular order.
Check the validity of a vote
This will ensure all candidates are valid, and there are no duplicate candidates.
Check the validity of a ranked vote
This will ensure all candidates are valid, and there are no duplicate candidates.
Auto Trait Implementations
impl<T, C> RefUnwindSafe for CondorcetTally<T, C> where
C: RefUnwindSafe,
T: RefUnwindSafe,
impl<T, C> Send for CondorcetTally<T, C> where
C: Send,
T: Send,
impl<T, C> Sync for CondorcetTally<T, C> where
C: Sync,
T: Sync,
impl<T, C> Unpin for CondorcetTally<T, C> where
C: Unpin,
T: Unpin,
impl<T, C> UnwindSafe for CondorcetTally<T, C> where
C: UnwindSafe,
T: UnwindSafe,