匈牙利算法

英文版的讲的很详细:

http://www.hungarianalgorithm.com/examplehungarianalgorithm.php

中文版的可以参考该博主:

https://blog.csdn.net/qq_33829154/article/details/62425921


匈牙利算法的流程:

匈牙利算法包含四步。前两步一次执行完,第三步和第三步会重复执行直到最优分配出现。算法的输入是n*n的矩阵,只有非负数。

Step 1: Subtract row minima (减去行最小值)

对于每一行,找到该行的最小值,然后该行的数都减去这个最小值

Step 2: Subtract column minima(减去列最小值)

同样的,对于每一列,找到该列的最小值,然后该列的数都减去这个最小值

Step 3: Cover all zeros with a minimum number of lines(用最少的线覆盖所有的0)

用最少的水平线和垂直线覆盖掉矩阵的所有0元素。如果需要n条线,那么在这些0中就存在最优解。算法结束

如果需要的线<n,继续第四步

Step 4: Create additional zeros(创建额外的0元素)

在第三步的的矩阵中,找到没被线覆盖的行列中的最小的元素,记作k。所有没被覆盖的元素都减去k,被覆盖两次的元素加上k

我们考虑一个例子,其中四个作业(J1、J2、J3和J4)需要由四个工人(W1、W2、W3和W4)执行,每个工人一个作业。下面的矩阵显示了将某个工人分配到某个工作的成本。其目标是使分配的总成本最小化。

 

下面我们将用这个例子来解释匈牙利算法。注意,算法的一般描述可以在这里找到。

Step 1: Subtract row minima

首先我们在每行找到该行的最小值,然后该行的元素都减去这个最小值。比如说在第一行,最小值是69,那么第一行的元素都减去69。结果就是:

Step 2: Subtract column minima

同样地,我们把列元素也检查一下:

Step 3: Cover all zeros with a minimum number of lines

我们现在来决定用最少的水平线和垂直线覆盖到矩阵中的所有0元素,这里我们用3条线就可以了:

因为所需要的线是3条,3<4,那么我们程序没办法停止,继续第4步

Step 4: Create additional zeros

首先,我们发现没被覆盖的元素里面,最小的值是6。那么矩阵中没有被覆盖的值都减去6,而被垂直线和水平线都覆盖的值就加上6

现在我们返回到第三步

Step 3: Cover all zeros with a minimum number of lines

再次,我们来决定水平线和垂直线。这次需要4条线了:

因为所需要的线是4条,4=(n=4),所有在这些0中存在最优解。因此程序停止了。

The optimal assignment

最优的分配:这些0就是最优解,它们覆盖的数字是69、37、11、23

因此,第一个工人应该做job3,第二个工人做job2,第三个工人做job1,第四个工人做job4。最优的cost是:69 + 37 + 11 + 23 = 140.

 

 

附加:

第一步第二部第四部用程序都好写,关键是第三部,怎么写程序找到最少的直线呢?方法:

       (1)对没有Θ的行打√号:;

  (2)对已打√号的行中所含0元素的列打√号;

  (3)再对所有打√号的列中的含有@元素的行打√号;

  (4)重复2、3直到得不出新的打√号的行列为止.

  (5)对没有打√号的行画一横线,有打√号的列画一纵线,这就得到覆盖所有0元素的最少直线数.

如果没看懂请去看链接里的中文博客。

---------------------------END-------------------------------------------------

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

keneyr

老爷~给小的赏点盘缠吧555~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值