线性规划例题5分配问题及匈牙利算法
- 格式:ppt
- 大小:2.41 MB
- 文档页数:91
hungarian methodHungarian method是一种经典的解决分配问题的算法。
该算法在二十世纪五六十年代由匈牙利数学家Dénes Kőnig和Jenő Egerváry所发明,用于解决在线性规划中常见的任务分配问题。
这种算法结合了图论和线性规划的技术,是一种非常高效和精准的优化算法。
1. 问题定义在任务分配问题中,我们需要将n项活动分配给n个人,每个人只能完成一项活动。
每项活动有一个与之相关联的成本或权重,我们需要最小化这些权重的总和。
该问题可描述为一个n*n的矩阵,其中每个元素aij代表将任务i分配给人j所需的代价。
2. 算法步骤Hungarian method的实现步骤如下:(1)首先,对原始的代价矩阵进行列减法和行减法,得到一个新的矩阵。
(2)使用最小化(或最大化)算法,将矩阵的元素分组为行和列,并将它们连接起来。
(3)通过在每个组内选择最小的元素并在每个组之间进行替换来得到最优解。
(4)如果问题没有得到解决,则回到步骤1并继续执行算法,直到找到最优解为止。
3. 矩阵的处理在第一步中,我们需要对原始的代价矩阵进行行减法和列减法。
对于每一行和每一列,我们从其中选择一个最小的元素,并将该最小元素从行(或列)的其他元素中减去。
通过这种方式,我们可以得到一个新的矩阵,它的元素最少有一个为0。
该矩阵称为减法矩阵。
4. 匈牙利算法的实现在第二步中,我们使用最小化算法将减法矩阵的元素分组为行和列。
我们将行中的最小元素和列中的最小元素连接起来,并用直线穿过它们。
接下来,我们用相邻线覆盖矩阵的其他元素,直到矩阵的每个元素都被覆盖。
第三步是通过在组内选择最小元素并在组和列之间进行替换来获得最优解的。
如果我们无法替换元素,例如在第二步中,我们没有找到足够的相邻行或列,则需要回到第1步并继续。
5. 求解复杂度的分析Hungarian method是一种精确的分配算法,可以在多项多项任务分配问题上得到最优解。
匈⽛利算法(⼆分图)---------------------------------------------------------------------题材⼤多来⾃⽹络,本篇由神犇整理基本概念—⼆分图⼆分图:是图论中的⼀种特殊模型。
若能将⽆向图G=(V,E)的顶点V划分为两个交集为空的顶点集,并且任意边的两个端点都分属于两个集合,则称图G为⼀个为⼆分图。
匹配:⼀个匹配即⼀个包含若⼲条边的集合,且其中任意两条边没有公共端点。
如下图,图3的红边即为图2的⼀个匹配。
1 最⼤匹配在G的⼀个⼦图M中,M的边集中的任意两条边都不依附于同⼀个顶点,则称M是⼀个匹配。
选择这样的边数最⼤的⼦集称为图的最⼤匹配问题,最⼤匹配的边数称为最⼤匹配数.如果⼀个匹配中,图中的每个顶点都和图中某条边相关联,则称此匹配为完全匹配,也称作完备匹配。
如果在左右两边加上源汇点后,图G等价于⼀个⽹络流,最⼤匹配问题可以转为最⼤流的问题。
解决此问的匈⽛利算法的本质就是寻找最⼤流的增⼴路径。
上图中的最⼤匹配如下图红边所⽰:2 最优匹配最优匹配⼜称为带权最⼤匹配,是指在带有权值边的⼆分图中,求⼀个匹配使得匹配边上的权值和最⼤。
⼀般X和Y集合顶点个数相同,最优匹配也是⼀个完备匹配,即每个顶点都被匹配。
如果个数不相等,可以通过补点加0边实现转化。
⼀般使⽤KM算法解决该问题。
3 最⼩覆盖⼆分图的最⼩覆盖分为最⼩顶点覆盖和最⼩路径覆盖:①最⼩顶点覆盖是指最少的顶点数使得⼆分图G中的每条边都⾄少与其中⼀个点相关联,⼆分图的最⼩顶点覆盖数=⼆分图的最⼤匹配数;②最⼩路径覆盖也称为最⼩边覆盖,是指⽤尽量少的不相交简单路径覆盖⼆分图中的所有顶点。
⼆分图的最⼩路径覆盖数=|V|-⼆分图的最⼤匹配数;4 最⼤独⽴集最⼤独⽴集是指寻找⼀个点集,使得其中任意两点在图中⽆对应边。
对于⼀般图来说,最⼤独⽴集是⼀个NP完全问题,对于⼆分图来说最⼤独⽴集=|V|-⼆分图的最⼤匹配数。
分配问题匈牙利算法的Matlab实现function [x,fVal]=Hungary(C)% 输出参数:% x--Decision Varables, n*n矩阵% fval--Objective function Value% 输入参数:% C--效益矩阵c=C; %将效益矩阵暂存入c,以下的操作将针对c进行[iMatrixRow,iMatrixCol]=size(c);%求约化矩阵:将效益矩阵的每行每列各减去其最小值c=c-repmat(min(c,[],2),1,iMatrixCol);c=c-repmat(min(c,[],1),iMatrixRow,1);%进行试分配,求出初始分配方案while 1%对所有零元素均已画⊙(inf)或画×(-inf)c=CircleOrCross(c);%划线,决定覆盖所有零元素的最少直线数iIndepentZeroNum=find(c==inf);if length(iIndepentZeroNum)==iMatrixRowbreak;else[Row,Col]=line(c);end%查找没有被直线段覆盖的元素中的最小元素,并存入fMininumVlaue中fMininumVlaue=inf;for i=1:iMatrixRowfor j=1:iMatrixColif Row(i)~=1 && Col(j)~=1 && c(i,j)<fmininumvlaue fMininumVlaue=c(i,j);endendend%修改约化矩阵中的相关数据for i=1:iMatrixRowfor j=1:iMatrixColif c(i,j)==inf||c(i,j)==-infc(i,j)=0;endif Row(i)~=1 && Col(j)~=1c(i,j)=c(i,j)-fMininumVlaue;endif Row(i)==1 && Col(j)==1c(i,j)=c(i,j)+fMininumVlaue;endendendend%返回分配方案及目标函数值fVal=0;for i=1:iMatrixRowfor j=1:iMatrixColif c(i,j)==infx(i,j)=1;fVal=fVal+C(i,j); elsex(i,j)=0;endendend</fmininumvlaue。