2011-01-21 29 views
12

相當任務分配給工人(有人問之前,這不是功課。)算法基於技能

我有一組利益的工人,即:

  • 鮑勃:Java中, XML,紅寶石

  • 蘇珊:Java的,HTML,Python的

  • 弗雷德:Python和Ruby

  • 山姆:Java中,紅寶石

(實際上有某處10-25 「利益」 爲每個工人的範圍,我有大約40-50工作者)

與此同時,我有一組非常大的任務需要在工作人員之間分配。每個任務被分配給至少 3名工人,工人必須在任務的利益至少一個匹配:

任務1:紅寶石,XML 任務2:XHTML,Python的

和等等。所以Bob,Fred或Sam可以得到任務1;蘇珊或者弗雷德可以得到任務2

這是所有存儲在數據庫中正是如此:

Task 
    id integer primary key 
    name varchar 

TaskInterests 
    task_id integer 
    interest_id integer 

Workers 
    id integer primary key 
    name varchar 
    max_assignments integer 

WorkerInterests 
    worker_id 
    interest_id 

Assignments 
    task_id 
    worker_id 
    date_assigned 

每個工人都有任務,他們會做的最大數量,在10左右。有些利益比其他人更少見(即只有1或2名工人將他們列爲利益),一些利益更爲普遍(即一半的工人列出他們)。

算法必須

  • 分配每個任務到3名工人(這是 假設 工人至少3感興趣的 利益的任務之一)。
  • 分配每個工人1個或多個任務

理想的情況下,該算法將:

  • 分配給每個工人的數成正比,其最大作業任務和任務的總數。例如,如果蘇珊說她將完成20項任務,大多數人只會完成10項任務,並且有50名工作人員和300項任務,她應該分配12項任務(20/10 *(300/50))。
  • 分配各種任務給每個工人,因此,如果蘇珊列出4和利益,她得到的是包括4和利益的任務(而不是讓10個任務都具有相同的利益)

