匈牙利算法的步骤:
匈牙利算法详细步骤例题

匈牙利算法详细步骤例题
嘿,朋友们!今天咱就来讲讲这神奇的匈牙利算法。
你可别小瞧它,这玩意儿在好多地方都大有用处呢!
咱先来看个具体的例子吧。
就说有一堆任务,还有一堆人,要把这
些任务分配给这些人,怎么分才能最合理呢?这时候匈牙利算法就闪
亮登场啦!
第一步,咱得弄个表格出来,把任务和人之间的关系都给标上。
比
如说,这个人干这个任务合适不合适呀,合适就标个高分,不合适就
标个低分。
这就好像给他们牵红线似的,得找到最合适的搭配。
然后呢,开始试着给任务找人。
从第一个任务开始,找个最合适的人。
要是这个人还没被别的任务占着,那太好了,直接就配对成功啦!要是已经被占了呢,那就得看看能不能换一换,让大家都更合适。
就好比是跳舞,你得找到最合适的舞伴,跳起来才带劲嘛!要是随
便找个人就跳,那多别扭呀。
这中间可能会遇到一些麻烦,比如好几个人都对同一个任务感兴趣,那可咋办?这就得好好琢磨琢磨啦,得权衡一下,谁更合适。
有时候你会发现,哎呀,怎么这么难呀,怎么都找不到最合适的搭配。
别急别急,慢慢来,就像解一道难题一样,得一点点分析。
咱再说说这算法的奇妙之处。
它就像是一个聪明的红娘,能把最合适的任务和人牵到一起。
你想啊,要是没有它,那咱不得乱点鸳鸯谱呀,那可不行,得把资源都好好利用起来才行呢。
比如说,有五个任务,五个。
指派问题匈牙利算法最大值

指派问题匈牙利算法最大值
指派问题是一个优化问题,旨在确定如何将 n 个任务分配给 n 个人员,以便完成总成本最小或总利润最大。
匈牙利算法是解决指派问题的经典算法之一,通过寻找增广路径来找到最大权值的匹配。
在指派问题中,我们有一个 n x n 的成本矩阵,其中的每个元素表
示将特定任务分配给特定人员的成本或利润。
问题的目标是找到一种分配方式,使得总成本最小或总利润最大。
匈牙利算法是一种基于图论的算法,它通过构建二分图和寻找增广路径来解决指派问题。
算法的核心思想是通过不断改进当前的匹配,直到找到最优解。
具体来说,匈牙利算法的步骤如下:
1. 初始化一个空的匹配集合。
2. 对于每个任务,找到一个未被分配的人员,并将其分配给该任务。
如果该任务没有未被分配的人员,则考虑将其他任务分配给当前人员,并将当前任务分配给其它人员。
3. 如果存在一个未被匹配的任务,寻找一条从该任务出发的增广路径。
增广路径是一条交替经过匹配边和非匹配边的路径,起点和终点都是未匹配的任务。
4. 如果存在增广路径,则改进当前的匹配,即通过将增广路径上的
非匹配边变为匹配边,并将增广路径上的匹配边变为非匹配边。
5. 重复步骤3和步骤4,直到不存在增广路径为止。
匈牙利算法的运行时间复杂度为 O(n^3),其中 n 是任务或人员的数量。
该算法可以找到指派问题的最优解,并且在实践中表现良好。
总之,指派问题是一个重要的优化问题,而匈牙利算法是一种解决指派问题的经典算法。
通过构建二分图并寻找增广路径,匈牙利算法可以找到指派问题的最优解。
匈牙利算法的描述

