设为首页收藏本站

EPS数据狗论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 1788|回复: 0

MATLAB实例:Munkres指派算法

[复制链接]

36

主题

375

金钱

563

积分

初级用户

发表于 2019-11-8 15:21:02 | 显示全部楼层 |阅读模式

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

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

下面的矩阵显示了工人和工作的每种组合所需的时间(以分钟为单位)。作业用J1,J2,J3和J4表示,工人用W1,W2,W3和W4表示。
1.png
每个工人应仅执行一项工作,目标是最大程度地减少执行所有工作所需的总时间。

    事实证明,将工人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. % This is vectorized implementation of the algorithm. It is the fastest
  10. % among all Matlab implementations of the algorithm.

  11. % Examples
  12. % Example 1: a 5 x 5 example
  13. %{
  14. [assignment,cost] = munkres(magic(5));
  15. [assignedrows,dum]=find(assignment);
  16. disp(assignedrows'); % 3 2 1 5 4
  17. disp(cost); %15
  18. %}
  19. % Example 2: 400 x 400 random data
  20. %{
  21. n=5;
  22. A=rand(n);
  23. tic
  24. [a,b]=munkres(A);
  25. toc               
  26. %}

  27. % Reference:
  28. % "Munkres' Assignment Algorithm, Modified for Rectangular Matrices",
  29. % http://csclab.murraystate.edu/bob.pilgrim/445/munkres.html

  30. % version 1.0 by Yi Cao at Cranfield University on 17th June 2008

  31. assignment = false(size(costMat));
  32. cost = 0;

  33. costMat(costMat~=costMat)=Inf;
  34. validMat = costMat<Inf;
  35. validCol = any(validMat);
  36. validRow = any(validMat,2);

  37. nRows = sum(validRow);
  38. nCols = sum(validCol);
  39. n = max(nRows,nCols);
  40. if ~n
  41.     return
  42. end
  43.      
  44. dMat = zeros(n);
  45. dMat(1:nRows,1:nCols) = costMat(validRow,validCol);

  46. %*************************************************
  47. % Munkres' Assignment Algorithm starts here
  48. %*************************************************

  49. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  50. %   STEP 1: Subtract the row minimum from each row.
  51. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  52. dMat = bsxfun(@minus, dMat, min(dMat,[],2));

  53. %**************************************************************************
  54. %   STEP 2: Find a zero of dMat. If there are no starred zeros in its
  55. %           column or row start the zero. Repeat for each zero
  56. %**************************************************************************
  57. zP = ~dMat;
  58. starZ = false(n);
  59. while any(zP(:))
  60.     [r,c]=find(zP,1);
  61.     starZ(r,c)=true;
  62.     zP(r,:)=false;
  63.     zP(:,c)=false;
  64. end

  65. while 1
  66. %**************************************************************************
  67. %   STEP 3: Cover each column with a starred zero. If all the columns are
  68. %           covered then the matching is maximum
  69. %**************************************************************************
  70.     primeZ = false(n);
  71.     coverColumn = any(starZ);
  72.     if ~any(~coverColumn)
  73.         break
  74.     end
  75.     coverRow = false(n,1);
  76.     while 1
  77.         %**************************************************************************
  78.         %   STEP 4: Find a noncovered zero and prime it.  If there is no starred
  79.         %           zero in the row containing this primed zero, Go to Step 5.
  80.         %           Otherwise, cover this row and uncover the column containing
  81.         %           the starred zero. Continue in this manner until there are no
  82.         %           uncovered zeros left. Save the smallest uncovered value and
  83.         %           Go to Step 6.
  84.         %**************************************************************************
  85.         zP(:) = false;
  86.         zP(~coverRow,~coverColumn) = ~dMat(~coverRow,~coverColumn);
  87.         Step = 6;
  88.         while any(any(zP(~coverRow,~coverColumn)))
  89.             [uZr,uZc] = find(zP,1);
  90.             primeZ(uZr,uZc) = true;
  91.             stz = starZ(uZr,:);
  92.             if ~any(stz)
  93.                 Step = 5;
  94.                 break;
  95.             end
  96.             coverRow(uZr) = true;
  97.             coverColumn(stz) = false;
  98.             zP(uZr,:) = false;
  99.             zP(~coverRow,stz) = ~dMat(~coverRow,stz);
  100.         end
  101.         if Step == 6
  102.             % *************************************************************************
  103.             % STEP 6: Add the minimum uncovered value to every element of each covered
  104.             %         row, and subtract it from every element of each uncovered column.
  105.             %         Return to Step 4 without altering any stars, primes, or covered lines.
  106.             %**************************************************************************
  107.             M=dMat(~coverRow,~coverColumn);
  108.             minval=min(min(M));
  109.             if minval==inf
  110.                 return
  111.             end
  112.             dMat(coverRow,coverColumn)=dMat(coverRow,coverColumn)+minval;
  113.             dMat(~coverRow,~coverColumn)=M-minval;
  114.         else
  115.             break
  116.         end
  117.     end
  118.     %**************************************************************************
  119.     % STEP 5:
  120.     %  Construct a series of alternating primed and starred zeros as
  121.     %  follows:
  122.     %  Let Z0 represent the uncovered primed zero found in Step 4.
  123.     %  Let Z1 denote the starred zero in the column of Z0 (if any).
  124.     %  Let Z2 denote the primed zero in the row of Z1 (there will always
  125.     %  be one).  Continue until the series terminates at a primed zero
  126.     %  that has no starred zero in its column.  Unstar each starred
  127.     %  zero of the series, star each primed zero of the series, erase
  128.     %  all primes and uncover every line in the matrix.  Return to Step 3.
  129.     %**************************************************************************
  130.     rowZ1 = starZ(:,uZc);
  131.     starZ(uZr,uZc)=true;
  132.     while any(rowZ1)
  133.         starZ(rowZ1,uZc)=false;
  134.         uZc = primeZ(rowZ1,:);
  135.         uZr = rowZ1;
  136.         rowZ1 = starZ(:,uZc);
  137.         starZ(uZr,uZc)=true;
  138.     end
  139. end

  140. % Cost of assignment
  141. assignment(validRow,validCol) = starZ(1:nRows,1:nCols);
  142. 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. assignment =

  3.   4×4 logical 数组

  4.    0   0   1   0
  5.    0   1   0   0
  6.    1   0   0   0
  7.    0   0   0   1


  8. cost =

  9.    140


  10. order =

  11.      3     2     1     4
复制代码
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

站长推荐上一条 /1 下一条

客服中心
关闭
在线时间:
周一~周五
8:30-17:30
QQ群:
653541906
联系电话:
010-85786021-8017
在线咨询
客服中心

意见反馈|网站地图|手机版|小黑屋|EPS数据狗论坛 ( 京ICP备09019565号-3 )   

Powered by BFIT! X3.4

© 2008-2028 BFIT Inc.

快速回复 返回顶部 返回列表