コード例 #1
0
ファイル: genprofiles.py プロジェクト: lumbric/abcvoting
def random_urn_party_list_profile(num_cand, num_voters, num_parties, replace, uniform=False):
    """Generate Polya Urn profile from a number of parties.
    If uniform each party gets the same amount of candidates."""
    currsize = 1.0
    approval_sets = []
    replacedsets = {}
    parties = list(range(num_parties))
    party_cands = __distribute_candidates_to_parties(num_cand, parties, uniform=uniform)
    for _ in range(num_voters):
        r = random.random() * currsize
        if r < 1.0:
            # base case: sample uniformly at random
            party = random.choice(parties)
            randpartyset = list(party_cands[party])
            approval_sets.append(randpartyset)
            if party in replacedsets:
                replacedsets[party] += 1
            else:
                replacedsets[party] = 1
            currsize += replace
        else:
            # sample from one of the parties
            r = random.randint(0, sum(replacedsets.values()))
            for party in replacedsets:
                count = replacedsets[party]
                if r <= count:
                    approval_sets.append(list(party_cands[party]))
                    break
                else:
                    r -= count
    profile = Profile(num_cand)
    profile.add_voters(approval_sets)
    return profile
コード例 #2
0
ファイル: test_abcrules.py プロジェクト: lumbric/abcvoting
def test_cvxpy_cant_compute_av():
    profile = Profile(4)
    profile.add_voters([[0, 1], [1, 2]])
    committeesize = 2

    with pytest.raises(ValueError):
        cvxpy_thiele_methods(profile, committeesize, "av", resolute=False, solver_id="glpk_mi")
コード例 #3
0
def random_ic_fixed_size_profile(num_voters, num_cand, setsize):
    """
    Generate a random profile using the *IC with fixed-size approval sets* distribution.

    Parameters
    ----------
        num_voters : int
            The desired number of voters in the profile.

        num_cand : int
            The desired number of candidates in the profile.

        setsize : int
            Number of candidates that each voter approves.

    Returns
    -------
        abcvoting.preferences.Profile
    """
    approval_sets = []
    for _ in range(num_voters):
        randset = list(range(num_cand))
        rng.shuffle(randset)
        randset = randset[:setsize]
        approval_sets.append(randset)
    profile = Profile(num_cand)
    profile.add_voters(approval_sets)
    return profile
コード例 #4
0
ファイル: genprofiles.py プロジェクト: lumbric/abcvoting
def random_urn_profile(num_cand, num_voters, setsize, replace):
    """Generate Polya Urn profile with fixed size approval sets."""
    currsize = 1.0
    approval_sets = []
    replacedsets = {}

    for _ in range(num_voters):
        r = random.random() * currsize
        if r < 1.0:
            # base case: sample uniformly at random
            randset = random.sample(range(num_cand), setsize)
            approval_sets.append(randset)
            key = tuple(set(randset))
            if key in replacedsets:
                replacedsets[key] += 1
            else:
                replacedsets[key] = 1
            currsize += replace
        else:
            # sample from one of the replaced ballots
            r = random.randint(0, sum(replacedsets.values()))
            for approval_set in replacedsets:
                count = replacedsets[approval_set]
                if r <= count:
                    approval_sets.append(list(approval_set))
                    break
                else:
                    r -= count
    profile = Profile(num_cand)
    profile.add_voters(approval_sets)
    return profile
コード例 #5
0
ファイル: test_abcrules.py プロジェクト: lumbric/abcvoting
def test_abcrules_correct_simple(rule_id, algorithm, resolute):
    def simple_checks(_committees):
        if rule_id == "rule-x-without-phragmen-phase":
            assert _committees == [set()]
            return
        if resolute:
            assert len(_committees) == 1
        else:
            assert len(_committees) == 6

    profile = Profile(4)
    profile.add_voters([{0}, {1}, {2}, {3}])
    committeesize = 2

    committees = abcrules.compute(
        rule_id, profile, committeesize, algorithm=algorithm, resolute=resolute
    )
    simple_checks(committees)

    # call abcrules function differently, results should be the same
    committees = abcrules.get_rule(rule_id).compute(
        profile,
        committeesize,
        algorithm=algorithm,
        resolute=resolute,
    )
    simple_checks(committees)

    # using the default algorithm
    committees = abcrules.compute(rule_id, profile, committeesize, resolute=resolute)
    simple_checks(committees)
