Tideman’s Ranked Pairs method (developed by Nicolaus Tideman) is a ranked-choice voting algorithm that selects a single winner by constructing a directed graph of pairwise victories and locking in the strongest preferences while avoiding cycles.
This repository provides an object-oriented, benchmarked, file-driven C++17 implementation, wrapped by a Flask API and a minimal HTML front end. It’s now Dockerized (multi-stage) and EC2-ready with Gunicorn for a production-style run.
Live demo: http://13.200.175.4/
- CSV input with support from thousands up to millions of ballots
- High-resolution benchmarking using
<chrono> - Object-oriented design (
TidemanElection,VoteParser,Benchmark) - Robust error handling (bad input, duplicates, file issues)
- Efficient in practice: millions of ballots with ≤9 candidates in milliseconds
- Web service wrapper: C++ executable exposed via Flask API + HTML
- Containerized: Multi-stage Dockerfile, Gunicorn server, EC2-ready (port 80 → 5000)
Example with 3 candidates (Alice, Bob, Charlie):
VoterID,Alice,Bob,Charlie
1,1,2,3
2,2,1,3
3,1,3,2
... up to N rowsEach row = one voter’s ranked preferences.
Header defines candidate names; numbers = rank order (1 = top choice).
Recording Preferences took 32109 µs
Adding Pairs took 0 µs
Locking Pairs took 0 µs
Winner: Charlie
Getting Winner took 999 µs
Handles 1,000,000 votes in milliseconds, showing the practicality of the O(n³) algorithm with small n.
- Build preference matrix from all ballots
- Sort candidate pairs by margin of victory
- Lock edges unless they create a cycle
- Candidate with no incoming edge = winner
In the demo below, the Condorcet winner was Charlie.
Recording.2025-08-19.100654.mp4
How the demo works
- Upload
ballots.csvfrom the HTML page - Flask API sends CSV to C++ binary (
tideman.exe) - Winner + benchmark timings returned as JSON
- UI displays winner (green badge) + raw API response
g++ -std=c++17 -O2 tideman.cpp -o tideman./tideman --file=ballots.csvpip install flask flask-cors
python app.pyThen open index.html (via VS Code Live Server or browser) and upload ballots.
-
Launch EC2 (Ubuntu), open Security Group inbound rules:
- 22 (SSH)
- 80 (HTTP)
-
Install Docker + Git:
sudo apt update
sudo apt install -y docker.io git- Clone & build:
git clone <your-repo-url>
cd <repo>
sudo docker build -t tideman:latest .- Run container:
sudo docker run -d --rm -p 80:5000 --name tideman tideman:latest-
Test:
- On EC2:
curl http://localhost/healthz - From your browser:
http://<EC2-Public-IP>(port 80 → 5000)
- On EC2: