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

Algorithm 算法:将n个任务分配给k>;n人,每个人都可以执行这些任务的一个子集,algorithm,variable-assignment,jobs,distribute,Algorithm,Variable Assignment,Jobs,Distribute,我正试图为以下问题找到一个有效的解决方案: 问题: 假设我有一些任务(A、A、B、B、C),我有一些人可以执行其中一项或多项任务: 人员1:A,B(人员1可以执行任务A或任务B) 人2:A,C 人物3:A 人4:B,C 人5:A,B 有可能把我所有的任务都交给这些人吗?一个人只能做一件事 可能有多种解决方案,但我只想知道是否有解决方案 我第一次尝试有效地解决这个问题是: 如果一个人只能完成一项任务,请将该任务分配给该人 如果一项任务需要做n次,并且有n个人可以做 此任务,将此任务分配给这n

我正试图为以下问题找到一个有效的解决方案:

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

  • 人员1:A,B(人员1可以执行任务A或任务B)
  • 人2:A,C
  • 人物3:A
  • 人4:B,C
  • 人5:A,B
有可能把我所有的任务都交给这些人吗?一个人只能做一件事

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

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

  • 如果一个人只能完成一项任务,请将该任务分配给该人
  • 如果一项任务需要做n次,并且有n个人可以做 此任务,将此任务分配给这n个人
这足以解决上述问题

  • 2个人可以做B,B需要做两次。
    • 剩下的任务:A、A、C
    • 左边的人:[A,C],[A],[B,C]
  • 2个人可以做一个。
    • 剩下的任务:C
    • 剩余人员:[B、C]
但这还不足以解决更复杂的问题,如: 职位:IGGGFFDDCCBBB 人: ABCDEFG CEI 贝 头孢吉 塞吉 阿德吉 塞吉 词 ADG 贝 DI BCDEFI 阿布德夫 ABEFG BCEGI ACDI 屋宇署 阿贝 BCDEFGI

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


谢谢阅读:)

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

这方面的算法并不十分简单,但可以有效地执行,例如:
是的,有一种有效的算法。这是最大二部匹配问题的一个实例。您要做的是创建一个二部图,其中节点是人员和任务,并且有一条边将每个人与他们能够执行的每个任务连接起来。将人员分配给任务将对应于此图的匹配

这方面的算法并不十分简单,但可以有效地执行,例如:

有效解决这一问题的一种方法是将其表述为一个整体

在人员和他们可以完成的任务之间添加边(容量1)

还可以在起点和每个人之间添加边(容量1)

以及任务和目标之间的边缘(容量=该任务需要完成的次数)

示例Python代码使用:


有效解决这一问题的一种方法是将其表述为一个整体

在人员和他们可以完成的任务之间添加边(容量1)

还可以在起点和每个人之间添加边(容量1)

以及任务和目标之间的边缘(容量=该任务需要完成的次数)

示例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)