Package {Coreset}


Title: Discrete Diversity, Dispersion, and Coverage Subset Selection
Version: 1.0.0
Description: Solves discrete location objectives on a distance matrix or Euclidean coordinate set. The Max-Min Diversity (MMDP / p-dispersion) objective, which maximizes the minimum pairwise distance within a selection of k items, is solved by farthest-first selection (Gonzalez 1985) <doi:10.1016/0304-3975(85)90224-5>; the DropAdd tabu-search heuristic (Porumbel, Hao & Glover 2011) <doi:10.1007/s10479-011-0898-z>, GRASP with path-relinking (Resende, Marti, Gallego & Duarte 2010) <doi:10.1016/j.cor.2008.05.011>, and an exact node-packing integer program (Sayyady & Fathi 2016) <doi:10.1016/j.ejor.2016.02.026>. The Max-Mean Dispersion objective, which selects a subset of unrestricted size maximising the sum of its pairwise distances divided by the number of selected elements, is solved by reinforcement-learning-guided tabu search (Nijimbere et al. 2020) <doi:10.3934/jimo.2020115>. The discrete k-centre (min-max covering / facility location) objective, which chooses k centres to minimise the largest distance from any point to its nearest centre, is solved via the CDSh heuristic (Garcia-Diaz et al. 2017 <doi:10.1007/s10732-017-9345-x>, 2019 <doi:10.1109/ACCESS.2019.2933875>), and an exact minimum-cover integer program. The maximum-entropy (maxdet) objective, which maximises the log-determinant of a similarity kernel built from the distances (Shewry & Wynn 1987 <doi:10.1080/02664768700000020>; the mode of a determinantal point process, Kulesza & Taskar 2012 <doi:10.1561/2200000044>), is solved by greedy pivoted-Cholesky selection and, for small instances, exact enumeration.
License: GPL (≥ 3)
Encoding: UTF-8
Language: en-GB
Depends: R (≥ 4.1)
Imports: cli (≥ 3.0.0), Rcpp, Rdpack (≥ 0.7), stats
RdMacros: Rdpack
Suggests: highs, knitr, Matrix, quarto, rprojroot, spelling, testthat (≥ 3.0.0)
VignetteBuilder: quarto
LinkingTo: Rcpp
URL: https://ms609.github.io/Coreset/
BugReports: https://github.com/ms609/Coreset/issues
Config/Needs/benchmark: bench, highs
Config/Needs/check: rcmdcheck, testthat
Config/Needs/coverage: covr
Config/Needs/memcheck: testthat, pkgdown
Config/Needs/metadata: codemeta
Config/Needs/revdeps: revdepcheck
Config/Needs/website: pkgdown
Config/roxygen2/version: 8.1.0
Config/testthat/edition: 3
Config/testthat/parallel: false
ByteCompile: true
NeedsCompilation: yes
Packaged: 2026-09-10 06:44:59 UTC; pjjg18
Author: Martin R. Smith ORCID iD [aut, cre, cph]
Maintainer: Martin R. Smith <martin.smith@durham.ac.uk>
Repository: CRAN
Date/Publication: 2026-09-17 14:50:29 UTC

Coreset: Discrete Diversity, Dispersion, and Coverage Subset Selection

Description

Selects a representative subset of a fixed candidate set.

Max-Min diversity solvers

The Max-Min Diversity Problem (MMDP) maximises the minimum pairwise distance within a subset (the discrete p-dispersion objective).

FarFirst()

Greedy farthest-first selection from a distance matrix, a coordinate matrix, or a distance-column oracle (for spaces with no coordinate embedding), with a choice of peripheral seeding strategies and a robust ensemble default.

DropAdd()

DropAdd tabu search heuristic.

Grasp()

GRASP with path relinking.

ExactMaxMin()

Exact node-packing optimum.

Max-Mean dispersion solver

The Max-Mean Dispersion Problem selects a subset of a size that maximises the mean pairwise distance.

MaxMean()

Reinforcement-learning tabu search.

k-centre solvers

The discrete k-centre problem minimises the largest distance from any element to its nearest selected element ('centre').

KCentre()

CDSh covering heuristic.

ExactKCentre()

Exact minimum-cover optimum.

Scoring

MinDist()

Minimum pairwise distance (the max-min objective).

MeanDist()

Mean pairwise dispersion (the max-mean objective).

KCentreRadius()

Covering radius (the k-centre objective).

Options

The solvers need d[i, j] and d[j, i] to agree exactly, being free to read whichever is the cheaper memory access. A matrix that misses this only through rounding has its triangles averaged, with a warning; options(Coreset.symmetryTolerance = ) sets how large a discrepancy — scaled by ⁠max(1, |d[i, j]|, |d[j, i]|)⁠ — is repaired rather than refused. It defaults to 100 * .Machine$double.eps, as R's own isSymmetric() does; set it to 0 to have any inexact matrix refused.

Relation to maximin

Not to be confused with the CRAN package maximin, which constructs continuous space-filling designs by generating new points in a coordinate region to maximise the minimum inter-point distance.

Author(s)

Maintainer: Martin R. Smith martin.smith@durham.ac.uk (ORCID) [copyright holder]

Authors:

See Also

Useful links:


Coerce distance input to a square matrix, skipping the round-trip when already a matrix.

Description

Coerce distance input to a square matrix, skipping the round-trip when already a matrix.

Usage

.AsDistMatrix(d, symmetric = TRUE)

Arguments

d

A dist object or a square numeric matrix.

symmetric

Logical: reconcile the two triangles of d.

Details

A dist object is symmetric by construction, so it bypasses the check.

Value

.AsDistMatrix() returns a square numeric matrix.


Stamp the MaxMeanSelection class onto a MaxMean() result

Description

Parallel to .AsMaxMinSelection() for the fixed-cardinality solvers. An empty selection is returned unchanged.

Usage

.AsMaxMeanSelection(x)

Arguments

x

Integer index vector carrying score, size, seconds, iters.

Value

.AsMaxMeanSelection() returns x with class "MaxMeanSelection", or x unchanged if it is empty.


Stamp the MaxMinSelection class onto a solver's index vector

Description

The selection-returning solvers each already attach their score (and any secondary attributes) via base::structure(); this adds the shared S3 class and a producer tag the print method reads to name the algorithm. An empty selection (⁠length 0⁠) is left bare: there is nothing to describe.

Usage

.AsMaxMinSelection(x, producer)

Arguments

x

Integer index vector carrying the solver's score attributes.

producer

Character tag naming the solver ("FarFirst", "DropAdd", "Grasp", "ExactMaxMin").

Value

.AsMaxMinSelection() returns x with producer attribute and "MaxMinSelection" class, or x unchanged if it is empty.


Coerce coordinate input for the on-the-fly (matrix-free) samplers

Description

The coordinate paths require a complete numeric ⁠N x dim⁠ matrix with double storage; the C++ kernels reproduce stats::dist()'s exact Euclidean bits, which is only defined for complete data.

Usage

.AsPointsMatrix(points)

Arguments

points

A numeric matrix (or coercible) of point coordinates.

Value

.AsPointsMatrix() returns a double numeric matrix.


Squared distance of every point to the coordinate anti_centroid

Description

The O(N * dim) basis of the "anti_centroid" seed: its argmax is the point farthest from the coordinate mean, an approximate diameter endpoint.

Usage

.CentroidSqDist(points)

Arguments

points

A double ⁠N x dim⁠ coordinate matrix.

Value

.CentroidSqDist() returns a numeric vector of length N of squared distances to the mean.


Normalise a distance-column oracle result to a masked length-N vector

Description

The user's colFn(i) may either report the self-distance (a length-N vector, position i ignored) or omit it (a length-N - 1 vector of the distances to the other elements, in index order). Either way this returns a length-N numeric vector with position i set to -Inf, so the downstream which.max() / pmin.int() never re-select i. The mask invariant for the oracle path lives here, not in the callers.

Usage

.DistColumn(colFn, i, N)

Arguments

colFn

Column oracle; see FarFirst().

i

Integer 1-based index whose distance column is requested.

N

Integer element count.

Value

.DistColumn() returns a numeric vector of length N, masked to -Inf at position i.


Draw distinct furthest-point seeds from random pivots

Description

