def integration_MxN(n_candidates, n_voters, voting_scheme, seed=None):
    """
    @param voting_scheme: one of the four voting schemes
    """
    if seed != None:
        np.random.seed(seed)
    candidates_num = range(65, 65+n_candidates)
    candidates = [str(chr(i)) for i in candidates_num]
    pref_list = list(permutations(candidates_num))
    pref_mat = np.zeros((n_candidates, n_voters), dtype=np.uint8)
    for i in range(n_voters):
        rand = np.random.randint(0, len(pref_list))
        pref_mat[:, i] = np.array(pref_list[rand])
    params = {"num_voters": n_voters,
              "num_candidates": n_candidates,
              "candidate_list": candidates,
              "pref_mat": pref_mat,
              "scheme": voting_scheme}
    pc = PC(**params)
    vsr = VSR()
    vsr.voting_simulation(pc.pref_mat, pc.scheme)
    tv = TV(pref_mat=pc.pref_mat,
            voting_outcome=vsr.results,
            scheme=pc.scheme)
    return pc, vsr, tv
Exemplo n.º 2
0
 def test_calculate_voter_happiness(self):
     pref_mat = np.array([65, 66, 67, 68]).reshape(-1, 1)
     voting_outcome = {66: 4, 65: 0, 67: 0, 68: 0}
     vsr = VSR()
     desired_outcome = 1 / (1 + abs(4 * (3 - 4) + 3 * (4 - 3) + 2 *
                                    (2 - 2) + 1 * (1 - 1)))
     self.assertEqual(vsr.get_happiness(pref_mat, voting_outcome),
                      np.array([desired_outcome]))
def integration_voting_for_two():
    """Integration test for voting_for_two"""
    params = {"num_voters": 3,
              "num_candidates": 2,
              "candidate_list": ["A", "B"],
              "pref_mat": np.array([[65, 66, 65], [66, 65, 66]]),
              "scheme": 1}  # scheme is not 2 as in manual selection
    pc = PC(**params)
    vsr = VSR()
    vsr.voting_simulation(pc.pref_mat, pc.scheme)
    tv = TV(pref_mat=pc.pref_mat,
            voting_outcome=vsr.results,
            scheme=pc.scheme)
    """Expected outcome: Bullet voting as well as compromising possible for all"""
    return pc, vsr, tv
 def __init__(self, pref_mat, voting_outcome, scheme):
     self.pref_mat = pref_mat
     self.voting_outcome = voting_outcome
     self.vsr = VSR()
     self.scheme = scheme
     self.n_candidates = pref_mat.shape[0]
     self.n_voters = pref_mat.shape[1]
     self.strategic_voting_options = [[] for _ in range(self.n_voters)]
