基于技能公平地为工人分配任务的算法

时间:2011-01-21 23:41:59

标签: algorithm task

(在有人问之前,这不是作业。)

我有一组有兴趣的工人,即:

  • Bob:Java,XML,Ruby

  • Susan:Java,HTML,Python

  • Fred:Python,Ruby

  • Sam:Java,Ruby

(每个工人实际上有10-25个“利益”的范围,我有大约40-50个工人)

与此同时,我有一大堆需要在工人中分配的任务。必须将每个任务分配给至少 3个工作人员,并且工作人员必须至少匹配任务中的一个:

任务1:Ruby,XML 任务2:XHTML,Python

等等。所以鲍勃,弗雷德或萨姆可以得到任务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))。
  • 为每个工作人员分配各种任务,因此如果Susan列出了4个兴趣,那么她将获得包含4个兴趣的任务(而不是让10个任务都具有相同的兴趣)

迄今为止最困难的方面是处理这些问题:

  • 与少数相应工人有兴趣的任务
  • 兴趣不大的工人,尤其是
  • 拥有少量兴趣的工人,其任务相对较少

4 个答案:

答案 0 :(得分:6)

答案 1 :(得分:3)

对于难以找到直接解决方案的问题,使用近似算法,评估函数和改进解决方案的方法可能是个好主意。有多种方法,例如genetic algorithmssimulated annealing

基本思想是使用某种简单的算法(例如贪婪算法)来获取模糊可用的内容并进行随机修改,保留那些可以提高评估分数并丢弃那些使其更糟糕的修改。< / p>

使用遗传算法生成一组例如100个随机解决方案并对其进行评分并保持最佳状态以产生新一代解决方案,其特征与前几代相似,但具有一些随机突变。

对于模拟退火,接受稍差的解决方案的可能性最初很高,但随着时间的推移而降低。这样可以降低早期陷入局部优化的风险。

答案 2 :(得分:1)

所以我给了这个问题一些想法,我认为你可以通过将它减少到min-cost max-flow的实例来获得一个好的解决方案(对于#34; good&#34;的某些定义)(参见{例如{3}}。这个想法如下。假设您作为输入给出了一组工作J,每个工作J都有一套必要的技能,还有一组工人W,每个工人都有一套才能。每个工人也会得到一个常数k_i,表示你希望他们做多少工作,以及一个常数m_i表示你可以分配给他们的最大工作数。您的目标是将工作分配给工人,使得每个工作都由具有技能的工人完成,工人不会超过m_i工作,并且工作人数超过&#34;工人完成的工作被最小化。例如,如果re是五个工人,每个人都想完成四个任务并且负载是平衡的,那么两个工人做四个工作,一个做三个,一个做五个,总多余是一个,因为一个工人再做一个工作比预期的要好。

减少如下。现在,我们将忽略平衡要求,只看汤姆如何将其减少到最大流量;我们将在最后添加负载平衡。构造具有指定的起始节点s和宿节点t的图G.为每个作业j和每个工作人员添加一个节点。从s到成本为零且容量为1的这些j节点中的每一个都存在边缘。从每个w节点到t还将存在成本为零且容量为m_i的边缘。最后,对于每个工作j和工人w,如果工人w具有完成工作j所需的才能,则从j到w存在成本为零和容量为1的优势。

我们的想法是,我们希望通过j和w节点将流从s推送到t,使得通过某个j节点到w节点的每个流路径意味着应该将job j赋予worker w。从s到j节点的边缘容量限制确保最多一个流量单位进入j节点,因此作业最多只分配一次。从w节点到节点t的边缘的容量限制防止每个工作者被分配太多次。由于所有容量都是积分的,因此从s到t存在积分最大流量,因此该图中的最大流量对应于工作人员的工作分配,这些工作是合法的,并且不超过任何工人的最大值加载。您可以通过查看图表中的总流量来检查是否已分配所有作业;如果它等于作业数量,则它们都被分配了。

然而,上述结构对平衡工人负荷没有任何作用。为了解决这个问题,我们稍微修改一下这个结构。相反,对于每个w节点,不是从每个w节点到t的边缘,而是向图形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节点分流到t的流程是免费的,因此工作人员可以承担k_i工作而不会产生费用。之后的任何工作都必须通过e路由,每过一个流量单位就需要花费一个。在此新图表中查找最大流量仍然确定了分配,但在图表中查找最小成本最大流量可以找到最小化分配给工人的多余工作的分配。

最小成本最大流量可以通过一些众所周知的算法在多项式时间内求解,所以希望这是一个有用的答案!

答案 3 :(得分:1)

尝试将您的任务映射到stable marriage problem。任务成为未来的妻子,你的员工成为追求者。

您可能希望添加一些额外的算法来为员工分配每项任务的首选项,反之亦然 - 您可以为每项任务的组件分配一些理想的熟练程度,然后让您的员工对每项任务进行排名。您可以为每个工作人员拥有的每个组件分配熟练程度,并使用它来获得工作人员中的每个任务偏好。

获得首选项后,运行算法,发布结果,然后允许人们成对应用于交换作业 - 毕竟这是一个人的问题,当人们有一定程度的控制。