数字化婚姻配对尝试
数字化婚姻配对尝试 |
这本来是一个大学比赛的题目,帮朋友写的,唉,我真实闲着蛋疼了
一、标题:
数字化婚姻配对尝试
二、题目:
建立一个模型,来模拟推导社会男女择偶过程。
为了模型简化,一个人的特性指标有三个,这里假设为财富、样貌、品格,每个指标均可取值1-100之间任意数字。同样也对这3项指标有自己的需求。这3个需求值取值范围都在1-98间,当然三者的和必须为100.所以任意一个人可以用以下数组来表述:
G(A、B、C、A1、B1、C1)G代表男,M代表女。
举例G11(80、50、40、10、30、60),表示男11号,拥有财富80、样貌50、品格40,对异性品格的偏好为:财富在乎程度百分之10、样貌在乎程度百分之30、品格在乎程度百分之60。
同样为了模型简化,假设信息是完全对称的,即是说,每个人都能一眼就能看清楚任意一个人的财富、样貌、品格。
还是为了模型简化,我建模所用样本为男女各100个,即男女人数相同。
每个人对异性的满意度将如下定义:每个偏好指标与异性的对应的禀赋指标相乘,三个指标的乘积再相加,即他(她)对某个异性的满意度。
举例G11(80、50、40、10、30、60)对M(50、60、80、40、10、50)的满意度为:
(10*50+30*60+60*80)= 7100分
相对的 MM 对 GG的满意度则为:
(40*80+10*50+50*40) = 5700分
好了,配对活动开始,设计的配对法则如下:
1、100个男方,顺序,轮流从0号到99号女方中挑选自己最满意的一位,然后向她发出配对邀请。
2、接受邀请最多的女方开始行动,对这些邀请的男性中,选择最满意的一位。
3、那么这两位配对成功,剔除出样本,剩下的99对继续这样配对。
4、循环该配对法则,直到最后一对男女配对成功。
在匹配时,如果发现有多个满意度相同的对象,要求自身三个属性(财富,外貌,品格)总和大的优先,如果再相同则id小的优先。如果有2位女士的选票相同,优先级规则同上。
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace zuohaoyouxi { internal class Program { private const int arrayLenth = 100; private static List<person> male = null; private static List<person> female = null; private static List<wedding> result = new List<wedding>(); private static void Main(string[] args) { male = generator(arrayLenth); female = generator(arrayLenth); selects(male,female); Console.WriteLine("一共产生了"+result.Count.ToString()+"对"); for (int i = 0; i <result.Count; i++) { Console.WriteLine("男:\n"); Console.WriteLine(result[i].male.ToString()); Console.WriteLine("女:\n"); Console.WriteLine(result[i].female.ToString()); } Console.ReadKey(); Console.ReadKey(); } /// <summary> /// 随机生成person 列表,个属性随机,但是之和为100 /// </summary> /// <param name="length">其实就是生成的人数</param> /// <returns></returns> private static List<person> generator(int length) { List<person> temp = new List<person>(); Random random = new Random(); for (int i = 0; i < length; i++) { int wealth = random.Next(1, 99); int appearance = random.Next(1, 100 - wealth); int character = 100 - wealth - appearance; int desireWealth = random.Next(1, 99); int desireAppearance = random.Next(1, 100 - desireWealth); int desireCharacter = 100 - desireWealth - desireAppearance; person tem = new person(i, wealth, appearance, character); tem.desirePersom = new person(-1, desireWealth, desireAppearance, desireCharacter); temp.Add(tem); } return temp; } /// <summary> /// 这个函数是核心迭代函数 /// </summary> /// <param name="males">男</param> /// <param name="females">女</param> private static void selects(List<person> males, List<person> females) { if (males.Count==0||males==null||females.Count==0||females==null) { return; } for (int i = 0; i < males.Count; i++) { //首先是每个男的在这一堆女的之中找到他认为最满意的 person satisfiedPerson = findSatisfied(males[i], females); // Console.WriteLine("男:"+males[i].ToString()+"对女:"+satisfiedPerson.ToString()); //然后这个男的把票投到他认为满意的人的箱子中 males[i].vote(satisfiedPerson); } //然后找到女的之中得到票数最多的一个 person personOfMaxinum =findTheMaxinum(females); // Console.WriteLine("得到票数最多的女:"+personOfMaxinum.ToString()+"\n"+personOfMaxinum.ticketBox.GetSenders().Count.ToString()); List<person> senders=personOfMaxinum.ticketBox.GetSenders(); //女的在选择她的男的中选择满意度最高的那个 person personOfSatisfied = findSatisfied(personOfMaxinum, senders); //男的女的 都选择了之后,把他们两用wedding 记录下来 wedding wedding=new wedding(personOfSatisfied,personOfMaxinum); result.Add(wedding); //从男的列表中删除已经配对好的 male.Remove(personOfSatisfied); //从女的列表中删除已经配对好的 female.Remove(personOfMaxinum); //迭代下面的选择 selects(males,female); } /// <summary> ///这个函数主要是筛选一堆人中,每个人箱子里面的票数最多的那个 /// </summary> /// <param name="persons">被筛选的人</param> /// <returns></returns> private static person findTheMaxinum(List<person> persons) { if (persons.Count==0||persons==null) { return null; } person maxinum = persons[0]; for (int i = 0; i < persons.Count; i++) { if (persons[i].ticketBox.GetSenders().Count > maxinum.ticketBox.GetSenders().Count) { maxinum = persons[i]; } else if (persons[i].ticketBox.GetSenders().Count == maxinum.ticketBox.GetSenders().Count) { if (persons[i].id<maxinum.id) { maxinum = persons[i]; } } } return maxinum; } /// <summary> /// 这个函数是一个人在一堆人之中找到他/她 满意度最高的 /// </summary> /// <param name="selector">主动要选的人</param> /// <param name="persons">被动的候选人</param> /// <returns></returns> private static person findSatisfied(person selector,List<person> persons) { if (selector==null||persons.Count==0|| persons==null) { return null; } person satisfied = persons[0]; for (int i = 0; i < persons.Count; i++) { if (person.SatiesfiedLevel(selector,persons[i])>person.SatiesfiedLevel(selector,satisfied)) { satisfied = persons[i]; } else if (person.SatiesfiedLevel(selector, persons[i]) == person.SatiesfiedLevel(selector, satisfied)) { if (persons[i].total()>satisfied.total()) { satisfied = persons[i]; } else if (persons[i].total() == satisfied.total()) { if (persons[i].id<satisfied.id) { satisfied = persons[i]; } } } } return satisfied; } } /// <summary> /// wedding 类是最后存储person的单元,一个weeding 其实就是一对男女 /// </summary> sealed class wedding { public person male = null; public person female = null; public wedding(person male, person female) { this.male = male; this.female = female; } } sealed class person { public int id=-1; private int wealth=0; private int appearance = 0; private int character = 0; public ticketBox ticketBox= null;//在这里,可以想象成一个人 抱着一个箱子,站在那里,然后让人选 public person desirePersom = null; public override string ToString() { return "id:"+id.ToString()+"\twealth:"+wealth.ToString()+"\tappearance"+appearance.ToString()+"\tcharacter:"+character.ToString(); } public person(int id,int wealth, int appearance, int character) { this.id = id; this.wealth = wealth; this.appearance = appearance; this.character = character; this.ticketBox = new ticketBox(this); } public static int SatiesfiedLevel(person person1, person person2) { return person1.desirePersom.wealth * person2.wealth + person1.desirePersom.appearance * person2.appearance + person1.desirePersom.character * person2.character; } /// <summary> /// 返回一个person实例三个属性之和 /// </summary> /// <returns></returns> public int total() { return id + wealth + appearance + character; } /// <summary> /// 当一个person 要投票的时候就用的哦啊这个函数,这是person的行为 /// </summary> /// <param name="reciver">票 的接收者</param> public void vote(person reciver) { reciver.ticketBox.AddTicket(this); } } class ticketBox { private List<ticket> tickets = null; private person holder; public ticketBox(person holder) { tickets=new List<ticket>(); this.holder = holder; } public void AddTicket(person sender) { if (tickets==null) { tickets = new List<ticket>(); } else { tickets.Add(new ticket(sender, holder)); } } public List<person> GetSenders() { if (tickets==null) { return null; } else { List<person> tem=new List<person>(); for (int i = 0; i < tickets.Count; i++) { tem.Add(tickets[i].sender); } return tem; } } private class ticket { public person sender; public person reciver; public ticket(person sender, person reciver) { this.sender = sender; this.reciver = reciver; } } } }
自己测试通过了,程序可以支持,男女不同的人数
我接到这个题目,第一感觉,这个题目太蛋疼了,现在中 根本不成立,研究这个有毛用,不过感觉程序的逻辑还是值得挑战的。哈哈