将对象的单位分配给组,而不必将同一对象的单位分配给组

时间:2020-04-01 00:00:04

标签: r algorithm

我尝试将元素随机分配给组,但似乎要么令人惊讶,要么我错过了明显的解决方案。

备注:我的尝试是用R编写的,但我对使用任何语言的所有可理解答案感到满意。

输入数据:

向量 o 包含对象的可用单位,其中从每个对象到最多 p-1 个单位都可用。 o 的示例:(0,1,5,8,p-1,...)

此外,还有一个向量 g ,该向量包含成组的可用斑点。每个组可以采用 p p + 1 个单位。 g 的示例:(p,p + 1,p,p,p + 1,...)

以下限制适用于输入数据:

  • 所有组的所有可用对象的正好都有点sum(o)== sum(g)

预期产量

可用对象应随机分配到组中,但每个对象组中最多只能容纳一个单元。将单元分配到组的顺序无关紧要。

示例

示例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]
  }

}

这不是有效的算法,因为在某个迭代过程中,某个对象的所有组可能都已经包含一个对象的单元,或者已经接收到另一个对象的单元。

0 个答案:

没有答案