递归分配任务


Recursion for assigning jobs

这是一个具体的问题,所以我先快速解释一下背景。我正在开发一种软件,它可以为员工分配每天的特定"工作"。为了让他们能胜任这项工作,他们必须接受培训,这样系统就知道每个员工都学过什么,没学过什么。

现在我正在做的是:

foreach ($jobs as $job){
   foreach($employees as $emp){
       if (job doesn't have employee && employee isn't assigned to job && employee has been trained on job){
          assign them;
          break;
       }
   }
}

这在一定程度上起作用,但是有一个问题。考虑下面的简化示例:

有2个工作:"Checkout"answers"Customer Service"

有两个雇员:"Bill"answers"Lucy"。Bill知道这两种工作,Lucy只知道Checkout。

当循环运行时,它将首先寻找工作Checkout的人。它会首先检查Bill,看他能不能完成任务,然后分配给他。这将使他们继续寻找客户服务。它跳过了bill,因为他已经被分配了,并检查了Lucy,但她无法工作!这会导致不必要的培训。

我可以很容易地对它进行编码,这样如果它在所有员工中运行并且没有找到任何人,它就会像这样运行:

//We didn't find anyone, let's look for a potential swap
foreach($employees as $emp){
   if (emp has been trained on job && emp is already assigned something else){
      //Find someone else to work their assigned job, so they can work this one
      foreach($employees as $emp2){
         if ($emp != $emp2 && emp2 can work emp's job && emp2 isn't already assigned anything){
            swap the two;
         }
      }
   }
}

相当简单。但这只适用于两个雇员的交换。如果交换非常复杂,需要移动四个人呢?理想情况下,我想提出一个递归的解决方案,我可以设置一个值$maxDepth = 5或其他。

如果它不能立即找到某人,它将进入深度2,寻找我上面描述的两个人交换。如果仍然不能,它将进入深度3寻找三人交换,等等。

具体来说,这是一个需要最大匹配数的二部图,可以简化为网络流问题,并使用Ford-Fulkerson算法解决。