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()
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()
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) }
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