Ballots

There are three different types of ballots that are used in preference voting.

  1. A linear order of the candidates: In this ballot, voters rank the candidates from most preferred to least preferred. The two main assumptions are that all the candidates must be ranked, and no two candidates can be tied for the same rank. This ballot is represented as a list.

  2. A (truncated) ranking of the candidates: In this ballot, voters rank the candidates from most preferred to the least preferred. Voters are not required to rank all the candidates, and multiple candidates can be tied for the same rank. This ballot is represented by the Ranking class described below.

  3. An assignment of grades to candidates: Given a fixed set of grades (which may be numbers or strings, such as “A”, “B”, “C”, etc.), voters assign a grade from this set to each candidate. Voters do not need to grade all the candidates, and multiple candidates may be assigned the same grade. This ballot is represented by the Grade class described below.

In addition to the above ballots, pref_voting includes a class representing utility functions. A utility function is a function that assigns a real number to each candidate (or alternative).

Ranking Class

class pref_voting.rankings.Ranking(rmap, cmap=None)[source]

A ranking of a set of candidates.

A ranking is a map from candidates to ranks (integers). There is no assumption that all candidates in an election are ranked.

Parameters:
  • rmap (dict[int or str: int]) – Dictionary in which the keys are the candidates and the values are the ranks.

  • cmap (dict[int: str], optional) – Dictionary mapping candidates (keys of the rmap) to candidate names (strings). If not provided, each candidate is mapped to itself.

Example:

The following code creates three rankings:

  1. rank1 is the ranking where 0 is ranked first, 2 is ranked in second-place, and 1 is ranked last.

  2. rank2 is the ranking where 0 and 1 are tied for first place, and 2 is ranked last.

  3. rank3 is the ranking where 0 is ranked first, and 2 is ranked in last place.

rank1 = Ranking({0:1, 1:3, 2:2})
rank2 = Ranking({0:1, 1:1, 2:2})
rank3 = Ranking({0:1, 2:3})

Important

The numerical value of the ranks do not mean anything. They are only used to make ordinal comparisons. For instance, each of the following represents the same ranking: 0 is ranked first, 2 is ranked second, and 1 is ranked in last place.

rank1 = Ranking({0:1, 1:3, 2:2})
rank2 = Ranking({0:1, 1:10, 2:3})
rank3 = Ranking({0:10, 1:100, 2:30})
AAdom(c1s, c2s, use_extended_preferences=False)[source]

Returns True if every candidate in c1s is weakly preferred to every candidate in c2s. If use_extended_preferences is True, then use the extended weak preference.

property cands

Returns a sorted list of the candidates that are ranked.

cands_at_rank(r)[source]

Returns a list of the candidates that are assigned the rank r.

display(cmap=None)[source]

Display the ranking vertically as a column of a table.

Example:

from pref_voting.profiles_with_ties import Ranking
r = Ranking({0:2, 1:1, 2:3})
print(r)
r.display()
print()

r = Ranking({0:1, 1:1, 2:3})
print(r)
r.display()

print()
r = Ranking({0:1,  2:3})
print(r)
r.display()
1 0 2 
+---+
| 1 |
| 0 |
| 2 |
+---+

( 0  1 ) 2 
+-----+
| 0 1 |
|  2  |
+-----+

0 2 
+---+
| 0 |
| 2 |
+---+
extended_indiff(c1, c2)[source]

Returns True when either both c1 and c2 are not ranked or the rank of c1 equals the rank of c2.

extended_strict_pref(c1, c2)[source]

Returns True when either c1 is ranked and c2 is not ranked or the rank of c1 is strictly smaller than the rank of c2.

extended_weak_pref(c1, c2)[source]

Returns True when either c1 and c2 are in the relation of extended indifference or c1 is extended strictly preferred to c2.

first(cs=None)[source]

Returns the list of candidates from cs that have the highest ranking. If cs is None, then use all the ranked candidates.

has_overvote()[source]

Return True if the voter submitted an overvote (a ranking with a tie).

has_skipped_rank()[source]

Returns True when a rank is skipped.

has_tie()[source]

Return True when the ranking has a tie.

indiff(c1, c2)[source]

Returns True if c1 and c2 are tied.

The return value is True when both c1 and c2 are ranked and the rank of c1 equals the rank of c2.

is_empty()[source]

Return True when the ranking is empty.

is_linear(num_cands)[source]

