算法:将n个任务分配给k&n; n个人,每个人都可以执行这些任务的子集

时间:2013-10-16 18:49:33

标签: algorithm variable-assignment jobs distribute

我正在尝试为以下问题找到有效的解决方案:

问题: 假设我有一些任务(A,A,B,B,C),我有一些人可以执行一项或多项任务:

  • person1:A,B(1人可以执行任务A或任务B)
  • person2:A,C
  • person3:A
  • person4:B,C
  • person5:A,B

是否有可能将我的所有任务都交给这些人?一个人只能完成一项任务。

可能有多种解决方案,但我只想知道是否有解决方案。

我第一次有效地解决这个问题的尝试是:

  • 如果一个人只能完成一项任务,则将该任务分配给该人
  • 如果一项任务需要进行n次,并且有n个人可以做 这项任务,将此任务分配给那些人。

这足以解决上述问题。

  • 2人可以做B,B需要做两次。
    • 剩下的任务:A,A,C
    • 留下的人:[A,C],[A],[B,C]
  • 2个人可以做A.
    • 剩下的任务:C
    • 留下的人:[B,C]

但这还不足以解决更复杂的问题,例如: 工作:IGGGFFDDCCBBB 人数: ABCDEFG CEI BEI CEFGI CEGI ADGI CEGI CI ADG BEI DI BCDEFI ABDF ABEFG BCEGI ACDI BD ABE BCDEFGI

有解决这个问题的有效方法吗?我可以用深度优先搜索算法来解决这个问题,但我想知道我是否可以在多项式时间内解决这个问题? 我不禁相信这是一个众所周知的问题,但我一直无法在谷歌上找到它。

感谢您阅读:)

2 个答案:

答案 0 :(得分:1)

有效解决此问题的一种方法是将其表述为maximum flow problem

在人员和他们可以执行的任务之间添加边缘(容量1)。

还在开始和每个人之间添加边缘(容量1)

任务和目的地之间的边缘(容量=需要完成任务的次数)。

使用NetworkX的示例Python代码:

import networkx as nx
from collections import Counter

jobs = 'IGGGFFDDCCBBB'
people = 'ABCDEFG CEI BEI CEFGI CEGI ADGI CEGI CI ADG BEI DI BCDEFI ABDF ABEFG BCEGI ACDI BD ABE BCDEFGI'

G=nx.DiGraph()
for person,tasks in enumerate(people.split()):
    P = 'person'+str(person)
    G.add_edge('start',P,capacity=1.0) # One person can do one thing
    for task in tasks:
        G.add_edge(P,'task'+task,capacity=1.0) # This person can do this task

C = Counter(jobs)
for task,count in C.items():
    G.add_edge('task'+task,'end',capacity=count) # Task appears count times in our job list

print nx.max_flow(G,'start','end') >= len(jobs)

答案 1 :(得分:0)

是的,有一个有效的算法。这是最大二分匹配问题的一个实例。你所做的就是创建一个二分图,其中节点是人和任务,并且每个人都有一条边连接他们能够执行的每个任务。将人员分配给任务将对应于此图表的匹配。

此算法并非完全无关紧要,但可以高效执行,例如: http://www.cs.cmu.edu/~ckingsf/bioinfo-lectures/matching.pdf