(一)、修正矩阵,使每行每列中都有零元素:
1.如果最终目标是求最大效能,那么改变所有元素的符号;
2.每行各元素都减去该行的最小元素;
3.每列各元素都减去该列的最小元素;
(二)、对矩阵进行试分配,对其中的零元素作标记:
4.对所有行和列作无标记处理;
5.从首行开始逐行处理,若该行只有一个0元素没有标记,就对该0元素标记△,并对该0同一列的0元素标记×;重复上述过程直到不能再进行标记为止;
6.从首列开始逐列处理,若该列只有一个0元素没有标记,就对该0元素标记△,并对该0同一行的其它0元素标记×;重复上述过程直到不能再进行标记为止;
7.三种情况的判断:
(1)每行都有一个△,其对应的元素就是最优解,输出△对应的元素,退出;
(2)不是每行都有△,但所有0都已标记,转8;
(3)如有多于2行或2列至少有2个没有标记的0,就对其中任一个0标△,并对同行同列的其他0标记×,转5;
(三)、作覆盖所有零元素的最少直线:
8.对无△的行作标记对号;
9.对标记对号行上的所有有0的列标记对号,无论该0标记什么;
10.对标记对号列上的所有有△的行标记对号;
11.重复9和10直到标记结束;
12.对无标记对号的行划横线,对有标记对号的行划竖线;
(四)、产生新的效能矩阵,使零元素移动:
13.在无直线覆盖的元素中找最小值d;
14.未画横线的行的所有元素减d;
15.已划竖线的列的所有元素加d;
16.转4。
hungarian method

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是一种精确的分配算法,可以在多项多项任务分配问题上得到最优解。
指派问题匈牙利算法步骤

匈牙利算法是解决二分图最大匹配问题的经典算法。
以下是匈牙利算法的步骤:
初始化:创建一个二分图,并将所有边的匹配状态初始化为未匹配。
选择一个未匹配的左侧顶点作为起始点,开始进行增广路径的寻找。
在增广路径的寻找过程中,首先选择一个未访问的左侧顶点作为当前路径的起点。
针对当前路径的起点,依次遍历与其相邻的右侧顶点。
对于每个右侧顶点,如果该顶点未被访问过,则标记为已访问,并判断该顶点是否已匹配。
如果该右侧顶点未匹配,则找到了一条增广路径,结束路径的寻找过程。
如果该右侧顶点已匹配,将其与之匹配的左侧顶点标记为已访问,并继续寻找与该左侧顶点相邻的右侧顶点,构建新的路径。
如果当前路径无法找到增广路径,则回溯到上一个路径的起点,并继续寻找其他路径。
当所有的路径都无法找到增广路径时,算法结束。
根据最终得到的匹配结果,即可得到二分图的最大匹配。
这些步骤描述了匈牙利算法的基本流程。
具体实现时,可以采用递归或迭代的方式来寻找增广路径,通过标记顶点的访问状态来进行路径的选择和回溯。
算法的时间复杂度为O(V*E),其中V是顶点的数量,E是边的数量。
运筹学指派问题的匈牙利法

