def schwartz_set_heuristic(self):

        # Iterate through using the Schwartz set heuristic
        self.actions = []
        while len(self.graph.edges()) > 0:
            access = nx.connected_components(self.graph)
            mutual_access = nx.strongly_connected_components(self.graph)
            candidates_to_remove = set()
            for candidate in self.graph.nodes():
                candidates_to_remove |= (set(access[candidate]) - set(mutual_access[candidate]))

            # Remove nodes at the end of non-cycle paths
            if len(candidates_to_remove) > 0:
                self.actions.append({'nodes': candidates_to_remove})
                for candidate in candidates_to_remove:
                    self.graph.remove_node(candidate)

            # If none exist, remove the weakest edges
            else:
                edge_weights = self.edge_weights(self.graph)
                self.actions.append({'edges': matching_keys(edge_weights, min(edge_weights.values()))})
                for edge in self.actions[-1]["edges"]:
                    self.graph.del_edge(edge)

        self.graph_winner()
    def schwartz_set_heuristic(self):

        # Iterate through using the Schwartz set heuristic
        self.actions = []
        while len(self.graph.edges()) > 0:
            access = accessibility(self.graph)
            mutual_access = mutual_accessibility(self.graph)
            candidates_to_remove = set()
            for candidate in self.graph.nodes():
                candidates_to_remove |= (set(access[candidate]) -
                                         set(mutual_access[candidate]))

            # Remove nodes at the end of non-cycle paths
            if len(candidates_to_remove) > 0:
                self.actions.append({'nodes': candidates_to_remove})
                for candidate in candidates_to_remove:
                    self.graph.del_node(candidate)

            # If none exist, remove the weakest edges
            else:
                edge_weights = self.edge_weights(self.graph)
                self.actions.append({
                    'edges':
                    matching_keys(edge_weights, min(edge_weights.values()))
                })
                for edge in self.actions[-1]["edges"]:
                    self.graph.del_edge(edge)

        self.graph_winner()
Exemple #3
0
    def condorcet_completion_method(self):

        # Initialize the candidate graph
        self.rounds = []
        graph = digraph()
        graph.add_nodes(self.candidates)

        # Loop until we've considered all possible pairs
        remaining_strong_pairs = deepcopy(self.strong_pairs)
        while len(remaining_strong_pairs) > 0:
            r = {}

            # Find the strongest pair
            largest_strength = max(remaining_strong_pairs.values())
            strongest_pairs = matching_keys(remaining_strong_pairs, largest_strength)
            if len(strongest_pairs) > 1:
                r["tied_pairs"] = strongest_pairs
                strongest_pair = self.break_ties(strongest_pairs)
            else:
                strongest_pair = list(strongest_pairs)[0]
            r["pair"] = strongest_pair

            # If the pair would add a cycle, skip it
            graph.add_edge(strongest_pair)
            if len(find_cycle(graph)) > 0:
                r["action"] = "skipped"
                graph.del_edge(strongest_pair)
            else:
                r["action"] = "added"
            del remaining_strong_pairs[strongest_pair]
            self.rounds.append(r)

        self.old_graph = self.graph
        self.graph = graph
        self.graph_winner()
Exemple #4
0
 def loser(self, tallies):
     losers = matching_keys(tallies, min(tallies.values()))
     if len(losers) == 1:
         return {"loser": list(losers)[0]}
     else:
         return {
             "tied_losers": losers,
             "loser": self.break_ties(losers, True)
         }
Exemple #5
0
 def loser(self, tallies):
     losers = matching_keys(tallies, min(tallies.values()))
     if len(losers) == 1:
         return {"loser": list(losers)[0]}
     else:
         return {
             "tied_losers": losers,
             "loser": self.break_ties(losers, True)
         }
