"""
This module provides the main tools for interacting with the metagraph of partitions.
The metagraph of partitions is the set of partitions that are reachable from the
current partition by a single flip.
Dependencies:
- itertools: Used for product() function.
- typing: Used for type hints.
Last Updated: 11 Jan 2024
"""
from itertools import product
from .constraints import Validator
from typing import Callable, Dict, Iterator, Iterable, Union
from gerrychain.partition import Partition
[docs]def all_cut_edge_flips(partition: Partition) -> Iterator[Dict]:
"""
Generate all possible flips of cut edges in a partition
without any constraints.
:param partition: The partition object.
:type partition: Partition
:returns: An iterator that yields dictionaries representing the flipped edges.
:rtype: Iterator[Dict]
"""
for edge, index in product(partition.cut_edges, (0, 1)):
yield {edge[index]: partition.assignment.mapping[edge[1 - index]]}
[docs]def all_valid_states_one_flip_away(
partition: Partition, constraints: Union[Iterable[Callable], Callable]
) -> Iterator[Partition]:
"""
Generates all valid Partitions that differ from the given partition
by one flip. These are the given partition's neighbors in the metagraph
of partitions. (The metagraph of partitions is the set of partitions
that is reachable from the given partition by a single flip under the
prescribed constraints.)
:param partition: The initial partition.
:type partition: Partition
:param constraints: Constraints to determine the validity of a partition.
It can be a single callable or an iterable of callables.
:type constraints: Union[Iterable[Callable], Callable]
:returns: An iterator that yields all valid partitions that differ from the
given partition by one flip.
:rtype: Iterator[Partition]
"""
if callable(constraints):
is_valid = constraints
else:
is_valid = Validator(constraints)
for flip in all_cut_edge_flips(partition):
next_state = partition.flip(flip)
if is_valid(next_state):
yield next_state
[docs]def all_valid_flips(
partition: Partition, constraints: Union[Iterable[Callable], Callable]
) -> Iterator[Dict]:
"""
Generate all valid flips for a given partition subject
to the prescribed constraints.
:param partition: The initial partition.
:type partition: Partition
:param constraints: The constraints to be satisfied. Can be a single
constraint or an iterable of constraints.
:type constraints: Union[Iterable[Callable], Callable]
:returns: An iterator that yields dictionaries representing valid flips.
:rtype: Iterator[Dict]
"""
for state in all_valid_states_one_flip_away(partition, constraints):
yield state.flips