为具有首选项的节点创建组

时间:2012-01-20 07:21:59

标签: algorithm

我有264个孩子需要分成24个游戏组。每组可包含10,11或12名儿童。此外,每个孩子都可以拥有一个喜欢与其合作的喜欢玩伴的列表。此列表可以为空,或最多包含5个孩子。

最后,一个有偏好的孩子不应该在没有任何首选玩伴的群体中:至少有一个朋友应该在小组中。

我尝试了一些伪代码:

Group[11] groups;
List<Node> nodes;
int x = 264;
int nrGroups = 24;
int maxNodesInGroup = 12;
int minNodesInGroup = 10;    
foreach(Node node in nodes) {
  if(node not in any group)
    add to a group
  else
    continue

  foreach(Node preferedFriend in node.Preferred) {
    if(node not in any group) {
      //add to a same group
      continue
    } else {
      continue
    }
  }     
}

有没有办法为每个孩子创造最理想的游戏小组?

3 个答案:

答案 0 :(得分:3)

这听起来像minimum k-cut问题。每个孩子都是图表中的一个节点。 k个已连接的组件是您的游戏组。在每对子项之间绘制一条边(对于完全连接的图形)。

如果一个孩子希望与另一个孩子一起玩,则用1标记边缘,否则0。或者如果两端的孩子都有较少的首选玩伴,可能会为边缘分配更多的重量。然后你的目标是在26个不同的组件中划分图形,同时最小化总的“切割”边缘。

答案 1 :(得分:1)

如果您想要最佳解决方案,可以尝试使用整数线性规划求解器。即使问题是NP难的,它们通常也很快。

您将拥有二元变量g ci ,如果子c在组i中,则为1。然后你得到每个c的不等式:Σ i g ci = 1并且对于每个i:Σ c g ci &gt; = 10和Σ c g ci &lt; = 12.然后你有每个子c的二进制变量s cd 列表中的子d,如果愿望被授予,则为1。为了确保g和s变量之间的一致性,需要对每个c,d和i进行约束:s cd &lt; = 1 +(g ci - g di )和s cd &lt; = 1 +(g di - g ci )。仅当所有g值匹配时,这允许s cd 为1。然后为每个c留下没有孩子:Σ d s cd &gt; = 1.最后,目标是最大化Σ c,d < /子>取值<子> CD

这个ILP有很多变量(大约7000个),但很有可能它可以通过像GLPK或Coin CBC这样的求解器来解决;另外,编写一个为这些求解器生成输入的脚本应该相当容易,例如“CPLEX LP”格式。

答案 2 :(得分:1)

不是答案,而是一些进一步的阅读和我自己的部分算法。

这似乎是stable roommates (SR) problem的变体(本身就是稳定婚姻问题的一种变体)。另外两个似乎特别相关的变体是stable roommates problem with ties (SRT)(PDF)和stable fixtures (SF) problem(PDF)。前者讨论了与&#34; tie&#34; (与您的所有偏好排名相同),而后者讨论匹配的组大于2。两者都包括伪代码算法,可以适应您的问题。

就我而言,考虑一下你的节点&#34;是有意义的。作为三组不同的人:

  • A ,没有偏好的
  • B ,那些只有一个偏好的人
  • C 具有多个偏好的