Used by .GonzEnsemble() and .GonzEnsembleFromPoints() to expand the "random_furthest" token (see FarFirst()): walks distinct random pivots (a partial shuffle of 1:nPts, so no pivot is ever tried twice), resolves each pivot's furthest-point seed via SeedFunc, and collects distinct seed indices until nSeeds are found or the draw budget is spent. A maxDraws cap bounds the work when the reachable seed pool is smaller than nSeeds. Returns between 1 and nSeeds distinct indices (ascending); set a seed (set.seed()) for a reproducible set.

Usage

.DrawDistinctSeeds(SeedFunc, nPts, nSeeds, maxDraws = NULL)

Arguments

SeedFunc

Function mapping a pivot index to its furthest-point seed index.

nPts

Integer number of points.

nSeeds

Integer target number of distinct seeds (⁠>= 1⁠).

maxDraws

Integer cap on the number of distinct pivots tried. Default max(40 * nSeeds, 100).

Value

.DrawDistinctSeeds() returns an integer vector of distinct seed indices (length in ⁠[1, nSeeds]⁠).


Fold a newly added element into the streamlined DropAdd records

Description

The ADD pass of Algorithm 3, shared by the construction and the tabu loop and mirroring the add-pass blocks of src/dropadd.cpp. Mutates st in place (the package forbids ⁠<<-⁠; st is a new.env(parent = emptyenv()) record bundle). xNew's own record is set by the caller, which knows which peers are current.

Usage

.DropAddApplyAdd(st, col, xNew)

Arguments

st

Record environment; see .DropAddConstructColumn().

col

Self-zeroed distance column of xNew; see .DropAddColumn().

xNew

Integer index of the element just added.

Value

.DropAddApplyAdd() returns NULL invisibly, for its effect on st.


Normalise a distance-column oracle result for the DropAdd records

Description

Reports the self-distance as 0, cf. -Inf in .DistColumn()

Usage

.DropAddColumn(colFn, i, N)

Arguments

colFn

Column oracle; see FarFirst().

i

Integer 1-based index whose distance column is requested.

N

Integer element count.

Value

.DropAddColumn() returns a numeric vector of length N whose position i is 0, matching a distance matrix's diagonal.


Constructive phase of DropAdd from a distance-column oracle

Description

Algorithm 1 of Porumbel et al. (2011) against a column oracle: the counterpart of .DropAddConstruct()that never materialises the distance matrix.

Usage

.DropAddConstructColumn(colFn, N, k, first)

Arguments

colFn

Column oracle; see DropAdd().

N

Integer element count.

k

Integer subset size (⁠2 <= k <= N⁠).

first

Integer 1-based index of the seed element.

Value

.DropAddConstructColumn() returns a new.env(parent = emptyenv()) holding S (the selection, in add order), inS, minDist, sumDist and minDistCount, matching the record set of .DropAddConstruct().

Seed deviation

The matrix kernel seeds at the O(n) two-sweep peripheral point (the same anchor as PickPoint(d, "peripheral")). Pass DropAdd(seed=) to override.

References

Porumbel D, Hao J, Glover F (2011). “A simple and effective algorithm for the MaxMin diversity problem.” Annals of Operations Research, 186, 275–293. doi:10.1007/s10479-011-0898-z.


DropAdd tabu search from a distance-column oracle

Description

The pure-R counterpart of DropAdd_cpp(), substituting an on-demand colFn(i) call for the matrix-column read dmat[, i].

Usage

.DropAddFromColumn(
  colFn,
  N,
  k,
  first,
  plateau = 5000L,
  maxSeconds = Inf,
  maxIter = .Machine$integer.max,
  trace = FALSE
)

Arguments

colFn

Column oracle; see DropAdd().

N

Integer element count.

k

Integer subset size (⁠2 <= k <= N⁠).

first

Integer 1-based index of the seed element.

plateau

Integer: stop after this many consecutive non-improving iterations.

maxSeconds

Numeric wall-clock budget. Checked once per iteration (an iteration is dominated by two oracle calls, so proc.time() is free by comparison and the 1024-iteration stride of the C++ kernel is unnecessary); the check is skipped entirely when the budget is infinite, keeping the default path deterministic.

maxIter

Integer cap on main-loop iterations.

trace

Logical: also return the dropped/added index sequences, for the trajectory-identity tests.

Value

.DropAddFromColumn() returns a list with the same shape as DropAdd_cpp()'s: indices (1-based, in FIFO buffer order), objective, secondary, iters, and – when trace is TRUEdrops and adds.


Choose the next element to add to a DropAdd selection

Description

The argmax over the unselected elements of ⁠(minDist, sumDist)⁠ taken lexicographically, ties broken to the smallest index.

Usage

.DropAddPick(st, exclude = 0L)

Arguments

st

Record environment; see .DropAddConstructColumn().

exclude

Integer index barred from selection this iteration (0L for none). Used for the just-dropped x#, which Porumbel et al. (2011, p. 281) exclude from ⁠Add X(k)⁠ for one iteration – the tabu rule.

Value

.DropAddPick() returns a single integer index.


Expand ensemble anchor names into labelled seed specs

Description

Maps each anchor name to a list(label, s1) spec. The "random_furthest" token expands to one spec per element of rfSeeds (already-resolved seed indices, labelled random_furthest1, ...); an empty vector contributes none.

Usage

.ExpandAnchors(anchors, rfSeeds, anchorSeed)

Arguments

anchors

Character vector of (de-duplicated) anchor names.

rfSeeds

Integer vector of already-resolved furthest-point seed indices for the "random_furthest" token.

anchorSeed

Function mapping a deterministic anchor name to an integer seed index.

Value

.ExpandAnchors() returns a list of list(label, s1) specs.


Name the seeding outcome of a FarFirst() selection

Description

A bare single pass is just "farthest-first"; an ensemble pass (which carries winning_strategy / strategy_results) additionally names the winning strategy and how many were tried.

Usage

.FarFirstSelectedBy(x)

Arguments

x

A MaxMinSelection from FarFirst().

Value

.FarFirstSelectedBy() returns a length-1 character phrase.


Run a solver on a farthest-first coreset and map indices back

Description

Implements the composable-coreset path of DropAdd() / Grasp() (dispatched there when their maxCandidates cap binds). It builds an m-point coreset with FarFirst(), restricts the problem to those m points, runs the supplied solver on the restriction, and maps the returned indices back to the original numbering.

Usage

.FarFirstThin(k, m, d = NULL, points = NULL, RunOnSubset, label)

Arguments

k

Integer: target subset size.

m

Integer: coreset size (⁠k <= m < N⁠, as returned by .ResolveCap()).

d

Square distance matrix of the full problem, or NULL on the coordinate path.

points

⁠N x dim⁠ coordinate matrix of the full problem, or NULL on the distance-matrix path. Exactly one of d / points is non-NULL.

RunOnSubset

Function ⁠function(d, points)⁠ that runs the downstream solver on the restricted problem and returns its MaxMinSelection. It is called with the restricted distance matrix (d = d[core, core]) on the matrix path, or the restricted coordinates (points = points[core, ]) on the coordinate path; the unused argument is NULL.

label

Character naming the calling solver, used in the thinning warning (e.g. "DropAdd").

Details

Only the integer index values returned by the solver need remapping. The result is sorted ascending.

Value

.FarFirstThin() returns the solver's MaxMinSelection with its indices mapped to original-space row indices (sorted ascending).


Format a selected-index list, optionally truncated

Description

Format a selected-index list, optionally truncated

Usage

.FormatIndexList(idx, maxShow = 20L)

Arguments

idx

Integer indices in their stored order.

maxShow

Integer: show at most this many before eliding the tail.

Value

.FormatIndexList() returns a length-1 character string such as "6 5 4 3 1 2", or "1 2 ... (+15 more)" when idx is longer than maxShow.


Ensemble Gonzalez over cheap peripheral-anchor strategies (distance matrix)

Description

Runs Gonzalez from each requested peripheral anchor and returns the subset maximising T_k. Internal driver for the ensemble path of FarFirst() (triggered when strategy is a character vector of length > 1 or "random_furthest"). The "random_furthest" token draws nSeeds distinct furthest-point seeds via .DrawDistinctSeeds(). The returned vector carries strategy_results and winning_strategy (character vector of all tied-best strategies, with random starts labelled random_furthest1, random_furthest2, ...) attributes.

