Attempts to separate repeated entries by swapping cells of
different entries. Distance thresholds increase from starting_dist
in steps of one. Candidate sampling, mean pairwise distance, and a centrality
penalty guide the search. The last successful threshold layout is returned;
if none succeeds, the original matrix is returned. A requested minimum
distance is not guaranteed.
Usage
swap_pairs(
X,
starting_dist = 3,
stop_iter = 10,
lambda = 0.5,
dist_method = "euclidean",
candidate_sample_size = 4,
seed = NULL
)Arguments
- X
A numeric matrix of whole-number entry identifiers within R's integer range. Missing cells are inactive positions and never move.
- starting_dist
First distance threshold; a finite nonnegative number. Default is 3.
- stop_iter
Maximum complete swap sweeps per threshold, as a nonnegative whole number within R's integer range. Default is 10.
- lambda
Finite nonnegative weight for the centrality penalty. Default is 0.5.
- dist_method
Coordinate distance used for candidate filtering, scoring, stopping, and reported distances: "euclidean" (default) or "manhattan".
- candidate_sample_size
Maximum candidates evaluated per swap, as a positive whole number within R's integer range. Default is 4.
- seed
Optional randomization seed. When omitted, one integer is drawn from the current random-number stream and recorded; the swap's own randomization does not change the caller's stream.
Value
A list containing:
- optim_design
The modified matrix.
- designs
A list of all intermediate designs, starting from the input matrix.
- distances
A list of all pair distances for each intermediate design.
- min_distance
The minimum distance between pairs of occurrences of the same integer in the final design.
- pairwise_distance
A data frame with the pairwise distances for the final design.
- rows_incidence
Row-repetition counts for retained threshold steps, or for the original matrix when no step succeeds.
- diagnostics
The distance metric, stop reason, total completed sweeps (
iterations), per-threshold budget, number of attempted thresholds, last threshold, last attempted minimum distance, and retained minimum distance. Stop reasons areiteration_limit,distance_range_complete, andno_distance_thresholds. A failed attempt is not retained inoptim_design.- metadata
The design identifier, schema and package versions, RNG settings, resolved seed and complete input parameters, including
X. The result inherits fromfieldhub_optimization.
Details
The finite threshold range is bounded by the field geometry. For
Euclidean distance without missing cells, the historical bound is
sqrt(nrow(X)^2 + ncol(X)^2); with missing cells it is the maximum
distance between active positions. For Manhattan distance it is the maximum
Manhattan distance between active positions. There are at most
floor(bound - starting_dist) + 1 thresholds when the bound is at least
starting_dist, and none otherwise. Each threshold permits at most
stop_iter complete sweeps. Diagnostics distinguish an exhausted
threshold budget from completing or skipping the distance range.
Standalone calls use the shared seed contract. To reproduce a previous
set.seed(s); swap_pairs(X) call, with X already constructed,
pass seed = s. Calls without a seed now select an automatic seed,
so their layouts can differ from previous versions. Optimization performed
inside field-design engines retains its existing draw sequence.
Use reproduce_design() to replay a recorded optimization result.
Examples
set.seed(123)
X <- matrix(sample(c(rep(1:10, 2), 11:50), replace = FALSE), ncol = 10)
B <- swap_pairs(
X,
starting_dist = 3,
stop_iter = 50,
lambda = 0.5,
dist_method = "euclidean",
candidate_sample_size = 3,
seed = 123
)
B$optim_design
#> [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
#> [1,] 3 37 50 49 26 17 41 47 5 10
#> [2,] 1 20 12 32 16 29 43 34 7 6
#> [3,] 8 6 10 39 31 28 14 11 9 4
#> [4,] 4 23 2 30 25 40 18 3 35 46
#> [5,] 5 15 22 45 21 36 27 19 8 38
#> [6,] 9 7 42 33 24 13 1 48 44 2