直观地,似乎 B 是您应该首先考虑的集合,因为根据您自己的规范,每个必须必须与他们偏好的人分组。从一个起点开始,这是一个(不完整的)算法背后的信封:

  1. 将节点划分为三个不连续的集合: A B C ,如上所述。

    < / LI>
  2. 构建一个包含 size(B) {x,y} Sb 集合 x < / em>是来自 B 的人, y 是他们的偏好人( y 可能出现在几对中)。丢弃 B

  3. 对于 Sb y A 成员的任何一对(即 x 喜欢 y y 没有首选项),在 Sba 中将对设置为一边,将其从 Sb 中移除。< / p>

  4. 对于 Sb {y,x} 的任何一对 {x,y} ,其中 {y,x} 也存在于 Sb (即相互单一偏好)在 Sbb 中设置 {x,y} ,并删除它和 {y,x} 来自 Sb

  5. 构建24集 G(1) ... G(24)。通过以下方式分发 Sba Sbb 的成员:

    1. G(1..24)之间均匀分配 Sba 的成员对,即从 Sba 添加一个成员每个 G(1..24),然后是第二个成员,依此类推,直到 Sba 耗尽,然后重复 Sbb 直到它也是,已经筋疲力尽了。

      此时 G(1..24)仅包含&#34;稳定&#34;成员,即每对中的每个成员现在都在 G(n)组中,这样 G(n)包含其唯一的首选项,而没有 x y 在多个组中。

    2. 以下列方式在 G(1..24)中分配 Sb 的剩余对 {x,y}

      • 如果 y 存在于任何组 G(n)中,请丢弃该对,并将 x 单独添加到 G( n)除非 size(G(n))= 12

        如果后一种情况属实,则添加 x 以设置 P

      • 否则将 {x,y} 添加到第一组 G(1..24) size(G(n) )= min(size(G(1..24)))或者,如果所有组具有相同的大小,则将其添加到 G(1)

      此时 Sb 已用尽。

  6. 这是事情变得多毛的地方,有很多可能的方法。只有一个跟随。

    对于 C 的每个成员 x (具有多个首选项的人员集),将 x 添加到 G(n )其中 G(n) C 的偏好比 G(1..24)中的任何其他 更多 em>和 size(G(n))&lt; 12 。如果有平局选择第一个尺寸(G(n))= min(尺寸(G(1..24)))

    如果 G(1..24)中没有 x 的偏好,则将 x 添加到的第一个 G(1..24) size(G(n))= min(size(G(1..24)))

    此时 C 已用尽,只留下 A

  7. 对于 C 的每个成员 q ,将 y 添加到 G(n)其中 G(n)有更多成员 p q p size(G(< n))&lt; 12 。如果有平局选择第一个尺寸(G(n))= min(尺寸(G(1..24)))

    如果 G(1..24)都没有 q 是首选项的成员,请选择第一个 G(1..24) size(G(n))= min(size(G(1..24)))

    此时 A 也已耗尽且所有人都是 G(1..24)中的一个且只有一个的成员。我想。

    这留下两组:

    • P ,我们预留的 Sb 中的成员 {x,y} x 他们没有适应&#34;在 G(n) y G(n)的成员。
    • Q C 的成员 x 已添加到 G(1..24)当 G(1..24)中的任何成员都不是 x 的偏好时。
  8. 让我们首先处理 Q

    对于 Q 的每个成员 x (也是成员 G(n)),如果 G(n)有一个或多个 x 偏好的成员,然后 x 的成员资格不变。

    否则请执行以下操作:

    • 如果 G(n)偏好设置为 x 的成员,则添加 x 设置 R ,但也将其保留为 G(n)的成员。

    • 否则从 G(n)中删除 x 并将其添加到 G(m) G( m)具有 x size(G(m))&lt; 12

      如果没有这样的设置,则添加 x 以设置 P ,但也将其保留为 G(n)的成员。

      如果存在平局,请选择 x 为首选项的成员最多的集合。如果仍然一个平局,则选择最小的一组,如果仍有平局,则选择其中的第一个。

      现在 Q 已用尽,我们留下了两套 P R

  9. 让我们选择 P ,其成员不会适应&#34;在任何 G(1..24)中,其任何偏好都是匹配。

    对于 P 的每个成员 x

    1. x 添加到第一组 G(n) size(G(n))= min(size(G(1) ..24)))

    2. 现在在 G(m)不 x 的首选项 y >其中包含偏好设置为 y 的其他成员 z 。每个 y 都添加到 Px

      Px 中找到 y 中的人

      如果存在平局,请选择 G(n) * y *的大多数成员为 Px 的成员 y 偏爱。如果仍然存在平局,则选择其 G(m)集合中 y 为首选项的成员最少的那个。如果仍然一个平局选择其 G(m)集合中 y 偏好的成员最少的那个。如果 仍然 一个平局选择其 G(m)集合最大的那个(并且如果有最大用途的平局)以上标准可供选择,最后诉诸 Tx 的第一个成员。

      y 添加到 G(n)并将其从 G(m)中删除。

      P 现已用尽。

  10. 我们现在留下了 R x 的一组人,他们有多个偏好并且在一个组中 G(n) 没有成员属于 x 的偏好,但不能被移动&#34;因为 G(n)有一个或多个成员 y 偏好 x 。 p>

    为了解决此问题,我们可能会尝试从其他组 G(m)移动 x 的成员 z 。当然,如果 G(m)包含 z 的任何成员 z ,我们就无法移动 z 。如果没有&#34;可移动&#34; z 存在我们可能会尝试将 {x,y} 对移动到 G(m),或者我们可能会尝试移动该对 {z,v} G(n),但如果 y v ,则可能无法实现同样纠缠不清。从那里我们可以尝试三元组,等等。

  11. 在最后一步(虽然可能之前,如果我忽略了某些事情),你可能会在一个周期中结束,或者问题可能是NP难以解决并且无法保证解决方案。我认为这对于博士来说是一个问题。但是,您可能会发现,您永远不会得到集合 P Q R ,或者它们足够小,您可以只是眼球解决方案。我希望无论如何这都会有所帮助。