Exemplo n.º 5
0
if __name__ == "__main__":
    modes = {
        1:
        "Manual input",
        2:
        "Integration test: 2 candidates, 3 voters, voting for two",
        3:
        "Integration test: M candidates, N voters, pick a voting scheme, random preferences"
    }
    for k, v in modes.items():
        print("{}: {}".format(k, v))
    mode = input("\nPlease choose one of the options listed [1/2/3]\n")
    if mode == "1":
        pc = PC()
        vsr = VSR()
        pc.get_preferences()
        vsr.voting_simulation(pc.pref_mat, pc.scheme)
        tv = TacticalVoting(pc.pref_mat, vsr.results, pc.scheme)
    elif mode == "2":
        pc, vsr, tv = IT.integration_voting_for_two()
    elif mode == "3":
        M = int(input("Enter number of candidates: "))
        if not (isinstance(M, int)) or (not M > 0):
            print("Select an Integer > 0")
            exit()
        N = int(input("Enter number of voters: "))
        if not (isinstance(N, int)) or (not N > 0):
            print("Select an Integer > 0")
            exit()
        voting_schemes = [
class TacticalVoting:
    def __init__(self, pref_mat, voting_outcome, scheme):
        self.pref_mat = pref_mat
        self.voting_outcome = voting_outcome
        self.vsr = VSR()
        self.scheme = scheme
        self.n_candidates = pref_mat.shape[0]
        self.n_voters = pref_mat.shape[1]
        self.strategic_voting_options = [[] for _ in range(self.n_voters)]

    def bullet_voting(self):
        """Calculate whether voting for just one of the alternatives can result in greater happiness"""

        # bullet voting can be applied, but it will not achieve anything
        # if self.scheme == 0:
            # print("Bullet voting cannot be applied to plurality voting.")

        happiness = self.vsr.get_happiness(self.pref_mat, self.voting_outcome)
        for voter in range(self.n_voters):
            for candidate in np.unique(self.pref_mat):
                # voter i attempts tactical voting for each possible candicate
                bullet_pref_mat = np.copy(self.pref_mat)
                bullet_pref_mat[1:, voter] = 0
                bullet_pref_mat[0, voter] = candidate

                tactical_results = self.vsr.voting_simulation(bullet_pref_mat, self.scheme)
                try:
                    del tactical_results[0]  # Delete the '0' candidate
                except KeyError:
                    pass
                tactical_happiness = self.vsr.get_happiness(self.pref_mat, tactical_results)
                happiness_gain = tactical_happiness[voter] - happiness[voter]
                str_tactical_results = dict(zip([chr(i) for i in tactical_results.keys()], tactical_results.values()))
                if happiness_gain > 0:
                    voter_num = voter +1
                    print_gain = np.round(happiness_gain, 3)
                    self.strategic_voting_options[voter].append({
                        "Preference list": [chr(i).replace('\x00','') for i in bullet_pref_mat[:, voter]],
                        "Voting result": deepcopy(str_tactical_results),
                        "New happiness": np.copy(sum(tactical_happiness)),
                        "Description": "Happiness of voter {} increased by : {} due to voting only for {}".format(
                            voter_num, print_gain, chr(candidate))
                    })

    def compromising_strategy(self):
        """Tactical voting by ranking alternatives insincerely higher (lower)"""
        happiness = self.vsr.get_happiness(self.pref_mat, self.voting_outcome)

        for voter in range(self.n_voters):
            for c1 in range(self.n_candidates):  # candidate 1
                for c2 in range(self.n_candidates):  # candidate 2
                    # tactic: swap candidates c1 and c2
                    if (c1 >= c2):
                        continue
                    comp_pref = np.copy(self.pref_mat)                    
                    comp_pref[c1, voter], comp_pref[c2, voter] = comp_pref[c2, voter], comp_pref[c1, voter]
                    tactical_results = self.vsr.voting_simulation(comp_pref, self.scheme)
                    tactical_happiness = self.vsr.get_happiness(self.pref_mat, tactical_results)
                    happiness_gain = tactical_happiness[voter] - happiness[voter]
                    str_tactical_results = dict(zip([chr(i) for i in tactical_results.keys()], tactical_results.values()))
                    if happiness_gain > 0:
                        c1_name = chr(self.pref_mat[c1, voter])
                        c2_name = chr(self.pref_mat[c2, voter])
                        voter_num = voter +1
                        print_gain = np.round(happiness_gain, 3)
                        self.strategic_voting_options[voter].append({
                            "Preference list": [chr(i) for i in comp_pref[:, voter]],
                            "Voting results": deepcopy(str_tactical_results),
                            "New happiness": np.copy(sum(tactical_happiness)),
                            "Description": "Happiness of voter {} increased by {} due to swapping {} with {}".format(
                                voter_num, print_gain, c1_name, c2_name)                       
                        })

    def compromising_strategy_permutations(self):
        """Compromising using permutations"""
        happiness = self.vsr.get_happiness(self.pref_mat, self.voting_outcome)
        for voter in range(self.n_voters):
            # create (n_candidates!)x(n_candidates) permutation matrix
            permutation_mat = np.array(list(permutations(self.pref_mat[:, voter])))
            for i in range(permutation_mat.shape[0]):
                comp_pref = np.copy(self.pref_mat)
                comp_pref[:, voter] = permutation_mat[i, :]

                tactical_results = self.vsr.voting_simulation(comp_pref, self.scheme)
                tactical_happiness = self.vsr.get_happiness(comp_pref, tactical_results)
                happiness_gain = tactical_happiness[voter] - happiness[voter]
                str_tactical_results = dict(zip([chr(i) for i in tactical_results.keys()], tactical_results.values()))
                if happiness_gain > 0:
                    voter_num = voter +1
                    print_gain = np.round(happiness_gain, 3)
                    self.strategic_voting_options[voter].append({
                        "Preference list": [chr(i) for i in comp_pref[:, voter]],
                        "Voting results": deepcopy(str_tactical_results),
                        "New happiness": np.copy(sum(tactical_happiness)),
                        "Description": "Happiness of voter {} increased by : {} due to reordering of preferences".format(
                                voter_num, print_gain)  
                    })
Exemplo n.º 7
0
 def test_anti_plurality_voting(self):
     pc = simple_test_scheme()
     vsr = VSR()
     desired_outcome = {65: 4, 66: 4, 67: 4, 68: 0}
     self.assertEqual(vsr.anti_plurality_voting(pc.pref_mat),
                      desired_outcome)
Exemplo n.º 8
0
 def test_borda_voting(self):
     pc = simple_test_scheme()
     vsr = VSR()
     desired_outcome = {65: 12, 66: 8, 67: 4, 68: 0}
     self.assertEqual(vsr.borda_voting(pc.pref_mat), desired_outcome)
Exemplo n.º 9
0
 def test_voting_for_two(self):
     pc = simple_test_scheme()
     vsr = VSR()
     desired_outcome = {65: 4, 66: 4, 67: 0, 68: 0}
     self.assertEqual(vsr.voting_for_two(pc.pref_mat), desired_outcome)