匈牙利算法解决指派问题

  • 指派问题背景介绍
  • 算法原理
  • 算法实现

指派问题背景介绍

在实践中经常会遇到这样一种问题:有n项不同的工作或任务,需要n个人去完成,要求每人只完成一项工作。由于每人的知识、能力、经验等不同,故各人完成不同任务所需要的时间不同。问应指派何人完成何项工作,使完成n项工作总耗时最少
这就是所谓的指派问题,指派问题也是整数规划问题

算法原理

定理1
设指派问题的效率矩阵为 ,若将该矩阵的某一行或列的各元素都减去同一个常数t,得到新的效率矩阵 ,则以C’为效率矩阵的新指派问题与原指派问题的最优解相同,但其最优值比原最优值减少t

定理2
若将指派问题的效率矩阵每一行及每一列分别减去各行及各列的最小元素,则得到的新指派问题与原指派问题有相同的最优解

  • 将效率矩阵的每一行减去各行最小元素,所得矩阵的每一列再减去当前列中最小元素,最后的新效率矩阵C’中必然会出现一些零元素
  • 元素 =0表示第i个人去干第j项工作效率最好,或表示第j项工作由第i个人来干效率最高

定理3
效率矩阵C中独立零元素的最多个数等于能覆盖所有零元素的最小直线数

定义1
在效率矩阵C中,有一组处在不同行不同列的零元素,称为独立零元素组,此时其中每个元素称为独立零元素

算法实现

Step 1

变化效率矩阵,将各行各列都减去当前各行各列最小元素

function [P_cond,stepnum] = step1(M)size = length(M);for i = 1:sizerow_min = min(M(i,:));M(i,:) = M(i,:)-row_min;endstepnum = 2;

Step 2
用圈零法求出新矩阵C1中独立零元素

  • 进行行检验
    对C1进行逐行检查,每行只有一个未标记的零元素时,用O记号将该元素圈起,然后将被圈起的零元素所在列的其他未标记的零元素用记号×划去
    重复行检验,直到每一行都没有未被标记的零元素或至少有两个未被标记的零元素为止
  • 进行列检验,与进行行检验类似
function [r_cov,c_cov,C,stepnum] = step2(M)% Define variablessize = length(M);r_cov = zeros(size,1);  % 显示是否覆盖行的向量c_cov = zeros(size,1);  % 显示是否覆盖列的向量C = zeros(size);        %显示一个位置是O还是×for i = 1:sizefor j = 1:sizeif M(i,j) == 0 && r_cov(i) == 0 && c_cov(j) == 0C(i,j) = 1;r_cov(i) = 1;c_cov(j) = 1;endendend
% Re-initialize the cover vectorsr_cov = zeros(size,1);  % A vector that shows if a row is coveredc_cov = zeros(size,1);  % A vector that shows if a column is coveredstepnum = 3;

Step 3
(1)每一行均有O出现,圈O的个数m恰好等于n,即m=n
(2)存在未标记过的零元素,但它们所在的行和列中,未标记过的零元素均至少有两个
(3)不存在未被标记过的零元素,但圈O的个数m<n

试指派

  • 若情况(1)出现,则可以进行指派:令圈0位置的决策变量取值为1,其他决策变量取值均为零,得到一个最优指派方案
%判断下一步往哪走
function [c_cov,stepnum] = step3(C,size)c_cov = sum(C,1);if sum(c_cov) == size  % m=nstepnum = 7;elsestepnum = 4;end
  • 若情况(2)出现,则再对每行每列中有两个未被标记过的零元素任选一个加上标记O。同时给同列或同行的其他未被标记的零元素加上标记×,然后再进行行与列检验,这时可能出现情况(1)或(3)。若出现情况(1),则由上述得到一最优指派方案,停止计算
  • 若情况(3)出现,则要转入第四步
