def test_grid_graph(self): """Tests random community generation with a graph of 100 precincts in a grid. """ G1 = graph() # A graph whose nodes are in a order of the grid. # Add nodes with Precinct object attributes. for x in range(10): for y in range(10): coords = Point(x * 10, y * 10).buffer(2) precinct = Precinct(0, coords, "North Montana", str(10 * x + y), 1, 2) G1.add_node(int(precinct.id), attrs=[precinct]) # Add edges so that degree can be calculated. for node in G1.nodes(): if node % 10 != 9: G1.add_edge((node, node + 1)) if node // 10 != 9: G1.add_edge((node, node + 10)) ordered_nodes = sorted(G1.nodes(), key=lambda n: len(G1.neighbors(n))) G2 = graph( ) # Graph whose node numbers correspond to their rank by degree. for node in G1.nodes(): G2.add_node(ordered_nodes.index(node), attrs=G1.node_attributes(node)) for node in G1.nodes(): G2_node = ordered_nodes.index(node) for neighbor in G1.neighbors(node): try: G2.add_edge((G2_node, ordered_nodes.index(neighbor))) except AdditionError: pass communities = create_initial_configuration(G2, 2) def get_color(node): precinct = G2.node_attributes(node)[0] for c, community in enumerate(communities): if precinct in community.precincts.values(): return COLORS[c] if SHOW: visualize_graph(G2, None, lambda v: G2.node_attributes(v)[0].centroid, colors=get_color, sizes=lambda x: 20, show=True)
def test_state(self): """Tests random community generation with an inputted state. """ global STATE_PATH with open(STATE_PATH, "rb") as f: state_graph = pickle.load(f) communities = create_initial_configuration(state_graph, 2) for community in communities: community.update_coords() if SHOW: visualize_map(communities, None, lambda c: c.coords, color=lambda c: COLORS[communities.index(c)], show=True)
def generate_communities(precinct_graph, n_communities, animation_dir=None): """Generates a set of political communities. :param precinct_graph: A graph with each node representing a precinct, with precincts stored as node attributes. :type precinct_graph: `pygraph.classes.graph.graph` :param n_communities: The number of communities to break the state into. :type n_communities: int :param animation_dir: Path to directory which will contain files for animation, defaults to None :type animation_dir: str or NoneType :return: A list of communities that represent the state. :rtype: list of `hacking_the_election.utils.community.Community` """ if animation_dir is not None: try: os.mkdir(animation_dir) except FileExistsError: pass communities = create_initial_configuration(precinct_graph, n_communities) # while True: # optimize_compactness(communities, precinct_graph, animation_dir) # optimize_partisanship_stdev(communities, precinct_graph, animation_dir) # optimize_population(communities, precinct_graph, # POPULATION_THRESHOLD, animation_dir) # optimize_population_stdev(communities, precinct_graph, animation_dir) for i in range(30): optimize_compactness(communities, precinct_graph, animation_dir) optimize_population(communities, precinct_graph, POPULATION_THRESHOLD, animation_dir) return communities
[c.population_stdev for c in communities]) if average_stdev > starting_stdev: community.give_precinct(other_community, precinct.id, update={"population_stdev"}) else: if animation_dir is not None: draw_state(graph, animation_dir) if __name__ == "__main__": with open(sys.argv[1], "rb") as f: graph = pickle.load(f) communities = create_initial_configuration(graph, int(sys.argv[2])) # TO LOAD INIT CONFIG FROM TEXT FILE: # with open("test_vermont_init_config.txt", "r") as f: # precinct_list = eval(f.read()) # communities = [] # from hacking_the_election.utils.community import Community # for i, community in enumerate(precinct_list): # c = Community(i, graph) # for precinct_id in community: # for node in graph.nodes(): # precinct = graph.node_attributes(node)[0] # if precinct.id == precinct_id:
def setUp(self): """Loads data files and saves as instance attributes. """ with open(f"{SOURCE_DIR}/data/graph/vermont_graph.pickle", "rb") as f: self.vermont_graph = pickle.load(f) self.communities = create_initial_configuration(self.vermont_graph, 2)