Main Author: Julien Boudry
License: MIT - Please say hello if you like or use this code!
Contribute: Contribution File
Donation: â‚ż bc1q3jllk3qd9fjvvuqy07tawkv7t6h7qjf55fc2gh or GitHub Sponsor Page
You can also offer me a bottle of good wine.
Presentation | Documentation Book | API References | Voting Methods | Tests
Condorcet manages the stages of an electoral process (configuration, votes ingestion & manipulation, integrity) and calculates the results. It offers natively the implementation of more than 20 voting methods compatible with preferential voting ballots, including Condorcet methods, Alternative Voting, STV, and many others. => Supported Voting Methods
Two different ways to use Condorcet:
- A command line application, for quick use of essential features without complicated technical knowledge. Allowing you to easily compute your election results and stats.
- A PHP library that you can include in your code to take advantage of 100% of the advanced features (advanced manipulations & configurations, extensions & modularity, cache & high performances simulations, advanced input and output methods...).
Both approaches can handle up to hundreds of millions of votes (or more) on modest hardware. Although using it as a library allows more configuration and control over this advanced usage.
- Condorcet PHP
Version | PHP Requirements | State | Support |
---|---|---|---|
4.7 | 8.3 | Stable | âś” support provided |
4.6 | 8.2 | Old Stable | âś” support provided |
3.x | 8.1 | Old Stable | ❌ not any support |
2.2 | 7.4 | Old Stable | ❌ support requiring some incentive |
2.0 | 7.1 | Old Stable | ❌ not any support |
1.0 | 5.6 | Old Stable | ❌ not any support |
0.9x | 5.5 | Old Stable | ❌ ℹ Since v0.90, you should consider then it's a new project (api, engine). |
0.14 | 5.5 | Old Stable | ❌ ready for the museum |
All versions require Json and Mbstring extensions (or polyfill). Pdo-Sqlite is recommended if you need to activate the default provided driver for big elections (hundreds of thousands of votes or more).
Support both single-winner methods (with or without the Condorcet criterion) and proportional methods.
Complete list of natively implemented methods, their options (variants), and implementation choices
Single-winner methods return a full ranking of all candidates, even though they are generally designed to designate only one winner.
Condorcet / Borda (+ Nauru variant) / Copeland / Dodgson (2 Approximations) / FPTP / Instant-runoff (alternative vote) / Kemeny–Young / Minimax (+ variants) / Ranked Pairs (+ variants) / Schulze (+ variants)
Random Ballot / Random Candidates
Designed for electing an assembly, return a full ranking of elected candidates.
Single Transferable Vote (STV) / Comparison of Pairs of Outcomes by the Single Transferable Vote (CPO-STV) / Highest Averages Methods (Sainte-Laguë, Jefferson/D'Hondt, and variants) / Largest Remainder Methods (with different quotas)
Condorcet is designed to be easily extensible with new algorithms (they don't need to share the same namespace).
- More explanations in this documentation
- Modules Skeleton: A template for starting development quickly and following best practices.
- Manage an election
- Respect an election cycle: Register candidates, register votes, get results from many algorithms.
- Ordered votes, tag votes, delete votes, simulate partial results.
- Many input types available (string, JSON, objects...)
- Import from Condorcet Election Format (and export to), Debian Format, David Hill Format
- Integrity check (checksumming)
- Support for storing elections (serializing Election object, export data...)
- Some methods can be used nearly by end users (vote constraints, anti-spam check, parsing input, human-friendly results and stats...)
- Get election results and stats
- Get the natural Condorcet Winner, Loser, Pairwise, Paradox...
- Get full ranking from advanced voting methods
- Get additional stats from these methods
- Force ranking of all candidates implicitly (default) or allow voters to not rank all candidates.
- Put weight on certain votes, and give more importance to certain voters.
- Be more powerful
- All are objects, all are abstract (But there are many higher-level functions and input types).
- Candidates and Votes are objects which can take part in multiple elections at the same time and change their name or ranking dynamically. This allows powerful tools to simulate elections.
- Manage hundreds of billions of votes by activating an external driver to store (instead of RAM) an unlimited number of votes during the computation phase. A PDO driver is provided by default, an example is provided with SQLite, and an interface that allows you to design other drivers.
- Smart cache system, allows calling computation methods multiple times without performance issues.
- Extend it! Configure it!
- Modular architecture to extend it without forking Condorcet PHP! Just make your module in your own namespace.
- Election, Candidate, and Vote classes are extensible.
- Add your own ranking algorithm.
- Create your own vote constraints.
- Use your own datastore driver to manage very large elections in your way without RAM limit.
- Many configuration options and methods.
- Modular architecture to extend it without forking Condorcet PHP! Just make your module in your own namespace.
Condorcet PHP is not designed for high performance. But it can handle virtually unlimited voting without limit or degrading performance, it's a linear and predictable scheme.
It has no certification or proven implementation that would guarantee a very high level of reliability. However, there are many written tests for each voting method and feature. This ensures an excellent level of confidence in the results.
Can be installed natively from source (with composer), from PHAR file, from Docker image (build or pull).
Condorcet as a command line application, installation instructions
Namespace \CondorcetPHP\Condorcet
is used.
Can be installed as you prefer with: Composer / Natively provided autoloader / Any PSR-4 compatible autoloader.
Living and learning examples, giving an overview but not exhaustive of the possibilities of the library.
The precise documentation of methods can be found in Markdown format in the "Documentation" folder for each release.
- General Overview (not exhaustive and partial, but just a great tour.)
- Advanced Object Management
- Condorcet Documentation Book provides many code examples
- Manage millions of votes with an external database driver Your own driver, or the provided simple driver for PDO.
The code closely follows PSR-12 standards (only method naming conventions might differ) when they are not unnecessarily authoritarian or conservative, and follows some additional rules. Code is checked and fixed with CS-Fixer custom rules through Laravel Pint.
- Complete and complex use case with all voting methods chained, 6 candidates, 2 seats, and one thousand votes (many with implicit ranking).
- Memory usage: less than 3M
- Execution time (after JIT compiling): less than 160ms
- Execution time (without JIT): less than 250ms
This varies because some voting methods are slow by design and others (like Schulze) are very fast. Have a look at the methods benchmarks.
1 000 random votes. Memory consumption comes from votes more than combinations.
- use Kemeny-Young 7 candidates: ~5MB - 10ms
- use Kemeny-Young 8 candidates: ~6MB - 10ms
- use Kemeny-Young 9 candidates: ~7MB - 1.1s
- use Kemeny-Young 10 candidates: ~7MB - 14s
- use Kemeny-Young 11 candidates: ~8MB - 193s
Extending PHP memory_limit allows you to manage hundreds of thousands of votes, but it can be slower than outsourcing this data (PHP doesn't like that) and it's not extensible to infinity.
If you need to manage an election with more than 50,000 votes, you should consider externalizing your data. Condorcet provides a simple PDO driver to store data outside RAM between processing steps. This driver stores it into a classical relational database system and supports hundreds of millions of votes (or more). A very simple example with SQLite is provided and very easy to activate.
You can also develop your own custom datastore driver (to store in NoSQL... or whatever you fancy), the modular architecture allows you to link it easily.
Have a look at the documentation book
Benchmark on a modern machine (Linux - x64 - PHP 8.1 - CLI).
- ...