2009-08-09 55 views
0

我試圖帶一組20個人(標記爲1 - 20),並將它們分成五個子組,每個子組基於這些人希望與之相關的表達偏好。根據偏好分組

20人組中的每個人可以表示0,1,2,3或4個偏好。例如,person1可以選擇0(與他們無關),或14(與person14組在一個組中),或者可以表示與14,20,6和7中的人在一個組中。理想情況下,每個具有偏好將在至少有一個選擇的組中。

關於算法的想法?

+0

作業? – 2009-08-09 12:39:31

+0

這是一個家庭作業,你有什麼嘗試,什麼是確切的標準,即。如果你將人14和人14連接在同一組中,那麼將這個人與14人分在一起會更好嗎? – 2009-08-09 12:46:32

+0

因此,你的朋友已經尋求幫助,而你正在尋求我們的幫助來幫助你的朋友,因爲你無法幫助他?!請求你的朋友來到StackOverflow.com並要求Jon Skeet! – 2009-08-09 13:21:07

回答

0

這可能是一個太多的要求在SO,但認爲這個問題很有趣,所以這裏有一些想法。

由於維克多Hurdugaci說,這主要是獨立於語言的算法問題(雖然我很樂意看到下面LINQ實現我的例子!)

在你的問題不能得到所描述的問題完美的結果,即它是一個優化問題(所以你不能用約束滿足算法來解決它)。您必須找到一種算法,該算法根據指示結果有多好的某個函數(稱爲適應函數)從所有可能結果集中找到最佳結果。

天真蠻力解決方案(僞代碼)

我們先從一組人(這裏:4把事情簡單化):

people = { a, b, c, d } 

我們可以找到的所有可能的亞組固定大小(此處:2)使用choose操作:

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

我們可以發現USI亞組的所有可能的組合再次納克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)) 

例如,如果ab,和bcd偏好沒有任何偏好,然後calculateScore應該返回一個更高的分數爲{ab,cd}{ac,bd}{ad,bc}

改進方案

有一個數的算法,用這種優化問題的解決。我認爲一個Hill climbing算法很適合這裏。