예제 #1
0
    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)
예제 #2
0
    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)
예제 #3
0
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)