It seems to me that you are trying to randomly assign the elements of the set (numbers from 1 to 20) to the clusters, provided that at least one element is assigned to each cluster.
One approach I could think of is to choose a random reward r_ij for assigning element i to cluster j . Then I would define binary decision variables x_ij that indicate whether element i assigned to cluster j . Finally, I would use a mixed whole optimization to select an assignment from elements to clusters, which maximizes the collected reward under the following conditions:
- Each element is assigned exactly one cluster.
- Each cluster has at least one member assigned to it.
This is equivalent to randomly choosing a destination, saving it if all the clusters have at least one member and otherwise drop it and try again until you get the correct random assignment.
From an implementation point of view, this is pretty easy to do in R using the lpSolve package:
library(lpSolve) N <- 20 K <- 10 set.seed(144) r <- matrix(rnorm(N*K), N, K) mod <- lp(direction = "max", objective.in = as.vector(r), const.mat = rbind(t(sapply(1:K, function(j) rep((1:K == j) * 1, each=N))), t(sapply(1:N, function(i) rep((1:N == i) * 1, K)))), const.dir = c(rep(">=", K), rep("=", N)), const.rhs = rep(1, N+K), all.bin = TRUE) (assignments <- apply(matrix(mod$solution, nrow=N), 1, function(x) which(x > 0.999))) # [1] 6 5 3 3 5 6 6 9 2 1 3 4 7 6 10 2 10 6 6 8 sort(unique(assignments)) # [1] 1 2 3 4 5 6 7 8 9 10
source share