ImageVerifierCode 换一换
格式:DOCX , 页数:11 ,大小:18.92KB ,
资源ID:29855264      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/29855264.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(稳定婚姻问题和延迟认可算法.docx)为本站会员(b****5)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

稳定婚姻问题和延迟认可算法.docx

1、稳定婚姻问题和延迟认可算法稳定婚姻问题和延迟认可算法作者:goal00001111 (高粱) 始发于goal00001111 的专栏;允许自由,但必须注明作者和出处摘要:延迟认可算法(Gale-Shapley算法)是解决稳定婚姻问题的经典算法,本文用C+来实现Gale-Shapley算法。文章详细介绍了Gale-Shapley算法的原理和编码思路,给出了一个直接从原理出发的原始算法及其改进版本,并对两个版本进行了比较分析。关键词:稳定婚姻问题延迟认可算法二维数组以空间换时间稳定婚姻问题 问题来自于一场“3分钟相亲”活动,参加活动的有n位男士和n位女士。要求每位男士都要和所有的女士进行短暂的单独

2、交流,并为她们打分,然后按照喜欢程度,对每一位女士进行排序;同样的,每位女士也要对所有男士进行打分和排序。 作为活动的组织者,当你拿到这些数据后,该如何为男,女士们配对,才能使大家皆大欢喜,组成稳定的婚姻呢? 插一句:什么样的婚姻才能称为稳定的婚姻呢? 所谓稳定的婚姻,就是指男女结婚后,双方都不会发生出轨行为。 那怎样才能做到双方都不出轨呢? 如果双方都是对方的最爱,自然不会出轨;如果有一方或双方都不是对方的最爱,则必须保证想出轨的人找不到出轨的对象。例如,男子i认为其妻子不是自己的最爱,他更爱的人是j女士,可是j女士认为自己的丈夫比男子i强,则不会选择与男子i出轨;另外有k女士很喜欢男子i,

3、可是男子i又觉得她不如自己的现任妻子,所以也不会选择和k女士出轨。这样男子i就找不到与之出轨的对象了;同理,如果他的妻子也找不到出轨对象的话,他们的婚姻就是稳定的。简言之,只要满足“除妻子(丈夫)外,我爱的人不爱我,爱我的人我不爱”条件,就可形成稳定的婚姻。回到我们的问题:如何让所有参加相亲活动的男女都组成各自的“稳定婚姻”?1962 年,美国数学家 David Gale 和 Lloyd Shapley 发明了一种寻找稳定婚姻的策略,人们称之为延迟认可算法(Gale-Shapley算法)。 先对所有男士进行落选标记,称其为自由男。当存在自由男时,进行以下操作: 每一位自由男在所有尚未拒绝她的女

4、士中选择一位被他排名最优先的女士; 每一位女士将正在追求她的自由男与其当前男友进行比较,选择其中排名优先的男士作为其男友,即若自由男优于当前男友,则抛弃前男友;否则保留其男友,拒绝自由男。 若某男士被其女友抛弃,重新变成自由男。在算法执行期间,自由男们主动出击,依次对最喜欢和次喜欢的女人求爱,一旦被接受,即失去自由身,进入订婚状态;而女人们则采取“守株待兔”和“喜新厌旧”策略,对前来求爱的男士进行选择:若该男子比未婚夫强,则悔婚,选择新的未婚夫;否则拒绝该男子的求婚。被女友抛弃的男人重获自由身,重新拥有了追求女人的权利当然,新的追求对象比不过前女友。这样,在算法执行期间,每个人都有可能订婚多次

5、也有可能一开始就找到了自己的最爱,从一而终每订一次婚,女人们的选择就会更有利,而男人们的品味则越来越差。只要男女生的数量相等,则经过多轮求婚,订婚,悔婚和再订婚之后,每位男女最终都会找到合适的伴侣虽然不一定是自己的最爱(男人没能追到自己的最爱,或女人没有等到自己的最爱来追求),但绝对不会出现“虽然彼此相爱,却不能在一起”的悲剧,所有人都会组成稳定的婚姻。本文用C+来实现Gale-Shapley算法,采用男士主动求爱,女士接受求爱的方式。假设男女生人数均为MAX,对每位男士和女士均进行编号,用自然数0,1,2,。,MAX-1表示其序号(依照C+的习惯,序号从0开始)。用二维数组liManMAXM

