smari / voting

A simulator for voting systems.
27 stars 10 forks source link
democracy simulation voting

Voting system simulator

This is a voting system simulator intended to simulate various methods used in proportional voting systems, in particular those that use a biproportional apportionment method for allocation of adjustment seats based on national outcomes. Such systems are common, such as in Iceland, Sweden, and Norway.

M.L. Balinski and G. Demange have shown that only one method, the Alternating-Scaling method, exists that upholds the five axioms for proportionality in matrices. All other methods are heuristic simplifications that approach the optimal solution to varying degrees. This software implements the Alternating-Scaling method, and various other methods for comparison, and provides mechanisms to compare them.

Biproportional allocation on matrices is a common issue that arises when you have multiple parties in multiple constituencies vying for a set number of seats which are pinned to different constituencies. The goal is to determine which parties get which seats in which constituencies.

More generally this approach could be used to allocate limited resources to factories depending on their relative importance or needs, or to solve a number of other biproportional optimization problems.

Installation

It is highly recommended that you use a Virtualenv for voting. Python 3 is recommended.

  1. Create a new Python3 Virtualenv, e.g. 'voting', and enter it.
  2. Make sure you have npm available on your system.
  3. Clone this repository (e.g. from git@github.com:smari/voting)
  4. (cd backend && pip install -r requirements.txt)
  5. (cd vue-frontend && npm install)
  6. (cd vue-frontend && npm run-script build)

That should be enough to start using the simulator.

Command Line Interface

The basic interaction mode. You feed it some data files, it feeds you some results.

For help, try:

python cli.py --help

A few usage examples follow below.

Apportionment

Basic apportioning is done through the apportion command. For help with that command, do:

python cli.py apportion --help

The apportion command takes several flags, including:

Example using the 2013 elections in Iceland and d'Hondt method:

python cli.py apportion \
    --constituencies=../data/constituencies/constituencies_iceland_2013.csv \
    --votes=../data/elections/iceland_landskjorstjorn_2013.csv \
    --divider=dhondt \
    --adjustment-method=alternating-scaling \
    --show-entropy

You can get HTML, LaTeX, MediaWiki or various other types of table output and swap out the divider methods as you please:

python cli.py apportion \
    --constituencies=../data/constituencies/constituencies_iceland_2013.csv \
    --votes=../data/elections/iceland_landskjorstjorn_2013.csv \
    --divider=sainte-lague \
    --adjustment-method=monge \
    --output=html

Simulation

Simulation is done through the simulate command. For help with that command, do:

python cli.py simulate --help

The simulate command takes several flags, including:

Script mode

Because all the parameters can be confusing and sometimes you just want to be able to work with a particular set of settings again and again, there is a "script mode" (for lack of a better term) which allows you to specify a set of rules which then execute:

python cli.py script ../data/presets/iceland2013.json

A script or preset is simply a JSON file that specifies what should happen, see examples in data/presets/.

Web Interface

The web interface can be started by:

python web.py

Then direct a browser to http://localhost:5000/ and start having fun. This is the recommended mode to use the simulator in.

Design

The web interface involves a Javascript Single Page App (SPA) which acts as a visual editor for data that is then passed to the backend for calculations. As such, the SPA is the source of truth, and the backend is "dumb", merely reacting to the frontend. The backend is made with Flask.

The SPA's data model should be the same as the backend's script-mode input model.

The SPA is built using vue.js.

Features

Basic functionality

Apportionment methods

Simulation

Evaluation of methods

Output formats

Web interface

Tickets

See our issue tracker on Github.

Authors

Licence

Released under the terms of the Affero GNU General Public License version 3.