Usage

.GonzEnsemble(d, m, anchors = "peripheral", nSeeds = 3L)

Arguments

d

Square numeric distance matrix (already coerced).

m

Integer subset size (⁠1 <= m < nrow(d)⁠).

anchors

Character vector of anchor names.

nSeeds

Integer number of distinct random-furthest seeds to draw when "random_furthest" is in anchors.

Value

.GonzEnsemble() returns an integer vector of selected indices with attributes.


Coordinate (matrix-free) multi-anchor Gonzalez ensemble

Description

Coordinate counterpart of .GonzEnsemble(); each anchor seed and the greedy expansion are computed from points via the coordinate primitives, so the returned indices and attributes match the matrix path on Euclidean data.

Usage

.GonzEnsembleFromPoints(points, m, anchors = "random_furthest", nSeeds = 3L)

Arguments

points

A double ⁠N x dim⁠ coordinate matrix.

m

Integer subset size.

anchors

Character vector of anchor names.

nSeeds

Integer number of distinct random-furthest seeds to draw when "random_furthest" is in anchors.

Value

.GonzEnsembleFromPoints() returns an integer vector of selected indices with attributes.


Gonzalez maximin from a distance-column oracle

Description

Implements the distance-column oracle path of FarFirst() (dispatched there when d is a function); see that function's Distance-column oracle section for the user-facing contract. At each greedy step the distances from the newly selected element to all N elements are obtained from colFn, and a running nearest-distance vector is maintained, so the ⁠N x N⁠ distance matrix is never materialised: O(N * k) oracle calls and O(N) memory.

Usage

.GonzalezColumn(
  colFn,
  N,
  k,
  first = NULL,
  progress = getOption("Coreset.progress", interactive())
)

Arguments

colFn

A function that, when passed an index i, must return a vector of distances from element i to either (i) every element in turn, including i; or (ii) every other element. See .DistColumn().

N

Integer: the total number of elements.

k

Integer: number of elements to select. If k > N, all N indices are returned in Gonzalez (farthest-first) order.

first

Integer index of the first selected element, or NULL (default) to use a deterministic peripheral seed computed from two oracle sweeps: the element furthest from element 1, then the element furthest from that (a diameter-endpoint approximation).

progress

Logical; show a progress bar during greedy selection.

Value

.GonzalezColumn() returns an integer vector of length min(k, N) of selected indices.


One randomised greedy construction.

Description

One randomised greedy construction.

Usage

.GraspConstruct(d, k, alpha, us)

Arguments

d

Square distance matrix.

k

Target subset size.

alpha

RCL threshold parameter (alpha=1 -> greedy, alpha=0 -> random).

us

Numeric vector of k pre-drawn uniforms. us[[1]] picks the first vertex and us[[h]] step h's RCL member, as floor(u * size) clamped to size - 1 — exactly the kernel's mapping, so R and C++ stay bit-identical. Steps whose RCL is a singleton (or empty; see below) leave their uniform unused: consumption is fixed at k draws either way, which is what lets whole batches be drawn up front and constructions run on threads that must not touch R's RNG.

Value

.GraspConstruct() returns an integer vector of length k.


Hamming distance in selection space: m - |intersection|.

Description

Hamming distance in selection space: m - |intersection|.

Usage

.GraspHammingToES(sel, ES)

Fast local search with the extended-improvement criterion.

Description

Iterates 1-swap moves on critical elements (those participating in a min-distance edge). A swap is accepted if it strictly increases d*, or if it preserves d* while reducing the count of pairs at d*.

Usage

.GraspLocalSearch(d, sel)

Arguments

d

Square distance matrix.

sel

Integer vector of size k.

Value

.GraspLocalSearch() returns an improved integer vector of size k.


Count pairs at the minimum distance (used by extended-improvement LS).

Description

Count pairs at the minimum distance (used by extended-improvement LS).

Usage

.GraspMinPairCount(d, sel, dstar)

For each i in sel, return its nearest-other-selected distance.

Description

For each i in sel, return its nearest-other-selected distance.

Usage

.GraspNearestInSel(d, sel)

Minimum pairwise distance over a selection.

Description

Minimum pairwise distance over a selection.

Usage

.GraspObjective(d, sel)

Description

Greedy path relinking from x toward y.

Usage

.GraspPathRelink(d, x, y)

Arguments

d

Square distance matrix.

x, y

Integer selections of equal length.

Value

.GraspPathRelink() returns ⁠list(best = best selection on path, intermediates = number of intermediate states visited including endpoints)⁠.


Try to insert sel into the elite set ES.

Description

Try to insert sel into the elite set ES.

Usage

.GraspTryInsert(d, ES, esZ, sel, selZ, dth)

Value

.GraspTryInsert() returns the updated ES (list of selections, sorted best-to-worst by z).


Compose the one-line selection summary shared by both print methods

Description

Compose the one-line selection summary shared by both print methods

Usage

.MaxMinSummaryLine(n, idx, by, tk, maxShow = 20L)

Arguments

n

Integer count of selected elements.

idx

Integer selected indices in stored order.

by

Character phrase naming the algorithm (the "selected by ..." part).

tk

Numeric achieved T_k (the minimum pairwise distance), or NA when there is no pairwise distance to report (a single element, or all elements selected).

maxShow

Integer index-list truncation threshold; see .FormatIndexList().

Value

.MaxMinSummaryLine() returns a length-1 character string.


Gonzalez maximin from a single starting index

Description

Internal helper: greedy furthest-point selection starting from a specified index.

Usage

.MaximinFrom(d, k, first)

Arguments

d

Square pairwise distance matrix.

k

Integer: target subsample size (⁠>= 1⁠).

first

Integer: index of the first selected point.

Value

.MaximinFrom() returns an integer vector of length k of selected row/col indices.


Gonzalez maximin from a distance-column oracle (worker)

Description

Mirrors MaximinFrom_cpp(), substituting an on-demand colFn(i) call for the matrix-column read d[, i]. which.max() uses R's first-maximum (strict >) rule, matching the kernel's tie-breaking, so the selection is identical to the matrix path on symmetric input.

Usage

.MaximinFromColumn(colFn, N, k, first, progress = FALSE)

Arguments

colFn

Column oracle; see FarFirst().

N

Integer element count.

k

Integer subset size (⁠>= 2⁠).

first

Integer seed index.

Value

.MaximinFromColumn() returns an integer vector of selected indices.


Gonzalez maximin from coordinates (matrix-free)

Description

Coordinate counterpart of .MaximinFrom(): greedy furthest-point selection that recomputes each needed distance column from points on the fly, never materialising the ⁠N x N⁠ matrix. Bit-identical selection to the matrix path on Euclidean data.

Usage

.MaximinFromPoints(points, k, first, mask = 0L)

Arguments

points

A double ⁠N x dim⁠ coordinate matrix.

k

Integer: target subsample size (⁠>= 1⁠).

first

Integer: index of the first selected point.

mask

Integer 1-based index of a point to forbid from selection (0L = none); used by the anti-medoid path to exclude the medoid.

Value

.MaximinFromPoints() returns an integer vector of selected indices.


Gonzalez maximin from several starting indices at once

Description

Ensemble counterpart of .MaximinFrom() / .MaximinFromPoints(): solves one greedy pass per seed. Each pass is an independent function of its seed, so under mc.cores > 1 the passes run concurrently, one per thread; a lone seed, or a problem large enough for a single pass to occupy every thread itself, falls back to the per-pass parallelism instead.

Usage

.MaximinMulti(k, firsts, d = NULL, points = NULL)

Arguments

k

Integer: target subsample size (⁠>= 1⁠).

firsts

Integer vector of distinct first-selected indices, one per pass.

d

Square pairwise distance matrix, or NULL when points is given.

points

A double ⁠N x dim⁠ coordinate matrix, or NULL.

Value

.MaximinMulti() returns a list with one list(idx, tK) per element of firsts, in that order.


Minimum pairwise distance within a selection, from coordinates

Description

Coordinate counterpart of .SubsetScore(d, idx, "min_pairwise"). Computes stats::dist() on the selected sub-coordinates only (⁠k x k⁠, never the full matrix); the per-pair bits are identical to the corresponding entries of the full distance matrix, so the returned scalar matches the matrix path.

Usage

.MinPairwiseFromPoints(points, idx)

