KM算法:指派问题(有权二分图2)

指派问题(Assignment problem)

在满足特定指派要求条件下,使指派方案总体效果最佳。(KM算法的另一种理解角度

如:有若干项工作需要分配给若干人(或部门)来完成;有若干项合同需要选择若干个投标者来承包:有若干班级需要安排在若干教室里上课等。

image

(结合参考一的代码和案例观看!!!)

总架构

void HungarianAlgorithm::RunAssignment() {
  (void)step_one();
  (void)step_two();
  int step = 3;
  int path_zero[2];
  while (true)
    switch (step) {
      case 3:
        step = step_three();
        break;
      case 4:
        step = step_four(path_zero);
        break;
      case 5:
        step = step_five(path_zero);
        break;
      case 6:
        step = step_six();
        break;
      case 7:
        return;
      default:
        assert(false);
    }
}

step 1

对于矩阵的每一行,找出最小的元素,并将其从矩阵的每一行中减去;

step 2

在新矩阵中,

​ 1.循环查找零点Z,且满足行或列未被标定的话,Z点标星(M矩阵对应置1),RowCover和ColCover置1;

​ 2.RowCover和ColCover数组分别置0;

step 3

计算标星点的列数,如果等于K(行数和列数的最小值),done;否则,step 4;

step 4

寻找cover行列之外的零点,设为斜点。(没有的话取未覆盖区域最小值,step 6)

​ 1.如果该斜点的行中无星点,step 5;

​ 2.有星点,cover行,并uncover星点列。以此类推,直到没有uncover的零点。保存最小的uncover值,step 6;

step 5

构造一系列交替斜点星点

  • Z0表示step 4中最后发现的斜点,Z1表示Z0同列的星点,Z2表示Z1同行的斜点,以此类推,直到终止于一个斜点

  • 清除路径上的各个星点,斜点变星点,并擦除所有的线,返回step 3;

存在终止于星点的情况,此时,该增广路是不反置的

step 6

  • 未覆盖区域最小值min:覆盖行各元素+min;未覆盖列-min;

  • 返回step 4,不改变斜点、星点和覆盖线;

参数列表

C: cost matrix,m x n,成本矩阵;

k=min(m,n)行列最小数;

Z:矩阵零点;

M: mask matrix,掩膜矩阵,与成本矩阵C同纬度,用来标注C中的星点(1)和斜点(2);

RowCoverColCover:标记成本矩阵C的行或列的记录;

path_row_0path_col_0:step 4中最后一个斜点的行和列;

path_count:路径的长度;

path:记录增广路径上各点的行与列;

参考

1.Munkres' Assignment Algorithm

2.匈牙利算法 (Kuhn-Munkres) 算法

你可能感兴趣的:(KM算法:指派问题(有权二分图2))