Gale Shapely算法的实现
来源:互联网 发布:mac倍速看视频 编辑:程序博客网 时间:2024/05/01 08:47
算法的第一趟课,老师将Gale Shapely算法作为课程的开始。听下来觉得这个算法蛮有趣的,课下自己用c#实现了一下。
“盖尔-沙普利算法”是实现稳定配对的一个算法。参与匹配的对象分为两组,主动匹配和被动匹配。每个对象都维护了自己的一个偏好列表,喜欢程度依次递减。开始时所有主动匹配组内的对象均设置为未配对。
算法的思想就是从主动匹配的组中挑选一个为匹配的对象,从他的偏好列表中依次查找,如果找到的对象未配对,则配对。
如果已配对,但是对方的偏好列表中更偏好你,那么你们配对,对方原先配对的对象被标注为未配对。
如果已配对,但是对方的偏好列表中你不如他当前配对的,那么你就继续从自己的偏好列表中往下找。
直到所有的主动匹配组中的对象都已配对,或者所有的偏好列表都找了一遍(没有找到稳定匹配)。
代码如下:
/// <summary> /// 匹配对象 /// </summary> public class GSMatchingItem { private GSMatchingItem matchingItem; public GSMatchingItem(string name) { this.Name = name; this.ID = Guid.NewGuid(); LastMathingIndex = 0; matchingItem = null; } public string Name { get; set; } public Guid ID { get; set; } /// <summary> /// 偏好列表 /// </summary> public List<Guid> PreferenceList { get; set; } public GSMatchingItem MatchingItem { get { return matchingItem; } set { matchingItem = value; } } public bool IsMatched { get { return matchingItem != null; } } //上一次从偏好列表匹配的索引 public int LastMathingIndex { get; set; } } /// <summary> /// 匹配算法类 /// </summary> public class GSMatching { private List<Guid> freeList; public GSMatching() { PositiveMathingItemList = new List<GSMatchingItem>(); NegativeMathingItemList = new List<GSMatchingItem>(); } public List<GSMatchingItem> PositiveMathingItemList { get; set; } public List<GSMatchingItem> NegativeMathingItemList { get; set; } public void AddPositiveMathingItem(List<GSMatchingItem> items) { PositiveMathingItemList.AddRange(items); } public void AddPositiveMathingItem(GSMatchingItem item) { PositiveMathingItemList.Add(item); } public void AddNegativeMathingItem(List<GSMatchingItem> items) { NegativeMathingItemList.AddRange(items); } public void AddNegativeMathingItem(GSMatchingItem item) { NegativeMathingItemList.Add(item); } private void Reset() { freeList = new List<Guid>(); freeList.AddRange(PositiveMathingItemList.Select(p => p.ID).ToArray()); foreach (var item in PositiveMathingItemList) { item.MatchingItem = null; } foreach (var item in NegativeMathingItemList) { item.MatchingItem = null; } } public List<GSMatchingItem> Match() { Reset(); int totalCount = PositiveMathingItemList.Sum(p => p.PreferenceList.Count); int count = 0; while (!(freeList.Count == 0 || count == totalCount)) { var pItem = PositiveMathingItemList.Where(p => p.ID == freeList[0]).FirstOrDefault(); //所有的偏好都找过了 if (pItem.PreferenceList.Count <= pItem.LastMathingIndex) continue; //找到可用的最喜欢的 var pItemTo = NegativeMathingItemList.Where(p => p.ID == pItem.PreferenceList[pItem.LastMathingIndex]).FirstOrDefault(); count++; //如果目标没有配对,则直接配对 if (!pItemTo.IsMatched) { pItemTo.MatchingItem = pItem; pItem.MatchingItem = pItemTo; freeList.Remove(pItem.ID); pItem.LastMathingIndex++; } else { var pItemPreferIndex = pItemTo.PreferenceList.IndexOf(pItem.ID); var pItemToMatchingItemPreferIndex = pItemTo.PreferenceList.IndexOf(pItemTo.MatchingItem.ID); //已配对,且目标偏好列表中当前配对的不如你 if (pItemPreferIndex != -1 && pItemPreferIndex < pItemToMatchingItemPreferIndex) { //已配对的那个扔回空闲队列 var matchedItem = pItemTo.MatchingItem; matchedItem.MatchingItem = null; freeList.Add(matchedItem.ID); pItem.MatchingItem = pItemTo; pItemTo.MatchingItem = pItem; freeList.Remove(pItem.ID); pItem.LastMathingIndex++; } //已配对的看不上你,继续找下一个 else { pItem.LastMathingIndex++; } } } List<GSMatchingItem> result = new List<GSMatchingItem>(); foreach (var item in PositiveMathingItemList) { if (item.IsMatched) { result.Add(item); } } return result; } } static void Main(string[] args) { GSMatching gsMatching = new GSMatching(); //主动匹配的对象 var p1 = new GSMatchingItem("A"); var p2 = new GSMatchingItem("B"); var p3 = new GSMatchingItem("C"); var p4 = new GSMatchingItem("D"); //被动匹配的对象 var n1 = new GSMatchingItem("1"); var n2 = new GSMatchingItem("2"); var n3 = new GSMatchingItem("3"); var n4 = new GSMatchingItem("4"); //p1,p2,p3...的偏好列表 p1.PreferenceList = new List<Guid>() { n3.ID, n4.ID, n2.ID, n1.ID }; p2.PreferenceList = new List<Guid>() { n3.ID, n2.ID, n4.ID, n1.ID }; p3.PreferenceList = new List<Guid>() { n1.ID, n3.ID, n4.ID, n2.ID }; p4.PreferenceList = new List<Guid>() { n2.ID, n4.ID, n3.ID, n1.ID }; //n1,n2,n3...的偏好列表 n1.PreferenceList = new List<Guid>() { p1.ID, p4.ID, p3.ID, p2.ID }; n2.PreferenceList = new List<Guid>() { p1.ID, p2.ID, p3.ID, p4.ID }; n3.PreferenceList = new List<Guid>() { p1.ID, p3.ID, p4.ID, p2.ID }; n4.PreferenceList = new List<Guid>() { p2.ID, p1.ID, p4.ID, p3.ID }; gsMatching.AddPositiveMathingItem(new List<GSMatchingItem>() { p1, p2, p3, p4 }); gsMatching.AddNegativeMathingItem(new List<GSMatchingItem>() { n1, n2, n3, n4 }); var result = gsMatching.Match(); foreach (var item in result) { Console.WriteLine("{0} hook up {1}", item.Name, item.MatchingItem.Name); } Console.Read(); }
0 0
- Gale Shapely算法的实现
- Gale-Shapely 匹配算法
- gale-shapley算法的C语言实现
- [算法]Gale-Shapley Algorithm-稳定匹配算法的设计、实现与探讨(上)
- [算法]Gale-Shapley Algorithm-稳定匹配算法的设计、实现与探讨(下)
- 稳定的匹配算法–Gale-Shapley
- 稳定婚姻问题和Gale-Shapley算法实现
- Gale-Shapley算法中 男性优势地位 的证明
- Gale和Church的句对齐算法解析
- Gale-Shapley algorithm 博弈算法
- Gale-Shapley---婚姻匹配算法算法
- 稳定婚姻问题和Gale-Shapley算法
- 稳定婚姻问题和Gale-Shapley算法
- 稳定婚姻问题和Gale-Shapley算法
- 稳定婚姻问题和Gale-Shapley算法
- 稳定婚姻问题和Gale-Shapley算法
- 稳定婚姻问题和Gale-Shapley算法
- 顾森:稳定婚姻问题和Gale-Shapley算法
- java正则表达式学习
- swift_02_基础知识
- Painting Fence题解
- fgetc
- 我的
- Gale Shapely算法的实现
- 嵌入式linux相关知识
- nfs安装失败
- [Android基础]Spanned与SpannableString
- linux文件的访问权限和文件模式
- mysql 遇到utf8mb4插入异常
- ios-日期组件
- Ubuntu配置apache二级域名
- seq_file实例