匈牙利算法讲解

简介

  • 匈牙利算法是一种在多项式时间内求解任务分配问题的组合优化算法,如果使用暴力穷举求解分配解的话,则是一个NP的问题。
  • 任务(目标):假设一个非负矩阵,第i行第j列的元素表示第i个工人完成第j个任务需要耗费的精力(时间等),希望找到一个最佳分配,使得所有工人完成所有的任务,同时总消耗量(cost)最小化。
  • 匈牙利算法的时间复杂度是 O(N3)O ( N 3 ) 的
步骤
  • 给定n个工人和任务,以及包含分配给每个工人一个任务的成本的 n×nn × n 矩阵,寻找成本最小化分配。
第一步
  • 对矩阵所有行,将该行所有数减去该行最小的值,得到新的矩阵,新矩阵中每行至少有一个0,如果他们都分配在不同的列上,则结束分配。否则进行第二步。
第二步
  • 对于第一步得到的矩阵,对于其所有列,减去该列的最小值,因此每行每列至少包含一个0,大部分情况下,这一步可以完成分配,如果不行,则进行第三步。、
第三步
  • 使用尽可能少的行或列来覆盖矩阵中的所有0,一种可行的方法如下:
    • 尽可能多地分配任务。即从第一行开始,如果有0就分配,同时划掉这一行和这一列;之后的行中如果有不能分配的,则不进行分配。
    • 画图
      • 标记所有未分配的行
      • 标记所有新标记的行中0所在的对应列。
      • 标记所有在新标记的列中0所在的行。
      • 对所有未分配的行重复上述过程。
    • 经过上述步骤,所有的0都能被以最小的线所覆盖。
第四步
  • 从上一步中未被覆盖的元素中找到最小值,然后把这些元素都减去这个最小值,给直线交叉点的元素加上这一最小值。
第五步
  • 重复第三步和第四步,直到所有任务都被分配。
注意
  • 第三步有很多做法,下面参考链接中的做法也不尽相同。
参考链接
  • https://blog.csdn.net/u011837761/article/details/52058703
  • https://zh.wikipedia.org/wiki/%E5%8C%88%E7%89%99%E5%88%A9%E7%AE%97%E6%B3%95

    推荐阅读