コード例 #6
0
ファイル: genprofiles.py プロジェクト: gregaw/abcvoting
def random_2d_points_party_list_profile(num_cand,
                                        num_voters,
                                        num_parties,
                                        partypointmode,
                                        voterpointmode,
                                        sigma,
                                        uniform=False):
    """Generates profiles from randomly generated 2d points according
    to some distributions with the given sigma.
    This selects parties for each voter, the parties are either
    uniform (equal size) or randomly generated (at least 1) candidate
    lists."""
    parties = list(range(num_parties))
    party_cands = __distribute_candidates_to_parties(num_cand,
                                                     parties,
                                                     uniform=uniform)
    voters = list(range(num_voters))

    voter_points = __generate_2d_points(voters, voterpointmode, sigma)
    party_points = __generate_2d_points(parties, partypointmode, sigma)

    party_sets = __get_profile_from_points(voters, parties, voter_points,
                                           party_points, 1.0)

    apprsets = []
    for p in party_sets:
        apprsets.append(party_cands[p[0]])
    profile = Profile(num_cand)
    profile.add_preferences(apprsets)
    return profile
コード例 #7
0
def test_thiele_scores(scorefct_id, score, num_cand):
    profile = Profile(num_cand)
    approval_sets = [[0, 1], [1], [1, 3], [4], [1, 2, 3, 4, 5], [1, 5, 3], [0, 1, 2, 4, 5]]
    profile.add_voters(approval_sets)
    committee = [6, 7]
    assert scores.thiele_score(scorefct_id, profile, committee) == 0
    committee = [1, 2, 3, 4]
    assert scores.thiele_score(scorefct_id, profile, committee) == score
コード例 #8
0
def test_fastest_algorithms(rule, resolute):
    profile = Profile(4)
    profile.add_preferences([[0, 1], [1, 2], [0, 2, 3]])
    committeesize = 2
    algo = rule.fastest_algo()
    if algo is None:
        pytest.skip("no supported algorithms for " + rule.shortname)
    rule.compute(profile, committeesize, algorithm=algo, resolute=resolute)
コード例 #9
0
ファイル: test_abcrules.py プロジェクト: lumbric/abcvoting
def test_monroe_indivisible(algorithm):
    profile = Profile(4)
    profile.add_voters([[0], [0], [0], [1, 2], [1, 2], [1], [3]])
    committeesize = 3

    assert abcrules.compute_monroe(
        profile, committeesize, algorithm=algorithm, resolute=False
    ) == [{0, 1, 2}, {0, 1, 3}, {0, 2, 3}]
コード例 #10
0
def random_mallows_profile(num_voters, num_cand, setsize, dispersion):
    """
    Generate a random profile using the *Truncated Mallows* probability distribution.

    Based on the definition for the repeated insertion model (RIM) in
    https://icml.cc/2011/papers/135_icmlpaper.pdf

    Parameters
    ----------
        num_voters : int
            The desired number of voters in the profile.

        num_cand : int
            The desired number of candidates in the profile.

        setsize : int
            Number of candidates that each voter approves.

        dispersion : float in [0, 1]
            Dispersion parameter of the Mallows model.

    Returns
    -------
        abcvoting.preferences.Profile
    """
    def _select_pos(distribution):
        """Returns a randomly selected value with the help of the distribution."""
        if round(sum(distribution), 10) != 1.0:
            raise Exception("Invalid Distribution", distribution, "sum:",
                            sum(distribution))
        r = round(rng.random(), 10)  # or random.uniform(0, 1)
        pos = -1
        s = 0
        for p in distribution:
            pos += 1
            s += p
            if s >= r:
                return pos

        return pos  # in case of rounding errors

    if not 0 < dispersion <= 1:
        raise Exception("Invalid dispersion, needs to be in (0, 1].")
    reference_ranking = list(range(num_cand))
    rng.shuffle(reference_ranking)
    insert_dist = _compute_mallows_insert_distributions(num_cand, dispersion)
    approval_sets = []
    for _ in range(num_voters):
        vote = []
        for i, distribution in enumerate(insert_dist):
            pos = _select_pos(distribution)
            vote.insert(pos, reference_ranking[i])

        approval_sets.append(vote[:setsize])
    profile = Profile(num_cand)
    profile.add_voters(approval_sets)
    return profile
