Perlkonig.Condorcet 0.2.0

dotnet add package Perlkonig.Condorcet --version 0.2.0
NuGet\Install-Package Perlkonig.Condorcet -Version 0.2.0
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Perlkonig.Condorcet" Version="0.2.0" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add Perlkonig.Condorcet --version 0.2.0
#r "nuget: Perlkonig.Condorcet, 0.2.0"
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install Perlkonig.Condorcet as a Cake Addin
#addin nuget:?package=Perlkonig.Condorcet&version=0.2.0

// Install Perlkonig.Condorcet as a Cake Tool
#tool nuget:?package=Perlkonig.Condorcet&version=0.2.0

Condorcet Library

A C# library that implements various Condorcet voting algorithms.

Hosted by GitHub

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:

Dictionary<char, uint> b1 = new Dictionary<char, uint>
{
    {'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.

using System.Collections.Generic;
using Condorcet;

HashSet<char> candidates = new HashSet<char> {'A', 'B', 'C', 'D', 'E'};

//Build the ballot
Dictionary<char, uint> ballot = new Dictionary<char, uint>
{
    {'A', 1},
    {'C', 2},
    {'B', 3},
    {'E', 4},
    {'D', 5}
};

//Construct the Schulze object with the list of candidates
Schulze<char> s = new Schulze<char>(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.

using System.Collections.Generic;
using Condorcet;

HashSet<string> candidates = new HashSet<string> {"Memphis", "Nashville", "Chattanooga", "Knoxville"};

Dictionary<string, uint> b1 = new Dictionary<string, uint>
{
    {"Chattanooga", 1},
    {"Knoxville", 2},
    {"Nashville", 3},
    {"Memphis", 4}
};

RankedPair<string> s = new RankedPair<string>(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.
Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

This package has no dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
0.2.0 892 12/14/2018
0.1.0 629 12/13/2018

Added RankedPair algorithm