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

function [assignment,cost] = munkres(costMat)
% MUNKRES Munkres Assign Algorithm
%
% [ASSIGN,COST] = munkres(COSTMAT) returns the optimal assignment in ASSIGN
% with the minimum COST based on the assignment problem represented by the
% COSTMAT, where the (i,j)th element represents the cost to assign the jth
% job to the ith worker.
% % This is vectorized implementation of the algorithm. It is the fastest
% among all Matlab implementations of the algorithm. % Examples
% Example 1: a 5 x 5 example
%{
[assignment,cost] = munkres(magic(5));
[assignedrows,dum]=find(assignment);
disp(assignedrows'); % 3 2 1 5 4
disp(cost); %15
%}
% Example 2: 400 x 400 random data
%{
n=5;
A=rand(n);
tic
[a,b]=munkres(A);
toc
%} % Reference:
% "Munkres' Assignment Algorithm, Modified for Rectangular Matrices",
% http://csclab.murraystate.edu/bob.pilgrim/445/munkres.html % version 1.0 by Yi Cao at Cranfield University on 17th June 2008 assignment = false(size(costMat));
cost = 0; costMat(costMat~=costMat)=Inf;
validMat = costMat<Inf;
validCol = any(validMat);
validRow = any(validMat,2); nRows = sum(validRow);
nCols = sum(validCol);
n = max(nRows,nCols);
if ~n
return
end dMat = zeros(n);
dMat(1:nRows,1:nCols) = costMat(validRow,validCol); %*************************************************
% Munkres' Assignment Algorithm starts here
%************************************************* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% STEP 1: Subtract the row minimum from each row.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
dMat = bsxfun(@minus, dMat, min(dMat,[],2)); %**************************************************************************
% STEP 2: Find a zero of dMat. If there are no starred zeros in its
% column or row start the zero. Repeat for each zero
%**************************************************************************
zP = ~dMat;
starZ = false(n);
while any(zP(:))
[r,c]=find(zP,1);
starZ(r,c)=true;
zP(r,:)=false;
zP(:,c)=false;
end while 1
%**************************************************************************
% STEP 3: Cover each column with a starred zero. If all the columns are
% covered then the matching is maximum
%**************************************************************************
primeZ = false(n);
coverColumn = any(starZ);
if ~any(~coverColumn)
break
end
coverRow = false(n,1);
while 1
%**************************************************************************
% STEP 4: Find a noncovered zero and prime it. If there is no starred
% zero in the row containing this primed zero, Go to Step 5.
% Otherwise, cover this row and uncover the column containing
% the starred zero. Continue in this manner until there are no
% uncovered zeros left. Save the smallest uncovered value and
% Go to Step 6.
%**************************************************************************
zP(:) = false;
zP(~coverRow,~coverColumn) = ~dMat(~coverRow,~coverColumn);
Step = 6;
while any(any(zP(~coverRow,~coverColumn)))
[uZr,uZc] = find(zP,1);
primeZ(uZr,uZc) = true;
stz = starZ(uZr,:);
if ~any(stz)
Step = 5;
break;
end
coverRow(uZr) = true;
coverColumn(stz) = false;
zP(uZr,:) = false;
zP(~coverRow,stz) = ~dMat(~coverRow,stz);
end
if Step == 6
% *************************************************************************
% STEP 6: Add the minimum uncovered value to every element of each covered
% row, and subtract it from every element of each uncovered column.
% Return to Step 4 without altering any stars, primes, or covered lines.
%**************************************************************************
M=dMat(~coverRow,~coverColumn);
minval=min(min(M));
if minval==inf
return
end
dMat(coverRow,coverColumn)=dMat(coverRow,coverColumn)+minval;
dMat(~coverRow,~coverColumn)=M-minval;
else
break
end
end
%**************************************************************************
% STEP 5:
% Construct a series of alternating primed and starred zeros as
% follows:
% Let Z0 represent the uncovered primed zero found in Step 4.
% Let Z1 denote the starred zero in the column of Z0 (if any).
% Let Z2 denote the primed zero in the row of Z1 (there will always
% be one). Continue until the series terminates at a primed zero
% that has no starred zero in its column. Unstar each starred
% zero of the series, star each primed zero of the series, erase
% all primes and uncover every line in the matrix. Return to Step 3.
%**************************************************************************
rowZ1 = starZ(:,uZc);
starZ(uZr,uZc)=true;
while any(rowZ1)
starZ(rowZ1,uZc)=false;
uZc = primeZ(rowZ1,:);
uZr = rowZ1;
rowZ1 = starZ(:,uZc);
starZ(uZr,uZc)=true;
end
end % Cost of assignment
assignment(validRow,validCol) = starZ(1:nRows,1:nCols);
cost = sum(costMat(assignment));

demo_munkres.m

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

3. 指派结果

>> demo_munkres

assignment =

  4×4 logical 数组

   0   0   1   0
0 1 0 0
1 0 0 0
0 0 0 1 cost = 140 order = 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. js实现常见排序算法

    电脑配置 CPU:AMD X4 640 内存: 宏想 DDR3 1600MHz 8g 主板:华擎 980DE3/U3S3 R2.0 浏览器:chrome 79.0.3945.88(正式版本) (64 ...

  2. JavaScript中常用的字符串方法

    1. charAt(x) charAt(x)返回字符串中x位置的字符,下标从 0 开始. //charAt(x) var myString = 'jQuery FTW!!!'; console.log ...

  3. React中refs持久化

    根据使用React的版本,选择合适的方法. 字符串模式 :废弃不建议使用 回调函数,React版本 < 16.3 React.createRef() :React版本 >= 16.3 回调 ...

  4. 从源码角度看 PHP 字符串类型转换

    PHP 的类型转换是比较方便的,但是越是容易使用的东西,底层的实现越是复杂,而且在使用中像我这样的新手也往往不清楚转换后的结果到底是什么.有时候,对于 Java 这种强类型的语言,使用的时候需要强制进 ...

  5. redis系列之------链表

    前言 链表提供了高效的节点重排能力, 以及顺序性的节点访问方式, 并且可以通过增删节点来灵活地调整链表的长度. 作为一种常用数据结构, 链表内置在很多高级的编程语言里面, 因为 Redis 使用的 C ...

  6. pandas 初识(五)

    1. 如何实现把一个属性(列)拆分成多列,产生pivot,形成向量信息,计算相关性? 例: class_ timestamp count 0 10 2019-01-20 13:23:00 1 1 10 ...

  7. How to: Map a Persistent Class to a Database View Which Has No Key Field如何:映射持久化类到无主键数据库视图

    With XAF, you can build new applications from scratch or maintain existing databases. The How to: Ge ...

  8. Geodesic 什么是“测地线的”?

    确定是使用上椭球体(测地线)还是平地上(平面)的最短路径.强烈建议将 Geodesic 方法用于在不适合进行距离测量的坐标系(例如 Web 墨卡托或任何地理坐标系)中存储的数据,以及任何地理区域跨度较 ...

  9. 分析Android APK-砸壳-Fdex2

    砸壳的工具千千万,但是FDex2 是最有能耐的,我尝试过各种壳,都是秒砸的.特别说明一下,360的壳,oncreated 方法还是空的,但是其他大部分内容还是有的,反正是可以参考一下的. 安装环境: ...

  10. Test Case:: 12C ASM New feature (Doc ID 1571975.1)

    Test Case:: 12C ASM New feature (Doc ID 1571975.1) APPLIES TO: Oracle Database - Enterprise Edition ...