Php 分配作业的递归

Php 分配作业的递归,php,cakephp,loops,recursion,logic,Php,Cakephp,Loops,Recursion,Logic,这是一个具体的问题,因此我将首先快速解释背景。我正在开发一种软件,可以为员工分配一天的特定“工作”。为了让他们工作,他们必须接受培训,这样系统就知道每个员工都接受过哪些培训,哪些没有接受过培训 现在我所做的是: foreach ($jobs as $job){ foreach($employees as $emp){ if (job doesn't have employee && employee isn't assigned to job &&am

这是一个具体的问题,因此我将首先快速解释背景。我正在开发一种软件,可以为员工分配一天的特定“工作”。为了让他们工作,他们必须接受培训,这样系统就知道每个员工都接受过哪些培训,哪些没有接受过培训

现在我所做的是:

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;
       }
   }
}
这在某种程度上是可行的,但是存在一个问题。考虑下面的简化例子。

有两种工作:“结账”和“客户服务”

有两名员工:“比尔”和“露西”。比尔两份工作都懂,露西只懂结帐

当循环运行时,它将首先查找要结帐的人。它会先看看比尔,看看他能不能工作,然后分配给他。这将使他们继续寻找客户服务。它跳过了比尔,因为他已经被分配了,并且检查了露西,但她不能工作!这会导致不必要的培训

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

//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算法解决。这是一个很好的解释。

这是背包问题的一个变种。wiki页面包含伪解决方案,也许有人可以帮助你。正如MaX所说,这个问题是NP完全问题。。。你的贪婪算法会给你带来麻烦。您可能需要考虑一个动态编程解决方案,它将有效地查看所有可能分配的子集,但以智能化的方式进行记忆。我一定会调查这些资源,非常感谢。斯维茨基,出于好奇,你说我的算法贪婪是什么意思?所谓贪婪算法,我指的是一种在每一步都尽可能做到最好的算法,但不能为了更好的整体结果而做出短期牺牲。示例:您的算法总是将工作分配给第一个自由员工,但无法知道它不应该为工作1选择Bill,因为在最佳解决方案中,工作2需要他。不明白为什么每个人都在考虑背包问题。在我看来,这是一个作业问题。可以使用O(n^3)或O(n^4)中的匈牙利算法求解。(维基百科的解释不是很好,希望你能通过谷歌搜索找到更好的解释。)这几乎是完美的!我唯一的问题是,你是否听说过一种方法,使它不是所有的边都相等。也就是说,一条边比另一条边更理想,但如果需要,较小的边仍然是一个选项。我最终使用了基于最大流量最小成本的改进版Ford Fulkerson算法。匈牙利算法也是一个很好的解决方案。谢谢找到解决方案的荣誉!:我不知道福特·富尔克森是如何处理权重的,因为在这种情况下首先想到的是匈牙利算法。这是正确的。我在下面提交的答案不正确,我已将其标记为删除。向上投票,但您需要提供链接,而不仅仅是提供链接。这可以防止linkrot。