匈牙利算法示例
匈牙利算法

C实现(作者BYVoid) CPP
#include <stdio.h> #include <string.h> #define MAX 102 long n,n1,match; long adjl[MAX][MAX]; long mat[MAX]; bool used[MAX]; FILE *fi,*fo; void readfile() { fi=fopen("flyer.in","r"); fo=fopen("flyer.out","w"); fscanf(fi,"%ld%ld",&n,&n1); long a,b; while (fscanf(fi,"%ld%ld",&a,&b)!=EOF) adjl[a][ ++adjl[a][0] ]=b; match=0; }
未盖点:设Vi是图G的一个顶点,如果Vi 不与任 未盖点 意一条属于匹配M的边相关联,就称Vi 是一个未 盖点。
交错路:设P是图G的一条路,如 交错路 果P的任意两条相邻的边一定是一 条属于M而另一条不属于M,就称 P是一条交错路。 可增广路:两个端点都是未盖点 可增广路 的交错路叫做可增广路。
---匈牙利算法(by_Beyond_the_Void)
procedure hungary; var i:longint; begin fillchar(b,sizeof(b),0); for i:=1 to m do begin fillchar(c,sizeof(c),0); if path(i) then inc(ans); end; end; begin fillchar(a,sizeof(a),0); readln(m,n,k); for i:=1 to k do begin readln(x,y); a[x,y]:=true; end; ans:=0; hungary; writeln(ans); end.
匈牙利算法解决二分图最大匹配

匈⽛利算法解决⼆分图最⼤匹配预备知识 匈⽛利算法是由匈⽛利数学家Edmonds于1965年提出,因⽽得名。
匈⽛利算法是基于Hall定理中充分性证明的思想,它是⼆分图匹配最常见的算法,该算法的核⼼就是寻找增⼴路径,它是⼀种⽤增⼴路径求⼆分图最⼤匹配的算法。
⼆分图 ⼆分图⼜称作⼆部图,是图论中的⼀种特殊模型。
设G=(V,E)是⼀个⽆向图,如果顶点V可分割为两个互不相交的⼦集(A,B),并且图中的每条边(i,j)所关联的两个顶点 i 和 j 分别属于这两个不同的顶点集(i in A,j in B),则称图G为⼀个⼆分图。
匹配 在图论中,⼀个图是⼀个匹配(或称独⽴边集)是指这个图之中,任意两条边都没有公共的顶点。
这时每个顶点都⾄多连出⼀条边,⽽每⼀条边都将⼀对顶点相匹配。
例如,图3、图4中红⾊的边就是图2的匹配。
图3中1、4、5、7为匹配点,其他顶点为⾮匹配点,1-5、4-7为匹配边,其他边为⾮匹配边。
最⼤匹配 ⼀个图所有匹配中,所含匹配边数最多的匹配,称为这个图的最⼤匹配。
图 4 是⼀个最⼤匹配,它包含 4 条匹配边。
任意图中,极⼤匹配的边数不少于最⼤匹配的边数的⼀半。
完美匹配 如果⼀个图的某个匹配中,所有的顶点都是匹配点,那么它就是⼀个完美匹配。
显然,完美匹配⼀定是最⼤匹配,但并⾮每个图都存在完美匹配。
最⼤匹配数:最⼤匹配的匹配边的数⽬。
最⼩点覆盖数:选取最少的点,使任意⼀条边⾄少有⼀个端点被选择。
最⼤独⽴数:选取最多的点,使任意所选两点均不相连。
最⼩路径覆盖数:对于⼀个DAG(有向⽆环图),选取最少条路径,使得每个顶点属于且仅属于⼀条路径,路径长可以为0(即单个点)定理1:Konig定理——最⼤匹配数 = 最⼩点覆盖数定理2:最⼤匹配数 = 最⼤独⽴数定理3:最⼩路径覆盖数 = 顶点数 - 最⼤匹配数匈⽛利算法例⼦ 为了便于理解,选取了dalao博客⾥找妹⼦的例⼦: 通过数代⼈的努⼒,你终于赶上了剩男剩⼥的⼤潮,假设你是⼀位光荣的新世纪媒⼈,在你的⼿上有N个剩男,M个剩⼥,每个⼈都可能对多名异性有好感(惊讶,-_-||暂时不考虑特殊的性取向) 如果⼀对男⼥互有好感,那么你就可以把这⼀对撮合在⼀起,现在让我们⽆视掉所有的单相思(好忧伤的感觉,快哭了),你拥有的⼤概就是下⾯这样⼀张关系图,每⼀条连线都表⽰互有好感。
匈牙利法求解指派问题

