经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » MATLAB » 查看文章
MATLAB实例:Munkres指派算法
来源:cnblogs  作者:凯鲁嘎吉  时间:2019/10/31 8:56:58  对本文有异议

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. dMat = zeros(n);
  51. dMat(1:nRows,1:nCols) = costMat(validRow,validCol);
  52.  
  53. %*************************************************
  54. % Munkres' Assignment Algorithm starts here
  55. %*************************************************
  56.  
  57. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  58. % STEP 1: Subtract the row minimum from each row.
  59. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  60. dMat = bsxfun(@minus, dMat, min(dMat,[],2));
  61.  
  62. %**************************************************************************
  63. % STEP 2: Find a zero of dMat. If there are no starred zeros in its
  64. % column or row start the zero. Repeat for each zero
  65. %**************************************************************************
  66. zP = ~dMat;
  67. starZ = false(n);
  68. while any(zP(:))
  69. [r,c]=find(zP,1);
  70. starZ(r,c)=true;
  71. zP(r,:)=false;
  72. zP(:,c)=false;
  73. end
  74.  
  75. while 1
  76. %**************************************************************************
  77. % STEP 3: Cover each column with a starred zero. If all the columns are
  78. % covered then the matching is maximum
  79. %**************************************************************************
  80. primeZ = false(n);
  81. coverColumn = any(starZ);
  82. if ~any(~coverColumn)
  83. break
  84. end
  85. coverRow = false(n,1);
  86. while 1
  87. %**************************************************************************
  88. % STEP 4: Find a noncovered zero and prime it. If there is no starred
  89. % zero in the row containing this primed zero, Go to Step 5.
  90. % Otherwise, cover this row and uncover the column containing
  91. % the starred zero. Continue in this manner until there are no
  92. % uncovered zeros left. Save the smallest uncovered value and
  93. % Go to Step 6.
  94. %**************************************************************************
  95. zP(:) = false;
  96. zP(~coverRow,~coverColumn) = ~dMat(~coverRow,~coverColumn);
  97. Step = 6;
  98. while any(any(zP(~coverRow,~coverColumn)))
  99. [uZr,uZc] = find(zP,1);
  100. primeZ(uZr,uZc) = true;
  101. stz = starZ(uZr,:);
  102. if ~any(stz)
  103. Step = 5;
  104. break;
  105. end
  106. coverRow(uZr) = true;
  107. coverColumn(stz) = false;
  108. zP(uZr,:) = false;
  109. zP(~coverRow,stz) = ~dMat(~coverRow,stz);
  110. end
  111. if Step == 6
  112. % *************************************************************************
  113. % STEP 6: Add the minimum uncovered value to every element of each covered
  114. % row, and subtract it from every element of each uncovered column.
  115. % Return to Step 4 without altering any stars, primes, or covered lines.
  116. %**************************************************************************
  117. M=dMat(~coverRow,~coverColumn);
  118. minval=min(min(M));
  119. if minval==inf
  120. return
  121. end
  122. dMat(coverRow,coverColumn)=dMat(coverRow,coverColumn)+minval;
  123. dMat(~coverRow,~coverColumn)=M-minval;
  124. else
  125. break
  126. end
  127. end
  128. %**************************************************************************
  129. % STEP 5:
  130. % Construct a series of alternating primed and starred zeros as
  131. % follows:
  132. % Let Z0 represent the uncovered primed zero found in Step 4.
  133. % Let Z1 denote the starred zero in the column of Z0 (if any).
  134. % Let Z2 denote the primed zero in the row of Z1 (there will always
  135. % be one). Continue until the series terminates at a primed zero
  136. % that has no starred zero in its column. Unstar each starred
  137. % zero of the series, star each primed zero of the series, erase
  138. % all primes and uncover every line in the matrix. Return to Step 3.
  139. %**************************************************************************
  140. rowZ1 = starZ(:,uZc);
  141. starZ(uZr,uZc)=true;
  142. while any(rowZ1)
  143. starZ(rowZ1,uZc)=false;
  144. uZc = primeZ(rowZ1,:);
  145. uZr = rowZ1;
  146. rowZ1 = starZ(:,uZc);
  147. starZ(uZr,uZc)=true;
  148. end
  149. end
  150.  
  151. % Cost of assignment
  152. assignment(validRow,validCol) = starZ(1:nRows,1:nCols);
  153. 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.  
  13. cost =
  14.  
  15. 140
  16.  
  17.  
  18. order =
  19.  
  20. 3 2 1 4

4. 参考文献

[1]  Munkres' Assignment Algorithm  Modified for Rectangular Matrices

[2] Munkres Assignment Algorithm

[3] Hungarian algorithm:The assignment problem

原文链接:http://www.cnblogs.com/kailugaji/p/11765596.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号