运筹学课程设计指派问题的匈牙利法专业:姓名:学号:1.算法思想:匈牙利算法的基本思想是修改效益矩阵的行或列,使得每一行或列中至少有一个为零的元素,经过修正后,直至在不同行、不同列中至少有一个零元素,从而得到与这些零元素相对应的一个完全分配方案。
当它用于效益矩阵时,这个完全分配方案就是一个最优分配,它使总的效益为最小。
这种方法总是在有限步內收敛于一个最优解。
该方法的理论基础是:在效益矩阵的任何行或列中,加上或减去一个常数后不会改变最优分配。
2.算法流程或步骤:1.将原始效益矩阵C的每行、每列各元素都依次减去该行、该列的最小元素,使每行、每列都至少出现一个0元素,以构成等价的效益矩阵C’。
2.圈0元素。
在C’中未被直线通过的含0元素最少的行(或列)中圈出一个0元素,通过这个0元素作一条竖(或横)线。
重复此步,若这样能圈出不同行不同列的n个0元素,转第四步,否则转第三步。
3.调整效益矩阵。
在C’中未被直线穿过的数集D中,找出最小的数d,D中所有数都减去d,C’中两条直线相交处的数都加的d。
去掉直线,组成新的等价效益矩阵仍叫C’,返回第二步。
X=0,这就是一种最优分配。
最低总4.令被圈0元素对应位置的X ij=1,其余ij耗费是C中使X=1的各位置上各元素的和。
ij算法流程图:3.算法源程序:#include<iostream.h>typedef struct matrix{float cost[101][101];int zeroelem[101][101];float costforout[101][101];int matrixsize;int personnumber;int jobnumber;}matrix;matrix sb;int result[501][2];void twozero(matrix &sb);void judge(matrix &sb,int result[501][2]);void refresh(matrix &sb);void circlezero(matrix &sb);matrix input();void output(int result[501][2],matrix sb);void zeroout(matrix &sb);matrix input(){matrix sb;int m;int pnumber,jnumber;int i,j;float k;char w;cout<<"指派问题的匈牙利解法:"<<endl;cout<<"求最大值,请输入1;求最小值,请输入0:"<<endl;cin>>m;while(m!=1&&m!=0){cout<<"请输入1或0:"<<endl;cin>>m;}cout<<"请输入人数(人数介于1和100之间):"<<endl;cin>>pnumber;while(pnumber<1||pnumber>100){cout<<"请输入合法数据:"<<endl;cin>>pnumber;}cout<<"请输入工作数(介于1和100之间):"<<endl;cin>>jnumber;while(jnumber<1||jnumber>100){cout<<"请输入合法数据:"<<endl;cin>>jnumber;}cout<<"请输入"<<pnumber<<"行"<<jnumber<<"列的矩阵,同一行内以空格间隔,不同行间以回车分隔,以$结束输入:\n";for(i=1;i<=pnumber;i++)for(j=1;j<=jnumber;j++){cin>>sb.cost[i][j];sb.costforout[i][j]=sb.cost[i][j];}cin>>w;if(jnumber>pnumber)for(i=pnumber+1;i<=jnumber;i++)for(j=1;j<=jnumber;j++){sb.cost[i][j]=0;sb.costforout[i][j]=0;}else{if(pnumber>jnumber)for(i=1;i<=pnumber;i++)for(j=jnumber+1;j<=pnumber;j++){sb.cost[i][j]=0;sb.costforout[i][j]=0;}}sb.matrixsize=pnumber;if(pnumber<jnumber)sb.matrixsize=jnumber;sb.personnumber=pnumber;sb.jobnumber=jnumber;if(m==1){k=0;for(i=1;i<=sb.matrixsize;i++)for(j=1;j<=sb.matrixsize;j++)if(sb.cost[i][j]>k)k=sb.cost[i][j];for(i=1;i<=sb.matrixsize;i++)for(j=1;j<=sb.matrixsize;j++)sb.cost[i][j]=k-sb.cost[i][j];}return sb;}void circlezero(matrix &sb){int i,j;float k;int p;for(i=0;i<=sb.matrixsize;i++)sb.cost[i][0]=0;for(j=1;j<=sb.matrixsize;j++)sb.cost[0][j]=0;for(i=1;i<=sb.matrixsize;i++)for(j=1;j<=sb.matrixsize;j++)if(sb.cost[i][j]==0){sb.cost[i][0]++;sb.cost[0][j]++;sb.cost[0][0]++;}for(i=0;i<=sb.matrixsize;i++)for(j=0;j<=sb.matrixsize;j++)sb.zeroelem[i][j]=0;k=sb.cost[0][0]+1;while(sb.cost[0][0]<k){k=sb.cost[0][0];for(i=1;i<=sb.matrixsize;i++){if(sb.cost[i][0]==1){for(j=1;j<=sb.matrixsize;j++)if(sb.cost[i][j]==0&&sb.zeroelem[i][j]==0)break;sb.zeroelem[i][j]=1;sb.cost[i][0]--;sb.cost[0][j]--;sb.cost[0][0]--;if(sb.cost[0][j]>0)for(p=1;p<=sb.matrixsize;p++)if(sb.cost[p][j]==0&&sb.zeroelem[p][j]==0){sb.zeroelem[p][j]=2;sb.cost[p][0]--;sb.cost[0][j]--;sb.cost[0][0]--;}}}for(j=1;j<=sb.matrixsize;j++){if(sb.cost[0][j]==1){for(i=1;i<=sb.matrixsize;i++)if(sb.cost[i][j]==0&&sb.zeroelem[i][j]==0)break;sb.zeroelem[i][j]=1;sb.cost[i][0]--;sb.cost[0][j]--;sb.cost[0][0]--;if(sb.cost[i][0]>0)for(p=1;p<=sb.matrixsize;p++)if(sb.cost[i][p]==0&&sb.zeroelem[i][p]==0){sb.zeroelem[i][p]=2;sb.cost[i][0]--;sb.cost[0][p]--;sb.cost[0][0]--;}}}}if(sb.cost[0][0]>0)twozero(sb);elsejudge(sb,result);}void twozero(matrix &sb){int i,j;int p,q;int m,n;float k;matrix st;for(i=1;i<=sb.matrixsize;i++)if(sb.cost[i][0]>0)break;if(i<=sb.matrixsize){for(j=1;j<=sb.matrixsize;j++){st=sb;if(sb.cost[i][j]==0&&sb.zeroelem[i][j]==0){sb.zeroelem[i][j]=1;sb.cost[i][0]--;sb.cost[0][j]--;sb.cost[0][0]--;for(q=1;q<=sb.matrixsize;q++)if(sb.cost[i][q]==0&&sb.zeroelem[i][q]==0){sb.zeroelem[i][q]=2;sb.cost[i][0]--;sb.cost[0][q]--;sb.cost[0][0]--;}for(p=1;p<=sb.matrixsize;p++)if(sb.cost[p][j]==0&&sb.zeroelem[p][j]==0){sb.zeroelem[p][j]=2;sb.cost[p][0]--;sb.cost[0][j]--;sb.cost[0][0]--;}k=sb.cost[0][0]+1;while(sb.cost[0][0]<k){k=sb.cost[0][0];for(p=i+1;p<=sb.matrixsize;p++){if(sb.cost[p][0]==1){for(q=1;q<=sb.matrixsize;q++)if(sb.cost[p][q]==0&&sb.zeroelem[p][q]==0)break;sb.zeroelem[p][q]=1;sb.cost[p][0]--;sb.cost[0][q]--;sb.cost[0][0]--;for(m=1;m<=sb.matrixsize;m++)if(sb.cost[m][q]=0&&sb.zeroelem[m][q]==0){sb.zeroelem[m][q]=2;sb.cost[m][0]--;sb.cost[0][q]--;sb.cost[0][0]--;}}}for(q=1;q<=sb.matrixsize;q++){if(sb.cost[0][q]==1){for(p=1;p<=sb.matrixsize;p++)if(sb.cost[p][q]==0&&sb.zeroelem[p][q]==0)break;sb.zeroelem[p][q]=1;sb.cost[p][q]--;sb.cost[0][q]--;sb.cost[0][0]--;for(n=1;n<=sb.matrixsize;n++)if(sb.cost[p][n]==0&&sb.zeroelem[p][n]==0){sb.zeroelem[p][n]=2;sb.cost[p][0]--;sb.cost[0][n]--;sb.cost[0][0]--;}}}}if(sb.cost[0][0]>0)twozero(sb);elsejudge(sb,result);}sb=st;}}}void judge(matrix &sb,int result[501][2]){int i,j;int m;int n;int k;m=0;for(i=1;i<=sb.matrixsize;i++)for(j=1;j<=sb.matrixsize;j++)if(sb.zeroelem[i][j]==1)m++;if(m==sb.matrixsize){k=1;for(n=1;n<=result[0][0];n++){for(i=1;i<=sb.matrixsize;i++){for(j=1;j<=sb.matrixsize;j++)if(sb.zeroelem[i][j]==1)break;if(i<=sb.personnumber&&j<=sb.jobnumber)if(j!=result[k][1])break;k++;}if(i==sb.matrixsize+1)break;elsek=n*sb.matrixsize+1;}if(n>result[0][0]){k=result[0][0]*sb.matrixsize+1;for(i=1;i<=sb.matrixsize;i++)for(j=1;j<=sb.matrixsize;j++)if(sb.zeroelem[i][j]==1){result[k][0]=i;result[k++][1]=j;}result[0][0]++;}}else{refresh(sb);}}void refresh(matrix &sb){int i,j;float k;int p;k=0;for(i=1;i<=sb.matrixsize;i++){for(j=1;j<=sb.matrixsize;j++)if(sb.zeroelem[i][j]==1){sb.zeroelem[i][0]=1;break;}}while(k==0){k=1;for(i=1;i<=sb.matrixsize;i++)if(sb.zeroelem[i][0]==0){sb.zeroelem[i][0]=2;for(j=1;j<=sb.matrixsize;j++)if(sb.zeroelem[i][j]==2){sb.zeroelem[0][j]=1;}}for(j=1;j<=sb.matrixsize;j++){if(sb.zeroelem[0][j]==1){sb.zeroelem[0][j]=2;for(i=1;i<=sb.matrixsize;i++)if(sb.zeroelem[i][j]==1){sb.zeroelem[i][0]=0;k=0;}}}}p=0;k=0;for(i=1;i<=sb.matrixsize;i++){if(sb.zeroelem[i][0]==2){for(j=1;j<=sb.matrixsize;j++){if(sb.zeroelem[0][j]!=2)if(p==0){k=sb.cost[i][j];p=1;}else{if(sb.cost[i][j]<k)k=sb.cost[i][j];}}}}for(i=1;i<=sb.matrixsize;i++){if(sb.zeroelem[i][0]==2)for(j=1;j<=sb.matrixsize;j++)sb.cost[i][j]=sb.cost[i][j]-k;}for(j=1;j<=sb.matrixsize;j++){if(sb.zeroelem[0][j]==2)for(i=1;i<=sb.matrixsize;i++)sb.cost[i][j]=sb.cost[i][j]+k;}for(i=0;i<=sb.matrixsize;i++)for(j=0;j<=sb.matrixsize;j++)sb.zeroelem[i][j]=0;circlezero(sb);}void zeroout(matrix &sb){int i,j;float k;for(i=1;i<=sb.matrixsize;i++){k=sb.cost[i][1];for(j=2;j<=sb.matrixsize;j++)if(sb.cost[i][j]<k)k=sb.cost[i][j];for(j=1;j<=sb.matrixsize;j++)sb.cost[i][j]=sb.cost[i][j]-k;}for(j=1;j<=sb.matrixsize;j++){k=sb.cost[1][j];for(i=2;i<=sb.matrixsize;i++)if(sb.cost[i][j]<k)k=sb.cost[i][j];for(i=1;i<=sb.matrixsize;i++)sb.cost[i][j]=sb.cost[i][j]-k;}}void output(int result[501][2],matrix sb) {int k;int i;int j;int p;char w;float v;v=0;for(i=1;i<=sb.matrixsize;i++){v=v+sb.costforout[i][result[i][1]];}cout<<"最优解的目标函数值为"<<v;k=result[0][0];if(k>5){cout<<"解的个数超过了限制."<<endl;k=5;}for(i=1;i<=k;i++){cout<<"输入任意字符后输出第"<<i<<"种解."<<endl;cin>>w;p=(i-1)*sb.matrixsize+1;for(j=p;j<p+sb.matrixsize;j++)if(result[j][0]<=sb.personnumber&&result[j][1]<=sb.jobnumber)cout<<"第"<<result[j][0]<<"个人做第"<<result[j][1]<<"件工作."<<endl;}}void main(){result[0][0]=0;sb=input();zeroout(sb);circlezero(sb);output(result,sb);}4. 算例和结果:自己运算结果为:->⎥⎥⎥⎥⎦⎤⎢⎢⎢⎢⎣⎡3302102512010321->⎥⎥⎥⎥⎦⎤⎢⎢⎢⎢⎣⎡330110241200032034526635546967562543----⎥⎥⎥⎥⎦⎤⎢⎢⎢⎢⎣⎡可以看出:第1人做第4件工作;第2人做第1件工作;第3人做第3件工作;第4人做第2件工作。
匈牙利算法代码解析