最困難的方面迄今已被處理論文的問題:有少數工人相應

  • 工人誰很少有興趣,尤其是
  • 工人誰有一些利益,對此有興趣

    • 任務是相對較少的任務
  • +3

    這是一個很棒的問題,但我很好奇你是否可以對你想要優化的內容做更具體的描述。是否有一些特定的價值想要最大化或最小化?如果是這樣,你能告訴我們它是什麼嗎?現在這是一個有趣的問題,但我認爲這有點低估。 – templatetypedef 2011-01-21 23:51:12

    +1

    目標是誠實地分配更公平的任務。目前沒有一個正式的算法,更多的是一種強力「循環通過任務,從首先按照最少匹配工作人員的任務排序,然後分配給工人,按已分配的人數排序」這最終會導致一些工作人員得到太多或太少的任務。 – 2011-01-25 07:16:51

    回答

    0

    嘗試將您的任務映射到stable marriage problem。任務成爲未來的妻子,你的員工成爲追求者。

    您可能需要添加一些額外的算法來分配每個任務的首選項給員工,反之亦然 - 您可以爲每個任務的組件分配一些理想的熟練程度,然後讓您的員工對每個任務進行排名。您可以爲每個工作人員擁有的每個組件分配熟練程度,並使用它來獲取工作人員的每個任務偏好。

    一旦你有了偏好,然後運行算法,發佈結果,然後允許人們成對申請交換分配 - 畢竟這是一個人的問題,當他們有一定程度的控制時人們工作得更好。

    3

    對於尋找直接解決方案困難的問題,使用近似算法,估計函數和方法來改進解決方案可能是一個好主意。有多種方法,例如genetic algorithmssimulated annealing

    其基本思想是使用某種簡單的算法(如貪婪算法)來獲得隱約可用的東西並進行隨機修改,保留那些可以提高評估分數的修改,並丟棄那些使其變得更糟的修改。

    使用遺傳算法,一組例如100個隨機解產生並計分,最好保留並「繁殖」以產生具有與前幾代相似的特徵,但具有一些隨機突變的新一代解。

    對於模擬退火,被接受的稍差的解決方案的概率起初很高,但隨着時間的推移而降低。這可以降低早期陷入本地優化的風險。

    1

    所以我給了這個問題一些想法,我認爲你可以通過將它降低到最小成本最大流量的實例(例如參見this)來獲得一個很好的解決方案(對於「良好」的一些定義) 。這個想法如下。假設給你一組工作J,每個工作都有一套必要的技能,還有一組工人W,每個工人都有一套人才。你也給每個工人一個固定的k_i,說你希望他們做多少工作,還有一個常數m_i表示你可以分配給他們的最大工作量。您的目標是將工作分配給工人,使每項工作都由具有技能的工人完成,沒有工人做超過m_i個工作,並且工人完成的「超額」工作的數量被最小化。例如,如果員工是五個工人,他們每個人都想完成四項任務,並且負載是平衡的,這樣兩個工人就可以完成四個工作,一個工作三個,一個工作五個,總超出量爲一個,因爲一個工人多做一個工作工作比預期的要好。

    減少如下。現在,我們將忽略平衡要求,並看看湯姆如何將其降至最大流量;我們將在最後添加負載平衡。用指定的起始節點s和匯聚節點t構建圖G。爲每個工作j和每個工人w添加一個節點。從這些節點到成本零和容量一的這j個節點中的每一個將存在邊緣。從成本零和容量m_i的每個w節點到t也將有一條邊。最後,對於每個工作j和工人w,如果工人w具有完成工作j所必需的才能,則從j到w具有成本零和能力1的邊。

    這個想法是我們想通過j和w節點推動從s到t的流動,使得每個流動路徑通過某個j節點到達一個w節點意味着工作j應該被給予工人w。從s到j節點的邊緣的容量限制確保最多一個流單元進入j節點,因此該作業最多隻能分配一次。從w節點到節點t的邊緣的容量限制防止每個工人被分配太多時間。由於所有能力都是不可分割的,因此從s到t存在整體最大流量,因此此圖中的最大流量對應於合法工作分配給工作人員,且不超過任何工人的最大負荷。您可以通過查看圖中的總流量來檢查是否分配了所有作業;如果它等於工作的數量,他們全部被分配。

    但是,上述結構對平衡工作負荷沒有任何作用。爲了解決這個問題,我們會修改一下這個構造。而不是從每個w節點到t的邊緣,相反,對於每個w節點,將兩個節點添加到圖c和e,並按如下方式連接它們。存在從w_i到c_i的邊,其容量k_i和成本爲零,並且具有從c_i到t的相同邊緣。從w_i到e_i也有一個邊,成本爲1,容量爲m_i - k_i。從e_i到t的邊緣也有相同的容量和零成本。直觀地說,我們沒有改變離開任何w節點的流量,但是我們改變了這個流量的成本。通過c節點分流的流程是免費的,因此工人可以承擔k_i工作,而不會產生成本。之後的任何工作都必須通過e路由,這對每個流通單位都要花費一分。在這個新圖中查找最大流量仍然會確定一個分配,但在圖表中查找最小成本最大流量會發現最大限度減少分配給工作人員的超額作業的分配。

    最小成本最大流量可以用多個有點衆所周知的算法在多項式時間內求解,所以希望這是一個有用的答案!

    +0

    非常好的解決方案(它應該可能是被接受的答案,儘管我沒有看到它如何處理工人所需的「各種任務」,但這是一個相對不重要的點)。另外,我認爲爲了滿足OP的要求,每個工作必須由3名工作人員完成,從s到j的邊應該具有容量3(而不是1)。 – MikeTeX 2017-12-20 21:10:45

    5

    此問題可以模擬爲 Maximum Flow Problem

    在最大流問題中,您有一個有兩個特殊節點的源節點和接收節點的有向圖。圖中的邊具有容量,並且您的目標是將源中的流圖分配給接收器,而不會超出任何邊的容量。

    通過(非常)精心製作的圖表,我們可以從最大流程中找到滿足您要求的任務。

    讓我編號的要求。

    要求:

    1. Workers are assigned no more than their maximum assignments. 
    2. Tasks can only be assigned to workers that match one of the task's interests. 
    3. Every task must be assigned to 3 workers. 
    4. Every worker must be assigned to at least 1 task. 
    

    可選:

    5. Each worker should be assigned a number of tasks proportional to that worker's maximum assignments 
    6. Each worker should be assigned a variety of tasks. 
    

    我假設的最大流量是使用 Edmonds-Karp Algorithm找到。

    我們首先找到符合要求1-3的圖。

    將圖形繪製爲4列節點,其中邊線僅從列中的節點到鄰近列中的節點向右。

    在第一列中我們有源節點。在下一列中,我們將爲每個工作人員提供節點。從源頭上看,每個工人的能力與工人的最大分配量相等。這將強制執行要求1.

    在第三列中,每個任務都有一個節點。從第二列中的每個工作人員看,該工作人員感興趣的每個任務的邊緣容量爲1(如果他們的興趣交集非空,則工作人員對任務感興趣)。這將執行要求2。1的容量將確保每個工作人員僅爲每個任務的3個插槽中的1個插槽。

    在第四欄中我們有水槽。有一個從每個任務水槽邊緣與容量3.這將強制要求3

    現在,我們發現在使用Edmonds-Karp算法此圖的最大流量。如果這個最大流量小於3 * (# of tasks)那麼沒有分配滿足要求1-3。如果沒有,就有這樣的任務,我們可以通過檢查最終的增強圖來找到它。在增強圖中,如果從任務到具有容量1的工人的邊緣,則該工人被分配到該任務。


    現在,我們將修改我們的圖形和算法以滿足其餘的要求。

    首先,讓我們滿足需求4.這將需要一個小的變化的算法。最初,將從源到工人的所有容量設置爲1.在此圖中查找最大流量。如果流量不等於工人數量,則沒有分配會議要求4.現在,在您的最終殘差圖中,對於每個工人,從源到該工人的邊緣具有容量0,反向邊具有容量1 。分別將這些更改爲that worker's maximum assignments - 10。現在像以前一樣繼續Edmonds-Karp算法。基本上我們所做的就是先找到一個任務,讓每個工人分配到一個任務。然後從該任務中刪除反向邊,以便始終將該工作人員分配給至少一個任務(儘管可能不是第一次分配的任務)。


    現在,讓我們滿足要求5.嚴格來說,這個要求只是意味着我們通過sum of all worker's maximum assignments/number of tasks將每個工人的最大任務。這很可能不會有令人滿意的任務。但沒關係。用這些新的最大分配初始化我們的圖。運行埃德蒙茲卡普。如果它發現一個使任務到邊緣的邊緣飽和的流程,我們就完成了。否則,我們可以在殘差圖中增加從接收器到工人的能力,並繼續運行Edmonds-Karp。重複,直到我們將邊緣浸入水槽。不要過多地增加容量,以至於工人分配的任務太多。另外,技術上,每個工人的增量應該與該工人的最大分配成正比。這些都很容易做到。


    最後讓我們來滿足要求6.這一個有點棘手。首先,在工作人員和任務之間添加一列,並從工作人員的任務中刪除所有邊緣。在這個新的專欄中,爲每個工人添加一個節點,用於每個工人的興趣。從這些新節點中的每一個節點,爲具有容量1的匹配興趣的每個任務添加一條邊。將每個工作者的邊添加到其容量爲1的每個感興趣節點。現在,此圖中的流將強制如果工人被分配給n個任務,那麼這些任務的利益與該員工的利益的交集至少爲n。同樣,如果沒有這項任務,可能會有令人滿意的任務,但是沒有任何人能夠完成這項任務。我們可以像要求5一樣處理這個問題:運行Edmonds-Karp來完成任務,如果沒有滿意的任務,將工人的能力增加到他們的興趣節點並重復。

    注意,在這個修改的圖我們不再滿足要求3,作爲一個工人可以被分配給一個任務的多個/所有插槽,如果他們的利益的交集有大小比1,我們可以解決這個問題更大。在興趣節點和任務節點之間添加一列新節點,並刪除這些節點之間的邊。對於每個員工,在新列中爲每個任務插入一個節點(因此每個員工對於每個任務都有自己的節點)。從這些新節點到其右側相應的任務,添加容量爲1的邊。從每個工作人員的興趣節點到該工作人員的任務節點,將每個感興趣的容量爲1的邊添加到每個匹配的任務。

    -

    編輯:讓我試圖澄清這一點。假設-(n)->是n容量的邊。

    以前我們有worker-(1)->task爲每個具有匹配興趣的工作 - 任務對。現在我們有worker-(k)->local interest-(1)->local task-(1)->global task。現在,您可以考慮將任務與工人利益對匹配。第一條邊說,對於一名工人來說,它的每個利益都可以匹配到k任務。第二個優勢是每個工作人員的興趣只能匹配一次到每個工作。第三條邊說,每個任務只能分配給每個工人一次。請注意,您可以將多個流從工作人員推送到本地任務(等於他們感興趣的交集的大小),但由於第三個邊緣,只有1個流從工作人員流向全局任務節點。

    -

    還要注意的是,我們不能真正與一個要求5正確混合此遞增。然而,對於worker-> interest邊緣,我們可以對每個容量{1,2,...,r}運行整個算法一次。然後,我們需要一種方法來對作業進行排序。也就是說,當我們放寬要求5時,我們可以更好地滿足要求6,反之亦然。不過,我還有另一種方法可以放鬆這些限制。


    一種更好的方法來要求放鬆(靈感 - 通過/拍攝 - 從templatetypedef)

    當我們希望能夠放寬多種需求(例如,5和6),我們可以將其模型化爲最小成本最大流量問題。這可能比我上面描述的增量搜索更簡單。

    例如,對於需求5,將所有邊緣成本設置爲0.我們有從源頭到工人的初始邊,容量等於worker's maximum assignments/(sum of all worker's maximum assignments/number of tasks),成本爲0.然後,您可以添加另一個邊該工作人員的能力和成本1.另一種可能性是使用某種累進成本,以便在向工作人員添加任務時向該用戶添加其他任務的成本增加。例如。您可以將工作人員的剩餘容量分成單獨的邊,費用爲1,2,3,4,...

    然後可以在工作節點和需求6的本地感興趣節點之間做類似的事情。加權需要平衡以反映不同需求的相對重要性。

    該方法也足以執行要求4.此外,要求5的成本可能應該使得它們與工人的最大分配成比例。然後分配1組額外的任務是用最大100人員將不及成本,最大2


    複雜性分析分配額外的工人

    n = # of employeesm = # of tasksk = max interests for a single task/workerl = # of interestsj = maximum of maximum assignments

    要求3意味着n = 0(m)。我們還假設l = O(m)j = O(m)

    在較小的圖中(在對請求6進行更改之前),該圖具有n + m + 2 = O(m)頂點和至多n + m + k*min(n, m) = O(km)邊緣。

    的變化之後,它具有2 + n + n * l + n * m + m = O(nm)頂點和n + k * n + k * m * n + n * m + m = O(kmn)邊緣(在技術上,我們可能需要更多的j * n + j * l節點和邊緣,以便有沒有從一個節點到另一個節點的多個邊緣,但是這不會改變漸進綁定)。還要注意,沒有邊需要容量> j。

    使用最小成本最大流量配方,我們可以在O(VEBlogV)中找到解決方案,其中V = # verticesE = # edgesB = max capacity on a single edge。在我們的情況下,這給出O(kjn^2m^2log(nm))

    +0

    有一些標準算法用於求解一些邊上流量下界的最大流問題;這會簡化分析和描述嗎?另外,你能否澄清步驟六的工作原理?看起來這可能會導致一些問題,在現有的法律任務中不再有解決方案。 – templatetypedef 2011-01-22 21:51:41