我有一个人的定义。我需要根据人员列表(及其适用的插槽)找到我能够获得的最多团队,因为一旦一个人被使用了#34;对于一个插槽,它们不能再使用。
简化示例:
**Team Requirements**
Slot A: 2 People
Slot B: 1 Person
Slot C: 1 Person
**People And Which Slots Are Applicable**
Person 1: A
Person 2: A,C
Person 3: A,B
Person 4: B
Person 5: A,B
Person 6: C
Person 7: C
Person 8: A
可能的答案
Team 1
A: P1, P8
B: P4
C: P6
Team 2
A: P2, P3
B: P5
C: P7
对于我的现实问题,我有多个插槽(每个团队1-10个)和1-1000个人,每个插槽最多可以有20个插槽。
有人可以推荐一种适合这种群体优化问题的算法吗?
答案 0 :(得分:3)
这可以通过在一系列图表中找到Maximum Cardinality Bipartite Matching来解决,整体时间为O(n ^ 2.5 log n)。
要做到这一点,首先将每个插槽类型转换为一组适当数量的不同插槽,以便我们最终使用插槽A1,A2,B,C。最终解决方案将分配一个人到特定团队的特定位置(例如,第1组中的人员3到插槽A2),但我们可以简单地忘记" 2" (以及团队的排序,同样纯粹是人为的)。
首先计算团队数量的乐观估计值k:RoundDown(n / 4)会做,因为每个团队使用4人,所以我们不能拥有比这更多的团队。现在在二分图的一部分中制作4k个顶点 - 即每个k个潜在团队中4个槽中每个槽的顶点:A1_1,A2_1,B_1,C_1,A1_2,A2_2,B_2,C_2,... 。,A1_k,A2_k,B_k,C_k。在二分图的另一部分中,为每个人创建一个顶点。最后,将每个人顶点与允许填充的所有插槽顶点连接起来:例如,如果一个人x可以占用插槽A或C,则它们应该通过边缘连接到以" A"开头的每个插槽。或" C" (对于8人的例子,这将是6条边。)
然后,解决此图表上的MCBM问题,例如使用Hopcroft-Karp algorithm在O(n ^ 2.5)时间内。结果将是边缘的一个子集,可以解释为将每个人分配给团队中的至多一个插槽,并在团队中填充最多一个人的每个插槽。如果这导致每个插槽都被填满,万岁!我们拥有尽可能多的团队。否则,如果有任何人未填充任何球队位置,请减少球队数量并重试。 (您可以每次减少1个团队的数量,这会导致需要解决的线性数量的MCBM问题 - 但您可以通过二进制搜索来节省时间。这意味着首先将团队数量减半,并且之后将团队数量减少或增加前一个数量的一半,减少一些团队有一个未填补的职位,并且当没有人没有时增加,直到收敛。)