# Initialisation

kPopFree <- function(object, ...) {
  n   <- object@nBits
  P   <- object@popSize
  Ks  <- sample(rep_len(2:Kmax, P))        # each K used about equally often
  pop <- matrix(0L, nrow = P, ncol = n)
  for (i in seq_len(P))
    pop[i, sample.int(n, Ks[i])] <- 1L
  pop
}

# Fitness

fitness_DB <- function(gamma) {        # fitness = -DB
  M <- which(gamma == 1); K <- length(M)
  if (K < 2) return(-Inf)
  DM <- D[, M, drop = FALSE]
  cl <- max.col(-DM, ties.method = "first")
  S  <- tapply(DM[cbind(1:nrow(D), cl)], factor(cl, 1:K), mean)
  if (anyNA(S)) return(-Inf)         # empty cluster
  R  <- outer(S, S, "+") / D[M, M]
  diag(R) <- -Inf
  -mean(apply(R, 1, max))
  }