然后划去所在的列的其他0 元素,记作Ø。
Ø 13 7 0 6 6 9 5 3 2 Ø1 0 0
➢给只有一个0元素的列的0 元素加圈,记。
Ø 13 7 0 6 6 9 5 3 2 Ø 1 0
然后划去所在的行的其他0元 素,记作Ø
Ø 13 7 0 6 6 9 5 3 2 Ø 1 Ø
➢给最后一个0元素加圈, 记。
Ø 13 7 6 6 9 5 3 2 Ø 1 Ø
可见m=n=4,得到最优解。
0001 0100 1000 0010
即甲译俄文、乙译日文、丙 译英文、丁译德文所需时间 最少。Z=28小时
例6 分配问题效率矩阵
任务 A B C D E 人员
甲 12 7 9 7 9 乙8 9 6 6 6 丙 7 17 12 14 9 丁 15 14 6 6 10 戊 4 10 7 10 9
12 7 9 7 9 7 89666 6 7 17 12 14 9 7 15 14 6 6 10 6 4 10 7 10 9 4
50202 23000 0 10 5 7 2 98004 06365
➢从只有一个0元素的行开始,给 这个0元素加圈,记
50202 23000
10 5 7 2
98004 06365
然后划去所在的列的其他0元素,记 作Ø。
70202 4 3 000 Ø 8350 11 8 0 0 4 4 1 4 3
➢从只有一个0元素的行开始,给这个0 元素加圈,记
70202 4 3 000 Ø 8 3 5 11 8 0 0 4 4 1 4 3
然后划去所在的列的其他0元素,记 作Ø。
70202 4 3 00Ø Ø 8 3 5 11 8 0 0 4 4 1 4 3
匈牙利算法详细步骤例题

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

匈牙利算法是一种求解指派问题的算法,其步骤如下:对指派问题的系数矩阵进行变换,使每行每列至少有一个元素为“0”。
具体做法是让系数矩阵的每行元素去减去该行的最小元素,再让系数矩阵的每列元素减去该列的最小元素。
从第一行开始,若该行只有一个零元素,就对这个零元素加括号,对加括号的零元素所在的列画一条线覆盖该列。
若该行没有零元素或者有两个以上零元素(已划去的不算在内),则转下一行,依次进行到最后一行。
从第一列开始,若该列只有一个零元素。
就对这个零元素加括号(同样不、考虑已划去的零元素)。
再对加括号的零元素所在行画一条直线覆盖该列。
若该列没有零元素或有两个以上零元素,则转下一列,依次进行到最后一列为止。
重复上述步骤(1)和(2)可能出现3种情况:(5)按定理进行如下变换:①从矩阵未被直线覆盖的数字中找出一个最小的k;②当矩阵中的第i行有直线覆盖时,令;无直线覆盖时。
最大二分图匹配(匈牙利算法)

