Giter VIP home page Giter VIP logo

clj-schulze's Introduction

clj-schulze

A Clojure implementation of the Schulze voting method.

Installation

Add the following to the dependency list in your project.clj:

[com.github.bdesham/clj-schulze "0.9.4"]

See the Clojars page for instructions for Gradle and Maven.

Usage

This library provides a single public function, called schulze-winner:

(use 'clj-schulze.core)

(let [candidates #{:a :b :c},
      ballots {[:a :b :c] 3,
               [:b :a :c] 3,
               [:b #{:a :c}] 1,
               [:c :b :a] 1}]
  (schulze-winner ballots candidates))

; returns :b

Just pass a list of candidates and a list of ballots to schulze-winner and it will return the winner or, if there is not a unique winner, a set consisting of the winners.

Input formats

candidates is a set specifying the valid candidates, i.e. the entries which may appear in ballots. Each entry in this set must be a keyword. An example is

(def candidates #{:a :b :c :d :e})

ballots is a map in which each key is a ballot and each corresponding value is the number of times that ballot occurs. Each ballot is a vector listing candidates from the most preferred (the first element of the vector) to the least preferred (the last element). For example, the vector

[:a :b :c]

expresses that the voter prefers candidate a over candidate b, and both of these over candidate c. Ties can be expressed by putting more than one candidate in a set:

[:a #{:b :c}]

expresses that the voter prefers candidate a over candidates b and c, but has no preference among b and c.

If any valid candidates are omitted from the ballot, it is assumed that (1) the voter has no preference between the omitted candidates, and (2) the voter prefers all listed candidates to all omitted candidates. Thus with the example set of candidates above, the preceding ballot is equivalent to

[:a #{:b :c} #{:d :e}]

Tip: if you just have a list of ballots without frequencies, you can use frequencies to get it into the form required by schulze-winner.

Implementation details

I wrote this library mostly as an exercise in Clojure, so I’ve cared more about writing idiomatic Clojure code than I have about making the code algorithmically efficient. (Since I’m a relative beginner, though, the code still isn’t necessarily as idiomatic as it could be.) The code is pretty well-documented; please feel free to fork it and make a pull request if you have any improvements.

Voting details

This library doesn’t currently implement any tie-breaking algorithm.

As suggested by Schulze, the strengths of pairwise links are measured by the number of winning votes.

I am not an expert in voting methods or algorithms. I release this code in the hope that someone will find it useful and instructive, but it has not been audited in any sense and is thus not a great choice in any serious application.

Ballot processing details

There is some leeway in the format of the ballots that are submitted; this section describes the transformations that are automatically applied so you know what you do and don’t need to do to the ballots before you pass them to the schulze-winner function.

Before any processing, each ballot is converted to a canonical form through the following process:

  1. All candidates not included in the ballot are added as shown in the example above.
  2. Any empty sets (#{}) in the ballot are removed.
  3. Any “bare” elements are put into single-element sets, so that the vector consists entirely of sets.

Given the example set of candidates above, the canonical form of the ballot

[:a #{:b :e} #{} #{:d}]

is

[#{:a} #{:b :e} #{:d} #{:c}]

No nesting of sets is permitted.

Further reading

For more information on the Schulze method, see

Author

This library was written by Benjamin Esham.

This project is hosted on GitHub. Please feel free to submit pull requests.

Thanks go to the fine folks in #clojure for answering tons of questions!

Version history

Beginning with version 1.0.0, the version numbers of this project will conform to Semantic Versioning 2.0.

  • 0.9.4 (2012-09-11)
    • Update project.clj, use Clojure 1.4, and change the license to the preferred Clojure license, EPL.
  • 0.9.2 (2011-06-17)
    • Mark all functions except for schulze-winner as private. (Continue to test the now-private functions using a workaround.)
  • 0.9.1 (2011-06-15)
    • Refine everything and update documentation in preparation for public release.
  • 0.9.0 (2011-06-14)
    • First working version! The library passes a number of tests extracted from online Schulze-method examples.
  • 2011-05-29
    • Project started

License

Copyright © 2011–2012 Benjamin D. Esham. This project is distributed under the Eclipse Public License, the same as that used by Clojure. A copy of the license is included as “epl-v10.html” in this distribution.

clj-schulze's People

Contributors

bdesham avatar

Watchers

James Cloos avatar Dave Dixon avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.