按首选项拆分组

时间:2009-08-09 12:29:59

标签: c# algorithm grouping

我正在尝试带一组二十人(标记为1 - 20)并将他们分成5个小组,每个小组4个,根据这些人希望与谁表达的偏好。

20人组中的每个人都可以表达0,1,2,3或4个偏好。例如,person1可以选择0(不喜欢他们与谁在一起),或14(在person14组中)或者可以表示与人14,20,6组成一组, 7.理想情况下,每个有偏好的人都会在一个至少有一个选择的群体中。

关于算法的想法?

2 个答案:

答案 0 :(得分:2)

您遇到的问题与C#无关,该算法与语言无关。

此问题的典型实现是backtracking

更多信息:

另一种方法(我会这样做):Genetic Algorithms

答案 1 :(得分:0)

这可能在SO上要求太多,但认为这个问题非常有趣,所以这里有一些想法。

正如 Victor Hurdugaci 所说,这主要是一个独立于语言的算法问题(虽然我很乐意看到下面的例子用LINQ实现!)

您的问题中描述的问题无法产生完美的结果,即它是一个优化问题(因此您无法使用约束满足算法来解决它)。您必须找到一种算法,该算法根据一些表明结果有多好的函数(称为适应度函数),从所有可能结果的集合中找到最佳结果。

Naive Brute force Solution(伪代码)

我们从一组人开始(这里:4简化事情):

people = { a, b, c, d }

我们可以使用choose运算符找到所有可能的固定大小的子组(此处为:2):

groups = people.choose(2)  // = { {a,b} {a,c} {a,d} {b,c} {b,d} {c,d} }

我们可以再次使用choose运算符找到所有可能的子组组合:

combi = groups.choose(4/2) // = { {ab,ac} {ab,ad} {ab,bc} {ab,bd}
                           //     {ab,cd} {ac,ad} {ac,bc} {ac,bd}
                           //     {ac,cd} {ad,bc} {ad,bd} {ad,cd}
                           //     {bc,bd} {bc,cd} {bd,cd} }

显然,人们不能同时分成两组,所以我们删除所有无效组合:

combi2 = combi.select(g => g.bigUnion().size == 4)
                           // = { {ab,cd}, {ac,bd}, {ad,bc} }

现在你必须根据一些健身功能找到“最佳”项目,即根据偏好得分最佳的组合。

result = combi2.maximumBy(g => fitness(g))

例如,如果a优先选择bbcd没有任何偏好,那么{{1应该为calculateScore返回的分数高于{ab,cd}{ac,bd}的分数。

改进的解决方案

有几种算法可以解决这种优化问题。我认为Hill climbing算法很适合。