function [C,r_cov,c_cov,Z_r,Z_c,stepnum] = step4(M,r_cov,c_cov,C)
size = length(M);
zflag = 1;
while zflag  % Find the first uncovered zerorow = 0; col = 0; exit_flag = 1;i = 1; j = 1;while exit_flag %判断是否存在未覆盖到的0if M(i,j) == 0 && r_cov(i) == 0 && c_cov(j) == 0row = i;col = j;exit_flag = 0;end      j = j + 1;      if j > size; j = 1; i = i+1; end      if i > size; exit_flag = 0; end      end% If there are no uncovered zeros go to step 6if row == 0stepnum = 6;zflag = 0;Z_r = 0;Z_c = 0;else% Prime the uncovered zeroC(row,col) = 2; %未被标记元素% If there is a starred zero in that row% Cover the row and uncover the column containing the zeroif sum(find(C(row,:)==1)) ~= 0 %一行中存在被标记元素r_cov(row) = 1;zcol = find(C(row,:)==1);c_cov(zcol) = 0;elsestepnum = 5;zflag = 0;Z_r = row;Z_c = col;end            end
end

Step 4
作最少直线覆盖当前所有零元素
(1)对所有不含圈0元素的行打√
(2)对打√的行中所有零元素所在列打√
(3)对所有打√列中圈0元素所在行打√
(4)重复上述第(2)和第(3)步,直到不能进一步打√为止
(5)对未打√的行画一直线,对已打√的每一列画一纵线即可

function [C,r_cov,c_cov,stepnum] = step5(C,Z_r,Z_c,r_cov,c_cov)zflag = 1;i = 1;while zflag % Find the index number of the starred zero in the columnrindex = find(C(:,Z_c(i))==1);if rindex > 0 % Save the starred zeroi = i+1;Z_r(i,1) = rindex; % Save the row of the starred zero% The column of the starred zero is the same as the column of the % primed zeroZ_c(i,1) = Z_c(i-1);elsezflag = 0;end% Continue if there is a starred zero in the column of the primed zeroif zflag == 1;% Find the column of the primed zero in the last starred zeros rowcindex = find(C(Z_r(i),:)==2);i = i+1;Z_r(i,1) = Z_r(i-1);Z_c(i,1) = cindex;    end    end% UNSTAR all the starred zeros in the path and STAR all primed zerosfor i = 1:length(Z_r)if C(Z_r(i),Z_c(i)) == 1C(Z_r(i),Z_c(i)) = 0;elseC(Z_r(i),Z_c(i)) = 1;endend% Clear the coversr_cov = r_cov.*0;c_cov = c_cov.*0;% Remove all the primesC(C==2) = 0;stepnum = 3;

Step 5
对矩阵作进一步交换,以增加0元素

  • 在未被直线覆盖过的元素中找出最小元素,将打√行的各元素减去这个最小元素,将打√列的各元素加上这个最小元素(以避免打√行中出现负元素),这样就增加了独立零元素的个数
function [P_cond,stepnum] = step6(P_cond,r_cov,c_cov)
a = find(r_cov == 0);
b = find(c_cov == 0);
minval = min(min(P_cond(a,b)));P_cond(find(r_cov == 1),:) = P_cond(find(r_cov == 1),:) + minval;
P_cond(:,find(c_cov == 0)) = P_cond(:,find(c_cov == 0)) - minval;stepnum = 4;

Step 6
对已增加独立零元素的矩阵,再用圈0法找出独立零元素组,即回到Step 2的(1)和(2),对矩阵进行行检验及列检验,直到出现圈0的个数m=n时为止

算法实现

传送门

