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 (eg f64 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

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 vote.

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

Blanket Implementations

Gets the TypeId of self. Read more

Immutably borrows from an owned value. Read more

Mutably borrows from an owned value. Read more

Performs the conversion.

Performs the conversion.

The type returned in the event of a conversion error.

Performs the conversion.

The type returned in the event of a conversion error.

Performs the conversion.