具有多个赋值的匈牙利算法

时间:2015-04-09 20:43:17

标签: algorithm optimization minimum hungarian-algorithm

让我们说我们有N个工作岗位和K工人来完成这些工作。但对于一些工作,我们需要2名员工,而对于一些人,我们只需要一名。员工也无法完成所有工作。例如,工人1可以完成工作1,2和5,而不是工作3和4.另外,如果我们雇佣工人1来做工作1,那么我们希望他做第2和第5工作,因为我们已经付了工资。

例如,假设我们有5个工作岗位和6个工人。对于1,2和4工作,我们需要2个人,而对于工作3和5,我们只需要一个。这里是每个工人可以做的工作清单和他需要的工资。

Worker 1 can do jobs 1,3,5 and he requires 1000 dollars. 
Worker 2 can do jobs 1,5 and he requires 2000 dollars. 
Worker 3 can do jobs 1,2 and he requires 1500 dollars. 
Worker 4 can do jobs 2,4 and he requires 2500 dollars. 
Worker 5 can do jobs 4,5 and he requires 1500 dollars. 
Worker 6 can do jobs 3,5 and he requires 1000 dollars. 

经过一些计算和逻辑思考,我们可以得出结论,我们必须雇用1,3,4和5工人,这意味着我们需要支付的最低工资是:1000 + 1500 + 2500 + 1500 = 5500美元。

但是我们如何才能找到一个可以输出该数量的有效算法呢?这让我想起匈牙利算法,但所有这些额外的约束使我无法应用它。

1 个答案:

答案 0 :(得分:2)

我们可以将所有工作的状态表示为三元系统中的数字(2个人剩余2个人,剩下1个人,如果已经完成则为0个人)。现在我们可以计算f(掩模,k)=在第一个k中雇佣一些工人的最小成本,使剩余工作的状态成为掩盖。过渡如下:我们要么去(掩码,k + 1)(不雇用当前的工人),要么去(new_mask,k + 1)(在这种情况下,我们向这个工人支付他的工资并让他做所有的工作他可以的工作)。答案是f(0,K)。

时间复杂度为O(3 ^ N * K * N)。

以下是如何进一步优化它(并摆脱N因素)的想法。我们假设当前的掩码为mask,并且该人可以从另一个mask'开始工作。我们实际上只需将mask添加到mask',但有一个问题:2中的mask1mask'的位置会破碎的。但我们可以修复:对于每个掩码,让我们预先计算包含数字不是allowed_mask的所有位置的二进制掩码2。对于每个人和每个allowed_mask,我们可以预先计算mask'值。现在每个过渡只是一个补充:

for i = 0 ... k - 1
    for mask = 0 ... 3^n - 1
        allowed_mask = precomputed_allowed_mask[mask]
        // make a transition to (i + 1, mask + add_for_allowed_mask[i][allowed_mask])
        // make a transition to (i + 1, mask)

请注意,只有2^n个允许的掩码。因此,此解决方案的时间复杂度为O(3^N * N + T * 2^N * K * N + T * 3^N * K)(第一个术语用于预先计算所有三元掩码的allowed_masks,第二个用于为所有allowed_masks和people预先计算mask',最后一个用于dp本身)。