最大二分图匹配(匈牙利算法)二分图指的是这样一种图:其所有的顶点分成两个集合M和N,其中M或N中任意两个在同一集合中的点都不相连。
二分图匹配是指求出一组边,其中的顶点分别在两个集合中,并且任意两条边都没有相同的顶点,这组边叫做二分图的匹配,而所能得到的最大的边的个数,叫做最大匹配。
计算二分图的算法有网络流算法和匈牙利算法(目前就知道这两种),其中匈牙利算法是比较巧妙的,具体过程如下(转自组合数学):令g=(x,*,y)是一个二分图,其中x={x1,x2...},y={y1,y2,....}.令m为g中的任意匹配。
1。
将x的所有不与m的边关联的顶点表上¥,并称所有的顶点为未扫描的。
转到2。
2。
如果在上一步没有新的标记加到x的顶点上,则停,否则,转33。
当存在x被标记但未被扫描的顶点时,选择一个被标记但未被扫描的x的顶点,比如xi,用(xi)标记y 的所有顶点,这些顶点被不属于m且尚未标记的边连到xi。
现在顶点xi 是被扫描的。
如果不存在被标记但未被扫描的顶点,转4。
4。
如果在步骤3没有新的标记被标记到y的顶点上,则停,否则转5。
5。
当存在y被标记但未被扫描的顶点时。
选择y的一个被标记但未被扫描的顶点,比如yj,用(yj)标记x的顶点,这些顶点被属于m且尚未标记的边连到yj。
现在,顶点yj是被扫描的。
如果不存在被标记但未被扫描的顶点则转道2。
由于每一个顶点最多被标记一次且由于每一个顶点最多被扫描一次,本匹配算法在有限步内终止。
代码实现:bfs过程:#include<stdio.h>#include<string.h>main(){bool map[100][300];inti,i1,i2,num,num1,que[300],cou,stu,match1[100],match2[300],pqu e,p1,now,prev[300],n;scanf("%d",&n);for(i=0;i<n;i++){scanf("%d%d",&cou,&stu);memset(map,0,sizeof(map));for(i1=0;i1<cou;i1++){scanf("%d",&num);for(i2=0;i2<num;i2++){scanf("%d",&num1);map[i1][num1-1]=true;}}num=0;memset(match1,int(-1),sizeof(match1)); memset(match2,int(-1),sizeof(match2)); for(i1=0;i1<cou;i1++){p1=0;pque=0;for(i2=0;i2<stu;i2++){if(map[i1][i2]){prev[i2]=-1;que[pque++]=i2;}elseprev[i2]=-2;}while(p1<pque){now=que[p1];if(match2[now]==-1)break;p1++;for(i2=0;i2<stu;i2++){if(prev[i2]==-2&&map[match2[now]][i2]){prev[i2]=now;que[pque++]=i2;}}}if(p1==pque)continue;while(prev[now]>=0){match1[match2[prev[now]]]=now; match2[now]=match2[prev[now]]; now=prev[now];}match2[now]=i1;match1[i1]=now;num++;}if(num==cou)printf("YES\n");elseprintf("NO\n");}}dfs实现过程:#include<stdio.h>#include<string.h>#define MAX 100bool map[MAX][MAX],searched[MAX]; int prev[MAX],m,n;bool dfs(int data){int i,temp;for(i=0;i<m;i++){if(map[data][i]&&!searched[i]){searched[i]=true;temp=prev[i];prev[i]=data;if(temp==-1||dfs(temp))return true;prev[i]=temp;}}return false;}main(){int num,i,k,temp1,temp2,job;while(scanf("%d",&n)!=EOF&&n!=0) {scanf("%d%d",&m,&k);memset(map,0,sizeof(map));memset(prev,int(-1),sizeof(prev)); memset(searched,0,sizeof(searched));for(i=0;i<k;i++){scanf("%d%d%d",&job,&temp1,&temp2); if(temp1!=0&&temp2!=0)map[temp1][temp2]=true;}num=0;for(i=0;i<n;i++){memset(searched,0,sizeof(searched)); dfs(i);}for(i=0;i<m;i++){if(prev[i]!=-1)num++;}printf("%d\n",num);}}。
匈牙利算法

