Beispiel #1
0
def test_strict_majority(tiebreaker):
    A, B, C = 0, 1, 2
    election = [
        [A, B, C],
        [B, C, A],
        [A, C, B],
    ]
    assert irv(election, tiebreaker) == A

    election = [
        *3 * [[A, B, C]],
        *7 * [[B, C, A]],
        *2 * [[C, B, A]],
    ]
    assert irv(election, tiebreaker) == B
Beispiel #2
0
def test_eliminate_no_votes():
    # First, 0 is eliminated for getting no votes.
    # Then 1 and 2 are tied.
    election = [[1, 0, 2], [2, 0, 1]]

    # With no tiebreaker, None is returned because of tie between 1 and 2.
    assert irv(election) is None

    # With order tiebreaker, 2 is eliminated, because lower IDs preferred.
    # Then 1 wins unanimously.
    # If 0 had not been eliminated, 0 would win the tie between 0 and 1.
    assert irv(election, 'order') == 1

    # With random tiebreaker, 0 should never win.
    assert collect_random_results(irv, election) == {1, 2}
Beispiel #3
0
def test_no_tiebreak_tied_losers():
    A, B, C = 0, 1, 2
    election = [
        [A, B, C],
        [B, C, A],
        [A, C, B],
        [B, C, A],
        [C, B, A],
        [C, A, B],
        [C, B, A],
    ]
    assert irv(election) is None
Beispiel #4
0
def test_one_round():
    # 60% majority, tie between others
    election = np.array([[2, 0, 1], [0, 1, 2], [2, 0, 1], [1, 2, 0], [2, 1, 0],
                         [2, 0, 1], [1, 0, 2], [2, 0, 1], [2, 1, 0], [0, 2,
                                                                      1]])
    assert irv(election) == 2
    assert irv(election, tiebreaker='order') == 2
    assert irv(election, tiebreaker='random') == 2

    # 50% winner, 30%, 20% for others
    # In this case, Candidate 2 picks up an additional vote in the runoff,
    # making it unambiguous.
    election = np.array([[2, 0, 1], [0, 1, 2], [1, 0, 2], [2, 0, 1], [2, 1, 0],
                         [0, 1, 2], [2, 0, 1], [1, 2, 0], [2, 1, 0], [0, 2,
                                                                      1]])
    assert irv(election) == 2
    assert irv(election, tiebreaker='order') == 2
    assert irv(election, tiebreaker='random') == 2

    # 50%, 30%, 20%
    # This is ambiguous. It would make sense for the 50% candidate to win
    # outright, but technically they don't have a majority, so we have to
    # eliminate another, so there's now a 50/50 split, and then tiebreak
    # between the two, which might pick a different candidate, even though they
    # got fewer first-preference votes.
    election = np.array([[2, 0, 1], [0, 1, 2], [1, 0, 2], [2, 0, 1], [2, 1, 0],
                         [0, 1, 2], [2, 0, 1], [1, 0, 2], [2, 1, 0], [0, 2,
                                                                      1]])
    assert irv(election) is None
    assert irv(election, tiebreaker='order') == 0
    assert collect_random_results(irv, election) == {0, 2}

    # 50%, 25%, 25%
    # If 0 eliminated by tiebreak, another transfers to each and 2 wins
    # If 1 eliminated by tiebreak, 2 transfer to 0 and a second tiebreak
    # So either 0 or 2 wins.
    election = np.array([[2, 0, 1], [0, 1, 2], [1, 0, 2], [2, 0, 1], [2, 0, 1],
                         [1, 0, 2], [2, 1, 0], [0, 2, 1]])
    assert irv(election) is None
    assert irv(election, tiebreaker='order') == 0
    assert collect_random_results(irv, election) == {0, 2}

    # 50%, 25%, 25%
    # 0 or 1 is eliminated and transfers votes to the other, making it a tie.
    # So any candidate can win.
    election = np.array([[2, 0, 1], [0, 1, 2], [1, 0, 2], [2, 0, 1], [2, 0, 1],
                         [1, 0, 2], [2, 1, 0], [0, 1, 2]])
    assert irv(election) is None
    assert irv(election, tiebreaker='order') == 0
    assert collect_random_results(irv, election) == {0, 1, 2}

    # 50% exact tie
    election = np.array([[2, 0, 1], [1, 0, 2], [1, 2, 0], [2, 1, 0]])
    assert irv(election) is None
    assert irv(election, tiebreaker='order') == 1
    assert collect_random_results(irv, election) == {1, 2}

    # Complete cycle, anyone can win
    election = np.array([[0, 1, 2], [1, 2, 0], [2, 0, 1]])
    assert irv(election) is None
    assert irv(election, tiebreaker='order') == 0
    assert collect_random_results(irv, election) == {0, 1, 2}
