我尝试将元素随机分配给组,但似乎要么令人惊讶,要么我错过了明显的解决方案。
备注:我的尝试是用R编写的,但我对使用任何语言的所有可理解答案感到满意。
输入数据:
向量 o 包含对象的可用单位,其中从每个对象到最多 p-1 个单位都可用。 o 的示例:(0,1,5,8,p-1,...)
此外,还有一个向量 g ,该向量包含成组的可用斑点。每个组可以采用 p 或 p + 1 个单位。 g 的示例:(p,p + 1,p,p,p + 1,...)
以下限制适用于输入数据:
预期产量
可用对象应随机分配到组中,但每个对象组中最多只能容纳一个单元。将单元分配到组的顺序无关紧要。
示例
示例1:
elements <- c(2, 1)
group_sizes <- c(1, 2)
唯一可能的解决方案是
(1), (1, 2)
说明:第一组中第一个对象的单位为1,这些组包含两个对象中的一个单位
示例2:
elements <- c(2,1,1)
group_sizes <- c(1, 2, 1)
可能的解决方案:
(1), (1, 2), (3)
(1), (1, 3), (2)
(1), (2, 3), (1)
(2), (1, 3), (1)
(3), (1, 2), (1)
我正在寻找一种算法,该算法返回给定输入的可能分布之一。所有发行版本都应有相等的机会退还。
**我的方法不成功**
我考虑过将每次迭代为每个组分配一个单元。无法将单位分配给已经包含同一对象单位的组。分配顺序从最常见的对象到最不常见的对象开始,然后从最常见的对象重新开始。
# Group sizes
group_sizes <- c(8,9,9,9,9,9,9,8,8)
# Available units of objects (already sorted by size)
object_units <- c(8,8,8,8,8,8,8,8,8,6)
# Generate a distributions order
dist_order <- numeric(0)
while(max(object_units) > 0){
dist_order <- c(dist_order, which(object_units > 0))
object_units <- object_units - 1
}
n_groups <- length(group_sizes)
result <- matrix(numeric(0), ncol = n_groups, nrow = min(group_sizes))
set.seed(1)
# distribute batch with
for(i in 1:min(group_sizes)){
# get the objects of which units are distributed in this batch
ind <- (i - 1) * n_groups + 1
current <- v[ind:(ind + n_groups - 1)]
# beginning with the batch all groups can be distributed
avail_groups <- 1: n_groups
#iterate over groups an select object to assign to group
for (j in 1:n_groups) {
# current object can only be assigned to where it has not been assigned yet
free <- which(colSums(result == current[j], na.rm = TRUE) == 0)
# current object can only be assigned to where no other object has been assigned to in this batch
current_avail_groups <- intersect(avail_groups, free)
# select from remaining groups on to assign the assign the object
if(length(current_avail_groups) == 1){
selected_group <- current_avail_groups
} else {
selected_group <- sample(current_avail_groups, size = 1)
}
# store assignment in result matrix
result[i, selected_group] <- current[j]
# remove group from available groups for this iteration
avail_groups <- avail_groups[selected_group != avail_groups]
}
}
这不是有效的算法,因为在某个迭代过程中,某个对象的所有组可能都已经包含一个对象的单元,或者已经接收到另一个对象的单元。