匈牙利算法(Edmonds算法)步聚:(1)首先用(*)标记X中所有的非M顶点,然后交替进行步骤(2),(3)。
(2)选取一个刚标记(用(*)或在步骤(3)中用(y i)标记)过的X中顶点,例如顶点x,如果x i与y为同一非匹配边的两端点,且在本步骤中y尚未被标记过,则用(x i)i去标记Y中顶点y。
重复步骤(2),直至对刚标记过的X中顶点全部完成一遍上述过程。
(3)选取一个刚标记(在步骤(2)中用(x i)标记)过的Y中结点,例如y i,如果y i与x为同一匹配边的两端点,且在本步骤中x尚未被标记过,则用(y i)去标记X中结点x。
重复步骤(3),直至对刚标记过的Y中结点全部完成一遍上述过程。
(2),(3)交替执行,直到下述情况之一出现为止:(I)标记到一个Y中顶点y,它不是M顶点。
这时从y出发循标记回溯,直到(*)标记的X中顶点x,我们求得一条交替链。
设其长度为2k+1,显然其中k条是匹配边,k+1条是非匹配边。
(II)步骤(2)或(3)找不到可标记结点,而又不是情况(I)。
(4)当(2),(3)步骤中断于情况(I),则将交替链中非匹配边改为匹配边,原匹配边改为非匹配边(从而得到一个比原匹配多一条边的新匹配),回到步骤(1),同时消除一切现有标记。
(5)对一切可能,(2)和(3)步骤均中断于情况(II),或步骤(1)无可标记结点,算法终止(算法找不到交替链).以上算法说穿了,就是从二分图中找出一条路径来,让路径的起点和终点都是还没有匹配过的点,并且路径经过的连线是一条没被匹配、一条已经匹配过交替出现。
找到这样的路径后,显然路径里没被匹配的连线比已经匹配了的连线多一条,于是修改匹配图,把路径里所有匹配过的连线去掉匹配关系,把没有匹配的连线变成匹配的,这样匹配数就比原来多1个。
不断执行上述操作,直到找不到这样的路径为止。
下面给出此算法的一个例子:(1)置M = 空,对x1-x6标记(*)。
(2)找到交替链(x1, y1)(由标记(x1),(*)回溯得),置M = {(x1, y1)}。
匈牙利算法示例范文

