def run_simple2(graph):
    election = Election("2014 Senate", {
        "Democratic": "sen_blue",
        "Republican": "sen_red"
    },
                        alias="2014_Senate")

    initial_partition = Partition(graph,
                                  assignment="con_distri",
                                  updaters={
                                      "2014_Senate":
                                      election,
                                      "population":
                                      Tally("population", alias="population"),
                                      "exterior_boundaries":
                                      exterior_boundaries,
                                      "interior_boundaries":
                                      interior_boundaries,
                                      "perimeter":
                                      perimeter,
                                      "boundary_nodes":
                                      boundary_nodes,
                                      "cut_edges":
                                      cut_edges,
                                      "area":
                                      Tally("area", alias="area"),
                                      "cut_edges_by_part":
                                      cut_edges_by_part,
                                      "county_split":
                                      county_splits('county_split',
                                                    "COUNTY_ID"),
                                      "black_population":
                                      Tally("black_pop",
                                            alias="black_population"),
                                  })
    districts_within_tolerance_2 = lambda part: districts_within_tolerance(
        part, 'population', 0.3)
    is_valid = Validator(
        [single_flip_contiguous, districts_within_tolerance_2])

    chain = MarkovChain(
        proposal=propose_random_flip,
        is_valid=is_valid,
        accept=always_accept,
        #     accept=accept, #THe acceptance criteria is what needs to be defined ourselves - to match the paper
        initial_state=initial_partition,
        total_steps=30,
    )
    efficiency_gaps = []
    wins = []

    for partition in chain:
        if (hasattr(partition, 'accepted') and partition.accepted):
            efficiency_gaps.append(
                gerrychain.scores.efficiency_gap(partition["2014_Senate"]))
            wins.append(partition["2014_Senate"].wins("Democratic"))

    return (efficiency_gaps, wins, partition)
graph = Graph.from_file(path_to_shapefile)
#graph = Graph.from_json(path_to_shapefile)
#graph = gpd.read_file(path_to_shapefile)

# ---- Updaters & Elections -----

updaters = {
    "population": updaters.Tally(pop_col, alias="population"),
    "cut_edges": cut_edges,
    "BVAP": updaters.Tally(BVAP_col, alias="BVAP"),
    "HVAP": updaters.Tally(HVAP_col, alias="HVAP"),
    "AVAP": updaters.Tally(AVAP_col, alias="AVAP"),
    "NVAP": updaters.Tally(Native_col, alias="NVAP"),
    "PVAP": updaters.Tally(Pacific_col, alias="PVAP"),
    "VAP": updaters.Tally(VAP_col, alias="VAP"),
    "county_splits": county_splits("county_splits", county_assignment_col)
}

num_elections = len(election_names)

elections = [
    Election(
        election_names[i],
        {
            "Dem": election_columns[i][0],
            "Rep": election_columns[i][1]
        },
    ) for i in range(num_elections)
]

election_updaters = {election.name: election for election in elections}
示例#3
0
## ## ## ## ## ## ## ## ## ## ## 
## creating an initial partition
## ## ## ## ## ## ## ## ## ## ## 
print("Reading in Data/Graph")

dat_path = "/Users/hopecj/projects/gerryspam/MO/dat/final_prec/prec_labeled.shp"
dat = gpd.read_file(dat_path)
list(dat.columns)
dat['SLDUST'].nunique()
dat['SLDLST'].nunique()

graph = Graph.from_file(dat_path)

mo_updaters = {"population" : Tally(POP_COL, alias="population"),
               "cut_edges": cut_edges,
               "county_splits": county_splits("county_splits", "COUNTYFP"),
               "num_vra_districts": num_vra_districts,
               "polsby_popper": polsby_popper}

elections = [Election("USSEN16", {"Dem": "G16USSDKAN", "Rep": "G16USSRBLU"}),
             Election("PRES16", {"Dem": "G16PREDCLI", "Rep": "G16PRERTRU"})]
election_updaters = {election.name: election for election in elections}

mo_updaters.update(election_updaters)

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