匈牙利算法代码解析匈牙利算法又称作增广路算法,主要用于解决二分图最大匹配问题。
它的基本思想是在二分图中查找增广路,然后将这条增广路上的边反转,这样可以将匹配数增加一个,由此不断寻找增广路并反转边直到无法找到为止,最后所找到的就是二分图的最大匹配。
匈牙利算法的流程如下:1. 从左边开始选择一个未匹配的节点,将其标记为当前节点;2. 再从当前节点出发,依次寻找与它相连的未匹配节点;3. 如果找到了一个未匹配节点,则记录该节点的位置,并将当前节点标记为该节点;4. 如果当前节点的所有连边都不能找到未匹配节点,则退回到上一个节点,再往其他的连接点继续搜索;5. 如果到达已经匹配节点,则将该节点标记为新的当前节点,返回步骤4;6. 如果找到了一条增广路,则将其上的边反转,并将匹配数+1;7. 重复以上步骤,直至无法找到增广路为止。
在匈牙利算法中,增广路的查找可以使用DFS或BFS,这里我们以DFS为例进行解释。
匈牙利算法的时间复杂度为O(nm),n和m分别表示左边和右边的节点数,因为每条边至多遍历两次,所以最多需要执行2n次DFS。
以下为匈牙利算法的Python代码:```Pythondef findPath(graph, u, match, visited):for v in range(len(graph)):if graph[u][v] and not visited[v]:visited[v] = Trueif match[v] == -1 or findPath(graph, match[v], match, visited):# 如果v没有匹配或者匹配的右匹配节点能找到新的匹配match[v] = u # 更新匹配return Truereturn Falsedef maxMatching(graph):n = len(graph)match = [-1] * n # 右部节点的匹配数组,初始化为-1表示没有匹配count = 0return match, count```其中,findPath函数是用来查找增广路的DFS函数,match数组是右边节点的匹配数组,初始化为-1表示没有匹配,count则表示匹配数。
munkres函数