6、AX来存储男士所喜欢的女士序号的排列表;同理,用二维数组libLadyMAXMAX+1来存储女士所喜欢的男士序号的排列表,例如v号女最喜欢i号男,则libLadyv0 = i;若t号男比i号男更招v号女喜欢,则在数组libLadyv中,元素值t的下标小于元素值i的下标。为了简化算法,增加一个“不存在”的男士(序号为MAX),作为女士最初的选择。在给二维数组libLadyMAXMAX+1赋初值时,对于任意一个女士v,总有libLadyvMAX = MAX。 为所有的男士(包括那个 “不存在”的)建立一个数组manMAX+1,用来存储他们追求女士的次数,i号男目前追求的女士序号为libManima

7、ni。例如,mani=0表示i号男尚未追求过女士,其所追求的女士序号为libMani0;mani=2表示i号男已经追求过两位女士,他下次追求的女士序号为libMani2(即在喜好表中排名第3位的女士)。很明显,manMAX+1的每个元素初始值均为0,表示刚开始时,每位男士都去追求自己最喜欢的女士,mani值越大,男士对所选择的女士越不满意。为所有的女士建立一个数组ladyMAX,用来存储她所选择的男士序号,数组的所有元素初始值均为MAX,表示女士的当前男友为一个“不存在”的男士,他的分值比任何男士都低,以保证当有一个真正的男人追求该女士时,她会毫不犹豫的抛弃MAX,而选择该男子。我们遍历数组m

8、anMAX+1,依次让每个男士去追求自己心仪的女士(当然不需要处理元素manMAX那个“不存在”的男人)。例如现在正逢i号男追求v号女,若i号男不如v号女当前男友,则遭拒绝,i号男继续追求其“次喜欢女”;反之,若i号男比v号女当前男友优秀,则v抛弃前男友,选择i号男为新男友,而其前男友(设为t号男)重获自由身,可以去追求自己的“次喜欢女”了。这里有一个地方要注意:因为我们是通过执行(i+)来遍历数组的,所以如果当ti时,必须要让i折回到t位置(使i=t),否则会漏掉t。当i = MAX时,表示所有男士都找到了自己的另一半,算法结束,输出结果。C+代码如下:#include using name

9、space std; const int MAX = 4;bool ChangeFriend(const int libLadyMAX+1, int v, int oldF, int newF);/判断是否需要换男友 int main() int libManMAXMAX = 2,1,3,0,0,2,3,1,2,3,1,0,1,3,2,0;/存储男士所喜欢的女士序号的排列表 int libLadyMAXMAX+1 = 0,3,1,2,MAX,1,3,2,3,MAX,0,2,3,1,MAX,1,0,3,2,MAX;/存储女士所喜欢的男士序号的排列表 int manMAX+1 = 0; int l

10、adyMAX = MAX,MAX,MAX,MAX; int i = 0; while (i i) /前男友序号t在新男友i之后,则今后顺序前行可以处理t i+; /处理下一个男士 else /前男友序号t在新男友i之前,返回t,否则会漏掉t i = t; else/继续处理i号男的“次喜欢女” mani+; for (int i=0; iMAX; i+)/输出每位男士追求女士的次数 cout mani + 1 , ; cout endl; for (int i=0; iMAX; i+)/输出每位男士的妻子的序号 cout libManimani , ; cout endl; for (int

11、i=0; iMAX; i+)/输出每位女士的丈夫的序号 cout ladyi , ; cout endl; system(pause); return 0;bool ChangeFriend(const int libLadyMAX+1, int v, int oldF, int newF)/判断是否需要换男友 for (int i=0; i=MAX; i+) if (libLadyvi = oldF) oldF = i; break; for (int i=0; i newF);在上述实现中,我设计了一个子函数bool ChangeFriend(const int libLadyMAX+1,

12、 int v, int oldF, int newF),用来判断女士v是否需要换男友,若男子序号newF在数组libLadyvi的位置比oldF靠前,则说明女士v更喜欢newF,需要换男友,否则不换。通过比较它们的下标,可以得出结论。这个子函数的引入可以让程序完成工作,但也带来一些效率上问题,每次调用函数都要分别遍历数组libLadyv两次,去寻找oldF和newF的下标,这样在MAX值很大的时候,时间消耗是相当大的。另外,由于我们是通过执行(i+)来遍历数组,每次遇到(t i)时,都要令i折回到t,然后再执行(i+),进行了很多重复的比较,浪费了宝贵的时间。那么,如何改进代码,解决上述两个问