匈牙利算法解决指派问题相关推荐

  1. 匈牙利算法解决指派问题清晰流程

    匈牙利算法解决指派问题清晰流程 百度词条上,指派问题(Assignment problem)是这么定义的:在满足特定指派要求条件下,使指派方案总体效果最佳.如:有若干项工作需要分配给若干人(或部门)来 ...

  2. Hungarian method 匈牙利算法 解决指派问题

    这个也讲得不错: https://blog.csdn.net/Wonz5130/article/details/80678410 from scipy.optimize import linear_s ...

  3. 学习匈牙利算法解决指派问题

    指派问题 指派问题的标准形式 指派问题的数学模型 非标准形式的指派问题 指派问题的匈牙利解法的一般步骤 以上步骤并不好理解下面进行一些实例展示方便理解 匈牙利解法的实例 这是一个比较友好的例子,一切按 ...

  4. 匈牙利算法求解指派问题(C++代码)

    前言 匈牙利算法能精确求解指派问题,获取最优分配方案.匈牙利算法求解指派问题基于以下原理:在一个成本矩阵中,对某一行或者某一列加上或减去一个数,最优的分配方案不变.基于此原理,我们可以对成本矩阵进行变 ...

  5. 匈牙利算法解决二分图匹配问题

    匈牙利算法是由匈牙利数学家Edmonds于1965年提出.匈牙利算法是基于Hall定理中充分性证明的思想,它是二分图匹配最常见的算法,该算法的核心就是寻找增广路径,它是一种用增广路径求二分图最大匹配的 ...

  6. 匈牙利算法解指派问题(Java代码)

    先介绍匈牙利算法 (Hungary) 的求解过程,我直接把代码贴上去就可以吧,有需要的可以联系我. 这个java代码是我根据 "数据魔术师" 公众号中的 c++ 代码改过来的,算是 ...

  7. 匈牙利算法解决加权二分图问题

    匈牙利方法是一种组合优化算法,它在多项式时间内解决了赋值问题,广泛应用于多目标跟踪的关联问题中. 图1:(a)二分图,(b)边权重矩阵,(c)边成本的替代表示形式 动机:分配问题 假设有 nnn 辆卡 ...

  8. C#实现指派问题的匈牙利算法(运筹学)

    代码平台 VS2019(32位) + Office2019(64位) 注意事项 1.运行过程中出现未注册JET.OLEDB.12.0错误信息,需要下载AccessDatabaseEngine数据访问组 ...

  9. 利用匈牙利算法Hopcroft-Karp算法解决二分图中的最大二分匹配问题 例poj 1469 COURSES...

    首先介绍一下题意:已知,有N个学生和P门课程,每个学生可以选0门,1门或者多门课程,要求在N个学生中选出P个学生使得这P个学生与P门课程一一对应. 这个问题既可以利用最大流算法解决也可以用匈牙利算法解 ...

  10. java蛮力法解决任务分配问题_【算法题】任务分配问题---匈牙利算法

    一.问题描述 问题描述:N个人分配N项任务,一个人只能分配一项任务,一项任务只能分配给一个人,将一项任务分配给一个人是需要支付报酬,如何分配任务,保证支付的报酬总数最小. 问题数学描述: 二.实例分析 ...

最新文章

  1. matlab 分子式
  2. 关于DataGridView的数据源绑定字符串两个值得注意的问题
  3. Lucene.Net学习
  4. WPF-003 popup实现下拉列表的问题
  5. pip代理解决pip下载失败问题
  6. 怎样搭建本地svn服务器环境-轻松掌握版本管理
  7. 深入理解Solaris内核中互斥锁(mutex)与条件变量(condvar)之协同工作原理
  8. element表格表头显示斜杠
  9. 山东计算机科学自考科目,山东自考本科专业考试科目(动画设计、电脑艺术、计算机、电子工程、)...
  10. 在n*n方阵里填入1,2,...n*n,要求填成蛇形
  11. Android解析XML文件(assets目录)
  12. js使用canvas画布画太极图案
  13. D. Robot Rapping Results Report(拓扑排序+二分)
  14. 一台计算机怎样介绍自己,一台电脑的自我介绍作文
  15. C/C++中的str系列函数大全
  16. 完全背包与01背包的区别
  17. ibm服务器报错代码大全_IBM_x系列服务器报错代码
  18. 一张图带你了解仙童半导体
  19. 【JY】结构概念设计之(隔震概念设计)
  20. 域名解析和内网穿透实验

热门文章

  1. TLS/SSL 通讯中的证书问题
  2. 信杂比公式_信噪比怎么计算
  3. 关于ATM机的JAVA实验报告书,Java实习报告(ATM自动柜员机)
  4. 专门查英语单词的软件_查英语单词的软件
  5. Spring实战(第4版)阅读笔记(一)
  6. 使用phpQuery抓取页面
  7. 使用phpQuery轻松采集网页内容
  8. 人机大战简史(第二版)
  9. zoom下载官网android最新,Zoom下载安卓最新版_手机app官方版免费安装下载_豌豆荚...
  10. 网络链路检测工具WinMTR下载