https://github.com/perlkonig/condorcet
A .NET Standard 2.0 library that implements various Condorcet voting algorithms
https://github.com/perlkonig/condorcet
algorithm ballot candidate choice condorcet condorcet-voting-algorithms csharp-library netstandard netstandard20 rank ranking-algorithm schulze-method vote voting
Last synced: about 1 month ago
JSON representation
A .NET Standard 2.0 library that implements various Condorcet voting algorithms
- Host: GitHub
- URL: https://github.com/perlkonig/condorcet
- Owner: Perlkonig
- License: mit
- Created: 2018-12-13T18:00:40.000Z (over 6 years ago)
- Default Branch: master
- Last Pushed: 2018-12-14T20:17:38.000Z (over 6 years ago)
- Last Synced: 2025-03-29T20:23:04.491Z (2 months ago)
- Topics: algorithm, ballot, candidate, choice, condorcet, condorcet-voting-algorithms, csharp-library, netstandard, netstandard20, rank, ranking-algorithm, schulze-method, vote, voting
- Language: C#
- Homepage:
- Size: 13.7 KB
- Stars: 6
- Watchers: 2
- Forks: 2
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Condorcet Library
A C# library that implements various Condorcet voting algorithms.
[Hosted by GitHub](https://github.com/Perlkonig/Condorcet)
## Ballots
All the algorithms use the same ballot: an dictionary whose key is the candidate name (of type `T`, which must implement `IComparable`) and whose value is the rank (which must be an unsigned integer). Typically, the absolute values of the ranks is irrelevant. All that matters is their sequence. For example, you could rank your first choice as `100` as long as your next choice was something like `110` and so on down the line. But this might differ by algorithm. Traditionally you indicate your first choice with a `1` and go from there. You do *not* need to vote for all candidates. Skipping a candidate simply means they're at the very bottom of your list.
Here's an example of a ballot ranking five candidates in the order ACBED:
```csharp
Dictionary b1 = new Dictionary
{
{'A', 1},
{'C', 2},
{'B', 3},
{'E', 4},
{'D', 5}
};
```## Available Algorithms
For all algorithms, the constructor takes the list of candidates, after which you can use the `AddBallot` method. You can then call the `Rank` method to get a list of candidates in order, winner first.
### Schulze
A description of the method can be found on [Wikipedia](https://en.wikipedia.org/wiki/Schulze_method).
```csharp
using System.Collections.Generic;
using Condorcet;HashSet candidates = new HashSet {'A', 'B', 'C', 'D', 'E'};
//Build the ballot
Dictionary ballot = new Dictionary
{
{'A', 1},
{'C', 2},
{'B', 3},
{'E', 4},
{'D', 5}
};//Construct the Schulze object with the list of candidates
Schulze s = new Schulze(candidates);//Assume 50 people all voted the same way
s.AddBallot(ballot, 50);//Get the rankings
char[] ranked = s.Rank();//Because everybody voted unanimously, you should get the array ['A', 'C', 'B', 'E', 'D'].
//See the tests for more examples.
```### Ranked Pairs
A description of the method can be found on [Wikipedia](https://en.wikipedia.org/wiki/Ranked_pairs).
```csharp
using System.Collections.Generic;
using Condorcet;HashSet candidates = new HashSet {"Memphis", "Nashville", "Chattanooga", "Knoxville"};
Dictionary b1 = new Dictionary
{
{"Chattanooga", 1},
{"Knoxville", 2},
{"Nashville", 3},
{"Memphis", 4}
};RankedPair s = new RankedPair(candidates);
s.AddBallot(b1, 42);
string[] expected = new string[] {"Chattanooga", "Knoxville", "Nashville", "Memphis"};
Assert.True(expected.SequenceEqual(s.Rank()));//Because everybody voted unanimously, you should get the array ["Chattanooga", "Knoxville", "Nashville", "Memphis"].
//See the tests for more examples.
```## TODO
* I'm a novice programmer. Any suggestions to improve efficiency or readability would be warmly welcomed.
* I'm always looking for more test cases. I need to add code for ties.