コード例 #11
0
def random_urn_fixed_size_profile(num_voters, num_cand, setsize, replace):
    """
    Generate a random profile using the *Polya Urn with fixed-size approval sets* distribution.

    Parameters
    ----------
        num_voters : int
            The desired number of voters in the profile.

        num_cand : int
            The desired number of candidates in the profile.

        setsize : int
            Number of candidates that each voter approves.

        replace : float
            New balls added to the urn in each iteration, relative to the original number.

            The urn starts with (`num_cand` choose `setsize`) balls, each representing a set
            of candidates with size `setsize`. This quantity is normalized to `1.0`.
            The `replace` value is a float that indicates how many balls are added using this
            normalization. Specifically, `replace` *  (`num_cand` choose `setsize`) are added
            in each iteration.

    Returns
    -------
        abcvoting.preferences.Profile
    """
    currsize = 1.0
    approval_sets = []
    replacedsets = {}

    for _ in range(num_voters):
        r = rng.random() * currsize
        if r < 1.0:
            # base case: sample uniformly at random
            randset = list(range(num_cand))
            rng.shuffle(randset)
            randset = randset[:setsize]
            approval_sets.append(randset)
            key = tuple(set(randset))
            if key in replacedsets:
                replacedsets[key] += 1
            else:
                replacedsets[key] = 1
            currsize += replace
        else:
            # sample from one of the replaced ballots
            r = rng.integers(0, sum(replacedsets.values()))
            for approval_set, count in replacedsets.items():
                if r <= count:
                    approval_sets.append(list(approval_set))
                    break
                r -= count
    profile = Profile(num_cand)
    profile.add_voters(approval_sets)
    return profile
コード例 #12
0
ファイル: test_abcrules.py プロジェクト: lumbric/abcvoting
def test_seqphragmen_irresolute():
    profile = Profile(3)
    profile.add_voters([[0, 1], [0, 1], [0], [1, 2], [2]])
    committeesize = 2
    committees = abcrules.compute("seqphragmen", profile, committeesize, resolute=False)
    assert committees == [{0, 1}, {0, 2}]

    committees = abcrules.compute("seqphragmen", profile, committeesize, resolute=True)
    assert committees == [{0, 2}]
コード例 #13
0
ファイル: test_abcrules.py プロジェクト: lumbric/abcvoting
def test_gurobi_cant_compute_av():
    profile = Profile(4)
    profile.add_voters([[0, 1], [1, 2]])
    committeesize = 2

    scorefct = scores.get_scorefct("av", committeesize)

    with pytest.raises(ValueError):
        _gurobi_thiele_methods(profile, committeesize, scorefct, resolute=False)
コード例 #14
0
def test_thiele_scores(scorefct_str, score, num_cand):
    profile = Profile(num_cand)
    preflist = [[0, 1], [1], [1, 3], [4], [1, 2, 3, 4, 5], [1, 5, 3],
                [0, 1, 2, 4, 5]]
    profile.add_preferences(preflist)
    committee = [6, 7]
    assert scores.thiele_score(scorefct_str, profile, committee) == 0
    committee = [1, 2, 3, 4]
    assert scores.thiele_score(scorefct_str, profile, committee) == score
コード例 #15
0
def test_dominate():
    profile = Profile(6)
    profile.add_voters([[0, 1], [0, 1], [1, 2, 3], [2, 3]])
    assert not misc.dominate(profile, {0, 2}, {1, 3})
    assert not misc.dominate(profile, {0, 2}, {1, 2})
    assert misc.dominate(profile, {1, 3}, {0, 2})
    assert misc.dominate(profile, {1, 2}, {0, 2})
    assert not misc.dominate(profile, {0, 2}, {0, 2})
    assert not misc.dominate(profile, {1}, {2})
    assert not misc.dominate(profile, {2}, {1})
コード例 #16
0
ファイル: genprofiles.py プロジェクト: lumbric/abcvoting
def random_IC_profile(num_cand, num_voters, setsize):
    """Generates profile with random assignment of candidates to
    the fix size of setsize."""
    approval_sets = []
    for _ in range(num_voters):
        randset = random.sample(range(num_cand), setsize)
        approval_sets.append(randset)
    profile = Profile(num_cand)
    profile.add_voters(approval_sets)
    return profile
