用匈牙利算法解决相亲类型问题的数学模型
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
⽤匈⽛利算法解决相亲类型问题的数学模型
关于玫瑰有约的数学模型
摘要:现在城市⼤龄青年的婚姻问题收起了社会的⼴泛关注,针对这⼀社会现象,我们假设某单位有20对⼤龄青年男⼥,每个⼈的基本条件都不相同,并且每个⼈的择偶条件也不相同。
该单位的妇联组织拟根据他们的年龄,基本条件和要求条件牵线搭桥。
本⽂根据每个⼈的情况和要求,建⽴数学模型帮助妇联解决3个问题。
关键词:数学模型;满意度;匈⽛利算法;KM 算法
The mathematical model about making an appointment for
life
Li wei
(Department of Mathematics and Computational Science Hunan University of
Science and Engineering,Yongzhou,425100,Hunan )
Abstract: Nowadays, the problem of the young ’s marriage has roused more and more public’s concern. According to this phenomenon, we assume that there are twenty pairs of aged people in a company, all of which have different basic condition and their demanding 。
The Women's Federation of this company wants to wire-pull for them on the basis of their age, basic condition and demand. This paper, according to everyone ’s condition and demands, helps the Women's Federation solving this problem.
Key words: mathematical model; the measurement of satisfaction; Hungary algorithm; KM algorithm;
1.引⾔
现在在城市⼤龄青年的婚姻问题引起了社会的⼴泛关注,针对这⼀现象,我们给出20对青年男⼥的基本条件和择偶条件的抽样是真实可靠的。
⾸先,我们将所给的两个表格按年龄升序重新进⾏排列,分别编号为1,2,3……20。
并且将外貌、性格、⽓质、事业、财富五个⽅⾯的五个等级A 、B 、C 、D 、E 分别赋值为5、4、3、2、1,这样我们就得到了男⼥青年的基本条件和要求条件的四个矩阵,A ,B ,C ,D ;其次,我们定义了“满意度”的概念,利⽤图论(⼆部图)的⽅法解决这个问题。
在模型中,根据男青年的基本条件和⼥青年的要求条件构造度量矩阵(权值矩阵)A ,男1号的基本条件和⼥1号的要求条件,⽐如在外貌⽅⾯,男1号满⾜⼥1号的要求则赋值为5-3+1,在事业⽅⾯,男1号不满⾜⼥1号的要求,则赋值为0,按照这个⽅法,如果满⾜条件则按公式(男青年基本条件值-⼥青年相应的要求条件+1)赋值,反之赋值为0,这样可以得到外貌,性格,⽓质,事业,财富五个⽅⾯的数值,并将这些数值相加得到ij t ,最终得到权值矩阵T=(ij t )20 20,同理可得,⼥青年的基本条件和男青年的要求条件所构成的权值矩阵
S=(ij s )20 20,那么男⼥青年配对的总权值矩阵(即为满意度矩阵)为R1=T+S ,(因为ij t 表⽰男i 号的基本条件对j 号的要求条件,ij s 表⽰⼥j 号的基本条件对男i 号的要求条件,那么⽤ij t + ij s 表⽰男i 号对⼥j 号的总权数即为他们之间的满意度):再次,我们根据年龄的限制在矩阵R1中将不满⾜条件的赋0,得到矩阵R ,利⽤匈⽛利算法可得到问题(1)的结果。
再在矩阵R 中将⼤于2的数字赋1反之赋0,再利⽤KM 算法可得问题(2)的结果。
由于以上的模型在构造权值矩阵R 时,男青年基本条件不满⾜⼥青年要求条件时赋值为0,实际上还存在男⼥青年的失望度,故在模型改进中针对失望度将模型中赋值为0的另外赋值为(⼥青年要求条件值–男青年相应的基本条件值)即考虑到可能单向⾯的满意度较⼤⽽另⼀⽅⾯的失望度也较⼤时同样不能配对成功,且在把模型⽆向化时是采⽤把每个结点分成两个结点的⽅法即把有向的平⾏边分成各⾃带⾃⼰权的⽆向边,同时在此模型中将初等模型中的五个等级A 、B 、C 、D 、E 量化为9、7、5、3、1(由于模型中的赋值尺度⽐较粗糙),其余的步骤与模型相同,从⽽得到了模型改进。
2.问题的提出
⽬前,在许多城市⼤龄青年的婚姻问题已引起了妇联和社会团体组织的关注。
某单位现在有20对⼤龄青年男⼥,每个⼈的基本条件都不相同,如外貌、性格、⽓质、事业、财富等。
每项条件通常可以分为五个等级A 、B 、C 、D 、E ,如外貌、性格、⽓质、事业可分为很好、好、较好、⼀般、差;财富可以分为很多、多、较多、⼀般、少。
每个⼈的择偶条件也不尽相同,即对每项基本条件的要求是不同的。
该单位的妇联组织拟根据他(她)们的年龄、基本条件和要求条件进⾏牵线搭桥。
下⾯给出20对⼤龄青年男⼥的年龄、基本条件和要求条件(如下表)。
⼀般认为,男青年⾄多⽐⼥青年的年龄⼤5岁,或⼥青年的年龄⽐男青年的⼤2岁,并且要⾄少满⾜个⼈要求5项条件中的2项,才有可能配对成功。
本⽂根据每个⼈的情况要求,建⽴数学模型帮助妇联解决如下问题:
(1)给出可能的配对⽅案,使得在尽量满⾜个⼈要求的条件下,使得配对成功率尽可能的⾼。
(2)给出⼀种20对男⼥青年可同时配对的最佳⽅案,使得全部配对成功的可能性最⼤。
(3)假设男⼥双⽅都相互了解了对⽅的条件和要求,让每⼀个⼈出⼀次选择,只有当男⼥双⽅相互选中对⽅时才认为配对成功,每⼀个⼈只有⼀次选择机会。
怎样告诉20对男⼥青年都应该如何做出选择,使得⾃⼰的成功的可能性最⼤?选择的⽅案最多能配对成功多少对?
注:表中的要求条件⼀般是指不低于所给的条件。
3.问题分析
该问题是现实⽣活中的实际问题,主要就是确定合理配对⽅案,使得在尽量满⾜个⼈要求条件下,使配对成功率尽可能的⾼。
由于每个⼈的基本条件和要求条件都是给定的,双⽅彼此是知道的,⽽且是相互之间有很⼤的差异,如果完全按照要求条件组合配对成功。
任意⼀对男⼥的配对可以看成⼀个随机事件,按某⼀概率可能配对成功,或不成功。
在这⾥双⽅的满意度主要反映出⼀个⼈对另⼀个⼈的客观和主观看法,因此,满意度的定义成为解决问题的⼀个关键。
所谓的“成功率”,就是男⼥双⽅最终配对的概率。
实际上,可以⽤他们相互之间的满意度来间接刻画。
相互的满意度越⾼,双⽅配对的成功率就越⼤。
对于问题(1),要使配对成功率尽可能的⾼明,也就是给出⼀种⽅案,使得20对男⼥的配对后的满意度之和最⾼。
对于问题(2),要使20对男⼥青年同时配对,使得全部同时成功的可能性(概率)最⼤。
对于问题(3),因为每⼈个只能选择⼀次,能不配对成功取决于双⽅是不是选中对⽅,即要看双⽅彼此的满意度如何。
实际中,假如⼀个男青年i A (120i ≤≤)对⼀个⼥青年j B (120j ≤≤)的满意度最⾼,但j B 对i A 的满意度不⼀定最⾼,即若i A 选择j B ,但j B 不⼀定选择i A 。
因此,i A 与j B 不⼀定配成对,反之亦然。
现在的问题是谁选谁,使配对成功的可能性最⼤呢?这个问题实际上是男⼥双⽅在彼此基本了解的情况下,在保证⾃⼰⼀定满意的条件下做出⾃⼰的选择,也需要猜测对⽅会做出怎样的选择。
因此,这个问题可能转化为男⼥双⽅的对策问题,即转化为求男⼥双⽅的⾮零和对策的纳什平衡点的问题。
4. 模型的假设与符号说明
4.1模型的假设
(1)题⽬所给出的男⼥青年的评价是客观真实的; (2)每个⼈在选择双⽅的时候是理智的; (3)男⼥青年不会受当时环境的影响。
4.2符号说明
K=1,2,3,4,5.分别表⽰外貌、性格、⽓质、事业、财富这5个条件;
i A (i=1,2…… 20)表⽰年龄升序排列后男青年编号;
j B (j=1,2…… 20)表⽰年龄升序排列后⼥青年编号; ik a ( i=1,2…… 20,k=1,2,3,4,5)表⽰男青年在k ⽅⾯的基本条件; ik b ( i=1,2…… 20,k=1,2,3,4,5)表⽰男青年在k ⽅⾯的要求;
jk c ( j=1,2…… 20,k=1,2,3,4,5)表⽰⼥青年在k ⽅⾯的基本条件;
jk d ( j=1,2…… 20,k=1,2,3,4,5)表⽰⼥青年在k ⽅⾯的要求;
k
ij
s 表⽰男青年i 对⼥青年j 在k ⽅⾯的满意度; k
ji
T 表⽰⼥青年j 对男青年i 在k ⽅⾯的满意度; k
ij
R 表⽰男青年i 与⼥青年j 在k ⽅⾯的满意度之和. 5.模型的建⽴和求解
5.1条件量化处理
对于每个⼈的外貌、性格、⽓质、事业、财富五项条件的5个等级A ,B ,C ,D ,E 分别作量化处理为5,4,3,2,1。
于
是根据上表可以得到男⼥青年的基本条件量化矩阵和要求条件量化矩阵(或称权值矩阵)以及满意度分量分别记为:
,,
,,()205,()205()205,()205ik ik jk jk A a B b C c D d ?=?==?=
0,1,jk ik k ij
jk ik jk ik
c b S c b c b
-+≥?
,1,ik jk k ji
ik jk ik jk
a d T a d a d
-+≥?
5.2 满意度
现在,我们对满意度进⾏说明,要确定i A 对j B 的第K (1,20,15)i j k ≤≤≤≤项条件的满意度。
先对年龄进⾏筛选,年龄为⼤于(2)i A +或⼤于(5)j B +的满意度为0;如果()j i B A 基本条件()jk ik c a 达不到()i j A B 的要求()ik jk b d 即
,()jk ik ik jk c b a d <<,给它赋值为0值.否则,满意度记为刚好达到为1,超过⼀个等级加1。
即满意度为1jk ik c b -+。
这样就体现了,当⼀⽅实际条件⾼于对⽅期望(要求)条件时,则对⽅对他(她)的好感(相对于要求条件)就会增加,超过得越多,好感增加得越多。
5.3模型的建⽴
我们把⼆⼗个青年男⼥抽象化为40个结点得到⼀个带权⼆部图,其中Aj 表⽰⼆⼗个男青年,Bj 表⽰⼆⼗个⼥青年,⽽从男青年到⼥青年有⼀条带权边,权则由上⾯求得的满意度矩阵决定,然后,我们⽤最⼤⼆部图匹配算法(匈⽛利算法)求出⼀个最⼤匹配的解;但是,⼀开始所求得的是⼀个有向图,因此我们
必须把它⽆向化,⾄此对问题(1)我们仅仅是采⽤把两结点间权值相加⽽转化为⼀个⽆向图,进⽽就可以⽤匈⽛利算法对其求解了。
⽽对于问题(2)则要采⽤图的完美匹配算法(KM 算法)进⾏求解,从⽽使全部配对成功的可能性最⼤,对于问题(3),则同样采⽤匈⽛利算法只是把权值改变即可,这⾥我们把结点间有向边的权值同时⼤于2且满意度和不满意度差别不是很⼤时才有可能配对成功此时把它赋为1,⽽在不满⾜条件时则赋为0,从⽽得出能配对成功最多的⽅案。
下⾯对匈⽛利算法和KM 算法进⾏说明。
匈⽛利算法的主要思想是在每次增⼴的时候不是找⼀条增⼴路⽽是同时找⼏条点不相交的最短增⼴路,形成极⼤增⼴路集,随后可以沿着这⼏条增⼴路同时进⾏增⼴。
可以证明在寻找增⼴路集的每⼀个阶段所寻找到的最短增⼴路都具有相等的长度,并且随着算法的进⾏最短增⼴路的长度是越来越长的,更进⼀步分析可以证明最多只需增⼴ceil(sqrt(n))次就可以得到最⼤匹配(证明在这⾥略去)。
KM 算法:(全称是Kuhn-Munkras,是这⼆个⼈在1957年提出来的),⾸先为每个点设⽴⼀个顶标Li ,设vi,j-为(i,j )边的权,如果可以求得⼀个完美匹配,使得每条匹配边vi,i j j L L =+,其余边i j j L L ≤+。
此时的解就是最优的,因为匹配边的权和=i L ∑,其余任意解的权和都不可能⽐这个⼤。
5.4模型的求解
以题中所给数据为例,我们⽤EXCEL 处理后得到权值,然后编程求得结果为:
5.5模型修正(1)对满意度的说明
⾸先要注意到两个事实:其⼀,如果i A 基本条件ik a ⽐j B 的要求条件jk d 差得越多,则i A 对j B 的第K 项条件的满意度ji T 就越⼩,反之亦然。
也就是说,如果⼀⽅的实际条件⽐对⽅期望(要求)的条件差距越⼤,则对⽅对另⼀⽅失望就越⼤,即满意度就越⼩。
其⼆,如果i A 的基本条件ik a ⽐j B 的要求条件jk d ⾼,则j B 对i A 的第k 项条件的满意度ji T (k )就会增加,但
增加不会太多。
即当⼀⽅的实际条件⾼于对⽅期望(要求)的条件时,则对⽅对加⼀⽅的好感(相对要求条件)增加不会太⼤。
⽽在模型中只考虑了实际条件⾼于要求条件,好感会增加并考虑到实际条件低于要求条件时,失望会增加,即满意度会减⼩。
现在模型的基础上加以改进:如果()i j A B 的基本条件()jk ik c a 达不到()j i B A 的要求()ik jk b d ,即j k i k c b <(ik jk a d <)时,给它赋值()jk ik ik jk c b a d --它是⼀个负值,体现了当⼀⽅实际条件低于期望(要求)的条件时,则对⽅对他(她)失望(相对于要求条件)就会增加差距越⼤,失望度就越⼤,相应的满意度就越⼩。
显然,改进后成功的解决了上⾯所提出的问题,所以显得更加合理。
满意度矩阵中的各分量分别表⽰如下:
,,1jk ik jk
ik k ij
jk ik jk ik c b c b S c b c b -
≥-+??
,,1ik jk ik jk k
ji ik
jk ik jk a d a d T a d a d -
≥-+??
(2) 模型的重新建⽴
⾸先,我们把量化的尺度改为1-9尺度把A,B,C,D,E 五个等级分别量化为9、7、5、3、1,然后在给出的⼆部图转化为⽆向图时则把每个结点分为两个结点,从⽽问题转化为求40对结点的⼆部图的最⼤匹配和完美匹配问题了,对问题1和问题2⽤同样算法求解,⽽对于问题3则当满意度矩阵中的权⼤于零时赋为1⽽在⼩于零时则赋为0。
(3)以题中所给数据为例,我们⽤EXCEL 处理后得到权值,然后编程求得结果为:
问题(1)
6. 模型结果的分析
从所得的结果分析可知,模型改进后所得到的结果⽐改进前所得到的结果更加合理,对问题1是为了要尽量满⾜个⼈要求的条件使配对成功率更⾼,即要使得⼆部图中的边的权值相对来说是⽐较⼤的,⽽对问题2则是要全部配对成功的可能性最⾼,即是要使得所得到的完美配对图的权值之和最⼤即使得要20对同进配对的可能性最⼤的⽅案。
⽽对问题3则要在男⼥双⽅都满意的前提下并且是双⽅都选择了双⽅。
则从我们得到的结果可知模型改进后得到的结果⽐模型要更优。
7. 模型的优缺点
对于两个模型,改进前的模型显然⽐改进后的模型粗糙得多,但是运⾏起来相对简单,⽽且在模型中我们运⽤了匈⽛利算法使问题更加简单化,充分体现了熟练运⽤数学软件在我们运⽤数学思想解决实际问题中的重要性。
⽽在改进后的模型中,我们利⽤图论的思想,运⽤匈⽛利算法(⼆部图的最⼤匹配算法)和KM算法(⼆部图的完美匹配算法),并且将原精度提⾼,采⽤1-9尺度,使得问题的解答更加精确,但是由于算法太复杂,在计算机计算⽅⾯显得⽐较吃⼒,运⾏也相对难以实现⼀点。
在社会上各⼈的择偶标准不同,所以他们在选择对象的侧重点也会不同,⽐⽅说;有的⼈会特别注重外表,然⽽有的⼈特别注重对⽅的事业和个⼈的⽓质等等。
⽽我们在两个模型中,只是简单的将五个⽅⾯的五个等级分别赋值为⼏个数值,不能体现个⼈的侧重点。
同时,我们在模型中假设了对各⼈的抽样是真实可靠的,然⽽各⼈的择偶标准还会随时间不断改变,所以假设不⼀定会长久成⽴,若在模型的改进
⽅向上再注意这些问题,结果会更接近现实。
参考⽂献
[1]韩中庚.数学建模⽅法及其应⽤[M].北京:⾼等教育出版社,2005.5.
[2]边馥萍,侯⽂华,梁冯珍.数学模型⽅法与算法[M].北京:⾼等教育出版社,2005.4.
[3]姜启源,谢⾦星.数学模型(第三版)[M].北京:⾼等教育出版社,2003.8.
[4]吴乃陵,况迎辉.C++程序设计(第⼆版)[M].北京:⾼等教育出版社,2006.3.
[5] Bczdek J, Pal S. Fuzzy Models for Pattern Recognition [M]. Piscataway: IEEE
Press, 1992.
[6] zdek J. Pattern Recognition with KM Algorithm [M]. New York: PlenumBe Press,
1981.
致谢
本⽂的选题得到了林依勤⽼师的指导,从撰写到完稿都得到了曾⽴波⽼师的悉⼼指导,在此,对曾⽴波⽼师和林依勤⽼师的帮助表⽰衷⼼的感谢。
另外本⽂的完成还得到了罗光辉同学和李鹏同学的帮助,在此也对他们表⽰衷⼼的感谢。
附录
匈⽛利算法
#include
#include
#include
using namespace std;
bool mark1[100],mark2[100];
int list[100];
int n,m,edge,num;c
ector > v;
bool dfs(int to)
{
register int i,point,s = list[to];
for(i=0;i
{
point = v[s][i];
if(!mark2[point])
continue;
mark2[point] = false;
if(list[point]==-1 || dfs(point)){
list[point] = s;
return true;
}
return false;
}
void Solve()
{
int i,j,point;
bool flog = false;
memset(mark1,true,sizeof(mark1)); memset(list,-1,sizeof(list)); num=0;
for(i=0;i
{
for(j=0;j
if(list[v[i][j]] == -1)
{
mark1[i] = false;
list[v[i][j]] = i;
num++;
if(i==0) flog = true;
break;
}
}
for(i=0;i
{
if(mark1[i])
{
if(!v[i].empty()){
memset(mark2,true,sizeof(mark2)); for(j=0;j
{
point = v[i][j];
if(!mark2[point]) continue;
mark2[point] = false;
if(list[point] == -1 || dfs(point)) {
list[point] = i;
num++;
break;
}
}mark1[i] = false;
}
}
if(flog || list[0] != -1)
cout << num-1 << endl;
else cout << num << endl;
}
int main()
{
int i,j,s,d;
while(cin>>n)
{
if(n == 0)break;
v.clear();
v.resize(n);
cin >> m >> edge;
for(i=0;i
{
cin >> j >> s >> d;
v[s].push_back(d);
}
Solve();
}
return 0;
}
KM算法:
#include
#include
#include
using namespace std;
const int size = 160;
const int INF = 100000000; // 相对⽆穷⼤
bool map[size][size]; // ⼆分图的相等⼦图, map[i][j] = true 代表Xi与Yj 有边
bool xckd[size], yckd[size]; // 标记在⼀次DFS中,Xi与Yi是否在交错树上
int match[size]; // 保存匹配信息,其中i为Y中的顶点标号,match[i]为X中顶点标号bool DFS(int, const int);
void KM_Perfect_Match(const int n, const int edge[][size]) {
int i, j;
int lx[size], ly[size]; // KM算法中Xi与Yi的标号
for(i = 0; i < n; i++) {
lx[i] = -INF;
ly[i] = 0;
for(j = 0; j < n; j++) {
lx[i] = max(lx[i], edge[i][j]);
}
}
bool perfect = false;
while(!perfect) {
// 初始化邻接矩阵
for(i = 0; i < n; i++) {
for(j = 0; j < n; j++) {
if(lx[i]+ly[j] == edge[i][j]) map[i][j] = true;
else map[i][j] = false;
}
}
// 匹配过程
int live = 0;
memset(match, -1, sizeof(match));
for(i = 0; i < n; i++) {
memset(xckd, false, sizeof(xckd));
memset(yckd, false, sizeof(yckd));
if(DFS(i, n)) live++;
else {
xckd[i] = true;
break;
}
if(live == n) perfect = true;
else {
// 修改标号过程
int ex = INF;
for(i = 0; i < n; i++) {
for(j = 0; xckd[i] && j < n; j++) {
if(!yckd[j]) ex = min(ex, lx[i]+ly[j]-edge[i][j]);
}
}
for(i = 0; i < n; i++) {
if(xckd[i]) lx[i] -= ex;
if(yckd[i]) ly[i] += ex;
}
}
}
}
// 此函数⽤来寻找是否有以Xp为起点的增⼴路径,返回值为是否含有增⼴路bool DFS(int p, const int n)
{
int i;
for(i = 0; i < n; i++) {
if(!yckd[i] && map[p][i]) {
yckd[i] = true;
int t = match[i];
match[i] = p;
if(t == -1 || DFS(t, n)) {
return true;
}
match[i] = t;
if(t != -1) xckd[t] = true;
}
return false;
}
int main()
{
int n, edge[size][size]; // edge[i][j]为连接Xi与Yj的边的权值 int i;
/*************************************************** * 在此处要做的⼯作:
* 读取⼆分图每两点间边的权并保存在edge[][]中,
* 若X与Y数⽬不等,应添加配合的顶点
* 保存⼆分图中X与Y的顶点数n,若上⼀步不等应保* 存添加顶点完毕后的n ***************************************************/
KM_Perfect_Match(n, edge);
int cost = 0;
for(i = 0; i < n; i++) {
cost += edge[match[i]][i];
}
// cost 为最⼤匹配的总和, match[]中保存匹配信息
return 0;
}。