13、题?首先解决关于子函数的问题。之所以引入子函数,是因为数组libLadyv存储的是女士v所喜欢的男士序号的排列表,而不是男士的分值表。如果我们创建一个二维数组libladyValueMAXMAX+1,用来存储女士v所喜欢的男士的分值,即数组元素libladyValuevi表示女士v给i号男打的分数,分数越高,则表示越招人喜欢。这样我们在判断女士v是否需要换男友时,就无需遍历数组,只要直接比较libladyValuevi和libladyValuevt的值就好了。其次解决重复比较的问题。我们可以创建一个栈,把所有自由男的序号存储到栈中,每当有男子订婚,则将其序号出栈;每当有男子被抛弃,则将其序号入

14、栈。这样就可以确保不会出现重复比较了。在解决上述两个问题的时候,我都采用了“以空间换时间”的策略,小小的自夸一下,呵呵!改进后的C+代码如下:#include using namespace std; const int MAX = 4;int main() int libManMAXMAX = 2,1,3,0,0,2,3,1,2,3,1,0,1,3,2,0;/存储男士所喜欢的女士序号的排列表 int libLadyMAXMAX+1 = 0,3,1,2,MAX,1,3,2,3,MAX,0,2,3,1,MAX,1,0,3,2,MAX;/存储女士所喜欢的男士序号的排列表 int libladyVa

15、lueMAXMAX+1 = 0; for (int i=0; i=0; j-,k+) libladyValueilibLadyij = k; int manMAX+1 = 0;/存储各个男士追求女士的次数 int ladyMAX = MAX,MAX,MAX,MAX;/序号初始值MAX表示一个“不存在”的男士,即其分值比任何男士都低 int SMAX = 0;/一个栈,用来存储所有自由男的序号 int top = 0; while (top = 0)/让自由男主动去追求自己喜欢的女士,直到所有的人都配对 int v = libManStopmanStop; /处在栈顶(序号为Stop)的男士喜欢

16、v号女 if (libladyValuevladyv libladyValuevStop) /若栈顶男比v号女当前男友优秀,则 v抛弃前男友,接受栈顶男 int t = ladyv; /存储前男友序号 mant+; /抛弃前男友,即前男友选择其“次喜欢女” ladyv = Stop-; /选择栈顶男为新男友,同时栈顶男出栈 if (t != MAX) /如果t号男不是那个“不存在”的男士 S+top = t; /t号男作为新的栈顶男 else/栈顶男追求下一号目标 manStop+; for (int i=0; iMAX; i+)/输出每位男士追求女士的次数 cout mani + 1 , ;

17、 cout endl; for (int i=0; iMAX; i+)/输出每位男士的妻子的序号 cout libManimani , ; cout endl; for (int i=0; iMAX; i+)/输出每位女士的丈夫的序号 cout ladyi , ; cout endl; system(pause); return 0;参考文献:(1) matrix67的博客 0引言 什么是算法 如何寻找稳定的婚姻搭配.matrix67./blog/archives/2976(2) 劼的博客稳定婚姻问题和延迟认可算法intowater.spaces.live./Blog/cns!1pe4f-ndtin3u1qQCckqiIWQ!949.entry

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1