コード例 #17
0
ファイル: partylist.py プロジェクト: szufix/mapel
def convert_election_to_profile(election):
    profile = Profile(num_cand=election.num_candidates)

    voters = []
    for i, vote in enumerate(election.votes):
        voter = Voter(vote)
        voters.append(voter)

    profile._voters = voters
    return profile
コード例 #18
0
ファイル: test_abcrules.py プロジェクト: lumbric/abcvoting
def test_fastest_available_algorithm(rule_id):
    profile = Profile(4)
    profile.add_voters([[0, 1], [1, 2], [0, 2, 3]])
    committeesize = 2
    algorithm = abcrules.get_rule(rule_id).fastest_available_algorithm
    if algorithm is None:
        pytest.skip("no supported algorithms for " + abcrules.get_rule(rule_id).shortname)
    for resolute in abcrules.get_rule(rule_id).resolute_values:
        abcrules.compute(rule_id, profile, committeesize, algorithm=algorithm, resolute=resolute)
    # second possibility
    abcrules.compute(rule_id, profile, committeesize, algorithm="fastest")
コード例 #19
0
ファイル: test_abcrules.py プロジェクト: lumbric/abcvoting
def test_abcrules_return_lists_of_sets(rule_id, algorithm, resolute):
    profile = Profile(4)
    profile.add_voters([{0}, [1], [2], {3}])
    committeesize = 2

    committees = abcrules.compute(
        rule_id, profile, committeesize, algorithm=algorithm, resolute=resolute
    )
    assert len(committees) >= 1
    for committee in committees:
        assert isinstance(committee, set)
コード例 #20
0
def test_unspecified_algorithms(rule, verbose, resolute):
    if resolute not in rule.resolute:
        return
    profile = Profile(3)
    profile.add_preferences([[0, 1], [1, 2]])
    committeesize = 2
    with pytest.raises(NotImplementedError):
        rule.compute(profile,
                     committeesize,
                     algorithm="made-up-algorithm",
                     resolute=resolute,
                     verbose=verbose)
コード例 #21
0
def test_monroe_indivisible(algorithm):
    if algorithm == "gurobi":
        pytest.importorskip("gurobipy")
    profile = Profile(4)
    profile.add_preferences([[0], [0], [0], [1, 2], [1, 2], [1], [3]])
    committeesize = 3

    assert (abcrules.compute_monroe(profile,
                                    committeesize,
                                    algorithm=algorithm,
                                    resolute=False) == [[0, 1, 2], [0, 1, 3],
                                                        [0, 2, 3]])
コード例 #22
0
ファイル: test_abcrules.py プロジェクト: lumbric/abcvoting
def test_cvxpy_wrong_score_fct():
    profile = Profile(4)
    profile.add_voters([[0, 1], [2, 3]])
    committeesize = 1
    with pytest.raises(NotImplementedError):
        cvxpy_thiele_methods(
            profile=profile,
            committeesize=committeesize,
            scorefct_id="non_existing",
            resolute=False,
            solver_id="glpk_mi",
        )
コード例 #23
0
def test_tiebreaking_order(rule_instance, verbose):
    rule_id, algorithm = rule_instance
    profile = Profile(4)
    profile.add_preferences([[1]] * 2 + [[0]] * 2 + [[2]] * 2)
    committeesize = 1

    committees = abcrules.compute(rule_id,
                                  profile,
                                  committeesize,
                                  algorithm=algorithm,
                                  resolute=True,
                                  verbose=verbose)
    assert committees == [[0]]
コード例 #24
0
ファイル: genprofiles.py プロジェクト: lumbric/abcvoting
def random_IC_party_list_profile(num_cand, num_voters, num_parties, uniform=False):
    """Generates profile with random assignment of parties.
    A party is a list of candidates.
    If uniform the number of candidates per party is the same,
    else at least 1."""
    parties = list(range(num_parties))
    party_cands = __distribute_candidates_to_parties(num_cand, parties, uniform=uniform)
    approval_sets = []
    for _ in range(num_voters):
        approval_sets.append(party_cands[random.choice(parties)])
    profile = Profile(num_cand)
    profile.add_voters(approval_sets)
    return profile
