diff --git a/docs/source/other_methods.md b/docs/source/other_methods.md index 7a88f33..2332400 100644 --- a/docs/source/other_methods.md +++ b/docs/source/other_methods.md @@ -10,7 +10,6 @@ Other Methods ``` - ## Kemeny-Young ```{eval-rst} @@ -28,6 +27,14 @@ Other Methods ``` +## Preliminary Weighted Condorcet + +```{eval-rst} + +.. autofunction:: pref_voting.other_methods.preliminary_weighted_condorcet + +``` + ## Bucklin ```{eval-rst} diff --git a/pref_voting/dominance_axioms.py b/pref_voting/dominance_axioms.py index 69e8ee7..5a4a5fd 100644 --- a/pref_voting/dominance_axioms.py +++ b/pref_voting/dominance_axioms.py @@ -230,7 +230,7 @@ def has_smith_violation(edata, vm, verbose=False): s_set = smith_set(edata) ws = vm(edata) - winners_not_in_smith = [w not in s_set for w in ws] + winners_not_in_smith = [w for w in ws if w not in s_set] if len(winners_not_in_smith) > 0: if verbose: if type(edata) == Profile or type(edata) == ProfileWithTies: @@ -259,7 +259,7 @@ def find_all_smith_violations(edata, vm, verbose=False): s_set = smith_set(edata) ws = vm(edata) - winners_not_in_smith = [w not in s_set for w in ws] + winners_not_in_smith = [w for w in ws if w not in s_set] if len(winners_not_in_smith) > 0: if verbose: if type(edata) == Profile or type(edata) == ProfileWithTies: diff --git a/pref_voting/other_methods.py b/pref_voting/other_methods.py index 1781f7e..d8117e5 100644 --- a/pref_voting/other_methods.py +++ b/pref_voting/other_methods.py @@ -198,6 +198,53 @@ def kemeny_young(profile, curr_cands = None): return sorted(list(set([r[0] for r in ky_rankings]))) + +@vm("Preliminary Weighted Condorcet") +def preliminary_weighted_condorcet(prof, curr_cands = None, show_orders = False, require_positive_plurality_score = False): + """The preliminary version of the Weighted Condorcet Rule in Tideman's book, Collective Decisions and Voting (p. 223). The winners are the candidates ranked first by some linear order of the candidates with highest score, where the score of an order (c_1,...,c_n) is the sum over all i 0 for c in cands]), "All candidates must have a positive plurality score." + + best_order_score = 0 + best_orders = [] + + for r in permutations(cands): + + score_of_r = 0 + for i in r[:-1]: + for j in r[r.index(i)+1:]: + score_of_r += (prof.plurality_scores(curr_cands=curr_cands)[i] * prof.plurality_scores(curr_cands=curr_cands)[j] * prof.margin(i,j)) + + if score_of_r > best_order_score: + best_order_score = score_of_r + best_orders = [r] + if score_of_r == best_order_score: + best_orders.append(r) + + if show_orders == True: + print(f"Best orders: {set(best_orders)}") + + winners = [r[0] for r in best_orders] + + return list(set(winners)) + ### Bucklin @vm(name = "Bucklin") @@ -558,6 +605,8 @@ def superior_voting(profile, curr_cands = None): other_vms = [ kemeny_young, + pareto, + preliminary_weighted_condorcet, majority, bucklin, simplified_bucklin, diff --git a/pref_voting/variable_voter_axioms.py b/pref_voting/variable_voter_axioms.py index a88d0f7..052eebd 100644 --- a/pref_voting/variable_voter_axioms.py +++ b/pref_voting/variable_voter_axioms.py @@ -275,7 +275,7 @@ def has_positive_involvement_violation(prof, vm, verbose=False, violation_type=" if uniform_coalition: for loser in losers: - relevant_ranking_types = [r for r in prof.ranking_types if prof.rankings.count(r) >= coalition_size] + relevant_ranking_types = [r for r in prof.ranking_types if r[0] == loser and prof.rankings.count(r) >= coalition_size] for r in relevant_ranking_types: