匈牙利算法

title: Layman对指派问题的解释.
content: 你有三个工人:吉姆,史提夫和艾伦。 你需要其中一个清洁浴室,另一个打扫地板,第三个洗窗,但他们每个人对各项任务要求不同数目数量的钱。 以最低成本的分配工作的方式是什么? 可以用工人做工的成本矩阵来表示该问题。例如: 当把匈牙利方法应用于上面的表格时,会给出最低成本:为6美元,让吉姆清洁浴室、史提夫打扫地板、艾伦清洗窗户就可以达到这一结果。
title: 设定.
content: 给定一个 formula_3 的非负矩阵,其中第 formula_4 行第 formula_5 列元素表示把第 formula_4 个工人派到第 formula_5个工作的成本。我们必须找到成本最低的工人工作分配。如果目标是找到最高成本的分配,该问题可以将每个成本都换为最高一个成本减去该成本以适应题目。  如果用二分图来阐述该问题可以更容易描述这个算法。对于一个有 formula_8个工人节点(formula_9)与 formula_8个工作节点(formula_11)的完全二分图 formula_12,每条边都有 formula_13 的非负成本。我们要找到最低成本的完美匹配。  如果函数 formula_14 满足对于每个 formula_15 都有 formula_16,则把该函数叫做势。势 formula_17 的值为 formula_18。可以看出,每个完美匹配的成本最低是每个势的值。匈牙利算法找出了完美匹配及与之成本/值相等的势,这证明了两者的最优性。实际上它找到了紧边集的完美匹配:紧边 formula_19 是指对于势 formula_17 满足 formula_21。我们将紧边子图表示为 formula_22。formula_22 中的完美匹配的成本(如果存在)就等于 formula_17的值。
title: 用二分图描述此算法.
content: 在算法中我们维持 formula_22 的势formula_17和方向(表示为 formula_27 ),该方向有从 formula_11到 formula_9 的边构成匹配 formula_30 的性质。初始时,formula_17 处处为 0, 所有边都由 formula_9 指向 formula_11(因此 formula_30 为空)。每一步中,我们或者改变 formula_17 使其值增加, 或者改变方向以得到更多的边。我们保持 formula_30 的所有边都是紧边不发生改变。当 formula_30 为完美匹配时结束。  在一般的步骤中,令 formula_38 和 formula_39 为 formula_30 未覆盖的节点 (则 formula_41 包含 formula_9 中入度为零的节点,而 formula_43 中包含 formula_11 中出度为零的节点)。 令 formula_45 为从 formula_41 只沿紧边的有向路径可到达 formula_27 的节点。可由广度优先搜索求得。  若 formula_48 非空,则将 formula_27 中从 formula_41 到 formula_43 的有向路径反向。则相应匹配数增加1。  若 formula_48 为空,则令 formula_53。formula_54 为正,因为 formula_55 与 formula_56 之间没有紧边。 在 formula_57 中的节点将formula_17增加formula_54 并在 formula_55 中节点将 formula_17减小 formula_54, 得到的formula_17仍然是势。图 formula_22 改变了,但它仍包含formula_30。我们把新的边从formula_9指向formula_11。 由 formula_54 的定义,formula_41 可达的节点集 formula_70 增大(注意到紧边的数量不一定增加)。  我们重复这些步骤直到formula_30为完美匹配,该情形下给出的是最小成本(即时间消耗)的匹配。此版本的运行时间为 formula_1:formula_30 增广 formula_8次, 在 formula_30 不改变的一个阶段中,势最多改变 formula_8 次(因为 formula_70 每次都增加)。改变势所需的时间在 formula_78。
title: 矩阵解释.
content: 给定 formula_79 个工人和任务,以及一个包含分配给每个工人一个任务的成本的 formula_80矩阵,寻找成本最小化分配。  首先把问题写成下面的矩阵形式  其中 formula_82是执行任务 1, 2, 3, 4 的工人。formula_83 分别表示当工人 formula_84 做任务 1, 2, 3, 4 时的时间损失(成本)。对于其他符号也同样适用。该矩阵是方阵,所以每个工人只能执行一个任务。  第 1 步  接下来我们对矩阵的行进行操作。将所有 formula_85 (formula_4 从 1 到 4)中最小的元素取走,并将该行每个元素都减去刚刚取走的元素。这会让该行至少出现一个零(当一行有两个相等的最小元素时会得到多个零)。对此过程为所有行重复。我们现在得到一个每行至少有一个零的矩阵。现在我们尝试给工人指派任务,以使每个工人只做一项任务,并且每个情况的耗散都为零。说明如下。  用 0' 表示的零为已指派的任务。  第 2 步  有时此阶段的该矩阵不能符合指派的要求,例如下面所示矩阵。  在上述情形下,不能做出指派。注意到任务 1 由工人 formula_87 和 formula_88 做都很高效。只是不能把两个工人分配到同一个任务中去。还注意到,没有任何一个工人能有效地做任务 3。 为了克服这个问题,我们对所有列重复上述流程(即每一行所有元素都减去该行最小元素)并检查是否可以完成分配。  大多数情况下,这都会给出结果,但如果仍然是不可行,那么我们需要继续下去。  第 3 步  必须用尽可能少的列或行标记来覆盖矩阵中的所有零。下面的过程是完成这个要求的一种方法:  首先,尽可能多地分配任务。  或者,分配的是第 3 行的 0,就会使第 1 行的 0 被划掉。  现在到了画图的部分。  现在划掉所有已标记的列和未标记的行(第 1 列和第 2, 4 行)。  上述详细的描述只是画出覆盖所有 0 的(直、行)线的一种方法。也可以使用其他方法。  第 4 步  现在删除已画线的行和列。这将留下一个矩阵如下:  返回到步骤 1,然后重复这个过程,直到矩阵是空的。
title: 外部链接.
title: 实现.
content: (请注意,并非所有这些都满足 formula_2 时间约束。)

Summary: 匈牙利算法是一种在多项式时间内求解任务分配问题的组合优化算法,并推动了后来的原始对偶方法。美国数学家哈罗德·库恩于1955年提出该算法。此算法之所以被称作匈牙利算法,是因为算法很大一部分是基于以前匈牙利数学家Dénes Kőnig和Jenő Egerváry的工作之上创建起来的。

Hungarian algorithm: The Hungarian method is a combinatorial optimization algorithm that solves the assignment problem in polynomial time and which anticipated later primal-dual methods. It was developed and published in 1955 by Harold Kuhn, who gave the name "Hungarian method" because the algorithm was largely based on the earlier works of two Hungarian mathematicians: Dénes Kőnig and Jenő Egerváry.