Proposals and Constraints¶
Proposals¶
- class gerrychain.proposals.MultiMemberReCom(*args: object, **kwargs: object)[source]¶
Ready-made builders for ReCom with fixed member counts by district label.
The methods mirror the four non-reversible
ReComvariants. They use a target population per member and do not provide reversible or letter-named variants. This class is a namespace and cannot be instantiated.- static A(pop_col: str, pop_target: int | float, epsilon: float, members_per_district: Mapping[Hashable, int], region_surcharge: dict[str, float] | None = None, allow_pair_reselection: bool = False) ProposalFn¶
Build multi-member ReCom with cut-edge pair selection and a minimum spanning tree.
A cut edge is selected uniformly at random, so district pairs are weighted by the number of boundary edges they share. The merged pair is split using a minimum spanning tree on random edge weights. Each district’s target population is
pop_targetmultiplied by its fixed member count inmembers_per_district.- Parameters:
pop_col (str) – Node attribute containing population data.
pop_target (int | float) – Target population for one elected member.
epsilon (float) – Allowed deviation from each district’s member-adjusted target. Must be in
[0, 1).members_per_district (Mapping[Hashable, int]) – Positive member count for every district label. Member counts remain attached to these labels throughout the chain.
region_surcharge (dict[str, float] | None, optional) – Surcharges used to discourage the spanning tree from crossing specified region boundaries. Defaults to
None.allow_pair_reselection (bool, optional) – Whether to try a different adjacent district pair when tree splitting fails for the selected pair. Defaults to
False.
- Returns:
A proposal function for use with
MarkovChain.- Return type:
- static B(pop_col: str, pop_target: int | float, epsilon: float, members_per_district: Mapping[Hashable, int], region_surcharge: dict[str, float] | None = None, allow_pair_reselection: bool = False) ProposalFn¶
Build multi-member ReCom with district-pair selection and a minimum spanning tree.
An adjacent district pair is selected uniformly, independent of shared boundary length and member count. The merged pair is split using a minimum spanning tree on random edge weights. Each district’s target population is
pop_targetmultiplied by its fixed member count inmembers_per_district.- Parameters:
pop_col (str) – Node attribute containing population data.
pop_target (int | float) – Target population for one elected member.
epsilon (float) – Allowed deviation from each district’s member-adjusted target. Must be in
[0, 1).members_per_district (Mapping[Hashable, int]) – Positive member count for every district label. Member counts remain attached to these labels throughout the chain.
region_surcharge (dict[str, float] | None, optional) – Surcharges used to discourage the spanning tree from crossing specified region boundaries. Defaults to
None.allow_pair_reselection (bool, optional) – Whether to try a different adjacent district pair when tree splitting fails for the selected pair. Defaults to
False.
- Returns:
A proposal function for use with
MarkovChain.- Return type:
- static C(pop_col: str, pop_target: int | float, epsilon: float, members_per_district: Mapping[Hashable, int], allow_pair_reselection: bool = False) ProposalFn¶
Build multi-member ReCom with cut-edge pair selection and a uniform spanning tree.
A cut edge is selected uniformly at random, so district pairs are weighted by the number of boundary edges they share. The merged pair is split using a spanning tree drawn uniformly with Wilson’s algorithm. Each district’s target population is
pop_targetmultiplied by its fixed member count inmembers_per_district. Region surcharges are not supported because a uniform spanning tree does not use edge weights.- Parameters:
pop_col (str) – Node attribute containing population data.
pop_target (int | float) – Target population for one elected member.
epsilon (float) – Allowed deviation from each district’s member-adjusted target. Must be in
[0, 1).members_per_district (Mapping[Hashable, int]) – Positive member count for every district label. Member counts remain attached to these labels throughout the chain.
allow_pair_reselection (bool, optional) – Whether to try a different adjacent district pair when tree splitting fails for the selected pair. Defaults to
False.
- Returns:
A proposal function for use with
MarkovChain.- Return type:
- static D(pop_col: str, pop_target: int | float, epsilon: float, members_per_district: Mapping[Hashable, int], allow_pair_reselection: bool = False) ProposalFn¶
Build multi-member ReCom with district-pair selection and a uniform spanning tree.
An adjacent district pair is selected uniformly, independent of shared boundary length and member count. The merged pair is split using a spanning tree drawn uniformly with Wilson’s algorithm. Each district’s target population is
pop_targetmultiplied by its fixed member count inmembers_per_district. Region surcharges are not supported because a uniform spanning tree does not use edge weights.- Parameters:
pop_col (str) – Node attribute containing population data.
pop_target (int | float) – Target population for one elected member.
epsilon (float) – Allowed deviation from each district’s member-adjusted target. Must be in
[0, 1).members_per_district (Mapping[Hashable, int]) – Positive member count for every district label. Member counts remain attached to these labels throughout the chain.
allow_pair_reselection (bool, optional) – Whether to try a different adjacent district pair when tree splitting fails for the selected pair. Defaults to
False.
- Returns:
A proposal function for use with
MarkovChain.- Return type:
- static cut_edges_mst(pop_col: str, pop_target: int | float, epsilon: float, members_per_district: Mapping[Hashable, int], region_surcharge: dict[str, float] | None = None, allow_pair_reselection: bool = False) ProposalFn[source]¶
Build multi-member ReCom with cut-edge pair selection and a minimum spanning tree.
A cut edge is selected uniformly at random, so district pairs are weighted by the number of boundary edges they share. The merged pair is split using a minimum spanning tree on random edge weights. Each district’s target population is
pop_targetmultiplied by its fixed member count inmembers_per_district.- Parameters:
pop_col (str) – Node attribute containing population data.
pop_target (int | float) – Target population for one elected member.
epsilon (float) – Allowed deviation from each district’s member-adjusted target. Must be in
[0, 1).members_per_district (Mapping[Hashable, int]) – Positive member count for every district label. Member counts remain attached to these labels throughout the chain.
region_surcharge (dict[str, float] | None, optional) – Surcharges used to discourage the spanning tree from crossing specified region boundaries. Defaults to
None.allow_pair_reselection (bool, optional) – Whether to try a different adjacent district pair when tree splitting fails for the selected pair. Defaults to
False.
- Returns:
A proposal function for use with
MarkovChain.- Return type:
- static cut_edges_ust(pop_col: str, pop_target: int | float, epsilon: float, members_per_district: Mapping[Hashable, int], allow_pair_reselection: bool = False) ProposalFn[source]¶
Build multi-member ReCom with cut-edge pair selection and a uniform spanning tree.
A cut edge is selected uniformly at random, so district pairs are weighted by the number of boundary edges they share. The merged pair is split using a spanning tree drawn uniformly with Wilson’s algorithm. Each district’s target population is
pop_targetmultiplied by its fixed member count inmembers_per_district. Region surcharges are not supported because a uniform spanning tree does not use edge weights.- Parameters:
pop_col (str) – Node attribute containing population data.
pop_target (int | float) – Target population for one elected member.
epsilon (float) – Allowed deviation from each district’s member-adjusted target. Must be in
[0, 1).members_per_district (Mapping[Hashable, int]) – Positive member count for every district label. Member counts remain attached to these labels throughout the chain.
allow_pair_reselection (bool, optional) – Whether to try a different adjacent district pair when tree splitting fails for the selected pair. Defaults to
False.
- Returns:
A proposal function for use with
MarkovChain.- Return type:
- static district_pairs_mst(pop_col: str, pop_target: int | float, epsilon: float, members_per_district: Mapping[Hashable, int], region_surcharge: dict[str, float] | None = None, allow_pair_reselection: bool = False) ProposalFn[source]¶
Build multi-member ReCom with district-pair selection and a minimum spanning tree.
An adjacent district pair is selected uniformly, independent of shared boundary length and member count. The merged pair is split using a minimum spanning tree on random edge weights. Each district’s target population is
pop_targetmultiplied by its fixed member count inmembers_per_district.- Parameters:
pop_col (str) – Node attribute containing population data.
pop_target (int | float) – Target population for one elected member.
epsilon (float) – Allowed deviation from each district’s member-adjusted target. Must be in
[0, 1).members_per_district (Mapping[Hashable, int]) – Positive member count for every district label. Member counts remain attached to these labels throughout the chain.
region_surcharge (dict[str, float] | None, optional) – Surcharges used to discourage the spanning tree from crossing specified region boundaries. Defaults to
None.allow_pair_reselection (bool, optional) – Whether to try a different adjacent district pair when tree splitting fails for the selected pair. Defaults to
False.
- Returns:
A proposal function for use with
MarkovChain.- Return type:
- static district_pairs_ust(pop_col: str, pop_target: int | float, epsilon: float, members_per_district: Mapping[Hashable, int], allow_pair_reselection: bool = False) ProposalFn[source]¶
Build multi-member ReCom with district-pair selection and a uniform spanning tree.
An adjacent district pair is selected uniformly, independent of shared boundary length and member count. The merged pair is split using a spanning tree drawn uniformly with Wilson’s algorithm. Each district’s target population is
pop_targetmultiplied by its fixed member count inmembers_per_district. Region surcharges are not supported because a uniform spanning tree does not use edge weights.- Parameters:
pop_col (str) – Node attribute containing population data.
pop_target (int | float) – Target population for one elected member.
epsilon (float) – Allowed deviation from each district’s member-adjusted target. Must be in
[0, 1).members_per_district (Mapping[Hashable, int]) – Positive member count for every district label. Member counts remain attached to these labels throughout the chain.
allow_pair_reselection (bool, optional) – Whether to try a different adjacent district pair when tree splitting fails for the selected pair. Defaults to
False.
- Returns:
A proposal function for use with
MarkovChain.- Return type:
- class gerrychain.proposals.ProposalFn(*args, **kwargs)[source]¶
Propose a new partition, called as
proposal_fn(partition, rng=rng).
- class gerrychain.proposals.ReCom(*args: object, **kwargs: object)[source]¶
Ready-made builders for the standard ReCom proposal variants.
Each method returns a proposal function ready to hand to
MarkovChain, so instead of thefunctools.partialincantation:from functools import partial proposal_fn = partial(recom, pop_col="TOTPOP", pop_target=ideal_pop, epsilon=0.01)
you can write:
proposal_fn = ReCom.district_pairs_mst(pop_col="TOTPOP", pop_target=ideal_pop, epsilon=0.01)
This class is a namespace, not a type: it cannot be instantiated.
The variants differ along two axes:
Pair selection:
cut_edges_*picks a cut edge uniformly at random and merges the two districts on either side of it, so a pair’s chance is proportional to the number of cut edges the districts share.district_pairs_*picks uniformly among the adjacent district pairs themselves.Spanning tree:
*_mstdraws a minimum spanning tree on random edge weights using Kruskal’s algorithm.*_ustdraws a uniform spanning tree using Wilson’s algorithm.
reversible()is the Reversible ReCom proposal, which samples exactly from the spanning-tree distribution; seereversible_recom().The aliases
A,B,C,D, andRname the same builders after the variants in “Spanning Tree Methods for Sampling Graph Partitions” (Cannon et al., 2022, https://arxiv.org/abs/2210.01401), to ease replication of results from that paper.These builders expose only the most common options. For anything else (a custom bipartition or spanning-tree function,
node_repeats, …), usebuild_recom_proposal_fn()orbuild_reversible_recom_proposal_fn(), which these methods wrap, or bindfunctools.partial(recom, ...)yourself.- static A(pop_col: str, pop_target: int | float, epsilon: float, region_surcharge: dict[str, float] | None = None, allow_pair_reselection: bool = False) ProposalFn¶
ReCom variant A: cut-edges pair selection, minimum spanning tree.
A cut edge is selected at random and the two districts on either side of it are merged. The merged region is split back into two districts by drawing a minimum spanning tree on random edge weights (Kruskal’s algorithm) and finding a population-balanced cut.
- Parameters:
pop_col (str) – The name of the population column.
pop_target (int | float) – The target population for each district.
epsilon (float) – Allowed population deviation as a percentage of the target population.
region_surcharge (dict | None, optional) – Surcharge dictionary for region-aware chains; see
random_spanning_tree(). Default is None.allow_pair_reselection (bool, optional) – Whether to fall back to a cut edge between a different district pair if bipartitioning the merged pair fails. Default is False.
- Returns:
A proposal function for use with
MarkovChain.- Return type:
- static B(pop_col: str, pop_target: int | float, epsilon: float, region_surcharge: dict[str, float] | None = None, allow_pair_reselection: bool = False) ProposalFn¶
ReCom variant B: district-pairs pair selection, minimum spanning tree.
A pair of adjacent districts is selected uniformly at random and merged. The merged region is split back into two districts by drawing a minimum spanning tree on random edge weights (Kruskal’s algorithm) and finding a population-balanced cut.
- Parameters:
pop_col (str) – The name of the population column.
pop_target (int | float) – The target population for each district.
epsilon (float) – Allowed population deviation as a percentage of the target population.
region_surcharge (dict | None, optional) – Surcharge dictionary for region-aware chains; see
random_spanning_tree(). Default is None.allow_pair_reselection (bool, optional) – Whether to allow reselection of the same district pair if bipartitioning fails. Default is False.
- Returns:
A proposal function for use with
MarkovChain.- Return type:
- static C(pop_col: str, pop_target: int | float, epsilon: float, allow_pair_reselection: bool = False) ProposalFn¶
ReCom variant C: cut-edges pair selection, uniform spanning tree.
Like
cut_edges_mst(), except the merged region is split using a spanning tree drawn uniformly at random (Wilson’s algorithm). Region surcharges are not supported: a uniform spanning tree ignores edge weights.- Parameters:
pop_col (str) – The name of the population column.
pop_target (int | float) – The target population for each district.
epsilon (float) – Allowed population deviation as a percentage of the target population.
allow_pair_reselection (bool, optional) – Whether to fall back to a cut edge between a different district pair if bipartitioning the merged pair fails. Default is False.
- Returns:
A proposal function for use with
MarkovChain.- Return type:
- static D(pop_col: str, pop_target: int | float, epsilon: float, allow_pair_reselection: bool = False) ProposalFn¶
ReCom variant D: district-pairs pair selection, uniform spanning tree.
Like
district_pairs_mst(), except the merged region is split using a spanning tree drawn uniformly at random (Wilson’s algorithm). Region surcharges are not supported: a uniform spanning tree ignores edge weights.- Parameters:
pop_col (str) – The name of the population column.
pop_target (int | float) – The target population for each district.
epsilon (float) – Allowed population deviation as a percentage of the target population.
allow_pair_reselection (bool, optional) – Whether to allow reselection of the same district pair if bipartitioning fails. Default is False.
- Returns:
A proposal function for use with
MarkovChain.- Return type:
- static R(pop_col: str, pop_target: int | float, epsilon: float, max_balanced_edge_cuts: int, repeat_until_valid: bool = False) ProposalFn¶
ReCom variant R: the reversible ReCom proposal.
Samples exactly from the spanning-tree distribution rather than an approximation of it; see
reversible_recom()and the paper “Spanning Tree Methods for Sampling Graph Partitions” (https://arxiv.org/abs/2210.01401) for details.- Parameters:
pop_col (str) – The name of the population column.
pop_target (int | float) – The target population for each district.
epsilon (float) – Allowed population deviation as a percentage of the target population.
max_balanced_edge_cuts (int) – The number of balanced edge cuts to draw from the spanning tree before selecting one, used to make the proposal reversible.
repeat_until_valid (bool, optional) – Whether to repeat until a valid partition is found. Default is False.
- Returns:
A proposal function for use with
MarkovChain.- Return type:
- static cut_edges_mst(pop_col: str, pop_target: int | float, epsilon: float, region_surcharge: dict[str, float] | None = None, allow_pair_reselection: bool = False) ProposalFn[source]¶
ReCom variant A: cut-edges pair selection, minimum spanning tree.
A cut edge is selected at random and the two districts on either side of it are merged. The merged region is split back into two districts by drawing a minimum spanning tree on random edge weights (Kruskal’s algorithm) and finding a population-balanced cut.
- Parameters:
pop_col (str) – The name of the population column.
pop_target (int | float) – The target population for each district.
epsilon (float) – Allowed population deviation as a percentage of the target population.
region_surcharge (dict | None, optional) – Surcharge dictionary for region-aware chains; see
random_spanning_tree(). Default is None.allow_pair_reselection (bool, optional) – Whether to fall back to a cut edge between a different district pair if bipartitioning the merged pair fails. Default is False.
- Returns:
A proposal function for use with
MarkovChain.- Return type:
- static cut_edges_ust(pop_col: str, pop_target: int | float, epsilon: float, allow_pair_reselection: bool = False) ProposalFn[source]¶
ReCom variant C: cut-edges pair selection, uniform spanning tree.
Like
cut_edges_mst(), except the merged region is split using a spanning tree drawn uniformly at random (Wilson’s algorithm). Region surcharges are not supported: a uniform spanning tree ignores edge weights.- Parameters:
pop_col (str) – The name of the population column.
pop_target (int | float) – The target population for each district.
epsilon (float) – Allowed population deviation as a percentage of the target population.
allow_pair_reselection (bool, optional) – Whether to fall back to a cut edge between a different district pair if bipartitioning the merged pair fails. Default is False.
- Returns:
A proposal function for use with
MarkovChain.- Return type:
- static district_pairs_mst(pop_col: str, pop_target: int | float, epsilon: float, region_surcharge: dict[str, float] | None = None, allow_pair_reselection: bool = False) ProposalFn[source]¶
ReCom variant B: district-pairs pair selection, minimum spanning tree.
A pair of adjacent districts is selected uniformly at random and merged. The merged region is split back into two districts by drawing a minimum spanning tree on random edge weights (Kruskal’s algorithm) and finding a population-balanced cut.
- Parameters:
pop_col (str) – The name of the population column.
pop_target (int | float) – The target population for each district.
epsilon (float) – Allowed population deviation as a percentage of the target population.
region_surcharge (dict | None, optional) – Surcharge dictionary for region-aware chains; see
random_spanning_tree(). Default is None.allow_pair_reselection (bool, optional) – Whether to allow reselection of the same district pair if bipartitioning fails. Default is False.
- Returns:
A proposal function for use with
MarkovChain.- Return type:
- static district_pairs_ust(pop_col: str, pop_target: int | float, epsilon: float, allow_pair_reselection: bool = False) ProposalFn[source]¶
ReCom variant D: district-pairs pair selection, uniform spanning tree.
Like
district_pairs_mst(), except the merged region is split using a spanning tree drawn uniformly at random (Wilson’s algorithm). Region surcharges are not supported: a uniform spanning tree ignores edge weights.- Parameters:
pop_col (str) – The name of the population column.
pop_target (int | float) – The target population for each district.
epsilon (float) – Allowed population deviation as a percentage of the target population.
allow_pair_reselection (bool, optional) – Whether to allow reselection of the same district pair if bipartitioning fails. Default is False.
- Returns:
A proposal function for use with
MarkovChain.- Return type:
- static reversible(pop_col: str, pop_target: int | float, epsilon: float, max_balanced_edge_cuts: int, repeat_until_valid: bool = False) ProposalFn[source]¶
ReCom variant R: the reversible ReCom proposal.
Samples exactly from the spanning-tree distribution rather than an approximation of it; see
reversible_recom()and the paper “Spanning Tree Methods for Sampling Graph Partitions” (https://arxiv.org/abs/2210.01401) for details.- Parameters:
pop_col (str) – The name of the population column.
pop_target (int | float) – The target population for each district.
epsilon (float) – Allowed population deviation as a percentage of the target population.
max_balanced_edge_cuts (int) – The number of balanced edge cuts to draw from the spanning tree before selecting one, used to make the proposal reversible.
repeat_until_valid (bool, optional) – Whether to repeat until a valid partition is found. Default is False.
- Returns:
A proposal function for use with
MarkovChain.- Return type:
- gerrychain.proposals.build_multi_member_recom_proposal_fn(pop_col: str, pop_target: int | float, epsilon: float, members_per_district: ~collections.abc.Mapping[~collections.abc.Hashable, int], node_repeats: int = 0, region_surcharge: dict[str, float] | None = None, bipartition_tree_fn: ~gerrychain.tree.bipartition_tree.ReComBipartitionTreeFn = <function bipartition_tree>, pair_selection: ~typing.Literal['district_pairs', 'cut_edges'] = 'district_pairs') ProposalFn[source]¶
Build a multi-member ReCom proposal with fixed member counts by district label.
- Parameters:
pop_col (str) – The name of the population column.
pop_target (int | float) – Target population for one member.
epsilon (float) – Allowed deviation from each district’s own target. Must be in
[0, 1).members_per_district (Mapping[Hashable, int]) – Positive member count for every district.
node_repeats (int, optional) – Additional roots to try per spanning tree. Defaults to 0.
region_surcharge (dict | None, optional) – Surcharges for region-aware spanning trees.
bipartition_tree_fn (ReComBipartitionTreeFn, optional) – Tree bipartition function.
pair_selection ("district_pairs" | "cut_edges", optional) – Adjacent-pair selection mode.
- Returns:
A proposal function for use with
MarkovChain.- Return type:
- gerrychain.proposals.build_recom_proposal_fn(pop_col: str, pop_target: int | float, epsilon: float, node_repeats: int = 0, region_surcharge: dict[str, float] | None=None, bipartition_tree_fn: ReComBipartitionTreeFn = <function bipartition_tree>, pair_selection: Literal['district_pairs', 'cut_edges']='district_pairs') ProposalFn[source]¶
Build a ReCom proposal function with its configuration bound.
This is the configurable form of the
ReComnamespace methods: it exposes everyrecom()option exceptpartitionandrng, whichMarkovChainsupplies at each step.- Parameters:
pop_col (str) – The name of the population column.
pop_target (int | float) – The target population for each district.
epsilon (float) – Allowed population deviation as a percentage of the target population.
node_repeats (int, optional) – Additional roots to try on each spanning tree before drawing a new tree. Defaults to 0. Positive values help only with cut finders whose result depends on the root; see
bipartition_tree().region_surcharge (dict | None, optional) – Surcharges for region-aware chains; see
random_spanning_tree(). Default is None.bipartition_tree_fn (ReComBipartitionTreeFn, optional) – The function used to split the merged district pair. To configure the bipartition or spanning-tree step (for example
max_attempts,allow_pair_reselection, or a uniform spanning tree), pass a pre-bound function such aspartial(bipartition_tree, max_attempts=100).pair_selection ("district_pairs" | "cut_edges", optional) – How to choose the adjacent district pair to merge.
"district_pairs"(default) draws uniformly among adjacent pairs;"cut_edges"weights each pair by the number of cut edges it shares.
- Returns:
A proposal function for use with
MarkovChain.- Return type:
- gerrychain.proposals.build_reversible_recom_proposal_fn(pop_col: str, pop_target: int | float, epsilon: float, max_balanced_edge_cuts: int, find_balanced_edge_cuts_fn: FindBalancedEdgeCutsFn = <function find_balanced_edge_cuts_memoization>, repeat_until_valid: bool = False) ProposalFn[source]¶
Build a reversible ReCom proposal function with its configuration bound.
Reversible ReCom samples exactly from the spanning-tree distribution rather than an approximation of it; see
reversible_recom(). This builder exposes every option exceptpartitionandrng, whichMarkovChainsupplies at each step.- Parameters:
pop_col (str) – The name of the population column.
pop_target (int | float) – The target population for each district.
epsilon (float) – Allowed population deviation as a percentage of the target population.
max_balanced_edge_cuts (int) – The number of balanced edge cuts to draw from the spanning tree before selecting one, which is what makes the proposal reversible. The proposal raises
ReversibilityErrorif a tree exceeds this bound.find_balanced_edge_cuts_fn (FindBalancedEdgeCutsFn, optional) – The balanced-cut finder. Default is
find_balanced_edge_cuts_memoization().repeat_until_valid (bool, optional) – Whether to keep drawing until a valid partition is found. Default is False.
- Returns:
A proposal function for use with
MarkovChain.- Return type:
- gerrychain.proposals.multi_member_recom(partition: ~gerrychain.partition.partition.Partition, pop_col: str, pop_target: int | float, epsilon: float, members_per_district: ~collections.abc.Mapping[~collections.abc.Hashable, int], node_repeats: int = 0, region_surcharge: dict[str, float] | None = None, bipartition_tree_fn: ~gerrychain.tree.bipartition_tree.ReComBipartitionTreeFn = <function bipartition_tree>, pair_selection: ~typing.Literal['district_pairs', 'cut_edges'] = 'district_pairs', *, rng: ~random.Random | int | None = None) Partition[source]¶
Return a ReCom proposal for districts with fixed, unequal member counts.
pop_targetis the target population for one member. Each district’s target ispop_target * members_per_district[label]. Member counts remain attached to district labels while ReCom changes their geography.- Parameters:
partition (Partition) – The current partition.
pop_col (str) – The name of the population column.
pop_target (int | float) – Target population for one member.
epsilon (float) – Allowed deviation from each district’s own target. Must be in
[0, 1).members_per_district (Mapping[Hashable, int]) – Positive member count for every district.
node_repeats (int, optional) – Additional roots to try per spanning tree. Defaults to 0.
region_surcharge (dict | None, optional) – Surcharges for region-aware spanning trees.
bipartition_tree_fn (ReComBipartitionTreeFn, optional) – Tree bipartition function.
pair_selection ("district_pairs" | "cut_edges", optional) – Adjacent-pair selection mode.
rng (random.Random | int | None, optional) – Source of randomness.
- Returns:
The proposed partition.
- Return type:
- gerrychain.proposals.propose_chunk_flip(partition: Partition, *, rng: Random | int | None = None) Partition[source]¶
Chooses a random boundary node and proposes to flip it and all of its neighbors.
This function chooses a random boundary node and proposes to flip it and all of its neighbors. It returns a possible next ~gerrychain.Partition.
- Parameters:
partition (Partition) – The current partition to propose a flip from.
rng (random.Random | int | None, optional) – Source of randomness. Pass a shared
Randomfor repeated standalone calls; an integer restarts the stream each call.
- Returns:
A possible next ~gerrychain.Partition
- Return type:
- gerrychain.proposals.propose_random_flip(partition: Partition, *, rng: Random | int | None = None) Partition[source]¶
Proposes a random boundary flip from the partition.
This function proposes a random boundary flip from the partition. It returns a possible next ~gerrychain.Partition.
- Parameters:
partition (Partition) – The current partition to propose a flip from.
rng (random.Random | int | None, optional) – Source of randomness. Pass a shared
Randomfor repeated standalone calls; an integer restarts the stream each call.
- Returns:
A possible next ~gerrychain.Partition
- Return type:
- gerrychain.proposals.recom(partition: Partition, pop_col: str, pop_target: int | float, epsilon: float, node_repeats: int = 0, region_surcharge: dict[str, float] | None=None, bipartition_tree_fn: ReComBipartitionTreeFn = <function bipartition_tree>, pair_selection: Literal['district_pairs', 'cut_edges']='district_pairs', *, rng: Random | int | None = None) Partition[source]¶
Return new partition resulting from the ReCom algorithm.
ReCom (short for ReCombination) is a Markov Chain Monte Carlo (MCMC) algorithm used for redistricting. At each step of the algorithm, a pair of adjacent districts is selected at random and merged into a single district. The region is then split into two new districts by generating a spanning tree using the Kruskal/Karger algorithm and cutting an edge at random. The edge is checked to ensure that it separates the region into two new districts that are population balanced, and, if not, a new edge is selected at random and the process is repeated.
Example usage:
from functools import partial from gerrychain import MarkovChain from gerrychain.proposals import recom
# …define constraints, acceptance_fn, partition, total_steps here…
# Ideal population: pop_target = sum(partition[“population”].values()) / len(partition)
proposal_fn = partial(recom, pop_col=”POP10”, pop_target=pop_target, epsilon=.05)
chain = MarkovChain(proposal_fn, constraints, acceptance_fn, partition, total_steps)
- Parameters:
partition (Partition) – The initial partition.
pop_col (str) – The name of the population column.
pop_target (int | float) – The target population for each district.
epsilon (float) – The epsilon value for population deviation as a percentage of the target population.
node_repeats (int, optional) – Additional roots to try on each spanning tree before drawing a new tree. Defaults to 0. Positive values are useful with contraction or custom cut-edge finders, but not with the default memoized finder.
region_surcharge (dict | None, optional) – The surcharge dictionary for the graph used for region-aware partitioning of the grid. Default is None.
bipartition_tree_fn (ReComBipartitionTreeFn, optional) – The method used for bipartitioning the tree. Default is gerrychain.tree.bipartition_tree. To configure the bipartition or spanning-tree step (e.g.
max_attempts, orspanning_tree_fn_kwargsfor spanning-tree options), pass a pre-bound function, e.g.partial(bipartition_tree, spanning_tree_fn_kwargs={...}).pair_selection ("district_pairs" | "cut_edges", optional) – How to choose the pair of adjacent districts to merge.
"district_pairs"(default) draws uniformly among the adjacent district pairs;"cut_edges"draws uniformly among the cut edges, so a pair’s chance is proportional to the number of cut edges the two districts share.rng (random.Random | int | None, optional) – Source of randomness. Pass a shared
Randomfor repeated standalone calls; an integer restarts the stream each call.
- Returns:
The new partition resulting from the ReCom algorithm.
- Return type:
- gerrychain.proposals.reversible_recom(partition: Partition, pop_col: str, pop_target: int | float, epsilon: float, max_balanced_edge_cuts: int, find_balanced_edge_cuts_fn: FindBalancedEdgeCutsFn = <function find_balanced_edge_cuts_memoization>, repeat_until_valid: bool = False, *, rng: Random | int | None = None) Partition[source]¶
Reversible ReCom algorithm for redistricting.
This function performs the reversible ReCom algorithm, which is a Markov Chain Monte Carlo (MCMC) algorithm used for redistricting. For more information, see the paper “Spanning Tree Methods for Sampling Graph Partitions” by Cannon, et al. (2022) at https://arxiv.org/abs/2210.01401
- Parameters:
partition (Partition) – The initial partition.
pop_col (str) – The name of the population column.
pop_target (int | float) – The target population for each district.
epsilon (float) – The epsilon value for population deviation as a percentage of the target population.
max_balanced_edge_cuts (int) – The number of balanced edge cuts to draw from the spanning tree before selecting one, used to make the proposal reversible.
find_balanced_edge_cuts_fn (Callable, optional) – The balance edge function. Default is find_balanced_edge_cuts_memoization.
repeat_until_valid (bool, optional) – Flag indicating whether to repeat until a valid partition is found. Default is False.
rng (random.Random | int | None, optional) – Source of randomness. Pass a shared
Randomfor repeated standalone calls; an integer restarts the stream each call.
- Returns:
The new partition resulting from the reversible ReCom algorithm.
- Return type:
- gerrychain.proposals.spectral_recom(partition: Partition, weight_type: str | None = None, lap_type: str = 'normalized', *, rng: Random | int | None = None) Partition[source]¶
Spectral ReCom proposal.
Uses spectral clustering to bipartition a subgraph of the original graph formed by merging the nodes corresponding to two adjacent districts.
Example usage:
from functools import partial from gerrychain import MarkovChain from gerrychain.proposals import recom # ...define constraints, acceptance_fn, partition, total_steps here... proposal_fn = partial( spectral_recom, weight_type=None, lap_type="normalized" ) chain = MarkovChain(proposal_fn, constraints, acceptance_fn, partition, total_steps)
- Parameters:
partition (Partition) – The initial partition.
weight_type (str | None, optional) – The type of weight to be used in the Laplacian. Default is None.
lap_type (str, optional) – The type of Laplacian to be used. Default is “normalized”.
rng (random.Random | int | None, optional) – Source of randomness. Pass a shared
Randomfor repeated standalone calls; an integer restarts the stream each call.
- Returns:
The new partition resulting from the spectral ReCom algorithm.
- Return type:
Constraints¶
The gerrychain.constraints module provides a collection of constraint functions and helper classes for the validation step in GerryChain.
Helper classes include Validator for collections of constraints, numeric Bounds and
UpperBound/LowerBound classes, self-configuring bounds, and percentage bounds.
Binary constraint functions include contiguity checks, no_vanishing_districts, and lower bounds
on reciprocal Polsby-Popper scores.
Each new step proposed to the chain is passed off to the constraint functions here to determine whether or not the step is valid. If it is invalid (breaks contiguity, for instance), then the step is immediately rejected.
A constraint function should take in a Partition instance, and should return whether or not the
instance is valid according to its rules (the ConstraintFn alias). Many top-level functions in
this module follow this signature.
- class gerrychain.constraints.Bounds(value_fn: Callable[[P], Iterable[float]], bounds: tuple[float, float])[source]¶
Wrapper for numeric-validators to enforce upper and lower limits.
This class is meant to be called as a function after instantiation; its return is
Trueif the numeric validator is within set limits, andFalseotherwise.Initialize a Bounds instance.
This initializer sets up Bounds with the provided arguments and validates required state.
- gerrychain.constraints.L1_polsby_popper(partition: Partition) float[source]¶
Returns the \(L^1\) norm of the Polsby-Popper scores for the given partition.
- gerrychain.constraints.L1_reciprocal_polsby_popper(partition: Partition) float[source]¶
Returns the \(L^1\) norm of the reciprocal Polsby-Popper scores for the given partition.
- gerrychain.constraints.L2_polsby_popper(partition: Partition) float[source]¶
Returns the \(L^2\) norm of the Polsby-Popper scores for the given partition.
- gerrychain.constraints.L_minus_1_polsby_popper(partition: Partition) float[source]¶
Returns the \(L^{-1}\) norm of the Polsby-Popper scores for the given partition.
- class gerrychain.constraints.LowerBound(value_fn: Callable[[P], float], bound: float)[source]¶
Wrapper for numeric-validators to enforce lower limits.
This class is meant to be called as a function after instantiation; its return is
Trueif the numeric validator is within a set lower limit, andFalseotherwise.Initialize a LowerBound instance.
This initializer sets up LowerBound with the provided arguments and validates required state.
- Parameters:
value_fn (Callable) – Numeric validator function. Should return a comparable value.
bound (float) – Comparable lower bound.
- class gerrychain.constraints.SelfConfiguringLowerBound(value_fn: Callable[[Partition], float], epsilon: float = 0.05)[source]¶
Wrapper for numeric-validators to enforce automatic lower limits.
When instantiated, the initial lower bound is set as the initial value of the numeric-validator minus some configurable ε.
This class is meant to be called as a function after instantiation; its return is
Trueif the numeric validator is within a set lower limit, andFalseotherwise.Initialize a SelfConfiguringLowerBound instance.
This initializer sets up SelfConfiguringLowerBound with the provided arguments and validates required state.
- Parameters:
value_fn (Callable) – Numeric validator function.
epsilon (float, optional) – Initial population deviation allowable by the validator as a percentage of the ideal population. Defaults to 0.05.
- class gerrychain.constraints.SelfConfiguringUpperBound(value_fn: Callable[[Partition], float])[source]¶
Wrapper for numeric-validators to enforce automatic upper limits.
When instantiated, the initial upper bound is set as the initial value of the numeric-validator.
This class is meant to be called as a function after instantiation; its return is
Trueif the numeric validator is within a set upper limit, andFalseotherwise.Initialize a SelfConfiguringUpperBound instance.
This initializer sets up SelfConfiguringUpperBound with the provided arguments and validates required state.
- Parameters:
value_fn (Callable) – Numeric validator function.
- class gerrychain.constraints.UpperBound(value_fn: Callable[[P], float], bound: float)[source]¶
Wrapper for numeric-validators to enforce upper limits.
This class is meant to be called as a function after instantiation; its return is
Trueif the numeric validator is within a set upper limit, andFalseotherwise.Initialize a UpperBound instance.
This initializer sets up UpperBound with the provided arguments and validates required state.
- Parameters:
value_fn (Callable) – Numeric validator function. Should return a comparable value.
bound (float) – Comparable upper bound.
- class gerrychain.constraints.Validator(constraints: Iterable[Callable[[Partition], bool]])[source]¶
A single callable that bundles a collection of constraint functions.
This is a callable class used to check partition satisfies a set of constraints, and it is intended to be passed as the
constraintsparameter when instantiating a MarkovChain.Example usage:
validator = Validator([constraint1, constraint2, constraint3]) chain = MarkovChain(proposal, validator, accept, initial_partition, total_steps)
Initialize a Validator instance.
- Parameters:
constraints (Iterable[ConstraintFn]) – Constraint functions that will check partitions.
- class gerrychain.constraints.WithinPercentRangeOfBounds(value_fn: Callable[[Partition], float], percent: float)[source]¶
Wrapper for numeric-validators to enforce upper and lower limits determined by a percentage of the initial value.
When instantiated, the initial upper and lower bounds are set as the initial value of the numeric-validator times (1 ± percent).
This class is meant to be called as a function after instantiation; its return is
Trueif the numeric validator is within the desired percentage range of the initial value, andFalseotherwise.Initialize a WithinPercentRangeOfBounds instance.
This initializer sets up WithinPercentRangeOfBounds with the provided arguments and validates required state.
- Parameters:
value_fn (Callable) – Numeric validator function.
percent (float) – Percentage of the initial value to use as the bounds.
Warning
The percentage is assumed to be in the range [0.0, 100.0].
- gerrychain.constraints.contiguous(partition: Partition) bool[source]¶
Check if the parts of a partition are connected.
This function checks if the parts of a partition are connected. It returns whether the all components of the partition are contiguous.
- gerrychain.constraints.contiguous_bfs(partition: Partition) bool¶
Check if the parts of a partition are connected.
This function checks if the parts of a partition are connected. It returns whether the all components of the partition are contiguous.
- gerrychain.constraints.deviation_from_ideal(partition: Partition, attribute: str = 'population') dict[Hashable, float][source]¶
Determine the deviation of the given attribute from the ideal value among parts of the partition.
Computes the deviation of the given
attributefrom exact equality among parts of the partition. Usuallyattributeis the population, and this function is used to compute how far a districting plan is from exact population equality.By “deviation” we mean
(actual_value - ideal)/ideal(not the absolute value).
- gerrychain.constraints.districts_within_tolerance(partition: Partition, attribute_name: str = 'population', percentage: float = 0.1) bool[source]¶
Return whether the districts are within specified tolerance.
Check if all districts are within a certain percentage of the “smallest” district, as defined by the given attribute. For example, if the attribute is population, this function checks if all districts are within a certain percentage of the smallest population district.
- Parameters:
- Returns:
Whether the districts are within specified tolerance
- Return type:
- gerrychain.constraints.no_vanishing_districts(partition: Partition) bool[source]¶
Require that no districts be completely consumed. Can happen in flip proposal.
- gerrychain.constraints.refuse_new_splits(partition_county_field: str) Callable[[Partition], bool][source]¶
Refuse all proposals that split a county that was previous unsplit.
This function refuse all proposals that split a county that was previous unsplit. It returns function that returns
Trueif the proposal does not split any new counties.
- gerrychain.constraints.single_flip_contiguous(partition: Partition) bool[source]¶
Check if swapping the given node from its old assignment disconnects the old assignment.
This optimized check assumes that the parent partition is contiguous and that the proposal changes one node. Use
contiguous()when either assumption does not hold.
- gerrychain.constraints.within_percent_of_ideal_population(initial_partition: Partition, percent: float = 0.01, pop_key: str = 'population') Partition'>,)][source]¶
Construct a bounds object to ensure all districts are closed to a target population.
- Parameters:
- Returns:
- A Bounds constraint on the population attribute identified by
pop_key.
- Return type:
- gerrychain.constraints.within_percent_of_ideal_population_per_member(initial_partition: Partition, members_per_district: Mapping[Hashable, int], percent: float = 0.01, pop_key: str = 'population') Partition'>,)][source]¶
Bound each district’s population per member around the plan-wide ideal.
The ideal population is the total population divided by the total number of members. Member counts are copied when the constraint is constructed, so they remain fixed to district labels.
- Parameters:
initial_partition (Partition) – Starting partition used to compute the ideal population.
members_per_district (Mapping[Hashable, int]) – Positive member count for every district.
percent (float, optional) – Allowed percentage deviation. Default is 1%.
pop_key (str, optional) – The name of the population Tally. Default is
"population".
- Returns:
A Bounds constraint on each district’s population divided by its member count.
- Return type: