我有一个问题要解决,并没有看到任何最佳解决方案:/问题是:
我有n个工人和k个工作。每项工作都由指定数量的工人完成,每个工人对每项工作都有自己的幸福感。我必须制定工作时间表,以便工人尽可能快乐。 所以,我有int [n,k]的数组a1(k> = n)。第i行的第k列包含第i个工作者对第k个工作的偏好(从0到10的数字)。我也有int [k]的数组a2,其中第i个元素包含将要完成这项工作的人数。每个工人都要做同样数量的工作。我必须找到最大可能的幸福总和,知道n> = max(a2)。 我的解决方案是使用递归。为第一个作业组合选择第一个工作人员,向总和添加首选项,检查总和是否高于已找到的最大值,如果是,则转到下一个工作人员。返回时,请检查第一个工作人员的下一个组合等。这适用于少量工作人员,但必须具有高计算复杂度才能解决更大的问题。您有什么想法可以获得更好的解决方案吗?
PS。来自另一个网站的家伙建议我使用匈牙利算法,但它假设n == k,我不知道如何使用n< = k
PS2是一个例子:a1:
job1 job2 job3 job4
wokrer1 1 3 4 2
worker2 9 8 1 2
worker3 6 7 8 9
a2:
job1 job2 job3 job4
count 1 2 2 1
example solution:
worker1: job2, job3 (7)
worker2: job1, job2 (17)
worker3: job3, job4 (17)
sum: 41
答案 0 :(得分:1)
这看起来像我的交通问题。但它可以使用匈牙利算法解决。首先让我们设置匈牙利算法的矩阵。
匈牙利算法用于查找最小总和。要使它解决最大和问题,首先必须反转所有的幸福值。
J1 J2 J3 J4
W1 1 3 4 2
W2 9 8 1 2
W3 6 7 8 9
用矩阵中的最大值减去每个值 该矩阵中的最大值是9。
J1 J2 J3 J4
W1 9-1 9-3 9-4 9-2
W2 9-9 9-8 9-1 9-2
W3 9-6 9-7 9-8 9-9
J1 J2 J3 J4
W1 8 6 5 7
W2 0 1 8 7
W3 3 2 1 0
现在,正如您所指出的,匈牙利算法仅适用于方形矩阵。为了使它在矩形矩阵上工作,我们必须使它成为正方形。我们可以通过添加用零填充的虚拟行或列来完成此操作。
J1 J2 J3 J4
W1 8 6 5 7
W2 0 1 8 7
W3 3 2 1 0
WD 0 0 0 0
现在我们以可用的形式提供它,我们可以解决最小的总和。我将跳到解决方案,因为有关如何使用匈牙利算法的说明在其他地方很容易获得。
W1 -> J3
W2 -> J1
W3 -> J4
WD -> J2 (Except this is a dummy row so it doesn't count.)
我们现在为每个工人分配了一份工作。这是你的第二个阵列发挥作用的地方。
J1 J2 J3 J4
1 2 2 1
我们已将工作人员分配给作业1,3和4,因此我们将从各自的值中减去1。
J1 J2 J3 J4
0 2 1 0
由于我们不再需要任何人做任务1或4,我们也可以从幸福矩阵中删除他们的列。
J2 J3
W1 6 5
W2 1 8
W3 2 1
我们仍然有工作要做,所以我们再次完成这个过程。
添加虚拟列以使矩阵成为正方形。
J2 J3 JD
W1 6 5 0
W2 1 8 0
W3 2 1 0
并解决。请记住,列适用于作业2和3,而不是1和2。
W1 -> JD
W2 -> J2
W3 -> J3
我们现在已经完成了两次算法,并分配了五个工作。
W1 -> J3
W2 -> J1, J2
W3 -> J4, J3
我们现在再次完成整个过程。由于只分配了一个作业,并且有一个人将其分配给(W1只分配了一个作业,但它们都必须分配相同的编号。),我们可以直接找到最终的解决方案。
W1 -> J3, J2
W2 -> J1, J2
W3 -> J4, J3
并且幸福值是:
W1 -> 4 + 3 = 7
W2 -> 9 + 8 = 17
W3 -> 9 + 8 = 17
总共41个。
答案 1 :(得分:0)
使用匈牙利算法的方法是为作业a2[i]
制作i
个顶点。希望a2
数组总和为n
。如果k << n
,那么你可能最好将其制定为最低成本的流通问题。