Munkres算法,也称为匈牙利算法,是一种用于解决二分图最大匹配问题的线性时间复杂度算法。
二分图最大匹配问题是在一个二分图中寻找最大的匹配,即找到最大的子集,使得图中的每条边都有一个与之匹配的顶点。
Munkres算法的基本思想是通过在原图中构造增广路径,并在增广路径上不断进行增广操作,最终得到最大匹配。
具体步骤如下:
1. 初始化:将所有未匹配的点标记为0,已匹配的点标记为无穷大。
2. 寻找增广路径:从任意一个未匹配的点开始,进行DFS或BFS 等搜索方法,直到找到一个增广路径。
增广路径是指从起点开始,沿着一条路径可以一直匹配到终点,但终点尚未匹配。
3. 进行增广操作:在增广路径上,将路径上的所有点与对应的未匹配点进行匹配,并将这些点标记为已匹配。
4. 重复步骤2和3,直到所有的点都已匹配或者找不到增广路径为止。
Munkres算法的时间复杂度为O(V^3),其中V是顶点的数量。
这是因为在最坏的情况下,需要枚举所有可能的增广路径,而每条增广路径最多包含V个顶点。
因此,Munkres算法是一种非常高效的算法,被广泛应用于解决二分图最大匹配问题。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
匈牙利算法的步骤:
第一步变换效率矩阵,使各行各列都出现 0 元素。
1°效率矩阵每行元素都减去该行最小元素;
2°效率矩阵每列元素都减去该列最小元素。
第二步圈出不同行且不同列的 0 元素,进行试指派。
1°(行搜索)给只有一个0 元素的行中的0 画圈,记作“◎”,并划去与其同列的其余0元素;
2°(列搜索)给只有一个0 元素的列中的0 画圈,记作“◎”,并划去与其同行的其余0元素;
3°反复进行1°、2°,直至所有0元素都有标记为止。
4°若行(列)的0元素均多于一个,则在0元素最少的行(列)中选定一个0元素,标“◎”,并划去与其同行同列的其余0元素。
5°若不同行且不同列的“◎”已达n个,则令它们对应的xij =1,其余xij =0,已得最优解,计算停,否则转第三步。
第三步用最少直线覆盖效率矩阵中的0元素。
1°对没有“◎”的行打“√”;
2°对打“√”行中的0元素所在列打“√”;
3°对打“√”列中“◎”所在行打“√”;
4°反复进行2°、 3°,直至打不出新“√”为止。
5°对没打“√”的行画横线,对打“√”列画竖线,则效率矩阵中所有0元素被这些直线所覆盖。
第四步调整效率矩阵,使出现新的0元素。
1°找出未被划去元素中的最小元素,以其作为调整量θ;2°矩阵中打“√”行各元素都减去θ,打“√”列各元素都加θ(以保证原来的0元素不变),然后去掉所有标记,转第二步。