Arguments

points

A double ⁠N x dim⁠ coordinate matrix.

idx

Integer indices of the selection.

Value

.MinPairwiseFromPoints() returns a numeric scalar; NA_real_ if length(idx) < 2.


Deterministic peripheral seed from a column oracle

Description

Two oracle sweeps, no RNG: the element furthest from element 1, then the element furthest from that. The second is a diameter-endpoint approximation and a markedly better Gonzalez anchor than an arbitrary start, at the cost of two of the O(N * n) sweeps. The richer peripheral anchors (diameter, anti-medoid) need O(N^2) work and are unreachable from a column oracle.

Usage

.PeripheralSeedColumn(colFn, N)

Arguments

colFn

Column oracle; see FarFirst().

N

Integer element count.

Value

.PeripheralSeedColumn() returns an integer index of the seed.


Peripheral seed index for Gonzalez selection (distance matrix)

Description

Peripheral seed index for Gonzalez selection (distance matrix)

Usage

.PickPoint(d, strategy)

Arguments

d

Square numeric distance matrix.

strategy

Anchor name; see PickPoint(). Also accepts "first" (1).

Value

.PickPoint() returns an integer seed index.


Peripheral seed index for Gonzalez selection (coordinates)

Description

Coordinate counterpart of .PickPoint(); each anchor is computed from the ⁠…FromPoints_cpp⁠ primitives, bit-identical to the matrix path on Euclidean data.

Usage

.PickPoints(points, strategy)

Arguments

points

A double ⁠N x dim⁠ coordinate matrix.

strategy

Anchor name; see PickPoint(). Also accepts "first" (1).

Value

.PickPoints() returns an integer seed index.


Promote the kernel's free t_k score to the user-facing score attribute

Description

The maximin kernels attach the selection's minimum pairwise distance as a t_k attribute (computed during the greedy pass at no extra cost). The ensemble drivers read it via base::attr() into strategy_results; a bare single pass exposes it directly as the score attribute, matching DropAdd() and Grasp().

Usage

.PromoteScore(idx)

Arguments

idx

Integer vector returned by a maximin kernel.

Value

.PromoteScore() returns idx with its t_k attribute renamed to score.


Validate and normalise a maxCandidates thinning cap

Description

Shared by DropAdd() and Grasp(). Decides whether candidate thinning is active and, if so, the intermediate coreset size m to thin to.

Usage

.ResolveCap(maxCandidates, n, k)

Arguments

maxCandidates

The user-supplied cap: a positive integer (thin to this many candidates when it is below n), or 0 / Inf to disable thinning.

n

Integer: the number of candidate points in the full problem.

k

Integer: the target subset size.

Value

.ResolveCap() returns NA_integer_ when thinning is disabled (0 / Inf) or non-binding (maxCandidates >= n); otherwise the integer coreset size m (⁠k <= m < n⁠). Errors on a non-integer, negative, NA, or non-scalar cap, or a positive cap below k.


Resolve an expanded ensemble into the winning subset

Description

Shared tail of the two ensemble drivers: solves the specs' distinct seeds in one batch via the driver's RunPasses closure, then returns the subset maximising T_k. The returned vector carries the strategy_results (one record per label) and winning_strategy (all tied-best labels) attributes.

Usage

.ResolveEnsemble(expanded, labels, RunPasses)

Arguments

expanded

List of list(label, s1) specs from .ExpandAnchors().

labels

Character vector of labels (one per spec).

RunPasses

Closure mapping a vector of distinct seeds to a list of list(idx, tK), one per seed and in the same order.

Value

.ResolveEnsemble() returns an integer vector of selected indices with attributes.


Score a Gonzalez subset by its minimum (or mean) pairwise distance

Description

Score a Gonzalez subset by its minimum (or mean) pairwise distance

Usage

.SubsetScore(d, idx, objective = c("min_pairwise", "mean_pairwise"))

Arguments

d

Full pairwise distance matrix.

idx

Integer indices of selected rows/cols.

objective

"min_pairwise" (default; canonical Gonzalez T_k) or "mean_pairwise".

Value

.SubsetScore() returns a numeric scalar; NA if length(idx) < 2.


Print the per-strategy T_k table of a FarFirst() ensemble

Description

One row per strategy tried, ordered best (largest T_k) first, with each tied-best strategy marked *. A bare single pass (no strategy_results) produces nothing.

Usage

.SummariseStrategies(object)

Arguments

object

A MaxMinSelection from an ensemble FarFirst() call.

Value

.SummariseStrategies() returns invisibly NULL; called for the side effect.


Print a label: value detail line under a summary headline

Description

Print a label: value detail line under a summary headline

Usage

.SummaryField(label, value, width)

Arguments

label, value

Character (or coercible) field label and value.

width

Integer column width the labels are padded to.

Value

.SummaryField() returns invisibly NULL; called for the side effect.


Format a numeric field for a summary, tolerating NA

Description

Format a numeric field for a summary, tolerating NA

Usage

.SummaryNum(v)

Arguments

v

Numeric scalar.

Value

.SummaryNum() returns a length-1 character: "NA", or four significant figures.


Reconcile the two triangles of a distance matrix

Description

Internal helper: returns d unchanged when its triangles already agree, averages them when they differ by no more than tolerance, and errors beyond it.

Usage

.Symmetrise(d, dev, tolerance = .SymmetryTolerance())

Arguments

d

A square numeric matrix, known finite.

dev

Numeric: its scaled asymmetry, from SymmetryScan_cpp().

tolerance

Numeric: largest scaled discrepancy to repair.

Details

Averaging costs one n * n copy per call: repair d yourself if calling a solver in a loop.

Value

.Symmetrise() returns an exactly symmetric matrix.


DropAdd Tabu Search for the Max-Min Diversity Problem

Description

DropAdd() selects a maximally-dispersed subset of k points using the DropAdd tabu search algorithm, which comprises a greedy construction followed by a first-in, first-out drop-add tabu search, with streamlined neighbour-evaluation tricks (algorithms 1–4 in Porumbel et al. 2011).

Usage

DropAdd(
  k,
  d = NULL,
  plateau = 5000L,
  maxSeconds = Inf,
  points = NULL,
  maxCandidates = 46340L,
  seed = NULL,
  N = NULL
)

Arguments

k

Integer: subset size, 2 \le k \le N.

d

A dist object, a square symmetric numeric matrix, or a distance-column function (see below).

plateau

Integer: stop after this many consecutive drop-add iterations do not improve the score.

maxSeconds

Numeric: terminate search after this many seconds have elapsed.

points

A numeric N \times \mathrm{dim} coordinate matrix (or an object coercible to one via as.matrix). Must be complete (no NA). Ignored if d specified. Avoids creating an N \times N distance matrix, enabling use at N \ge 46340).

maxCandidates

Integer: when the number of candidate points N exceeds maxCandidates, the solver runs on a coreset of maxCandidates chosen by FarFirst(). maxCandidates = 0 (or Inf) disables thinning.

seed

Optional integer specifying the index of an element with which to seed the warm-start search.

N

Integer: the total number of elements. Required only if d is a function.

Value

DropAdd() returns an integer vector of length k containing the selected indices, sorted ascending, with attributes:

score

numeric specifying the achieved MaxMin objective \min_{i \ne j \in S} d_{ij}.

secondary

numeric specifying the achieved (upper triangle) sum of pairwise distances over S.

seconds

numeric specifying wall-clock seconds spent.

iters

integer specifying main-loop iterations executed, excluding the construction phase.

The vector has class "MaxMinSelection" and prints as a one-line summary (see print.MaxMinSelection()).

Progress bar

In interactive sessions, status messages are shown. To toggle, set options("Coreset.progress" = FALSE) (or TRUE).

Parallelism

To parallelize computation when OpenMP is available, set the "mc.cores" option:

options(mc.cores = 2L)                       # use a fixed number of cores
options(mc.cores = parallel::detectCores())  # or all available cores

Distance function

When d is a function, d(i) must return the distances from element i to every element (length N, with the self-distance ignored), or to every element except i (length N - 1, in order). N is required, and memory is O(N). This suits metrics where no stored matrix or coordinate embedding is available.

Because d is typically called many times; specifying a distance matrix (where memory permits) is likely to require less calculation than multiple calls to d, unless d implements efficient caching.

References

