Ejemplo n.º 1
0
def convert_opt_data_to_gerrychain_input(state, opt_data='', plan=None):
    state_df, adj_graph, _, _ = load_opt_data(state, opt_data)
    election_df = load_election_df(state, opt_data)

    state_df = state_df[['population']]
    metric_df = pd.concat([state_df, election_df], axis=1)

    if plan is not None:
        plan_inverse_map = {}
        for district_ix, tract_ixs in plan.items():
            for tix in tract_ixs:
                plan_inverse_map[tix] = district_ix
        metric_df['initial_plan'] = pd.Series(plan_inverse_map, dtype=str)
    else:
        k = constants.seats[state]['house']
        ideal_pop = state_df.population.sum() / k
        nx.set_node_attributes(adj_graph, metric_df.T.to_dict())
        plan = recursive_tree_part(adj_graph, range(k), ideal_pop,
                                   'population', 0.01)
        metric_df['initial_plan'] = pd.Series(plan, dtype=str)

    nx.set_node_attributes(adj_graph, metric_df.T.to_dict())

    elections = [
        Election(election, {
            'Democratic': 'D_' + election,
            'Republican': 'R_' + election
        })
        for election in wrappers[state]().election_columns(include_party=False)
    ]
    return adj_graph, elections
Ejemplo n.º 2
0
def build_balanced_k_partition(graph, k, pop_col, pop_target, epsilon):
    
    assignment = recursive_tree_part(graph, k, pop_target, pop_col, epsilon)
    updaters = {'population': Tally('population'),
                        'cut_edges': cut_edges,
                        'step_num': step_num,
                        }
    partition = Partition(graph, assignment=assignment, updaters=updaters)
    return partition
Ejemplo n.º 3
0
def test_recursive_tree_part_returns_within_epsilon_of_target_pop(twelve_by_twelve_with_pop):
    n_districts = 7  # 144/7 ≈ 20.5 nodes/subgraph (1 person/node)
    ideal_pop = (sum(twelve_by_twelve_with_pop.nodes[node]["pop"]
                     for node in twelve_by_twelve_with_pop)) / n_districts
    epsilon = 0.05
    result = recursive_tree_part(twelve_by_twelve_with_pop, range(n_districts),
                                 ideal_pop, "pop", epsilon)
    partition = Partition(twelve_by_twelve_with_pop, result,
                          updaters={"pop": Tally("pop")})
    return all(abs(part_pop - ideal_pop) / ideal_pop < epsilon
               for part_pop in partition['pop'].values())
Ejemplo n.º 4
0
def test():

    graph_path = "./Data/PA_VTDALL.json"
    graph = Graph.from_json(graph_path)
    k = 18
    ep = 0.05
    unit_id = "GEOID10"
    pop_col = "TOT_POP"

    plot_path = "./Data/VTD_FINAL"
    unit_df = gpd.read_file(plot_path)
    division_col = "COUNTYFP10"
    divisions = unit_df[[division_col, 'geometry']].dissolve(by=division_col,
                                                             aggfunc='sum')

    updaters = {"population": updaters.Tally(pop_col, alias="population")}
    cddict = recursive_tree_part(graph,
                                 range(k),
                                 df[pop_col].sum() / k,
                                 pop_col,
                                 .01,
                                 node_repeats=1)
    initial_partition = Partition(graph, cddict, updaters)
    ideal_population = sum(
        initial_partition["population"].values()) / len(initial_partition)
    division_proposal = partial(recom,
                                pop_col=pop_col,
                                pop_target=ideal_population,
                                epsilon=0.05,
                                method=partial(division_bipartition_tree,
                                               division_col=division_col),
                                node_repeats=2)

    chain = MarkovChain(proposal=division_proposal,
                        constraints=[
                            constraints.within_percent_of_ideal_population(
                                initial_partition, 0.05),
                        ],
                        accept=accept.always_accept,
                        initial_state=initial_partition,
                        total_steps=1000)

    t = 0
    snapshot = 100
    for part in chain:
        if t % snapshot == 0:
            draw_graph(graph,
                       part.assignment,
                       unit_df,
                       divisions,
                       './chain_' + str(t) + '.png',
                       geo_id=unit_id)
        t += 1
Ejemplo n.º 5
0
def split_districts(part, factor, pop_target, pop_col, pop_tol):
    '''
    Takes a districting plan and splits each district into smaller ones
    '''
    #must be 0-indexed
    ass = {}
    graph = part.graph
    for d in part.parts:
        subgraph = graph.subgraph(part.parts[d])
        twodistricts = recursive_tree_part(subgraph, range(factor), pop_target,
                                           pop_col, pop_tol)
        for x in subgraph.nodes:
            ass[x] = d * factor + twodistricts[x]
    return ass