Beispiel #5
0
def test_legit_winner_none(election):
    election = np.asarray(election)
    n_cands = election.shape[1]
    assert irv(election) in {None} | set(range(n_cands))
Beispiel #6
0
def test_legit_winner(election, tiebreaker):
    election = np.asarray(election)
    n_cands = election.shape[1]
    assert irv(election, tiebreaker) in range(n_cands)
Beispiel #7
0
def test_examples(tiebreaker):
    # Standard Tennessee example (three round)
    # https://en.wikipedia.org/wiki/Template:Tenn_voting_example
    Memphis, Nashville, Chattanooga, Knoxville = 0, 1, 2, 3
    election = [
        *42 * [[Memphis, Nashville, Chattanooga, Knoxville]],
        *26 * [[Nashville, Chattanooga, Knoxville, Memphis]],
        *15 * [[Chattanooga, Knoxville, Nashville, Memphis]],
        *17 * [[Knoxville, Chattanooga, Nashville, Memphis]],
    ]
    assert irv(election, tiebreaker) == Knoxville

    # Three-round example from Ques 9
    # http://www.yorku.ca/bucovets/4380/exercises/exercises_1_a.pdf
    v, w, x, y, z = 0, 1, 2, 3, 4
    election = [
        *11 * [[v, w, x, y, z]],
        *12 * [[w, x, y, z, v]],
        *13 * [[x, v, w, y, z]],
        *14 * [[y, w, v, z, x]],
        *15 * [[z, v, x, w, y]],
    ]
    assert irv(election, tiebreaker) == w

    # Two-round example from
    # https://en.wikipedia.org/wiki/Instant-runoff_voting#Five_voters,_three_candidates
    Bob, Bill, Sue = 0, 1, 2
    election = np.array([
        [Bob, Bill, Sue],  # a
        [Sue, Bob, Bill],  # b
        [Bill, Sue, Bob],  # c
        [Bob, Bill, Sue],  # d
        [Sue, Bob, Bill],  # e
    ])
    assert irv(election, tiebreaker) == Sue

    # Two-round example from
    # https://en.wikipedia.org/wiki/Condorcet_method#Comparison_with_instant_runoff_and_first-past-the-post_(plurality)
    A, B, C = 0, 1, 2
    election = [
        *499 * [[A, B, C]],
        *3 * [[B, C, A]],
        *498 * [[C, B, A]],
    ]
    assert irv(election, tiebreaker) == C  # "IRV elects C"

    # Two-round example from
    # http://pi.math.cornell.edu/~ismythe/Lec_04_web.pdf#page=16
    election = [
        [A, C, B],
        [A, C, B],
        [B, C, A],
        [B, C, A],
        [C, A, B],
    ]
    assert irv(election, tiebreaker) == A  # "A wins under IRV"

    # Examples from http://pi.math.cornell.edu/~ismythe/Lec_05_web.pdf#page=19
    # Two-round
    election = [
        *6 * [[A, B, C]],
        *5 * [[C, A, B]],
        *4 * [[B, C, A]],
        *2 * [[B, A, C]],
    ]
    assert irv(election, tiebreaker) == A  # A wins IRV

    # Two-round
    election = [
        *6 * [[A, B, C]],
        *5 * [[C, A, B]],
        *4 * [[B, C, A]],
        *2 * [[A, B, C]],
    ]
    assert irv(election, tiebreaker) == C  # C wins IRV

    # Four-round example from
    # https://medium.com/@t2ee6ydscv/how-ranked-choice-voting-elects-extremists-fa101b7ffb8e
    r, b, g, o, y = 0, 1, 2, 3, 4
    election = [
        *31 * [[r, b, g, o, y]],
        *5 * [[b, r, g, o, y]],
        *8 * [[b, g, r, o, y]],
        *1 * [[b, g, o, r, y]],
        *6 * [[g, b, o, r, y]],
        *1 * [[g, b, o, y, r]],
        *6 * [[g, o, b, y, r]],
        *2 * [[o, g, b, y, r]],
        *5 * [[o, g, y, b, r]],
        *7 * [[o, y, g, b, r]],
        *28 * [[y, o, g, b, r]],
    ]
    assert irv(election) == r