2021-05-17 01:30:31 +10:00
|
|
|
# pyRCV2: Preferential vote counting
|
|
|
|
# Copyright © 2020–2021 Lee Yingtong Li (RunasSudo)
|
|
|
|
#
|
|
|
|
# This program is free software: you can redistribute it and/or modify
|
|
|
|
# it under the terms of the GNU Affero General Public License as published by
|
|
|
|
# the Free Software Foundation, either version 3 of the License, or
|
|
|
|
# (at your option) any later version.
|
|
|
|
#
|
|
|
|
# This program is distributed in the hope that it will be useful,
|
|
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
# GNU Affero General Public License for more details.
|
|
|
|
#
|
|
|
|
# You should have received a copy of the GNU Affero General Public License
|
|
|
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
|
|
|
|
from pyRCV2 import constraints
|
|
|
|
|
|
|
|
class CounterStub:
|
|
|
|
pass
|
|
|
|
|
|
|
|
def test_constraints_otten():
|
2021-05-22 17:04:33 +10:00
|
|
|
"""Check constraints matrix is stabilised correctly, according to example by Otten J. Voting Matters 2001;13(3):4-7"""
|
2021-05-17 01:30:31 +10:00
|
|
|
counter = CounterStub()
|
|
|
|
counter._constraint_matrix = constraints.ConstraintMatrix([2, 3])
|
|
|
|
cm = counter._constraint_matrix
|
|
|
|
|
|
|
|
# Fill in details
|
|
|
|
c = cm.get([0, 0]); c.max = 7; c.cands = 4
|
|
|
|
c = cm.get([0, 1]); c.max = 6; c.cands = 11
|
|
|
|
c = cm.get([0, 2]); c.max = 1; c.cands = 2
|
|
|
|
c = cm.get([0, -1]); c.min = 7; c.max = 7; c.cands = 17
|
|
|
|
|
|
|
|
c = cm.get([1, 0]); c.max = 7; c.cands = 7
|
|
|
|
c = cm.get([1, 1]); c.max = 6; c.cands = 3
|
|
|
|
c = cm.get([1, 2]); c.max = 1; c.cands = 1
|
|
|
|
c = cm.get([1, -1]); c.min = 7; c.max = 7; c.cands = 11
|
|
|
|
|
|
|
|
c = cm.get([-1, 0]); c.min = 7; c.max = 7; c.cands = 11
|
|
|
|
c = cm.get([-1, 1]); c.min = 6; c.max = 6; c.cands = 14
|
|
|
|
c = cm.get([-1, 2]); c.min = 1; c.max = 1; c.cands = 3
|
|
|
|
c = cm.get([-1, -1]); c.min = 14; c.max = 14; c.cands = 28
|
|
|
|
|
|
|
|
assert cm.get([0, 0]).max != 4
|
|
|
|
assert cm.get([1, 1]).max != 3
|
|
|
|
assert cm.get([0, 1]).min != 3
|
|
|
|
assert cm.get([1, 0]).min != 3
|
|
|
|
|
|
|
|
assert constraints.step_matrix(counter) == False
|
|
|
|
assert constraints.step_matrix(counter) == False
|
|
|
|
assert constraints.step_matrix(counter) == False
|
|
|
|
assert constraints.step_matrix(counter) == False
|
2021-05-16 22:32:49 +10:00
|
|
|
assert constraints.step_matrix(counter) == False
|
2021-05-17 01:30:31 +10:00
|
|
|
assert constraints.step_matrix(counter) == True
|
|
|
|
|
|
|
|
assert cm.get([0, 0]).max == 4
|
|
|
|
assert cm.get([1, 1]).max == 3
|
|
|
|
assert cm.get([0, 1]).min == 3
|
|
|
|
assert cm.get([1, 0]).min == 3
|
|
|
|
|
|
|
|
# Election of Welsh Man
|
|
|
|
cm.get([0, 2]).elected += 1
|
|
|
|
cm.get([-1, 2]).elected += 1
|
|
|
|
cm.get([0, -1]).elected += 1
|
|
|
|
|
|
|
|
assert cm.get([0, 2]).min != 1
|
|
|
|
assert cm.get([0, 0]).max != 3
|
|
|
|
assert cm.get([1, 0]).min != 4
|
|
|
|
assert cm.get([1, 2]).max != 0
|
|
|
|
|
|
|
|
assert constraints.step_matrix(counter) == False
|
|
|
|
assert constraints.step_matrix(counter) == False
|
|
|
|
assert constraints.step_matrix(counter) == False
|
|
|
|
assert constraints.step_matrix(counter) == False
|
|
|
|
assert constraints.step_matrix(counter) == True
|
|
|
|
|
|
|
|
assert cm.get([0, 2]).min == 1
|
|
|
|
assert cm.get([0, 0]).max == 3
|
|
|
|
assert cm.get([1, 0]).min == 4
|
|
|
|
assert cm.get([1, 2]).max == 0
|
|
|
|
|
|
|
|
# Welsh Man and Welsh Woman are doomed
|
|
|
|
assert cm.get([0, 2]).elected == cm.get([0, 2]).max
|
|
|
|
assert cm.get([1, 2]).elected == cm.get([1, 2]).max
|
|
|
|
cm.get([0, 2]).cands = 1
|
|
|
|
cm.get([1, 2]).cands = 0
|
|
|
|
|
|
|
|
# Election of 2 English Men
|
|
|
|
cm.get([0, 0]).elected += 2
|
|
|
|
cm.get([-1, 0]).elected += 2
|
|
|
|
cm.get([0, -1]).elected += 2
|
|
|
|
|
|
|
|
# Election of 2 English Women
|
|
|
|
cm.get([1, 0]).elected += 2
|
|
|
|
cm.get([-1, 0]).elected += 2
|
|
|
|
cm.get([1, -1]).elected += 2
|
|
|
|
|
|
|
|
# Exclusion of Scottish Woman
|
|
|
|
cm.get([1, 1]).cands -= 1
|
|
|
|
cm.get([-1, 1]).cands -= 1
|
|
|
|
cm.get([1, -1]).cands -= 1
|
|
|
|
|
|
|
|
assert cm.get([0, 0]).min != 2
|
|
|
|
assert cm.get([1, 1]).max != 2
|
|
|
|
assert cm.get([0, 1]).min != 4
|
|
|
|
assert cm.get([1, 0]).min != 5
|
|
|
|
assert cm.get([0, 0]).max != 2
|
|
|
|
assert cm.get([0, 1]).max != 4
|
|
|
|
assert cm.get([1, 1]).min != 2
|
|
|
|
assert cm.get([1, 0]).max != 5
|
|
|
|
|
|
|
|
assert constraints.step_matrix(counter) == False
|
|
|
|
assert constraints.step_matrix(counter) == False
|
|
|
|
assert constraints.step_matrix(counter) == False
|
|
|
|
assert constraints.step_matrix(counter) == False
|
|
|
|
assert constraints.step_matrix(counter) == False
|
|
|
|
assert constraints.step_matrix(counter) == False
|
|
|
|
assert constraints.step_matrix(counter) == False
|
|
|
|
assert constraints.step_matrix(counter) == False
|
|
|
|
assert constraints.step_matrix(counter) == True
|
|
|
|
|
|
|
|
assert cm.get([0, 0]).min == 2
|
|
|
|
assert cm.get([1, 1]).max == 2
|
|
|
|
assert cm.get([0, 1]).min == 4
|
|
|
|
assert cm.get([1, 0]).min == 5
|
|
|
|
assert cm.get([0, 0]).max == 2
|
|
|
|
assert cm.get([0, 1]).max == 4
|
|
|
|
assert cm.get([1, 1]).min == 2
|
|
|
|
assert cm.get([1, 0]).max == 5
|
|
|
|
|
|
|
|
# English Men doomed
|
|
|
|
assert cm.get([0, 0]).elected == cm.get([0, 0]).max
|
|
|
|
# Scottish Women guarded
|
|
|
|
assert cm.get([1, 1]).cands == cm.get([1, 1]).min
|