Ejemplo n.º 6
0
def create_graph():
    graph = nx.grid_graph([k * gn, k * gn])

    for e in graph.edges():
        graph[e[0]][e[1]]["shared_perim"] = 1

    graph.remove_nodes_from([(0, 0), (0, k * gn - 1), (k * gn - 1, 0),
                             (k * gn - 1, k * gn - 1)])

    cddict = {x: int(x[0] / gn) for x in graph.nodes()}
    for n in graph.nodes():
        graph.node[n]["population"] = 1
        graph.node[n]["part_sum"] = cddict[n]
        graph.node[n]["last_flipped"] = 0
        graph.node[n]["num_flips"] = 0
        graph.node[n]["COUNTY1"] = (-1)**(int(n[1] < k * gn / 2)) * int(
            n[0] / gn)

        if random.random() < p:
            graph.node[n]["pink"] = 1
            graph.node[n]["purple"] = 0
        else:
            graph.node[n]["pink"] = 0
            graph.node[n]["purple"] = 1
        if 0 in n or k * gn - 1 in n:
            graph.node[n]["boundary_node"] = True
            graph.node[n]["boundary_perim"] = 1

        else:
            graph.node[n]["boundary_node"] = False

    countydict = recursive_tree_part(graph, range(15),
                                     len(graph.nodes()) / 15, "population", .1,
                                     1)

    for n in graph.nodes():
        graph.node[n]["COUNTY2"] = countydict[n]

    # this part adds queen adjacency
    # for i in range(gn-1):
    #    for j in range(gn):
    #        if j<(gn-1):
    #            graph.add_edge((i,j),(i+1,j+1))
    #            graph[(i,j)][(i+1,j+1)]["shared_perim"]=0
    #        if j >0:
    #            graph.add_edge((i,j),(i+1,j-1))
    #            graph[(i,j)][(i+1,j-1)]["shared_perim"]=0

    return graph, cddict
Ejemplo n.º 7
0
def tree_grid(n=20, m=20, k=40, varepsilon=0.01):
    graph = nx.grid_graph([n, m])

    for node in graph.nodes():
        graph.node[node]["population"] = 1

    cddict = recursive_tree_part(graph, range(k), m * n / k, "population",
                                 varepsilon, 1)

    updater = {"cut_edges": cut_edges}

    initial_partition = Partition(graph, cddict, updater)

    dg = nx.Graph()
    for edge in initial_partition["cut_edges"]:
        dg.add_edge(cddict[edge[0]], cddict[edge[1]])

    return dg
Ejemplo n.º 8
0
def run_GerryChain_heuristic(G, population_deviation, k, iterations):

    my_updaters = {"population": updaters.Tally("TOTPOP", alias="population")}
    start = recursive_tree_part(
        G, range(k),
        sum(G.nodes[i]["TOTPOP"] for i in G.nodes()) / k, "TOTPOP",
        population_deviation / 2, 1)
    initial_partition = GeographicPartition(G, start, updaters=my_updaters)

    proposal = partial(recom,
                       pop_col="TOTPOP",
                       pop_target=sum(G.nodes[i]["TOTPOP"]
                                      for i in G.nodes()) / k,
                       epsilon=population_deviation / 2,
                       node_repeats=2)

    compactness_bound = constraints.UpperBound(
        lambda p: len(p["cut_edges"]),
        1.5 * len(initial_partition["cut_edges"]))

    pop_constraint = constraints.within_percent_of_ideal_population(
        initial_partition, population_deviation / 2)

    my_chain = MarkovChain(proposal=proposal,
                           constraints=[pop_constraint, compactness_bound],
                           accept=accept.always_accept,
                           initial_state=initial_partition,
                           total_steps=iterations)

    min_cut_edges = sum(G[i][j]['edge_length'] for i, j in G.edges)
    print("In GerryChain heuristic, current # of cut edges: ", end='')
    print(min_cut_edges, ",", sep='', end=' ')
    for partition in my_chain:
        current_cut_edges = sum(G[i][j]['edge_length']
                                for i, j in partition["cut_edges"])
        print(current_cut_edges, ",", sep='', end=' ')
        if current_cut_edges < min_cut_edges:
            best_partition = partition
            min_cut_edges = current_cut_edges

    print("Best heuristic solution has # cut edges =", min_cut_edges)
    return ([[i for i in G.nodes if best_partition.assignment[i] == j]
             for j in range(k)], min_cut_edges)
Ejemplo n.º 9
0
from gerrychain.tree import recursive_tree_part