Exemple #6
0
    def calculate_results(self):

        # Standardize the ballot format and extract the candidates
        self.candidates = set()
        for ballot in self.ballots:

            # Convert single candidate ballots into ballot lists
            if not isinstance(ballot["ballot"], types.ListType):
                ballot["ballot"] = [ballot["ballot"]]

            # Ensure no ballot has an excess of votes
            if len(ballot["ballot"]) > self.required_winners:
                raise Exception("A ballot contained too many candidates")

            # Add all candidates on the ballot to the set
            self.candidates.update(set(ballot["ballot"]))

        # Sum up all votes for each candidate
        self.tallies = dict.fromkeys(self.candidates, 0)
        for ballot in self.ballots:
            for candidate in ballot["ballot"]:
                self.tallies[candidate] += ballot["count"]
        tallies = copy.deepcopy(self.tallies)

        # Determine which candidates win
        winning_candidates = set()
        while len(winning_candidates) < self.required_winners:

            # Find the remaining candidates with the most votes
            largest_tally = max(tallies.values())
            top_candidates = matching_keys(tallies, largest_tally)

            # Reduce the found candidates if there are too many
            if len(top_candidates
                   | winning_candidates) > self.required_winners:
                self.tied_winners = top_candidates.copy()
                while len(top_candidates
                          | winning_candidates) > self.required_winners:
                    top_candidates.remove(self.break_ties(
                        top_candidates, True))

            # Move the top candidates into the winning pile
            winning_candidates |= top_candidates
            for candidate in top_candidates:
                del tallies[candidate]

        self.winners = winning_candidates
    def calculate_results(self):

        # Standardize the ballot format and extract the candidates
        self.candidates = set()
        for ballot in self.ballots:

            # Convert single candidate ballots into ballot lists
            if type(ballot["ballot"]) != types.ListType:
                ballot["ballot"] = [ballot["ballot"]]

            # Ensure no ballot has an excess of votes
            if len(ballot["ballot"]) > self.required_winners:
                raise Exception("A ballot contained too many candidates")

            # Add all candidates on the ballot to the set
            self.candidates.update(set(ballot["ballot"]))

        # Sum up all votes for each candidate
        self.tallies = dict.fromkeys(self.candidates, 0)
        for ballot in self.ballots:
            for candidate in ballot["ballot"]:
                self.tallies[candidate] += ballot["count"]
        tallies = copy.deepcopy(self.tallies)

        # Determine which candidates win
        winning_candidates = set()
        while len(winning_candidates) < self.required_winners:

            # Find the remaining candidates with the most votes
            largest_tally = max(tallies.values())
            top_candidates = matching_keys(tallies, largest_tally)

            # Reduce the found candidates if there are too many
            if len(top_candidates | winning_candidates) > self.required_winners:
                self.tied_winners = top_candidates.copy()
                while len(top_candidates | winning_candidates) > self.required_winners:
                    top_candidates.remove(self.break_ties(top_candidates, True))

            # Move the top candidates into the winning pile
            winning_candidates |= top_candidates
            for candidate in top_candidates:
                del tallies[candidate]

        self.winners = winning_candidates
Exemple #8
0
    def condorcet_completion_method(self):

        # Initialize the candidate graph
        self.rounds = []
        graph = digraph()
        graph.add_nodes(self.candidates)

        # Loop until we've considered all possible pairs
        remaining_strong_pairs = deepcopy(self.strong_pairs)
        while len(remaining_strong_pairs) > 0:
            r = {}

            # Find the strongest pair
            largest_strength = max(remaining_strong_pairs.values())
            strongest_pairs = matching_keys(remaining_strong_pairs,
                                            largest_strength)
            if len(strongest_pairs) > 1:
                r["tied_pairs"] = strongest_pairs
                strongest_pair = self.break_ties(strongest_pairs)
            else:
                strongest_pair = list(strongest_pairs)[0]
            r["pair"] = strongest_pair

            # If the pair would add a cycle, skip it
            graph.add_edge(strongest_pair)
            if len(find_cycle(graph)) > 0:
                r["action"] = "skipped"
                graph.del_edge(strongest_pair)
            else:
                r["action"] = "added"
            del remaining_strong_pairs[strongest_pair]
            self.rounds.append(r)

        self.old_graph = self.graph
        self.graph = graph
        self.graph_winner()