Porumbel D, Hao J, Glover F (2011). “A simple and effective algorithm for the MaxMin diversity problem.” Annals of Operations Research, 186, 275–293. doi:10.1007/s10479-011-0898-z.

Examples

set.seed(1)
pts <- matrix(rnorm(200), ncol = 2)
DropAdd(5L, dist(pts))

# Composable coreset: thin to 40 candidates with farthest-first, then run
# DropAdd on the coreset. Returned indices are original-space row indices.
suppressWarnings(DropAdd(5L, points = pts, maxCandidates = 40L))

# Disable thinning on the full problem
DropAdd(5L, points = pts, maxCandidates = 0L)

# Distance function; `cache` memoizes the columns to reduce computation.
data("USArrests")
ArrestDist <- function(dat) {
  scaled <- scale(as.matrix(dat))                 # derived once
  cache <- new.env(parent = emptyenv())
  function(i) {
    key <- as.character(i)
    if (is.null(cache[[key]])) {
      cache[[key]] <- sqrt(rowSums(sweep(scaled, 2, scaled[i, ], "-") ^ 2))
    }
    cache[[key]]
  }
}
arrests <- USArrests[, c("Murder", "Assault", "Rape")]
idx <- DropAdd(4L, ArrestDist(arrests), N = nrow(arrests), plateau = 200L)
USArrests[idx, ]

Exact discrete k-centre optimum

Description

ExactKCentre() finds an optimal solution to the discrete k-centre problem.

Usage

ExactKCentre(k, d, maxSeconds = 60)

ExactKCenter(k, d, maxSeconds = 60)

Arguments

k

Integer specifying maximum number of centres to identify, from 1 to nrow(d).

d

dist object or a square symmetric numeric distance matrix.

maxSeconds

Numeric specifying wall-clock budget, in seconds, for the search. If the time expires before the optimum is proven, the smallest radius proven feasible is returned, with the attribute proven = FALSE.

Details

The optimum covering radius is the smallest threshold r, over the achieved distinct distances, for which k centres can cover every point within r.

Each probe asks whether k centres cover every point within a candidate radius. This is decided combinatorially via unit propagation and dominance reduction, then an exhaustive component-wise search. The search is warm-started from the KCentre() radius, then bisects downwards.

Value

ExactKCentre() returns an integer vector of length \le k listing the chosen centres in ascending order. It has class c("KCentreExact", "KCentreSelection") and attributes:

radius

The covering radius achieved; the proven optimum when proven is TRUE, otherwise an upper bound.

proven

Logical: TRUE if optimality is certified.

seconds

Wall-clock seconds elapsed.

N, k

Instance size and centre budget.

Progress bar

In interactive sessions, a progress indicator is shown. To toggle, set options("Coreset.progress" = FALSE) (or TRUE).

See Also

KCentre() for the fast near-optimal heuristic; ExactMaxMin() for the dual MMDP optimum.

Examples

set.seed(1)
pts <- matrix(rnorm(40), ncol = 2)
d <- dist(pts)
ExactKCentre(3L, d)

Exact Max-Min Diversity Problem solution

Description

ExactMaxMin() finds the optimal solution to the Max-Min Diversity Problem (discrete p-dispersion) by iterated node-packing (Sayyady and Fathi 2016) (which may be slow or intractable on large sets).

Usage

ExactMaxMin(
  k,
  d,
  maxSeconds = 60,
  warmStart = NULL,
  nStart = 1L,
  graspPlateau = 50L,
  dropPlateau = 512L
)

Arguments

k

Integer: target subset size, between 2 and nrow(d).

d

dist object or a square symmetric numeric distance matrix.

maxSeconds

Numeric: search terminates after this many seconds have elapsed, returning largest threshold proven feasible.

warmStart

Optional integer vector giving indices of a candidate subset to add to the heuristic warm-start pool.

nStart

Integer: how many Grasp() restarts enter the warm-start pool.

graspPlateau, dropPlateau

Integer: the stopping plateaus given to the pool's Grasp() restarts and its DropAdd() pass. Deeper searches cost more, but raise the lower bound the exact search starts from.

Details

The search is warm-started from a heuristic lower bound (the best of nStart Grasp() restarts and a DropAdd() pass), then gallops upward from that bound to the first infeasible threshold and bisects the resulting bracket.

To parallelize computation when OpenMP is available, set the "mc.cores" option:

options(mc.cores = 2L)                       # use a fixed number of cores
options(mc.cores = parallel::detectCores())  # or all available cores

Parallelization returns identical results under a given seed.

Value

ExactMaxMin() returns an integer vector of length k (sorted ascending) with class "MaxMinSelection", carrying attributes:

score

The minimum pairwise distance within the selection. When proven is TRUE this is the optimum; otherwise a lower bound.

proven

Logical: TRUE if the search certified optimality within the budget, FALSE if it returned an unproven incumbent.

seconds

Wall-clock seconds elapsed.

N, k

Instance size and target subset size.

Prints as a terse summary via print.MaxMinSelection().

Progress bar

In interactive sessions, a progress indicator is shown. To toggle, set options("Coreset.progress" = FALSE) (or TRUE).

References

Sayyady F, Fathi Y (2016). “An integer programming approach for solving the p-dispersion problem.” European Journal of Operational Research, 253(1), 216–225. doi:10.1016/j.ejor.2016.02.026.

Examples

set.seed(1)
pts <- matrix(rnorm(18), ncol = 2)
ExactMaxMin(3L, dist(pts))

Exact Maximum Diversity Problem (max-sum) solution

Description

ExactMaxSum() finds the optimal solution to the Max-Sum Diversity Problem (the "maximum diversity problem"): it selects the k points that maximizes the total pairwise distance between points. As the problem is NP-hard, it is feasible only for small sets.

Usage

ExactMaxSum(k, d, maxSeconds = 30, warmStart = NULL)

Arguments

k

Integer: target subset size, between 2 and nrow(d).

d

dist object or a square symmetric numeric distance matrix.

maxSeconds

Numeric: search terminates after this many seconds have elapsed, returning largest threshold proven feasible.

warmStart

Optional integer vector giving indices of a candidate subset to add to the heuristic warm-start pool.

Details

The solver uses per-node integer-program linearisation (Kuo et al. 1993), starting from a multi-start 1-swap local search, whose result is returned when optimality cannot be proven within maxSeconds.

Value

ExactMaxSum() returns an integer vector of length k, sorted ascending, with class "MaxSumSelection", carrying attributes:

score

Numeric specifying the achieved total pairwise distance within the selection. When proven is TRUE this is the optimum; otherwise a lower bound.

proven

Logical: TRUE if optimality was certified.

seconds, N, k

Numerics reporting the wall-clock seconds elapsed; instance size; and target size.

References

Kuo C, Glover F, Dhir KS (1993). “Analyzing and modeling the maximum diversity problem by zero-one programming.” Decision Sciences, 24(6), 1171–1185. doi:10.1111/j.1540-5915.1993.tb00509.x.

Examples

set.seed(1)
pts <- matrix(rnorm(20), ncol = 2)
# Package 'highs' is required for ExactMaxSum
if (requireNamespace("highs", quietly = TRUE)) {
  ExactMaxSum(3L, dist(pts))
}

Greedy farthest-first point selection

Description

Greedy farthest-first selection (González 1985; Hochbaum and Shmoys 1985) iteratively selects the point furthest from the current selection to yield a 2-approximation to the k-centre and Max Min Diversity problems.

Usage

FarFirst(
  k,
  d = NULL,
  points = NULL,
  N = NULL,
  strategy = "random_furthest",
  nSeeds = 3L
)

Arguments

k

Integer: number of points to select.

d

A dist object, a square numeric matrix of pairwise distances, or a distance function that takes an index i and returns the distance from i to each other element (optionally including the self-distance). Ignored when points is supplied.

points

Optional ⁠N x dim⁠ numeric coordinate matrix. When supplied, the selection is computed directly from coordinates in O(N \cdot k \cdot dim) time and O(N) memory, which avoids creating an O(N^2) distance matrix. Missing entries (NA) are not supported.

N

Integer: the total number of elements. Required (and used) only on the distance-column oracle path, where it cannot be inferred from the closure; ignored for the matrix and coordinate paths.

strategy

Integer or character defining how to seed the greedy pass. Pass the name of one or more seeding strategies described in PickPoint() to run each strategy and return the best solution.