##################################################################
def plan_evaluation(partition):
    graph = partition.graph

    # Naming constants
    county_column = "COUNTY"
    municipality_column = "TOWN"

    # Contiguity
    split_districts = []
    for district in partition.parts.keys():
        if district != -1:
            part_contiguous = nx.is_connected(partition.subgraphs[district])
            if not part_contiguous:
                split_districts.append(district)
    contiguity = (len(split_districts) == 0)

    # Calculate cut edges
    cut_edges = updaters.cut_edges(partition)

    # Polsby Popper
    try:
        polsbypopper = [
            v for _k, v in metrics.polsby_popper(partition).items()
        ]
        polsbypopper_stats = {
            'max': max(polsbypopper),
            'min': min(polsbypopper),
            'mean': statistics.mean(polsbypopper),
            'median': statistics.median(polsbypopper)
        }
        if len(polsbypopper) > 1:
            polsbypopper_stats['variance'] = statistics.variance(polsbypopper)
    except:
        polsbypopper = []
        polsbypopper_stats = "Polsby Popper unavailable for this geometry."

    # county splits

    try:
        county_splits = updaters.county_splits("county_splits",
                                               county_column)(partition)
        county_response = {}
        counties = set([graph.nodes[n][county_column] for n in graph.nodes])
        county_response['num_counties'] = len(counties)
        try:
            county_partition = GeographicPartition(
                graph, county_column,
                {"population": updaters.Tally('TOTPOP', alias="population")})
            county_pop_dict = {
                c: county_partition.population[c]
                for c in counties
            }
            county_response['population'] = county_pop_dict
        except KeyError:
            county_response['population'] = -1
        split_list = {}
        splits = 0
        num_split = 0
        for c in counties:
            s = county_splits[c].contains
            # this is caused by a bug in some states in gerrychain I think
            if -1 in s:
                s.remove(-1)
            if len(s) > 1:
                num_split += 1
                split_list[c] = list(s)
                splits += len(s) - 1
        county_response['splits'] = splits
        county_response['split_list'] = split_list
    except:
        county_response = -1

    # municipality splits
    try:
        municipality_splits = updaters.county_splits(
            "muni_splits", municipality_column)(partition)
        muni_response = {}
        munis = set([graph.nodes[n][municipality_column] for n in graph.nodes])
        muni_response['num_counties'] = len(munis)
        try:
            muni_partition = GeographicPartition(
                graph, municipality_column,
                {"population": updaters.Tally('TOTPOP', alias="population")})
            muni_pop_dict = {m: muni_partition.population[m] for m in munis}
            muni_response['population'] = muni_pop_dict
            muni_response['num_counties'] = len(munis)
        except KeyError:
            muni_response['population'] = -1
        split_list = {}
        splits = 0
        num_split = 0
        for m in munis:
            s = municipality_splits[m].contains
            # this is caused by a bug in some states in gerrychain I think
            if -1 in s:
                s.remove(-1)
            if len(s) > 1:
                num_split += 1
                split_list[m] = list(s)
                splits += len(s) - 1
        muni_response['splits'] = splits
        muni_response['split_list'] = split_list
    except:
        muni_response = -1

    # Build Response dictionary
    response = {
        'cut_edges': len(cut_edges),
        'contiguity': contiguity,
        'split': split_districts,
        'polsbypopper': polsbypopper_stats,
        'pp_scores': polsbypopper,
        'num_units': len(graph.nodes),
        'counties': county_response,
        'municipalities': muni_response
    }
    return response
