MATLAB实例:Munkres指派算法

作者:凯鲁嘎吉 - 博客园 http://www.cnblogs.com/kailugaji/

1. 指派问题陈述

指派问题涉及将机器分配给任务,将工人分配给工作,将足球运动员分配给职位等。目标是确定最佳分配,例如,使总成本最小化或使团队效率最大化。指派问题是组合优化领域中的一个基本问题。

例如,假设我们有四个工作需要由四个工作人员执行。因为每个工人都有不同的技能,所以执行工作所需的时间取决于分配给该工人的工人。

下面的矩阵显示了工人和工作的每种组合所需的时间(以分钟为单位)。作业用J1,J2,J3和J4表示,工人用W1,W2,W3和W4表示。

  J1 J2 J3 J4
W1 82 83 69 92
W2 77 37 49 92
W3 11 69 5 86
W4 8 9 98 23

每个工人应仅执行一项工作,目标是最大程度地减少执行所有工作所需的总时间。

事实证明,将工人1分配给作业3,将工人2分配给作业2,将工人3分配给作业1,将工人4分配给作业4是最佳选择。那么,总时间为69 + 37 + 11 + 23 = 140分钟。所有其他任务导致需要更多时间。

2. Munkres指派算法MATLAB程序

munkres.m

  1. function [assignment,cost] = munkres(costMat)
  2. % MUNKRES Munkres Assign Algorithm
  3. %
  4. % [ASSIGN,COST] = munkres(COSTMAT) returns the optimal assignment in ASSIGN
  5. % with the minimum COST based on the assignment problem represented by the
  6. % COSTMAT, where the (i,j)th element represents the cost to assign the jth
  7. % job to the ith worker.
  8. %
  9.  
  10. % This is vectorized implementation of the algorithm. It is the fastest
  11. % among all Matlab implementations of the algorithm.
  12.  
  13. % Examples
  14. % Example 1: a 5 x 5 example
  15. %{
  16. [assignment,cost] = munkres(magic(5));
  17. [assignedrows,dum]=find(assignment);
  18. disp(assignedrows'); % 3 2 1 5 4
  19. disp(cost); %15
  20. %}
  21. % Example 2: 400 x 400 random data
  22. %{
  23. n=5;
  24. A=rand(n);
  25. tic
  26. [a,b]=munkres(A);
  27. toc
  28. %}
  29.  
  30. % Reference:
  31. % "Munkres' Assignment Algorithm, Modified for Rectangular Matrices",
  32. % http://csclab.murraystate.edu/bob.pilgrim/445/munkres.html
  33.  
  34. % version 1.0 by Yi Cao at Cranfield University on 17th June 2008
  35.  
  36. assignment = false(size(costMat));
  37. cost = 0;
  38.  
  39. costMat(costMat~=costMat)=Inf;
  40. validMat = costMat<Inf;
  41. validCol = any(validMat);
  42. validRow = any(validMat,2);
  43.  
  44. nRows = sum(validRow);
  45. nCols = sum(validCol);
  46. n = max(nRows,nCols);
  47. if ~n
  48. return
  49. end
  50.  
  51. dMat = zeros(n);
  52. dMat(1:nRows,1:nCols) = costMat(validRow,validCol);
  53.  
  54. %*************************************************
  55. % Munkres' Assignment Algorithm starts here
  56. %*************************************************
  57.  
  58. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  59. % STEP 1: Subtract the row minimum from each row.
  60. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  61. dMat = bsxfun(@minus, dMat, min(dMat,[],2));
  62.  
  63. %**************************************************************************
  64. % STEP 2: Find a zero of dMat. If there are no starred zeros in its
  65. % column or row start the zero. Repeat for each zero
  66. %**************************************************************************
  67. zP = ~dMat;
  68. starZ = false(n);
  69. while any(zP(:))
  70. [r,c]=find(zP,1);
  71. starZ(r,c)=true;
  72. zP(r,:)=false;
  73. zP(:,c)=false;
  74. end
  75.  
  76. while 1
  77. %**************************************************************************
  78. % STEP 3: Cover each column with a starred zero. If all the columns are
  79. % covered then the matching is maximum
  80. %**************************************************************************
  81. primeZ = false(n);
  82. coverColumn = any(starZ);
  83. if ~any(~coverColumn)
  84. break
  85. end
  86. coverRow = false(n,1);
  87. while 1
  88. %**************************************************************************
  89. % STEP 4: Find a noncovered zero and prime it. If there is no starred
  90. % zero in the row containing this primed zero, Go to Step 5.
  91. % Otherwise, cover this row and uncover the column containing
  92. % the starred zero. Continue in this manner until there are no
  93. % uncovered zeros left. Save the smallest uncovered value and
  94. % Go to Step 6.
  95. %**************************************************************************
  96. zP(:) = false;
  97. zP(~coverRow,~coverColumn) = ~dMat(~coverRow,~coverColumn);
  98. Step = 6;
  99. while any(any(zP(~coverRow,~coverColumn)))
  100. [uZr,uZc] = find(zP,1);
  101. primeZ(uZr,uZc) = true;
  102. stz = starZ(uZr,:);
  103. if ~any(stz)
  104. Step = 5;
  105. break;
  106. end
  107. coverRow(uZr) = true;
  108. coverColumn(stz) = false;
  109. zP(uZr,:) = false;
  110. zP(~coverRow,stz) = ~dMat(~coverRow,stz);
  111. end
  112. if Step == 6
  113. % *************************************************************************
  114. % STEP 6: Add the minimum uncovered value to every element of each covered
  115. % row, and subtract it from every element of each uncovered column.
  116. % Return to Step 4 without altering any stars, primes, or covered lines.
  117. %**************************************************************************
  118. M=dMat(~coverRow,~coverColumn);
  119. minval=min(min(M));
  120. if minval==inf
  121. return
  122. end
  123. dMat(coverRow,coverColumn)=dMat(coverRow,coverColumn)+minval;
  124. dMat(~coverRow,~coverColumn)=M-minval;
  125. else
  126. break
  127. end
  128. end
  129. %**************************************************************************
  130. % STEP 5:
  131. % Construct a series of alternating primed and starred zeros as
  132. % follows:
  133. % Let Z0 represent the uncovered primed zero found in Step 4.
  134. % Let Z1 denote the starred zero in the column of Z0 (if any).
  135. % Let Z2 denote the primed zero in the row of Z1 (there will always
  136. % be one). Continue until the series terminates at a primed zero
  137. % that has no starred zero in its column. Unstar each starred
  138. % zero of the series, star each primed zero of the series, erase
  139. % all primes and uncover every line in the matrix. Return to Step 3.
  140. %**************************************************************************
  141. rowZ1 = starZ(:,uZc);
  142. starZ(uZr,uZc)=true;
  143. while any(rowZ1)
  144. starZ(rowZ1,uZc)=false;
  145. uZc = primeZ(rowZ1,:);
  146. uZr = rowZ1;
  147. rowZ1 = starZ(:,uZc);
  148. starZ(uZr,uZc)=true;
  149. end
  150. end
  151.  
  152. % Cost of assignment
  153. assignment(validRow,validCol) = starZ(1:nRows,1:nCols);
  154. cost = sum(costMat(assignment));

demo_munkres.m

  1. A=[82,83,69,92;77,37,49,92;11,69,5,86;8,9,98,23];
  2. [assignment,cost]=munkres(A)
  3. [assignedrows,dum]=find(assignment);
  4. order=assignedrows'

3. 指派结果

  1. >> demo_munkres
  2.  
  3. assignment =
  4.  
  5. 4×4 logical 数组
  6.  
  7. 0 0 1 0
  8. 0 1 0 0
  9. 1 0 0 0
  10. 0 0 0 1
  11.  
  12. cost =
  13.  
  14. 140
  15.  
  16. order =
  17.  
  18. 3 2 1 4

4. 参考文献

[1]  Munkres' Assignment Algorithm  Modified for Rectangular Matrices

[2] Munkres Assignment Algorithm

[3] Hungarian algorithm:The assignment problem

MATLAB实例:Munkres指派算法的更多相关文章

  1. MATLAB实例:为匹配真实标签,对训练得到的标签进行调整

    MATLAB实例:为匹配真实标签,对训练得到的标签进行调整 作者:凯鲁嘎吉 - 博客园 http://www.cnblogs.com/kailugaji/ 1. MATLAB程序 munkres.m ...

  2. MATLAB实例:聚类初始化方法与数据归一化方法

    MATLAB实例:聚类初始化方法与数据归一化方法 作者:凯鲁嘎吉 - 博客园 http://www.cnblogs.com/kailugaji/ 1. 聚类初始化方法:init_methods.m f ...

  3. MATLAB实例:散点密度图

    MATLAB实例:散点密度图 作者:凯鲁嘎吉 - 博客园http://www.cnblogs.com/kailugaji/ MATLAB绘制用颜色表示数据密度的散点图 数据来源:MATLAB中“fit ...

  4. MATLAB实例:聚类网络连接图

    MATLAB实例:聚类网络连接图 作者:凯鲁嘎吉 - 博客园 http://www.cnblogs.com/kailugaji/ 本文给出一个简单实例,先生成2维高斯数据,得到数据之后,用模糊C均值( ...

  5. 非刚性图像配准 matlab简单示例 demons算法

    2011-05-25 17:21 非刚性图像配准 matlab简单示例 demons算法, % Clean clc; clear all; close all; % Compile the mex f ...

  6. 基于MATLAB的人脸识别算法的研究

    基于MATLAB的人脸识别算法的研究 作者:lee神 现如今机器视觉越来越盛行,从智能交通系统的车辆识别,车牌识别到交通标牌的识别:从智能手机的人脸识别的性别识别:如今无人驾驶汽车更是应用了大量的机器 ...

  7. 基于MATLAB的腐蚀膨胀算法实现

    本篇文章要分享的是基于MATLAB的腐蚀膨胀算法实现,腐蚀膨胀是形态学图像处理的基础,腐蚀在二值图像的基础上做“收缩”或“细化”操作,膨胀在二值图像的基础上做“加长”或“变粗”的操作. 什么是二值图像 ...

  8. MATLAB实例:新建文件夹,保存.mat文件并保存数据到.txt文件中

    MATLAB实例:新建文件夹,保存.mat文件并保存数据到.txt文件中 作者:凯鲁嘎吉 - 博客园 http://www.cnblogs.com/kailugaji/ 用MATLAB实现:指定路径下 ...

  9. MATLAB实例:求相关系数、绘制热图并找到强相关对

    MATLAB实例:求相关系数.绘制热图并找到强相关对 作者:凯鲁嘎吉 - 博客园 http://www.cnblogs.com/kailugaji/ 用MATLAB编程,求给定数据不同维度之间的相关系 ...

随机推荐

  1. 字符串模式匹配——KMP算法

    KMP算法匹配字符串 朴素匹配算法   字符串的模式匹配的方法刚开始是朴素匹配算法,也就是经常说的暴力匹配,说白了就是用子串去和父串一个一个匹配,从父串的第一个字符开始匹配,如果匹配到某一个失配了,就 ...

  2. Burp Suite渗透操作指南 【暴力破解】

    1.1 Intruder高效暴力破解 其实更喜欢称Intruder爆破为Fuzzing.Intruder支持多种爆破模式.分别是:单一字典爆破.多字段相同字典爆破.多字典意义对应爆破.聚合式爆破.最常 ...

  3. swift声明属性为某个类型同时遵循某协议

    swift声明属性为某个类型同时遵循某协议 var instanse:(协议A & 类B)

  4. 5、netty第四个例子,空闲检测handle

    netty可支持空闲检测的处理器,用于心态检测,当服务器端超出等待时间,没发生事件时,会触发handler中的方法 userEventTriggered. initializer import io. ...

  5. [Go] 利用函数类型实现封装中的回调

    当进行业务逻辑开发的时候,经常要进行封装,封装成独立的类文件,在类文件的属性中预留出函数类型的API 在调用该类文件中某些方法的时候,也根据业务需要调用类属性中的函数, 在主业务中可以传递特定的函数注 ...

  6. [Go] golang定时器的使用

    golang中的定时器是使用的chanel阻塞来实现的,主要使用到了time包中的内容,如果有多个定时器的channel,为了防止阻塞,可以使用select来获取遍历channel 定时器获取的cha ...

  7. 【问题解决】vim 打开文档后提醒 E325: ATTENTION 怎么办?

    这是经典的 vi/vim 的报错情形. 在 Linux 下,使用 vim 或是 vi 查看文件时,可能每次都会出现下面贴出的 E325 错误提醒,然后按 E 进行 Edit anyway 才能继续读写 ...

  8. robotframework框架 - 在Pycharm当中编写RobotFramework测试用例

    众所周知,pycharm是个写python极好用的编辑器.也可以装很多的插件来完成各种骚操作. 某一天,心血来潮在pycharm的插件库里,搜索了一下robot,恩,发现有支持robotframewo ...

  9. Linux基础 —基础要点

    一.请简述Linux安装时的两个必备分区.挂载点和类型. 一般情况下,安装红旗Linux需要两个必备分区,即一个根文件系统分区,挂载点(/),类型为ext3.ext2或reiserfs:一个交换分区, ...

  10. day96_11_28 mongoDB与scrapy框架

    一.mongodb mongodb是一个面向文档的数据库,而不是关系型数据库.不采用关系型是为了获得更好的扩展性. 它与mysql的区别在于它没有表连接,但是可以通过其他办法实现. 安装数据库. 上官 ...