nSeeds

Integer: number of distinct seeds to draw under the (default) "random_furthest" strategy. Beyond ~3, DropAdd() will tend to return higher quality results faster.

Value

FarFirst() returns an integer vector with class MaxMinSelection, listing the selected indices in the order they were selected. Attributes report:

Progress bar

In interactive sessions, the distance-column path shows a progress bar. To toggle, set options("Coreset.progress" = FALSE) (or TRUE).

Parallelism

To parallelize computation when OpenMP is available, set the "mc.cores" option:

options(mc.cores = 2L)                       # use a fixed number of cores
options(mc.cores = parallel::detectCores())  # or all available cores

The main use case for parallelization is when nSeeds is a multiple of mc.cores, so each seed point can be evaluated in parallel.

References

González TF (1985). “Clustering to minimize the maximum intercluster distance.” Theoretical Computer Science, 38, 293–306. doi:10.1016/0304-3975(85)90224-5.

Hochbaum DS, Shmoys DB (1985). “A best possible heuristic for the k-center problem.” Mathematics of Operations Research, 10(2), 180–184. doi:10.1287/moor.10.2.180.

See Also

PickPoint() for the seed indices alone; DropAdd() and ExactMaxMin() for higher-effort solvers.

Examples

set.seed(1)
pts <- matrix(rnorm(60), ncol = 2)
d <- dist(pts)

# Default: best of three random-furthest starts (set.seed for reproducibility):
FarFirst(5L, d)

# More random-furthest starts:
FarFirst(5L, d, nSeeds = 15L)

# Custom two-anchor ensemble:
FarFirst(5L, d, strategy = c("diameter", "anti_medoid"))

# A single strategy:
FarFirst(5L, d, strategy = "diameter")

# An explicit start index (integer strategy):
FarFirst(5L, d, strategy = 1L)

# Matrix-free coordinate path (identical result, O(N) memory):
FarFirst(5L, points = pts, strategy = 1L)

# Distance-column oracle: supply one column at a time, never the full matrix.
data("USArrests")
arrestTypes <- USArrests[, c("Murder", "Assault", "Rape")]
StateDist <- function(i) {
  diffs <- sweep(arrestTypes, 2, unlist(arrestTypes[i, ]), "-")
  sqrt(rowSums(diffs ^ 2))
}
idx <- FarFirst(4L, StateDist, N = nrow(arrestTypes), strategy = 1L)
arrestTypes[idx, ]

GRASP with Path Relinking for the Max-Min Diversity Problem

Description

Grasp() solves the Max-Min Diversity Problem (discrete p-dispersion) with the static variant of the GRASP / path-relinking metaheuristic (Resende et al. 2010, fig. 4). This expensive heuristic often attains high-quality selections.

Usage

Grasp(
  k,
  d,
  plateau = 100L,
  eliteSize = 10L,
  alpha = 0.8,
  maxSeconds = Inf,
  maxCandidates = 2000L
)

Arguments

k

Integer subset size, ⁠2 <= k <= nrow(d)⁠.

d

Either a dist object or a square symmetric numeric matrix.

plateau

Integer; stop after this many consecutive GRASP iterations have not improved the best elite objective.

eliteSize

Size of the elite set |ES|.

alpha

Numeric in ⁠[0, 1]⁠ specifying construction greediness. Each step draws the next point at random from a shortlist of the strongest candidates whose gain lies within a fraction alpha of the best-to-worst spread. alpha = 1 is pure greedy; alpha = 0 is uniform random among candidates.

maxSeconds

Numeric specifying wall-clock ceiling, in seconds.

maxCandidates

Integer: when the number of candidate points N exceeds maxCandidates, the solver runs on a coreset of maxCandidates chosen by FarFirst(). maxCandidates = 0 (or Inf) disables thinning.

Details

The GRASP with path-relinking algorithm conducts a randomised-greedy construction with extended-improvement local search builds; it identifies an elite set, then conducts a single pass of path relinking over all elite pairs (Resende et al. 2010).

The refinement loop stops after plateau consecutive GRASP iterations fail to improve the best elite objective, or once maxSeconds have elapsed.

This method will fail if the complete N \times N distance matrix is too large to fit into memory.

Value

Grasp() returns an integer vector of length k specifying the indices of the selected points, with attributes:

score

Achieved MaxMin objective T_k.

seconds

Wall-clock seconds spent.

iters

Number of GRASP refinement iterations executed.

pr_calls

Number of path-relinking pair-applications run.

The vector has class "MaxMinSelection" and prints as a one-line summary (see print.MaxMinSelection()).

Parallelism

To parallelize computation when OpenMP is available, set the "mc.cores" option:

options(mc.cores = 2L)                       # use a fixed number of cores
options(mc.cores = parallel::detectCores())  # or all available cores

Progress bar

In interactive sessions, a bar tracks how close the search is to its plateau stopping criterion, snapping back each time a better solution is found. To toggle, set options("Coreset.progress" = FALSE) (or TRUE).

References

Resende MGC, Martí R, Gallego M, Duarte A (2010). “GRASP and path relinking for the max-min diversity problem.” Computers & Operations Research, 37(3), 498–508. doi:10.1016/j.cor.2008.05.011.

See Also

DropAdd() for scalable refinement; ExactMaxMin() for the proven optimum on small instances.

Examples

set.seed(1)
pts <- matrix(rnorm(60), ncol = 2)
Grasp(5L, dist(pts), plateau = 20L, eliteSize = 4L)

# Composable coreset: thin to 20 candidates with farthest-first, then run
# GRASP on the coreset. Returned indices are original-space row indices.
suppressWarnings(Grasp(5L, dist(pts), plateau = 20L, maxCandidates = 20L))

Discrete k-centre solver

Description

KCentre() selects k elements (centres) so as to minimize the largest distance from any point to its nearest centre (the covering radius), using the Critical Dominating Set heuristic (CDSh) (García-Díaz et al. 2017; García-Díaz et al. 2019).

Usage

KCentre(k, d, nstart = 1L, effort = 1L)

KCenter(k, d, nstart = 1L, effort = 1L)

Arguments

k

Integer specifying maximum number of centres to identify, from 1 to nrow(d).

d

dist object or a square symmetric numeric distance matrix.

nstart

Integer specifying how many deterministic peripheral seeds to try.

effort

Integer: if ⁠> 0⁠, run effort parallel FarFirst() searches, each seeded on a distinct starting point, and return the best result found.

Details

On the benchmark instances of García-Díaz et al. (2019), the CDS heuristic reaches roughly 1–3.5% of the optimum at O(N^2 \log N), far tighter than FarFirst().

Despite this good performance in practice, the CDSh is a 3-approximation. To guard against occasional cases where a better candidate is missed, KCentre() runs by default an exhaustive search of a small candidate grid (for n up to ~150); and an additional FarFirst() pass (controlled via the effort argument). These safeguards ensure that KCentre() always returns at least a 2-approximation.

Value

KCentre() returns an integer vector of length \le k specifying the chosen centres in ascending order. The achieved covering radius is attached as attribute radius. The vector has class "KCentreSelection" and prints as a one-line summary.

References

García-Díaz J, Menchaca-Méndez R, Menchaca-Méndez R, Pomares Hernández S, Pérez-Sansalvador JC, Lakouari N (2019). “Approximation algorithms for the vertex k-center problem: survey and experimental evaluation.” IEEE Access, 7, 109228–109245. doi:10.1109/ACCESS.2019.2933875.

García-Díaz J, Sánchez-Hernández J, Menchaca-Méndez R, Menchaca-Méndez R (2017). “When a worse approximation factor gives better performance: a 3-approximation algorithm for the vertex k-center problem.” Journal of Heuristics, 23(5), 349–366. doi:10.1007/s10732-017-9345-x.

González TF (1985). “Clustering to minimize the maximum intercluster distance.” Theoretical Computer Science, 38, 293–306. doi:10.1016/0304-3975(85)90224-5.

See Also

ExactKCentre() for the proven optimum; KCentreRadius() for a selection's score; FarFirst() for the González (1985) 2-approximation baseline.

Examples

set.seed(1)
pts <- matrix(rnorm(120), ncol = 2)
d <- dist(pts)
centres <- KCentre(5L, d)
KCentreRadius(d, centres)
# Results will beat a Gonzalez 2-approximation:
KCentreRadius(d, FarFirst(5L, d, nSeeds = 1))