def run_simple(graph):
    election = Election("2016 President", {
        "Democratic": "T16PRESD",
        "Republican": "T16PRESR"
    },
                        alias="2016_President")

    initial_partition = Partition(graph,
                                  assignment="2011_PLA_1",
                                  updaters={
                                      "2016_President":
                                      election,
                                      "population":
                                      Tally("TOT_POP", alias="population"),
                                      "perimeter":
                                      perimeter,
                                      "exterior_boundaries":
                                      exterior_boundaries,
                                      "interior_boundaries":
                                      interior_boundaries,
                                      "boundary_nodes":
                                      boundary_nodes,
                                      "cut_edges":
                                      cut_edges,
                                      "area":
                                      Tally("area", alias="area"),
                                      "cut_edges_by_part":
                                      cut_edges_by_part,
                                      "county_split":
                                      county_splits('county_split',
                                                    "COUNTYFP10"),
                                      "black_population":
                                      Tally("BLACK_POP",
                                            alias="black_population"),
                                  })

    efficiency_gaps = []
    wins = []
    beta = 0
    wp = 1
    wi = 1
    wc = 0
    wm = 1

    def accept(partition):
        return (metro_scoring_prob(partition, beta, wp, wi, wc, wm))

    is_valid = Validator([single_flip_contiguous, districts_within_tolerance])
    chain = MarkovChain(
        proposal=propose_random_flip,
        is_valid=is_valid,
        #accept = always_accept,
        accept=
        accept,  #THe acceptance criteria is what needs to be defined ourselves - to match the paper
        initial_state=initial_partition,
        total_steps=30)

    for partition in chain:
        if (hasattr(partition, 'accepted') and partition.accepted):
            efficiency_gaps.append(
                gerrychain.scores.efficiency_gap(partition["2016_President"]))
            wins.append(partition["2016_President"].wins("Democratic"))
    return (efficiency_gaps, wins, partition)
示例#6
0
def run_simple(graph, num_samples = 80000, wp = 3000, wi = 2.5, wc = 0.4, wm = 800, get_parts = 5):
    election = Election(
        "2014 Senate",
        {"Democratic": "sen_blue", "Republican": "sen_red"},
        alias="2014_Senate"
    )
    
    initial_partition = Partition(
            graph,
            assignment="2014_CD",
            updaters={
                "2014_Senate": election,
                "population": Tally("population", alias="population"), 
                "exterior_boundaries": exterior_boundaries,
                "interior_boundaries": interior_boundaries,
                "perimeter": perimeter,
                "boundary_nodes": boundary_nodes,
               "cut_edges": cut_edges,
                "area": Tally("area", alias="area"),
               "cut_edges_by_part": cut_edges_by_part, 
                "county_split" : county_splits( 'county_split', "COUNTY_ID"),
                "black_population": Tally("black_pop", alias = "black_population"),
            }
        )
    
    def vra_validator(part):
        if(vra_district_requirement(part, 2, [0.4, 0.335]) > 0):
            return False
        return True

    districts_within_tolerance_2 = lambda part : districts_within_tolerance(part, 'population', 0.12)
    is_valid = Validator([single_flip_contiguous, districts_within_tolerance_2, vra_validator ])
    def accept(partition, counter):
        if(counter < 40000):
            beta = 0
        elif(counter < 60000):
            beta = (counter - 40000) /(60000-40000)
        else:
            beta = 1
        return(metro_scoring_prob(partition, beta, wp, wi, wc, wm))

    chain = MarkovChainAnneal(
        proposal=propose_random_flip,
        is_valid=is_valid,
        accept=accept,
        initial_state=initial_partition,
        total_steps= num_samples * 100,
    )
    # going to show 5 partitions from this sample
    part_con = max(1, num_samples / get_parts)
    
    efficiency_gaps = []
    wins = []
    voting_percents = []
    sample_parts = []
    tbefore = time.time()
    for partition in chain:
        if(hasattr(partition, 'accepted') and partition.accepted):
            efficiency_gaps.append(gerrychain.scores.efficiency_gap(partition["2014_Senate"]))
            wins.append(partition["2014_Senate"].wins("Democratic"))
            voting_percents.append(partition["2014_Senate"].percents("Democratic"))
            num_s = len(wins)
            if(num_s % part_con) == 0:
                sample_parts.append(partition)
            if(num_s> num_samples):
                break
            if(num_s % 1000 == 0):
                tnext = time.time()
                print("It took %i time to get 1000 samples" % (tnext - tbefore))
                tbefore = time.time()
    return(efficiency_gaps, wins, voting_percents, sample_parts)