Return True when the ranking is a linear order of num_cands candidates.

is_ranked(c)[source]

Returns True if the candidate c is ranked.

is_truncated_linear(num_cands)[source]

Return True when the ranking is a truncated linear order, so it is linear but ranks fewer than num_cands candidates.

last(cs=None)[source]

Returns the list of candidates from cs that have the worst ranking. If cs is None, then use all the ranked candidates.

normalize_ranks()[source]

Change the ranks so that they start with 1, and the next rank is the next integer after the previous rank.

Example:

from pref_voting.profiles_with_ties import Ranking
r = Ranking({0:1, 1:3, 2:2})
print(r.rmap)
r.normalize_ranks()
print("After normalizing: ", r.rmap)

r = Ranking({0:1, 1:10, 2:3})
print(r.rmap)
r.normalize_ranks()
print("After normalizing: ", r.rmap)

r = Ranking({0:-100, 1:123, 2:0})
print(r.rmap)
r.normalize_ranks()
print("After normalizing: ", r.rmap)

r = Ranking({0:10, 1:10, 2:100})
print(r.rmap)
r.normalize_ranks()
print("After normalizing: ", r.rmap)
{0: 1, 1: 3, 2: 2}
After normalizing:  {0: 1, 1: 3, 2: 2}
{0: 1, 1: 10, 2: 3}
After normalizing:  {0: 1, 1: 3, 2: 2}
{0: -100, 1: 123, 2: 0}
After normalizing:  {0: 1, 1: 3, 2: 2}
{0: 10, 1: 10, 2: 100}
After normalizing:  {0: 1, 1: 1, 2: 2}
property ranks

Returns a sorted list of the ranks.

remove_cand(a)[source]

Returns a Ranking with the candidate a removed.

strict_pref(c1, c2)[source]

Returns True if c1 is strictly preferred to c2.

The return value is True when both c1 and c2 are ranked and the rank of c1 is strictly smaller than the rank of c2.

strong_dom(c1s, c2s, use_extended_preferences=False)[source]

Returns True if AAdom(c1s, c2s) and there is some candidate in c1s that is strictly preferred to every candidate in c2s. If use_extended_preferences is True, then use the extended preferences.

to_indiff_list()[source]

Returns the ranking as a tuple of indifference classes (represented as a tuple).

to_linear()[source]

If the ranking has no ties, return a tuple representing the ranking; otherwise, return None.

truncate_overvote()[source]

Truncate the ranking at an overvote.

weak_dom(c1s, c2s, use_extended_preferences=False)[source]

Returns True if AAdom(c1s, c2s) and there is some candidate in c1s that is strictly preferred to some candidate in c2s. If use_extended_preferences is True, then use the extended preferences.

weak_pref(c1, c2)[source]

Returns True if c1 is weakly preferred to c2.

The return value is True if either c1 is tied with c2 or c1 is strictly preferred to c2.

Mappings

Both the Grade class and Utility class are subclasses of the _Mapping class representing a partial function from a set of candidates to a set of grades or to any floating point number. The _Mapping class is not intended to be used directly, but is used as a base class for the Grade and Utility classes.

class pref_voting.mappings._Mapping(mapping, domain=None, codomain=None, compare_function=None, item_map=None, val_map=None)[source]

A partial function on a set of items.

mapping

a dictionary representing the mapping

domain

the domain of the mapping

codomain

the codomain of the mapping

item_map

a dictionary mapping items to their names

val_map

a dictionary mapping values to their names

compare_function

a function used to compare values

as_dict()[source]

Return the mapping as a dictionary.

average(**kwargs)[source]

Return the average utility of all elements in alternatives. If alternatives is None, then find the average utility of all elements that are assigned a utility.

compare(x, y)[source]

Return 1 if the value of x is greater than the value of y, 0 if they are equal, and -1 if the value of x is less than the value of y.

If either x or y is not defined, then None is returned.

display_str(func_name)[source]

Return a string representation of the mapping.

extended_compare(x, y)[source]

Return 1 if the value of x is greater than the value of y or x has a value and y does not have a value, 0 if they are equal or both do not have values, and -1 if the value of y is greater than the value of x or y has a value and x does not have a value.

If either x or y is not defined, then None is returned.

extended_indiff(x, y)[source]

Returns True if x is indifferent with y using the extended_compare function.

The return value is True when the value of x equals the value of y or both x and y are not assigned values.