Covering radius of a set of centres

Description

KCentreRadius() computes the covering radius of a set of centres: the largest distance from any of the N points to its nearest centre, R = \max_p \min_{c \in \mathrm{idx}} d(p, c). This is the min-max k-centre objective (González 1985) minimized by KCentre() and ExactKCentre().

Usage

KCentreRadius(d = NULL, idx, points = NULL)

KCenterRadius(d = NULL, idx, points = NULL)

Arguments

d

Pairwise distance matrix or dist object. Ignored when points is supplied.

idx

Integer vector of centre indices (⁠>= 1⁠).

points

⁠N x dim⁠ numeric coordinate matrix. When supplied, the per-point nearest-centre distances are computed from coordinates one column at a time. This supports sets with large N, in which the full ⁠N x N⁠ matrix would overflow available memory.

Value

KCentreRadius() returns a numeric denoting the covering radius.

References

González TF (1985). “Clustering to minimize the maximum intercluster distance.” Theoretical Computer Science, 38, 293–306. doi:10.1016/0304-3975(85)90224-5.

See Also

KCentre() and ExactKCentre() (which minimise this); MinDist() for the complementary MMDP objective.

Examples

set.seed(1)
pts <- matrix(rnorm(60), ncol = 2)
d <- dist(pts)
centres <- KCentre(4L, d)
KCentreRadius(d, centres)

Maximum-entropy (maxdet) subset selection

Description

MaxEntropy() selects the k points that maximise the log-determinant of their kernel block, \log\det K_S. This is equivalent to finding the set of k points that span the largest volume, which corresponds to the maximum-entropy sampling criterion (Shewry and Wynn 1987) and the maximum-a-posteriori mode of a determinantal point process (Kulesza and Taskar 2012).

Usage

MaxEntropy(
  k,
  d,
  sigma = NULL,
  repair = c("clip", "shift", "truncate"),
  exact = NA,
  maxCombos = 300000L
)

Arguments

k

Integer specifying target selection size, 1 \le k \le n.

d

dist object or square numeric distance matrix over the n points.

sigma

Optional numeric specifying kernel bandwidth; defaults to the median positive distance.

repair

Character selecting a positive semi-definite repair method: "clip" (nearest), "shift" (diagonal loading) or "truncate" (low-rank embedding).

exact

Logical: TRUE uses explicit enumeration, failing with an error if maxCombos is exceeded; FALSE uses the greedy approximation. NA uses exact enumeration when choose(n, k) <= maxCombos, greedy otherwise.

maxCombos

Integer specifying ceiling on choose(n, k) for exact enumeration.

Details

A radial-basis kernel K_{ij} = \exp(-d_{ij}^2 / 2\sigma^2) is built from the supplied distances and repaired to a positive-semidefinite matrix. The exact argmax is NP-hard (Kulesza and Taskar 2012). A greedy approximation is built by pivoted Cholesky, adding at each step the point of largest residual conditional variance. Ties are broken by selecting the more peripheral point.

Value

MaxEntropy() returns an integer vector of length k (sorted ascending) with class "MaxEntropySelection", carrying attributes:

score

The retained \log\det K_S of the selection. -Inf is returned for a degenerate selection where k exceeds the number of distinct points.

negMass

Fraction of spectral mass removed by the positive semi-definite repair.

sigma, repair, exact

The bandwidth, repair, and whether the optimum was certified by enumeration.

seed, N, k

The peripheral seed index, instance size, target size.

References

Kulesza A, Taskar B (2012). “Determinantal point processes for machine learning.” Foundations and Trends in Machine Learning, 5(2–3), 123–286. doi:10.1561/2200000044.

Shewry MC, Wynn HP (1987). “Maximum entropy sampling.” Journal of Applied Statistics, 14(2), 165–170. doi:10.1080/02664768700000020.

Examples

set.seed(1)
pts <- matrix(rnorm(40), ncol = 2)
MaxEntropy(4L, dist(pts))

Max-Mean Dispersion Problem solver

Description

MaxMean() selects a maximally dispersed subset of elements from a pairwise distance matrix, maximising the max-mean objective:

f(S) = \frac{\displaystyle\sum_{i < j,\, i,j \in S} d_{ij}}{|S|}

The number of elements in the subset |S| \ge 2 is chosen so as to maximise the mean dispersion.

Usage

MaxMean(d, maxSeconds = 0.1, maxIter = 1000, useRL = TRUE)

Arguments

d

A dist object or square numeric matrix of pairwise distances; values may be negative, and an asymmetric matrix is symmetrized to (d_{ij} + d_{ji})/2 before solving.

maxSeconds

Numeric: wall-clock time budget, in seconds.

maxIter

Numeric: cap on the total tabu-search iterations across restarts.

useRL

Logical: if TRUE (the default) a Q-learning layer guides initial-solution construction across restarts; if FALSE, each restart starts from a random solution.

Details

MaxMean() implements the reinforcement-learning tabu search algorithm of (Nijimbere et al. 2020). An initial solution is constructed randomly for the first restart and via Q-learning thereafter; each initial solution is then refined by a tabu search using one-flip moves (adding or removing one element per step). Restarts continue until either the maxSeconds or maxIter budget is reached.

The reinforcement-learning and tabu hyperparameters are fixed at the tuned values reported by Nijimbere et al. (2020): greedy factor \epsilon = 0.7, learning rate \alpha = 0.5, discount \gamma = 0.5, maximum tabu tenure 120, search depth 50 000.

Value

MaxMean() returns an integer vector of selected 1-based indices (sorted ascending) with class "MaxMeanSelection" and attributes:

score

numeric, achieved objective \sum_{i<j \in S} d_{ij} / |S|.

size

integer, number of selected elements |S|.

seconds

numeric, wall-clock seconds spent.

iters

numeric, total tabu-search iterations across restarts.

The vector has class "MaxMeanSelection" and prints as a one-line summary (see print.MaxMeanSelection()); it is otherwise an ordinary integer vector that indexes the distance matrix directly.

Progress bar

In interactive sessions, status messages are shown. To toggle, set options("Coreset.progress" = FALSE) (or TRUE).

References

Nijimbere D, Zhao S, Gu X, Esangbedo MO, Dominique N (2020). “Tabu search guided by reinforcement learning for the max-mean dispersion problem.” Journal of Industrial & Management Optimization, 17, 3223–3254. doi:10.3934/jimo.2020115.

See Also

MeanDist() to score an arbitrary selection under this objective; FarFirst(), DropAdd() and Grasp() for fixed-cardinality max-min solvers.

Examples

# The max-mean problem is defined for signed dissimilarities; with these the
# optimal subset has an interior size, chosen to maximise mean dispersion.
set.seed(1)
x <- matrix(runif(100, -5, 5), 10)
d <- (x + t(x)) / 2          # symmetric, signed
selection <- MaxMean(d)
selection                    # 5 of the 10 elements: {2, 5, 6, 8, 10}
MeanDist(d, selection)       # 2.714 — equals attr(selection, "score")

Mean dispersion of a selection

Description

MeanDist() reports the sum of pairwise distances divided by the number of selected elements,

f(S) = \frac{\displaystyle\sum_{i < j,\, i,j \in S} d_{ij}}{|S|}

, the objective maximised by MaxMean().

Usage

MeanDist(d, idx)

Arguments

d

Pairwise distance matrix or dist object.

idx

Integer vector of selected row/col indices.

Value

MeanDist() returns a numeric scalar, or NA_real_ if length(idx) < 2.

See Also

MaxMean() which maximises this objective; MinDist() for the max-min (MMDP) analogue.

Examples

# The max-mean problem is defined for signed dissimilarities; with these the
# optimal subset has an interior size, chosen to maximise mean dispersion.
set.seed(1)
x <- matrix(runif(100, -5, 5), 10)
d <- (x + t(x)) / 2          # symmetric, signed
selection <- MaxMean(d)
selection                    # 5 of the 10 elements: {2, 5, 6, 8, 10}
MeanDist(d, selection)       # 2.714 — equals attr(selection, "score")

Minimum pairwise distance within a selection

Description

Returns the minimum pairwise distance among selected points T_k. A set of points that is more dispersed will exhibit a higher value.