匈牙利算法示例范文匈牙利算法是一种解决二分图最大匹配问题的经典算法,也称为增广路径算法。
它的核心思想是通过不断寻找增广路径来不断增加匹配数,直到无法找到新的增广路径为止。
下面我将通过一个示例来详细介绍匈牙利算法的流程和原理。
假设有一个二分图G=(V,E),其中V={U,V}是图的两个顶点集合,E 是边集合。
我们的目标是找到一个最大的匹配M,即图中不存在更多的边可以加入到匹配中。
首先,我们需要为每个顶点u∈U找到一个能和它相连的顶点v∈V,这个过程称为初始化匹配。
我们可以将所有的顶点u初始化为null,表示还没有和它相连的顶点v。
然后,我们选择一个u∈U的顶点作为起始点,尝试寻找一条增广路径。
增广路径是指一条交替经过未匹配边和已匹配边的路径。
我们从起始点u开始,按照深度优先的方式扩展路径,不断寻找下一个可以加入路径的顶点v。
1. 如果u没有和任何顶点相连,那么说明找到了一条增广路径。
我们将路径上的未匹配边变为已匹配边,已匹配边变为未匹配边,然后返回true,表示找到了一条增广路径。
2. 如果u有和一些顶点v相连,但是v还没有和其他顶点相连,即v的匹配点为null,那么说明找到了一条增广路径。
我们将路径上的未匹配边变为已匹配边,已匹配边变为未匹配边,并将v设置为u的匹配点。
然后返回true,表示找到了一条增广路径。
3. 如果v已经和其他顶点相连,那么我们尝试寻找一条从v的匹配点u'出发的增广路径。
如果找到了一条增广路径,我们将路径上的未匹配边变为已匹配边,已匹配边变为未匹配边,并将v设置为u'的匹配点。
然后返回true,表示找到了一条增广路径。
4. 如果无法找到可行的增广路径,返回false。
通过不断重复上述过程,直到无法找到新的增广路径为止。
此时,我们得到的匹配M就是最大匹配。
下面我们通过一个具体的例子来演示匈牙利算法的运行过程。
假设我们有一个二分图,U={1,2,3},V={4,5,6},边集E={(1,4),(1,5),(2,4),(3,5),(3,6)}。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
0 0 0 1 1 0 0 0
15
3 ◎ 2 2
3 ◎ Ø 5 1 ◎ 4 4 6 ◎ Ø 4
得到4个独 立零元素, 所以最优解 矩阵为:
练习:
费 工作 用 人员
A
7
B
5
C
9
D
8
E
11
甲
乙
丙 丁 戊
9
8 7 4
12
5 3 6
7
4 6 7
11
6 9 5
0 13 11 2 6 0 10 11 0 5 7 4 0 1 4 2
4 2
0 13 7 0 6 0 6 9 0 5 3 2 0 1 0 0
Ø 0 0 13 7 ◎ 6 0 6 9 ◎ ◎ 0 5 3 2 ◎ Ø 0 0 1 0 Ø
0 0 1 0
0 0 1 1 0 0 0 0 0 0 1 0
例二、 有一份中文说明书,需译成英、日、德、俄四种 文字,分别记作A、B、C、D。现有甲、乙、丙、丁四 人,他们将中文说明书译成不同语种的说明书所需时 间如下表所示,问如何分派任务,可使总时间最少?
任务
人员
例一:
任务
人员
A 2
10 9 7
B 15
4 14 8
C 13
14 16 11
D 4
15 13 9
甲
乙 丙 丁
2 10 9 7
15 13 4 4 14 15 14 16 13 8 11 9
2 4
9
7
0 13 11 2 6 0 10 11 0 5 7 4 0 1 4 2
2 2 4 4 ◎ 0
◎
0 4 2 4 5 Ø 3 ◎ 0 0 1 ◎ 1 3 0 Ø 3 5 1 0 Ø 2 3 0 5
√
√
√ l =m=4 < n=5
2 2 4 4 ◎ 0
◎
0 4 2 4 5 Ø 3 ◎ 0 0 1 ◎ 1 3 0 Ø 3 5 1 0 Ø 2 3 0 5
第三步,作最少的直线覆盖所有0元素:
4 ◎ 2 3 4 ◎ √ 1 Ø 4 ◎ 4 3 √ 7 1 Ø √ 5
独立零元素的个数m等于最少直线数l,即l=m=3<n=4; 第四步,变换矩阵(bij)以增加0元素:没有被直线 覆盖的所有元素中的最小元素为1,然后打√各行都减 去1;打√各列都加上1,得如下矩阵,并转第二步进 行试指派:
5 9 0 1 5 4 0 9 3 7 6 0 -5
4 0 2 3
5 4 0 1 0 4 0 4 3 7 1 0
4 ◎ 2 3
4 ◎ 1 Ø 4 ◎ 4 3 找到 3 个独立零元素 Ø 但 m = 3 < n = 4 7 1 5
√
0 1 3 2 0
0 3 0 3 6 0 2 0 2 0 0 3 0 2 3 0 4 4 0 6
Ø 0 1 3 2 ◎ 0
◎
0 3 0 3 பைடு நூலகம் ◎ 6 0 2 Ø 0 Ø ◎ 2 0 0 3 Ø 2 3 ◎ 0 0 Ø 4 4 0 6
4 ◎ 2 3
4 ◎ √ Ø 4 1 ◎ 4 3 √ 7 1 Ø √ 5
3 ◎ 2 2
3 ◎ 1 Ø 5 ◎ 4 4 6 0 Ø 4
3 4 0 1 2 0 2 6
0 1 0 0 0 0 1 0
3 0 0 5 4 4 0 0
√ √
√ √ √ √
√
l =m=4 < n=5
1 2 4 3 ◎ 0
◎
0 3 1 3 6 ◎ 3 Ø 0 0 2 Ø 1 3 0 Ø 2 4 ◎ 0 0 3 3 Ø 5 0
√ √
√ √ √ √
0 1 3 2 0
0 3 0 3 6 0 2 0 2 0 0 3 0 2 3 0 4 4 0 6
9
8 6 11
7 9 8 7 4
5 9 8 11 5 7 12 7 11 9 5 4 6 94 3 6 9 63 6 7 5 11 4
2 2 4 4 0
0 4 3 6 5 0 4 2 1 0 2 5 0 3 6 3 2 3 1 7
第三步:作最少的直线覆盖所有0元素。 (1)对没有◎的行打√号; (2)对已打√号的行中所有含Ø元素的列打√号; (3)再对打有√号的列中含◎ 元素的行打√号;
(4)重复(2),(3)直到得不出新的打√号的行、列为止; (5)对没有打√号的行画横线,有打√号的列画纵线, 这就得到覆盖所有0元素的最少直线数 l 。l 应等于m, 若不相等,说明试指派过程有误,回到第二步(4),另 行试指派;若 l=m < n,须再变换当前的系数矩阵, 以找到n个独立的0元素,为此转第四步。 第四步:变换矩阵(bij)以增加0元素。 在没有被直线覆盖的所有元素中找出最小元素,然后 打√各行都减去这最小元素;打√各列都加上这最小元 素(以保证系数矩阵中不出现负元素)。新系数矩阵 的最优解和原问题仍相同。转回第二步。
1 2 4 3 0
0 3 1 3 6 0 3 0 2 0 1 3 0 2 4 0 3 3 0 5
1 2 4 3 0
0 3 1 3 6 0 3 0 2 0 1 3 0 2 4 0 3 3 0 5
1 2 4 3 ◎ 0
28
此问题有多个最优解
◎ 0 1 3 2 0 Ø
Ø 0
3
Ø 0
◎ 0
Ø 0
6 2
◎
2
Ø 0
0 4
2 4
3
◎ 0
3 ◎ 0 3 Ø 0 6
0 Ø 1 3 2 ◎ 0
Ø
0 6 2
3
Ø 0
◎ 0
◎
0 2
Ø 0
◎
0 4
2 4
3
Ø 0
3 ◎ 0 3 Ø 0 6
A
6 4 3
B
7 5 1
C
11 9 10
D
2 8 4
甲 乙 丙
丁
5
9
8
2
求解过程如下:
第一步,变换系数矩阵:
6 4 (c ij ) 3 5 7 11 2 2 4 5 9 8 1 10 4 1 9 8 2 2
4 0 2 3
第二步,试指派:
◎
0 3 1 3 √ √ 6 ◎ 3 Ø 0 0 2 Ø 1 3 √ 0 √ Ø 2 4 ◎ 0 0 3 3 Ø 5 0
√ √
√
1 2 4 3 ◎ 0
◎
0 3 1 3 6 ◎ 3 Ø 0 0 2 Ø 1 3 0 0 0 Ø 2 4 ◎ 3 3 Ø 5 0
匈牙利算法示例
(二)、解题步骤: 指派问题是0-1 规划的特例,也是运输问题的特例, 当然可用整数规划,0-1 规划或运输问题的解法去求 解,这就如同用单纯型法求解运输问题一样是不合算 的。利用指派问题的特点可有更简便的解法,这就是 匈牙利法,即系数矩阵中独立 0 元素的最多个数等于 能覆盖所有 0 元素的最少直线数。
-1 -2
2 2 4 4 0
0 4 2 4 5 0 3 0 1 0 1 3 0 3 5 1 2 3 0 5
2 2 4 4 ◎ 0
◎
0 4 2 4 5 Ø 3 ◎ 0 0 1 ◎ 1 3 0 Ø 3 5 1 0 Ø 2 3 0 5
第一步:变换指派问题的系数矩阵(cij )为(bij),使 在(bij)的各行各列中都出现0元素,即 (1) 从(cij)的每行元素都减去该行的最小元素; (2) 再从所得新系数矩阵的每列元素中减去该列的最 小元素。
第二步:进行试指派,以寻求最优解。 在(bij)中找尽可能多的独立0元素,若能找出n个独 立0元素,就以这n个独立0元素对应解矩阵(xij)中的元 素为1,其余为0,这就得到最优解。找独立0元素,常 用的步骤为: (1)从只有一个0元素的行(列)开始,给这个0元素加 圈,记作◎ 。然后划去◎ 所在列(行)的其它0元素,记 作Ø ;这表示这列所代表的任务已指派完,不必再考 虑别人了。 (2)给只有一个0元素的列(行)中的0元素加圈,记作 ◎;然后划去◎ 所在行的0元素,记作Ø . (3)反复进行(1),(2)两步,直到尽可能多的0元素都 被圈出和划掉为止。
(4)若仍有没有划圈的0元素,且同行(列)的0元素至 少有两个,则从剩有0元素最少的行(列)开始,比较这 行各0元素所在列中0元素的数目,选择0元素少的那列 的这个0元素加圈(表示选择性多的要“礼让”选择性 少的)。然后划掉同行同列的其它0元素。可反复进行, 直到所有0元素都已圈出和划掉为止。
(5)若◎ 元素的数目m 等于矩阵的阶数n,那么这指 派问题的最优解已得到。若m < n, 则转入下一步。
用匈牙利法求解下列指派问题,已知效率矩 阵分别如下:
7 13 15 11
9 10 12 12 16 17 16 14 15 12 15 16
3 8 8 7 6 4 8 4 9 10
2 10 2 2 2 6 9 7 3 9
3 7 5 5 10