extended_strict_pref(x, y)[source]

Returns True if x is strictly preferred to y using the extended compare function.

The return value is True when the value of x is strictly greater than the value of y or x is assigned a value and y is not assigned a value.

extended_weak_pref(x, y)[source]

Returns True if x is weakly preferred to y.

The return value is True when both x and y are assigned utilities and the utility of x is at least as greater than the utility of y.

image(items=None)[source]

The image of the mapping.

indiff(x, y)[source]

Returns True if x is indifferent with y.

The return value is True when both x and y are assigned values and the value of x equals the value of y.

inverse_image(v)[source]

Return all the elements in the domain that are mapped to v.

median(**kwargs)[source]

Return the median utility of all elements in alternatives. If alternatives is None, then find the average utility of all elements that are assigned a utility.

property range

The range of the mapping.

sorted_domain(extended=False)[source]

Return a list of the indifference classes sorted according to the compare function (or extended compare function if extended is True).

strict_pref(x, y)[source]

Returns True if x is strictly preferred to y.

The return value is True when both x and y are assigned values and the value of x is strictly greater than the utility of y according to the compare function.

val(x)[source]

The value assigned to x by the mapping. If x is in the domain but not defined by the mapping, then None is returned.

weak_pref(x, y)[source]

Returns True if x is weakly preferred to y.

The return value is True when both x and y are assigned utilities and the utility of x is at least as greater than the utility of y.

Grade Class

class pref_voting.mappings.Grade(grade_map, grades, candidates=None, cmap=None, gmap=None, compare_function=None)[source]
candidates_with_grade(g)[source]

Returns a list of the items that are assigned the grade g.

extended_ranking()[source]

Return the ranking generated by this grade function.

property graded_candidates

Returns a list of the items that are assigned a grade.

has_grade(x)[source]

Return True if x has a grade.

has_tie(use_extended=False)[source]

Return True when the utility has a tie.

is_linear(num_cands)[source]

Return True when the assignment of grades is a linear order of num_cands candidates.

ranking()[source]

Return the ranking generated by this grade function.

remove_cand(x)[source]

Returns a grade function with the item x removed.

Utility Class

class pref_voting.mappings.Utility(utils, **kwargs)[source]
expectation(prob)[source]

Return the expected utility given a probability distribution prob.

extended_ranking()[source]

Return the ranking generated by this utility function.

has_tie(use_extended=False)[source]

Return True when there are at least two candidates that are assigned the same utility.

has_utility(x)[source]

Return True if x has a utility.

is_linear(num_cands)[source]

Return True when the assignment of utilities is a linear order of num_cands candidates.

items_with_util(u)[source]

Returns a list of the items that are assigned the utility u.

linear_transformation(a=1, b=0)[source]

Return a linear transformation of the utility function: a * u(x) + b.

normalize_by_range()[source]

Return a normalized utility function. Applies the Kaplan normalization to the utility function: The new utility of an element x of the domain is (u(x) - min({u(x) | x in the domain})) / (max({u(x) | x in the domain })).

normalize_by_standard_score()[source]

Replace each utility value with its standard score. The standard score of a value is the number of standard deviations it is above the mean.

ranking()[source]

Return the ranking generated by this utility function.

remove_cand(x)[source]

Returns a utility with the item x removed.

represents_ranking(r, use_extended=False)[source]

Return True when the utility represents the ranking r.

to_approval_ballot(prob_to_cont_approving=1.0, decay_rate=0.0)[source]

Return an approval ballot representation of the mapping. It is assumed that the voter approves of all candidates with a utility greater than the average of the utilities assigned to the candidates.

The parameter prob_to_cont_approving is the probability that the voter continues to approve of candidates after the first candidate is approved. The parameter decay_rate is the exponential decay rate constant in the exponential decay of the probability to continue approving.

to_k_approval_ballot(k, prob_to_cont_approving=1.0, decay_rate=0.0)[source]

Return an k-approval ballot representation of the mapping. It is assumed that the voter approves of the top k candidates with a utility greater than the average of the utilities assigned to the candidates.

The parameter prob_to_cont_approving is the probability that the voter continues to approve of candidates after the first candidate is approved. The parameter decay_rate is the exponential decay rate constant in the exponential decay of the probability to continue approving.

transformation(func)[source]

Return a new utility function that is the transformation of this utility function by the function func.