コード例 #25
0
def test_seqphragmen_irresolute():
    profile = Profile(3)
    profile.add_preferences([[0, 1], [0, 1], [0], [1, 2], [2]])
    committeesize = 2
    committees = abcrules.rules["seqphrag"].compute(profile,
                                                    committeesize,
                                                    resolute=False)
    assert committees == [[0, 1], [0, 2]]

    committees = abcrules.rules["seqphrag"].compute(profile,
                                                    committeesize,
                                                    resolute=True)
    assert committees == [[0, 2]]
コード例 #26
0
def test_read_and_write_preflib_file():
    currdir = os.path.dirname(os.path.abspath(__file__))
    profile1 = Profile(6)
    profile1.add_voters([[3], [4, 1, 5], [0, 2], [], [0, 1, 2, 3, 4, 5], [5],
                         [1], [1]])
    fileio.write_profile_to_preflib_toi_file(currdir + "/data/test5.toi",
                                             profile1)
    for use_weights in [True, False]:
        profile2 = fileio.read_preflib_file(currdir + "/data/test5.toi",
                                            use_weights=use_weights)
        assert len(profile1) == len(profile2)
        for i, voter in enumerate(profile1):
            assert voter.weight == profile2[i].weight
            assert voter.approved == set(profile2[i].approved)
コード例 #27
0
def test_read_special_abc_yaml_file2():
    currdir = os.path.dirname(os.path.abspath(__file__))
    filename = currdir + "/data/test8.abc.yaml"

    profile1 = Profile(6)
    profile1.add_voters([{3}, {1, 4, 5}, {0, 2}, {}, {0, 1, 2, 3, 4, 5},
                         {1, 3}, {1}, {1}])

    profile2, committeesize, compute_instances, data = fileio.read_abcvoting_yaml_file(
        filename)
    assert str(profile1) == str(profile2)
    assert committeesize == 2
    assert len(compute_instances) == 1
    assert abcrules.compute(**compute_instances[0]) == [{1, 3}]
コード例 #28
0
ファイル: partylist.py プロジェクト: szufix/mapel
def pav_time(election):

    profile = Profile(election.num_candidates)
    profile.add_voters(election.votes)
    committee_size = 10
    resolute = True
    rule_name = 'pav'
    start = time.time()
    winning_committees = abcrules.compute(rule_name,
                                          profile,
                                          committee_size,
                                          algorithm="gurobi",
                                          resolute=resolute)
    return time.time() - start
コード例 #29
0
ファイル: test_abcrules.py プロジェクト: lumbric/abcvoting
def test_abcrules_weightsconsidered(rule_id, algorithm, resolute):
    profile = Profile(3)
    profile.add_voter(Voter([0]))
    profile.add_voter(Voter([0]))
    profile.add_voter(Voter([1], 5))
    profile.add_voter(Voter([0]))
    committeesize = 1

    if "monroe" in rule_id or rule_id in [
        "lexminimaxav",
        "rule-x",
        "rule-x-without-phragmen-phase",
        "phragmen-enestroem",
    ]:
        with pytest.raises(ValueError):
            abcrules.compute(rule_id, profile, committeesize, algorithm=algorithm)
        return

    result = abcrules.compute(
        rule_id, profile, committeesize, algorithm=algorithm, resolute=resolute
    )

    if rule_id == "minimaxav":
        # Minimax AV ignores weights by definition
        if resolute:
            assert result == [{0}] or result == [{1}] or result == [{2}]
        else:
            assert result == [{0}, {1}, {2}]
    else:
        assert len(result) == 1
        assert result[0] == {1}
コード例 #30
0
ファイル: test_abcrules.py プロジェクト: lumbric/abcvoting
def test_unspecified_algorithms(rule_id, resolute):
    rule = abcrules.get_rule(rule_id)
    if resolute not in rule.resolute_values:
        return
    profile = Profile(3)
    profile.add_voters([[0, 1], [1, 2]])
    committeesize = 2
    with pytest.raises(NotImplementedError):
        rule.compute(
            profile,
            committeesize,
            algorithm="made-up-algorithm",
            resolute=resolute,
        )