This function uses redist_mergesplit() or redist_flip() to optimize a redistrict plan according to a user-provided criteria. It does so by running the Markov chain for "short bursts" of usually 10 iterations, and then starting the chain anew from the best plan in the burst, according to the criteria. This implements the ideas in the below-referenced paper, "Voting Rights, Markov Chains, and Optimization by Short Bursts."

redist_shortburst(
  map,
  score_fn = NULL,
  stop_at = NULL,
  burst_size = ifelse(backend == "mergesplit", 10L, 50L),
  max_bursts = 500L,
  maximize = TRUE,
  init_plan = NULL,
  counties = NULL,
  constraints = redist_constr(map),
  compactness = 1,
  adapt_k_thresh = 0.95,
  return_all = TRUE,
  thin = 1L,
  backend = "mergesplit",
  flip_lambda = 0,
  flip_eprob = 0.05,
  verbose = TRUE
)

Arguments

map

A redist_map object.

score_fn

A function which takes a matrix of plans and returns a score for each plan. Can also be a purrr-style anonymous function. See ?scorers for some function factories for common scoring rules.

stop_at

A threshold to stop optimization at.

burst_size

The size of each burst. 10 is recommended for mergesplit and 50 for flip.

max_bursts

The maximum number of bursts to run before returning.

maximize

If TRUE, try to maximize the score; otherwise, try to minimize it.

init_plan

The initial state of the map. If not provided, will default to the reference map of the map object, or if none exists, will sample a random initial state using redist_smc. You can also request a random initial state by setting init_plan="sample".

counties

A vector containing county (or other administrative or geographic unit) labels for each unit, which may be integers ranging from 1 to the number of counties, or a factor or character vector. If provided, the algorithm will only generate maps which split up to ndists-1 counties. If no county-split constraint is desired, this parameter should be left blank.

constraints

A redist_constr with Gibbs constraints.

compactness

Controls the compactness of the generated districts, with higher values preferring more compact districts. Must be non-negative. See redist_mergesplit for more information.

adapt_k_thresh

The threshold value used in the heuristic to select a value k_i for each splitting iteration. Set to 0.9999 or 1 if the algorithm does not appear to be sampling from the target distribution. Must be between 0 and 1.

return_all

Whether to return all the Recommended for monitoring purposes.

thin

Save every thin-th sample. Defaults to no thinning (1). Ignored if return_all=TRUE.

backend

the MCMC algorithm to use within each burst, either "mergesplit" or "flip".

flip_lambda

The parameter determining the number of swaps to attempt each iteration of flip mcmc. The number of swaps each iteration is equal to Pois(lambda) + 1. The default is 0.

flip_eprob

The probability of keeping an edge connected in flip mcmc. The default is 0.05.

verbose

Whether to print out intermediate information while sampling. Recommended for monitoring purposes.

Value

a redist_plans object containing the final best plan (or the best plans after each burst, if return_all=TRUE.

References

Cannon, S., Goldbloom-Helzner, A., Gupta, V., Matthews, J. N., & Suwal, B. (2020). Voting Rights, Markov Chains, and Optimization by Short Bursts. arXiv preprint arXiv:2011.02288.

Examples

# \donttest{
data(iowa)

iowa_map <- redist_map(iowa, existing_plan = cd_2010, pop_tol = 0.01)
redist_shortburst(iowa_map, scorer_frac_kept(iowa_map), max_bursts = 50)
#> MERGE-SPLIT SHORT BURSTS
#> Sampling up to 50 bursts of 10 iterations each.
#> Burst  Improve?  Score
#>     1     🎆     0.810811
#>     3     🌟     0.819820
#>     4     🙂     0.824324
#>     5            0.824324
#>     8     ⛄     0.833333
#>    10     🌈     0.842342
#>    11     😎     0.846847
#>    15            0.846847
#>    20            0.846847
#>    25            0.846847
#>    30            0.846847
#>    35            0.846847
#>    40            0.846847
#>    45            0.846847
#>    50            0.846847
#> A <redist_plans> containing 50 sampled plans and 1 reference plan
#> Plans have 4 districts from a 99-unit map, and were drawn using short bursts.
#> Plans matrix: int [1:99, 1:51] 3 3 1 2 4 1 1 4 1 1 ...
#> # A tibble: 204 × 4
#>    draw   district total_pop score
#>    <fct>     <int>     <dbl> <dbl>
#>  1 <init>        1    761548 0.811
#>  2 <init>        2    761624 0.811
#>  3 <init>        3    761612 0.811
#>  4 <init>        4    761571 0.811
#>  5 1             1    754497 0.811
#>  6 1             2    761624 0.811
#>  7 1             3    761612 0.811
#>  8 1             4    768622 0.811
#>  9 2             1    754497 0.811
#> 10 2             2    761624 0.811
#> # … with 194 more rows
redist_shortburst(iowa_map, ~ 1 - scorer_frac_kept(iowa_map)(.), max_bursts = 50)
#> MERGE-SPLIT SHORT BURSTS
#> Sampling up to 50 bursts of 10 iterations each.
#> Burst  Improve?  Score
#>     2     🌈     0.243243
#>     4     🎉     0.252252
#>     5            0.252252
#>     7     💥     0.261261
#>     8     🥳     0.288288
#>    10            0.288288
#>    14     🎆     0.301802
#>    15            0.301802
#>    20            0.301802
#>    25            0.301802
#>    30            0.301802
#>    35            0.301802
#>    40            0.301802
#>    45            0.301802
#>    50            0.301802
#> A <redist_plans> containing 50 sampled plans and 1 reference plan
#> Plans have 4 districts from a 99-unit map, and were drawn using short bursts.
#> Plans matrix: int [1:99, 1:51] 3 3 1 2 4 1 1 4 1 1 ...
#> # A tibble: 204 × 4
#>    draw   district total_pop score
#>    <fct>     <int>     <dbl> <dbl>
#>  1 <init>        1    761548 0.212
#>  2 <init>        2    761624 0.212
#>  3 <init>        3    761612 0.212
#>  4 <init>        4    761571 0.212
#>  5 1             1    761548 0.212
#>  6 1             2    761624 0.212
#>  7 1             3    761612 0.212
#>  8 1             4    761571 0.212
#>  9 2             1    764373 0.243
#> 10 2             2    763930 0.243
#> # … with 194 more rows
# }