graph = Graph.from_json("./County05.json")
df = gpd.read_file("./County05.shp")

centroids = df.centroid
c_x = centroids.x
c_y = centroids.y

totpop = 0
for node in graph.nodes():
    graph.node[node]["TOTPOP"] = int(graph.node[node]["TOTPOP"])

    totpop += graph.node[node]["TOTPOP"]

cddict = recursive_tree_part(graph, range(4), totpop / 4, "TOTPOP", .01, 1)

pos = {node: (c_x[node], c_y[node]) for node in graph.nodes}


def step_num(partition):
    parent = partition.parent
    if not parent:
        return 0
    return parent["step_num"] + 1


updaters = {
    "population": Tally("TOTPOP"),
    "cut_edges": cut_edges,
    "step_num": step_num,
Ejemplo n.º 10
0



partition_2011 = Partition(graph, "2011_PLA_1", updaters)
partition_GOV = Partition(graph, "GOV", updaters)
partition_TS = Partition(graph, "TS", updaters)
partition_REMEDIAL = Partition(graph, "REMEDIAL_P", updaters)
partition_CPCT = Partition(graph, "538CPCT__1", updaters)
partition_DEM = Partition(graph, "538DEM_PL", updaters)
partition_GOP = Partition(graph, "538GOP_PL", updaters)
partition_8th = Partition(graph, "8THGRADE_1", updaters)
tree_partitions = []
for i in range(5):
    print(f'Finished {i} tree plan(s)')
    cddict =  recursive_tree_part(graph,range(18),df["TOT_POP"].sum()/18,"TOT_POP", .01,1)
    tree_partitions.append(Partition(graph, cddict, updaters))

    
    
print("The 2011 plan has" , len(partition_2011["cut_edges"]), "cut edges.")
print("The GOV plan has" , len(partition_GOV["cut_edges"]), "cut edges.")
print("The TS plan has" , len(partition_TS["cut_edges"]), "cut edges.")
print("The REMEDIAL plan has" , len(partition_REMEDIAL["cut_edges"]), "cut edges.")
print("The 538 Compact plan has" , len(partition_CPCT["cut_edges"]), "cut edges.")
print("The 538 DEM plan has" , len(partition_DEM["cut_edges"]), "cut edges.")
print("The 538 GOP plan has" , len(partition_GOP["cut_edges"]), "cut edges.")
print("The 8th grade plan has" , len(partition_8th["cut_edges"]), "cut edges.")
for i in range(5):
    print(f"Tree plan #{i} has" , len(tree_partitions[i]["cut_edges"]), "cut edges.")
Ejemplo n.º 11
0

or_updaters = {"population" : Tally(POP_COL, alias="population"),
               "cut_edges": cut_edges}

election_updaters = {election.name: election for election in elections}
or_updaters.update(election_updaters)

## Create seed plans and Set up Markov chain

print("Creating seed plan")

total_pop = sum(df[POP_COL])
ideal_pop = total_pop / NUM_DISTRICTS

cddict = recursive_tree_part(graph=graph, parts=range(NUM_DISTRICTS), 
                             pop_target=ideal_pop, pop_col=POP_COL, epsilon=EPS)

init_partition = Partition(graph, assignment=cddict, updaters=or_updaters)


## Setup chain

proposal = partial(recom, pop_col=POP_COL, pop_target=ideal_pop, epsilon=EPS, 
                   node_repeats=1)

compactness_bound = constraints.UpperBound(lambda p: len(p["cut_edges"]), 
                                           2*len(init_partition["cut_edges"]))

chain = MarkovChain(
        proposal,
Ejemplo n.º 12
0
def run_GerryChain_heuristic(G, population_deviation, k, threshold,
                             iterations):

    my_updaters = {"population": updaters.Tally("TOTPOP", alias="population")}
    start = recursive_tree_part(
        G, range(k),
        sum(G.nodes[i]["TOTPOP"] for i in G.nodes()) / k, "TOTPOP",
        population_deviation / 2, 1)
    initial_partition = GeographicPartition(G, start, updaters=my_updaters)

    proposal = partial(recom,
                       pop_col="TOTPOP",
                       pop_target=sum(G.nodes[i]["TOTPOP"]
                                      for i in G.nodes()) / k,
                       epsilon=population_deviation / 2,
                       node_repeats=2)

    compactness_bound = constraints.UpperBound(
        lambda p: len(p["cut_edges"]),
        1.5 * len(initial_partition["cut_edges"]))

    pop_constraint = constraints.within_percent_of_ideal_population(
        initial_partition, population_deviation / 2)

    my_chain = MarkovChain(proposal=proposal,
                           constraints=[pop_constraint, compactness_bound],
                           accept=accept.always_accept,
                           initial_state=initial_partition,
                           total_steps=iterations)

    min_cut_edges = sum(G[i][j]['edge_length'] for i, j in G.edges)
    print(
        "In GerryChain heuristic, current # of cut edges and minority districts: ",
        end='')
    print(min_cut_edges, ",", sep='', end=' ')
    max_of_minority_districts = -1
    all_maps = []
    pareto_frontier = []
    obj_vals = []
    for partition in my_chain:
        current_cut_edges = sum(G[i][j]['edge_length']
                                for i, j in partition["cut_edges"])
        number_minority_district = 0
        for district in range(k):
            total_pop_district = 0
            total_pop_minority = 0
            for node in partition.graph:
                if partition.assignment[node] == district:
                    total_pop_district += G.node[node]["VAP"]
                    total_pop_minority += G.node[node]["BVAP"]
                    #total_pop_minority += G.node[node]["HVAP"]
                    #total_pop_minority += G.node[node]["AMINVAP"]
                    #total_pop_minority += G.node[node]["ASIANVAP"]
                    #total_pop_minority += G.node[node]["NHPIVAP"]
            if (total_pop_minority > threshold * total_pop_district):
                number_minority_district += 1
        if number_minority_district > max_of_minority_districts:
            max_of_minority_districts = number_minority_district
        if current_cut_edges < min_cut_edges:
            min_cut_edges = current_cut_edges
        print((current_cut_edges, number_minority_district),
              ",",
              sep='',
              end=' ')
        obj_vals.append([current_cut_edges, number_minority_district])
        all_maps.append(
            [partition, current_cut_edges, number_minority_district])

    print("Best heuristic solution has # cut edges =", min_cut_edges)
    print("Best heuristic solution has # minority districts =",
          max_of_minority_districts)

    all_maps.sort(key=lambda x: x[1])
    all_maps.sort(key=lambda x: x[2], reverse=True)
    pareto_frontier.append(all_maps[0])
    least_number_of_cut_edges = all_maps[0][1]
    for i in range(1, len(all_maps)):
        if all_maps[i][1] < least_number_of_cut_edges:
            pareto_frontier.append(all_maps[i])
            least_number_of_cut_edges = all_maps[i][1]

    print("Pareto Frontier: ", pareto_frontier)

    optimal_maps = []
    optimal_cut_edges = []
    optimal_minority_districts = []

    for plan in pareto_frontier:
        optimal_maps.append(
            [[i for i in G.nodes if plan[0].assignment[i] == j]
             for j in range(k)])
        optimal_cut_edges.append(plan[1])
        optimal_minority_districts.append(plan[2])

    return (optimal_maps, optimal_cut_edges, optimal_minority_districts,
            obj_vals)
my_updaters = {
    "population": Tally(pop_col, alias="population"),
    "cpop": Tally(ccol, alias="cpop"),
    "cut_edges": cut_edges
}
election_updaters = {election.name: election for election in elections}
my_updaters.update(election_updaters)

tot_pop_col = 0
tot_ccol = 0
#for tallying over totpop:
for n in graph.nodes():
    graph.node[n][pop_col] = int(graph.node[n][pop_col])
    tot_pop_col += graph.node[n][pop_col]

cddict = recursive_tree_part(graph, range(num_districts),
                             tot_pop_col / num_districts, pop_col, 0.01, 1)

starting_partition = Partition(graph, assignment=cddict, updaters=my_updaters)
#for tallying over citizen pop:
#for n in graph.nodes():
#   graph.node[n][ccol] = int(graph.node[n][ccol])
#  tot_ccol += graph.node[n][ccol]

#cddict = recursive_tree_part(graph,range(num_districts),tot_ccol/num_districts,ccol,0.01,1)

#starting_partition = Partition(graph,assignment=cddict,updaters=my_updaters)
# =============================================================================
#
# starting_partition = GeographicPartition(
#     graph,
#     assignment="GOV",
def metamander_around_partition(graph, dual, target_partition, tag, num_dist, secret):
    updaters = {'population': Tally('population'),
                'cut_edges': cut_edges,
                'step_num': step_num,
                }

    assignment = {}
    for x in graph.nodes():
        color = 0
        for block in target_partition.keys():
            if x in target_partition[block]:
                assignment[x] = color
            color += 1

    target_partition = Partition(graph, assignment, updaters=updaters)

    facefinder.viz(graph, set([]), target_partition.parts)
    plt.savefig("./plots/large_sample/target_maps/target_map" + tag + ".png", format='png')
    plt.close()

    print("made partition")
    crosses = facefinder.compute_cross_edge(graph, target_partition)

    k = len(target_partition.parts)

    dual_crosses = []
    for edge in dual.edges:
        if dual.edges[edge]["original_name"] in crosses:
            dual_crosses.append(edge)

    print("making dual distances")
    dual = facefinder.distance_from_partition(dual, dual_crosses)
    print('finished making dual distances')
    if secret:
        special_faces = assign_special_faces_random(dual)
        # special_faces = assign_special_faces_sqrt(dual)
    else:
        special_faces = assign_special_faces(dual, 2)
    print('finished assigning special faces')
    g_sierpinsky = face_sierpinski_mesh(graph, special_faces)
    print("made metamander")
    # change from RVAP and UVAP to approprate election data columns
    for node in g_sierpinsky:
        g_sierpinsky.nodes[node]['C_X'] = g_sierpinsky.nodes[node]['pos'][0]
        g_sierpinsky.nodes[node]['C_Y'] = g_sierpinsky.nodes[node]['pos'][1]
        if 'population' not in g_sierpinsky.nodes[node]:
            g_sierpinsky.nodes[node]['population'] = 0
        if 'EL16G_PR_D' not in g_sierpinsky.nodes[node]:
            g_sierpinsky.nodes[node]['EL16G_PR_D'] = 0
        if 'EL16G_PR_R' not in g_sierpinsky.nodes[node]:
            g_sierpinsky.nodes[node]['EL16G_PR_R'] = 0
        ##Need to add the voting data
    print("assigning districts to metamander")

    total_pop = sum( [ g_sierpinsky.nodes[node]['population'] for node in g_sierpinsky])
    cddict = recursive_tree_part(graph,range(num_dist),total_pop/num_dist,"population", .01,1)
    for node in graph.nodes():
        graph.nodes[node]['part'] = cddict[node]
    #sierp_partition = build_trivial_partition(g_sierpinsky)

    print("assigned districts")
    plt.figure()
    nx.draw(g_sierpinsky, pos=nx.get_node_attributes(g_sierpinsky, 'pos'), node_size=1, width=1,
            cmap=plt.get_cmap('jet'))
    plt.savefig("./plots/large_sample/sierpinsky_plots/sierpinsky_mesh" + tag + ".png", format='png')
    plt.close()
    return g_sierpinsky, k
Ejemplo n.º 15
0
for i in range(4):
    graph = graph_list[i]

    for n in graph.nodes():
        graph.node[n]["BVAP"] = int(graph.node[n]["BVAP"])
        graph.node[n][vap_list[i]] = int(graph.node[n][vap_list[i]])
        graph.node[n]["TOTPOP"] = int(graph.node[n]["TOTPOP"])
        totpop[i] += graph.node[n]["TOTPOP"]

        graph.node[n]["nBVAP"] = graph.node[n][
            vap_list[i]] - graph.node[n]["BVAP"]

starts = []
for i in range(4):
    starts.append(
        recursive_tree_part(graph_list[i], range(num_districts),
                            totpop[i] / num_districts, "TOTPOP", .02, 1))

updater = {
    "population": updaters.Tally("TOTPOP", alias="population"),
    "cut_edges": cut_edges,
    "BVAP": Election("BVAP", {
        "BVAP": "BVAP",
        "nBVAP": "nBVAP"
    })
}

initial_partitions = []
proposals = []
compactness_bounds = []
chains = []
Ejemplo n.º 16
0
#with open("./State_Data/VA_Trimmedj.json", 'w') as outfile:
#    json.dump(json_graph.adjacency_data(graph), outfile)

#graph.to_json("./State_Data/VA_Trimmed.json")

graph = Graph.from_json("./State_Data/VA_Trimmed.json")

df = gpd.read_file("./State_Data/VA_Trimmed.shp")

print("nodes", len(graph.nodes()))
print("edges", len(graph.edges()))

num_districts = 33

for i in range(100):
    cddict = recursive_tree_part(graph, range(num_districts),
                                 df["TAPERSONS"].sum() / num_districts,
                                 "TAPERSONS", .001, 1)

    df["initial"] = df.index.map(cddict)

    df.plot(column="initial", cmap="jet")
    plt.savefig(newdir + "initial.png")
    plt.close()

    with open(newdir + "init" + str(i) + ".json", 'w') as jf1:
        json.dump(cddict, jf1)

    print("saved Initial", i)
Ejemplo n.º 17
0
df["VAP"]=pd.to_numeric(df["VAP"])
df["BVAP"]=pd.to_numeric(df["BVAP"])




df["nBVAP"] = df["VAP"]-df["BVAP"]


graph = Graph.from_json(graph_path)

graph.join(df)


for i in range(1):
    cddict =  recursive_tree_part(graph,range(num_districts),df["TOTPOP"].sum()/num_districts,"TOTPOP", .001,1)
    
    df["initial"]=df.index.map(cddict)
    
    df.plot(column="initial",cmap="jet")
    plt.savefig(newdir+"initial.png")
    plt.close()

with open(newdir+"init.json", 'w') as jf1:
	    json.dump(cddict, jf1)

print("saved Initial")
updater = {
        "population": updaters.Tally("TOTPOP", alias="population"),
    "cut_edges": cut_edges,
    "BVAP":Election("BVAP",{"BVAP":"BVAP","nBVAP":"nBVAP"})
Ejemplo n.º 18
0
def demo():
    graph_path = "./Data/PA_VTDALL.json"
    graph = Graph.from_json(graph_path)
    k = 18
    ep = 0.05
    pop_col = "TOT_POP"

    plot_path = "./Data/VTD_FINAL"
    unit_df = gpd.read_file(plot_path)
    unit_col = "GEOID10"
    division_col = "COUNTYFP10"
    divisions = unit_df[[division_col, 'geometry']].dissolve(by=division_col,
                                                             aggfunc='sum')
    county_dict = pd.Series(unit_df[division_col].values,
                            index=unit_df[unit_col]).to_dict()

    for v in graph.nodes:
        graph.nodes[v]['division'] = county_dict[v]
        graph.nodes[v][unit_col] = v

    updaters = {
        "population": Tally("TOT_POP", alias="population"),
        "cut_edges": cut_edges,
    }
    cddict = recursive_tree_part(graph,
                                 range(k),
                                 unit_df[pop_col].sum() / k,
                                 pop_col,
                                 .01,
                                 node_repeats=1)
    initial_partition = Partition(graph, cddict, updaters)
    ideal_population = sum(
        initial_partition["population"].values()) / len(initial_partition)
    division_proposal = partial(recom,
                                pop_col=pop_col,
                                pop_target=ideal_population,
                                epsilon=0.05,
                                method=partial(division_bipartition_tree,
                                               division_col='division'),
                                node_repeats=2)

    chain = MarkovChain(proposal=division_proposal,
                        constraints=[
                            constraints.within_percent_of_ideal_population(
                                initial_partition, 0.05),
                        ],
                        accept=accept.always_accept,
                        initial_state=initial_partition,
                        total_steps=1000)

    t = 0
    snapshot = 100
    for part in chain:
        if t % snapshot == 0:
            draw_graph(graph,
                       part.assignment,
                       unit_df,
                       divisions,
                       './figs/chain_' + str(t) + '.png',
                       geo_id=unit_col)
            print(
                "t: ", t, ", num_splits: ",
                num_splits(part,
                           unit_df,
                           geo_id=unit_col,
                           division_col=division_col), ", cut_length",
                cut_length(part))
        t += 1
Ejemplo n.º 19
0
my_updaters.update(election_updaters)

election_functions = [Election(j, candidates[j]) for j in elections]
election_updaters = {
    election.name: election
    for election in election_functions
}
my_updaters.update(election_updaters)

#initial partition#######################################################
step_Num = 0
total_population = state_gdf[tot_pop].sum()
ideal_population = total_population / num_districts

if start_map == 'new_seed':
    start_map = recursive_tree_part(graph, range(num_districts),
                                    ideal_population, tot_pop, pop_tol, 3)

initial_partition = GeographicPartition(graph=graph,
                                        assignment=start_map,
                                        updaters=my_updaters)

proposal = partial(recom,
                   pop_col=tot_pop,
                   pop_target=ideal_population,
                   epsilon=pop_tol,
                   node_repeats=3)


#constraints ############################################
def inclusion(partition):
    """
Ejemplo n.º 20
0
totpop = 0
for node in g.nodes():
    g.node[node]["TOT_POP"] = int(g.node[node]["TOT_POP"])

    totpop += g.node[node]["TOT_POP"]

if shape:
    pos = {node: (c_x[node], c_y[node]) for node in g.nodes}

cddicts = []

num_trees = 8
for i in range(num_trees):
    cddicts.append(
        recursive_tree_part(g, range(18), totpop / 18, "TOT_POP", .02, 1))


def step_num(partition):
    parent = partition.parent
    if not parent:
        return 0
    return parent["step_num"] + 1


def b_nodes_bi(partition):
    return {x[0]
            for x in partition["cut_edges"]
            }.union({x[1]
                     for x in partition["cut_edges"]})
Ejemplo n.º 21
0
        "cut_edges": cut_edges,
    }
    elections = [
        Election(
            election_names[i],
            {
                "Democratic": election_columns[i][0],
                "Republican": election_columns[i][1]
            },
        ) for i in range(len(election_names))
    ]
    election_updaters = {election.name: election for election in elections}
    myupdaters.update(election_updaters)

    #initial partition
    ass = recursive_tree_part(graph, range(k), total_population / k, pop_col,
                              pop_tol)
    initial_partition = Partition(graph, ass, myupdaters)
    dev = max([
        np.abs(initial_partition["population"][d] - pop_target)
        for d in initial_partition.parts
    ])
    print(" Using initial", k, "districts with population deviation = ",
          100 * dev / pop_target, "% of ideal.")

    #chain
    myconstraints = [
        constraints.within_percent_of_ideal_population(initial_partition,
                                                       pop_tol)
    ]
    chain = MarkovChain(proposal=myproposal,
                        constraints=myconstraints,
Ejemplo n.º 22
0
another_dists = np.add(0.1 * geo_dists, partisan)

# In[56]:

another_dists

# In[22]:

cddicts = []

num_cong_dists = 18

num_trees = 0
for i in range(num_trees):
    cddicts.append(
        recursive_tree_part(g, range(num_cong_dists), totpop / num_cong_dists,
                            "TOT_POP", .02, 1))

ideal_population = totpop / num_cong_dists

proposal = propose_random_flip


def cut_length(partition):
    return len(partition["cut_edges"])


num_flips = 5
num_flip_steps = 1000


def step_num(partition):
Ejemplo n.º 23
0
graph.add_data(df, columns=new_cols)

# In[9]:

graph.nodes[1]['CVAP']

# In[5]:

# INITIAL PARTITION ASSIGNMENT USING RECURSIVE TREE PARTITION

starts = []

for i in range(1):
    starts.append(
        recursive_tree_part(graph, range(num_districts),
                            df['CVAP'].sum() / num_districts, "CVAP", .001, 1))
    #starts.append(recursive_tree_part(graph,range(num_districts),df['TOTPOP'].sum()/num_districts, "TOTPOP", .001, 1))

# In[6]:

updater = {
    "population": updaters.Tally("TOTPOP", alias="population"),
    "cut_edges": cut_edges,
    "BVAP": Election("BVAP", {
        "BVAP": "BVAP",
        "nBVAP": "nBVAP"
    }),
    "BCVAP": Election("BCVAP", {
        "BCVAP": "BCVAP",
        "nBCVAP": "nBCVAP"
    })
Ejemplo n.º 24
0
    "VAP": Tally(VAP, alias="VAP"),
    "cpop": Tally(ccol, alias="cpop"),
    "cut_edges": cut_edges
}
election_updaters = {election.name: election for election in elections}
my_updaters.update(election_updaters)

tot_pop_col = 0
tot_ccol = 0
tot_VAP = 0
#for tallying over VAP:
for n in graph.nodes():
    graph.node[n][VAP] = int(graph.node[n][VAP])
    tot_VAP += graph.node[n][VAP]

cddict = recursive_tree_part(graph, range(num_districts),
                             tot_VAP / num_districts, VAP, 0.01, 1)

starting_partition = Partition(graph, assignment=cddict, updaters=my_updaters)

#-------------------------------------------------------------------------------------------

#CHAIN FOR TOTPOP
proposal = partial(recom,
                   pop_col=VAP,
                   pop_target=tot_VAP / num_districts,
                   epsilon=0.02,
                   node_repeats=1)

compactness_bound = constraints.UpperBound(
    lambda p: len(p["cut_edges"]), 2 * len(starting_partition["cut_edges"]))
    elections = [
        Election(
            election_names[i],
            {"Democratic": election_columns[i][0], "Republican": election_columns[i][1]},
        )
        for i in range(len(election_names))
    ]
    election_updaters = {election.name: election for election in elections}
    myupdaters.update(election_updaters)

    #initial partition
    print("Creating seed with", k, "districts.")
    dev = pop_tol*pop_target + 1
    while dev > pop_tol*pop_target:
        print(".", end="")
        initial_ass = recursive_tree_part(graph, range(k), pop_target, pop_col, pop_tol, node_repeats=10)
        initial_partition = Partition(graph, initial_ass, myupdaters)
        dev = max([np.abs(initial_partition["population"][d] - pop_target) for d in initial_partition.parts])
    dev = max([np.abs(initial_partition["population"][d] - pop_target) for d in initial_partition.parts])
    print(" Using initial", k, "districts with population deviation = ", 100*dev/pop_target, "% of ideal.")

    #chain
    compactness_bound = constraints.UpperBound(
        lambda p: len(p["cut_edges"]),
        2*len(initial_partition["cut_edges"])
    )
    myconstraints = [
        constraints.within_percent_of_ideal_population(initial_partition, pop_tol),
        compactness_bound
    ]
    chain = MarkovChain(
Ejemplo n.º 26
0
mo_updaters.update(election_updaters)

## ## ## ## ## ## ## ## ## ## ## 
## Initial partition
## ## ## ## ## ## ## ## ## ## ## 
print("Creating seed plan")

##################################################################
######## ! if using a random map as the initial partition
##################################################################
# NUM_DISTRICTS=34
# EPS=0.05
total_pop = sum(dat[POP_COL])
ideal_pop = total_pop / NUM_DISTRICTS
cddict = recursive_tree_part(graph=graph, parts=range(NUM_DISTRICTS), 
                                pop_target=ideal_pop, pop_col=POP_COL, epsilon=EPS)

init_partition = GeographicPartition(graph, assignment=cddict, updaters=mo_updaters)
# init_partition["USSEN16"].efficiency_gap() #PRES EG = -0.08, USSEN EG = -0.18

##################################################################
######## ! if using the enacted state senate map as the initial partition
##################################################################
# init_partition = GeographicPartition(graph, assignment="SLDUST", updaters=mo_updaters)
# init_partition["USSEN16"].efficiency_gap() 
# ideal_pop = sum(init_partition['population'].values()) / len(init_partition)

# # show stuff about the initial partition
# init_partition.graph
# init_partition.graph.nodes[0] 
# init_partition['population']
Ejemplo n.º 27
0
    race_con(racial_vap_ref, 3))
nvap_con = constraints.LowerBound(
    lambda p: race_con(p["racial_demographics"], 4),
    race_con(racial_vap_ref, 4))
pvap_con = constraints.LowerBound(
    lambda p: race_con(p["racial_demographics"], 5),
    race_con(racial_vap_ref, 5))

racial_bound = constraints.Validator(
    [bvap_con, hvap_con, avap_con, nvap_con, pvap_con])

if old_dist != num_dist:
    # do random initial partition optimization
    recursive_part = recursive_tree_part(graph,
                                         range(num_dist),
                                         pop_target=pop / num_dist,
                                         pop_col=pop_col,
                                         epsilon=0.05,
                                         node_repeats=3)
    random_init_partition = GeographicPartition(graph, recursive_part,
                                                updaters)

    # Racial backsliding test
    racial_breakdown = random_init_partition["racial_demographics"]
    if not (backsliding_pass(racial_vap_ref, racial_breakdown)):

        chain_racial_requirements = MarkovChain(
            proposal=proposal,
            constraints=[
                constraints.within_percent_of_ideal_population(
                    random_init_partition, 0.05)
            ],
shape = True

nlist = list(g.nodes())
n = len(nlist)

totpop = 0
for node in g.nodes():
    g.node[node]["TOTPOP"] = int(g.node[node]["TOTPOP"])

    totpop += g.node[node]["TOTPOP"]

pos = nx.kamada_kawai_layout(g)
if shape:
    pos = {node: (c_x[node], c_y[node]) for node in g.nodes}

cddict1 = recursive_tree_part(g, range(4), totpop / 4, "TOTPOP", .01, 1)

cddict2 = recursive_tree_part(g, range(4), totpop / 4, "TOTPOP", .01, 1)


def step_num(partition):
    parent = partition.parent
    if not parent:
        return 0
    return parent["step_num"] + 1


def b_nodes_bi(partition):
    return {x[0]
            for x in partition["cut_edges"]
            }.union({x[1]
Ejemplo n.º 29
0
betas = []
ts = []
myupdaters = {
    'population': Tally('TOTPOP', alias="population"),
    'cut_edges': cut_edges,
    'step_num': step_num,
}

runlist = [0]
partdict = {r: [] for r in runlist}
allparts = []

#run annealing flip
for run in runlist:
    initial_ass = recursive_tree_part(graph, range(6), totpop / 6, "TOTPOP",
                                      .01, 1)
    initial_partition = Partition(graph,
                                  assignment=initial_ass,
                                  updaters=myupdaters)
    popbound = within_percent_of_ideal_population(initial_partition, pop_tol)
    ideal_population = totpop / 6

    print("Dumping seed", run)
    pickle.dump(initial_ass, open("oneseed" + str(run), "wb"))

    #make flip chain
    exp_chain = MarkovChain(propose_random_flip,
                            constraints=[single_flip_contiguous, popbound],
                            accept=annealing_cut_accept2,
                            initial_state=initial_partition,
                            total_steps=STEPS)