Usage

MinDist(d = NULL, idx, points = NULL)

Arguments

d

Pairwise distance matrix or dist object. Ignored when points is supplied.

idx

Integer vector of selected row/col indices.

points

Optional ⁠N x dim⁠ numeric coordinate matrix. When supplied, the score is computed from stats::dist() on the selected sub-coordinates only (⁠k x k⁠).

Details

The solvers in this package (FarFirst(), DropAdd(), Grasp()) already attach the achieved T_k as a score attribute. MinDist() allows arbitrary selections to be scored, or an existing selection to be scored against a different distance matrix.

Value

MinDist() returns a numeric specifying the minimum distance between two selected points (or NA_real_, if length(idx) < 2).

See Also

FarFirst(), DropAdd(), Grasp() and ExactMaxMin().

Examples

set.seed(1)
pts <- matrix(rnorm(60), ncol = 2)
d <- dist(pts)
MinDist(d, FarFirst(5L, d))

Seed to initialize farthest-first selection

Description

PickPoint() implements a range of strategies to select a seed for greedy farthest-first selection. Propitious seeds yield better solutions.

Usage

PickPoint(
  d = NULL,
  points = NULL,
  strategy = c("peripheral", "anti_centroid", "random_furthest", "diameter",
    "anti_medoid", "medoid", "rowsum", "rownorm")
)

Arguments

d

A dist object or square symmetric numeric matrix. Ignored when points is supplied.

points

Optional ⁠N x dim⁠ numeric coordinate matrix; when supplied the seed is computed from coordinates in O(N) memory. Required for the "anti_centroid" anchor, which has no distance-matrix form.

strategy

Character specifying method to employ:

"peripheral"(default)

Two sweeps: the point furthest from point 1, then the point furthest from that (a diameter-endpoint approximation). O(N).

"anti_centroid"

The point farthest from the coordinate mean (\arg\max \|x - \bar{x}\|). O(N * dim). Requires points.

"random_furthest"

The point furthest from a random pivot. O(N).

"diameter"

A row endpoint of the diameter pair (the maximum pairwise distance).

"medoid"

The 1-median (medoid): the point minimising the sum of distances to all others.

"anti_medoid"

The point furthest from the 1-median (medoid).

"rowsum"

The point maximising the sum of distances to all others (the 1-anti-median).

"rownorm"

The point maximising \sqrt(\sum{d^2}), the L2 counterpart of "rowsum".

Value

PickPoint() returns an integer that identifies the index of a proposed seed in d or points.

See Also

FarFirst(), which seeds and runs the greedy pass in one call.

Examples

set.seed(1)
pts <- matrix(rnorm(60), ncol = 2)
d <- dist(pts)
PickPoint(d, strategy = "diameter")
FarFirst(5L, d, strategy = PickPoint(d, strategy = "diameter"))

Format and print Coreset solver results

Description

Terse summaries of the objects returned by the Coreset solvers.

Usage

## S3 method for class 'MaxMinSelection'
format(x, ...)

## S3 method for class 'MaxMinSelection'
print(x, ...)

Arguments

x

A MaxMinSelection object (from any solver, including ExactMaxMin()).

...

Ignored; present for S3 compatibility.

Value

print.Coreset() returns x, invisibly. It is called for its side-effect of printing format(x) to the console. format.Coreset() returns a character string reporting the selection size, the selected indices, the algorithm (and if applicable strategy or proof status), and the achieved T_k.

See Also

Other reporting functions: print.KCentre, print.MaxEntropy, print.MaxMeanSelection(), print.MaxSum, summary.Coreset

Examples

set.seed(1)
pts <- matrix(rnorm(60), ncol = 2)
print(FarFirst(5L, dist(pts)))

Format and print k-centre solver results

Description

Terse summaries of the objects returned by KCentre() ("KCentreSelection") and ExactKCentre() ("KCentreExact")

Usage

## S3 method for class 'KCentreSelection'
format(x, ...)

## S3 method for class 'KCentreSelection'
print(x, ...)

## S3 method for class 'KCentreExact'
format(x, ...)

## S3 method for class 'KCentreExact'
print(x, ...)

Arguments

x

A "KCentreSelection" or "KCentreExact" object.

...

Ignored; present for S3 compatibility.

Value

print.KCentre() returns x, invisibly. It is called for its side-effect of printing format(x) to the console. format.KCentre() returns a character string describing a KCentreSelection; it reports the centre count, the chosen indices, the method, and the achieved covering radius (with proof status for the exact solver).

See Also

Other reporting functions: print.Coreset, print.MaxEntropy, print.MaxMeanSelection(), print.MaxSum, summary.Coreset

Examples

set.seed(1)
KCentre(4L, dist(matrix(rnorm(60), ncol = 2)))

Format and print maximum-entropy (maxdet) solver results

Description

Terse summary of the object returned by MaxEntropy() ("MaxEntropySelection"), reporting the retained log-determinant (\log\det K_S, the maxdet objective) and the magnitude of the positive-semidefinite repair.

Usage

## S3 method for class 'MaxEntropySelection'
format(x, ...)

## S3 method for class 'MaxEntropySelection'
print(x, ...)

Arguments

x

A "MaxEntropySelection" object.

...

Ignored; present for S3 compatibility.

Value

format.MaxEntropySelection() returns a one-line character summary; print.MaxEntropySelection() returns x invisibly, called for its side-effect.

See Also

Other reporting functions: print.Coreset, print.KCentre, print.MaxMeanSelection(), print.MaxSum, summary.Coreset

Examples

set.seed(1)
MaxEntropy(4L, dist(matrix(rnorm(40), ncol = 2)))

Format and print Max-Mean solver results

Description

Terse one-line and detailed summaries of the objects returned by MaxMean().

Usage

## S3 method for class 'MaxMeanSelection'
format(x, ...)

## S3 method for class 'MaxMeanSelection'
print(x, ...)

## S3 method for class 'MaxMeanSelection'
summary(object, ...)

Arguments

x

A MaxMeanSelection object returned by MaxMean().

...

Ignored; present for S3 compatibility.

object

A MaxMeanSelection object returned by MaxMean().

Value

print.MaxMeanSelection() returns x, invisibly. format.MaxMeanSelection() returns a character string reporting the selection size, the selected indices, and the achieved max-mean objective f(S).

See Also

Other reporting functions: print.Coreset, print.KCentre, print.MaxEntropy, print.MaxSum, summary.Coreset

Examples

set.seed(1)
pts <- matrix(rnorm(60), ncol = 2)
print(MaxMean(dist(pts), maxSeconds = 1))

Format and print Max-Sum (maximum diversity) solver results

Description

Terse summary of the object returned by ExactMaxSum() ("MaxSumSelection"), reporting the achieved total pairwise distance (the max-sum objective) rather than the minimum distance of ExactMaxMin().

Usage

## S3 method for class 'MaxSumSelection'
format(x, ...)

## S3 method for class 'MaxSumSelection'
print(x, ...)

Arguments

x

A "MaxSumSelection" object.

...

Ignored; present for S3 compatibility.

Value

format.MaxSumSelection() returns a one-line character summary; print.MaxSumSelection() returns x invisibly, called for its side-effect.

See Also

Other reporting functions: print.Coreset, print.KCentre, print.MaxEntropy, print.MaxMeanSelection(), summary.Coreset

Examples

set.seed(1)
# Package 'highs' is required for ExactMaxSum()
if (requireNamespace("highs", quietly = TRUE)) {
  ExactMaxSum(3L, dist(matrix(rnorm(20), ncol = 2)))
}

Detailed summaries of Coreset solver results

Description

A fuller counterpart to print.MaxMinSelection(): the one-line headline, followed by the achieved objective(s), search effort, and – for a FarFirst() ensemble – the per-strategy T_k table.

Usage

## S3 method for class 'MaxMinSelection'
summary(object, ...)

Arguments

object

A MaxMinSelection object (from any solver).

...

Ignored; present for S3 compatibility.

Value

summary.Coreset() returns object, invisibly.

See Also

Other reporting functions: print.Coreset, print.KCentre, print.MaxEntropy, print.MaxMeanSelection(), print.MaxSum

Examples

set.seed(1)
pts <- matrix(rnorm(60), ncol = 2)
summary(FarFirst(5L, dist(pts)))