数字化婚姻配对尝试
建立一个模型,来模拟推导社会男女择偶过程。
题目内容:
为了模型简化,一个人的特性指标有三个,这里假设为财富、样貌、品格,每个指标均可取值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)的满意度为:
(1050+3060+60*80)= 7100分
相对的 MM 对 GG的满意度则为:
(4080+1050+50*40) = 5700分
好了,配对活动开始,设计的配对法则如下:
1、100个男方,顺序,轮流从0号到99号女方中挑选自己最满意的一位,然后向她发出配对邀请。
2、接受邀请最多的女方开始行动,对这些邀请的男性中,选择最满意的一位。
3、那么这两位配对成功,剔除出样本,剩下的99对继续这样配对。
4、循环该配对法则,直到最后一对男女配对成功。
要求:
1、编程语言为java,C++或C语言任意一种;运行环境windows。
2、能让用户输入自己的参数以及对各项数值的偏好,然后随机生成100位男性100位女性(包括用户在内。如果用为男性则为99男100女),数值全部随机但需满足题设限制。按照上述规则给出一个匹配结果呈现给用户。
3、若采用c/c++,要输出可执行程序;若采用java,给出jar和bat。
4、在匹配时,如果发现有多个满意度相同的对象,要求自身三个属性(财富,外貌,品格)总和大的优先,如果再相同则id小的优先。如果有2位女士的选票相同,优先级规则同上。请把主角的id置为最小值,以便在前2个条件相同情况下,主角可以优先选择。
5、程序读取指定的配置文件,获取样本,然后根据指定的输入,输出结果。同时会给出一组源数据和标准答案给学生自测。最后再让学生根据不同的,指定的输入,给出考试答案。
请点击下载配置文件附件。附件中,male.txt,female.txt,players.txt 分别是男士样本、女士样本和主角样本各 100位。 男女样本中,每行都代表一位男士或女士的基本属性,从左到右依次是ID, 样貌,品格,财富 , 期望样貌,期望品格,期望财富,没有加入性别,需要在解析时手动添加,每个txt文本的性别都是一样的,请注意。另外,主角样本中没有ID属性,换成了性别属性,其中 0表示女性,1表示男性,其余属性依次为样貌,品格,财富,期望样貌 ,期望品格,期望财富。建议把主角的id都设置为 -1,以便满足优先选择的条件。
给出标准答案2组,用于考生自测:
1号主角(文本第一行),选择的对象属性为(6,18,82,87,3,10)
2号主角(文本第二行),选择的对象属性为(27,74,22,22,58,20)
同时要求考生输出9号主角(0,72,55,53,8,87,5),19号主角(0,11,4,63,22,60,18),47号主角(1,19,8,21,1,53,46),83号主角(1,23,11,17,58,31,11),99号主角(1,26,66,1,78,11,11)以及100号主角(0,68,28,19,43,11,46)的选择结果。
代码展示(java):
import java.util.ArrayList;
import java.util.HashMap;
/**
* 描述:进行婚配
*
* @Author administrator{GINO ZHANG}
* @Date2018/11/10
*/
public class Main {
private static int x=1 ;
//100对
private static int couple = 100;
public static void main(String[] args) {
//男人的文件路径
String malePath = "F:\\tulun java\\作业\\male.txt";
//进行转换
ArrayList<Message> males = Until.FIleTrasPersonClassList(malePath,1);
//女人的文件路径
String famalPath="F:\\tulun java\\作业\\female.txt";
//进行转换
ArrayList<Message> females = Until.FIleTrasPersonClassList(famalPath,0);
//主角文件路径
String playerPath="F:\\tulun java\\作业\\players.txt";
//转换
ArrayList<Message> players = Until.FIleTrasPlayerClassList(playerPath);
//逐个加入主角进行匹配
for (int i = 0; i < players.size() ; i++) {
//匹配
Mate((ArrayList<Message>)males.clone(),(ArrayList<Message>) females.clone(),players.get(i));
}
}
/**
* 匹配
* @param males 男性数组
* @param females 女性数组
* @param player 主角
*/
public static void Mate(ArrayList<Message> males,ArrayList<Message> females,Message player) {
//存放一对格式为男--->女
HashMap<Message, Message> maleFemale = new HashMap<Message, Message>();
//存放格式为女--->男
HashMap<Message, Message> Femalemale = new HashMap<Message, Message>();
//主角的性别
int sex = player.getSex();
//根据性别不同放入到不同的集合中
if (sex == 0) {
females.add(player);
} else {
males.add(player);
}
//进行couple次配对
for (int p = 0; p < couple; p++) {
//统计每个女生的追求者
HashMap<Message, ArrayList<Message>> femaleScore = new HashMap<Message, ArrayList<Message>>();
int maleSize = males.size();
int femaleSize = females.size();
//让每个男的都选择自己喜欢的女生,并且统计每个女生被喜欢数
for (int i = 0; i < maleSize; i++) {
Message male = males.get(i);
int max = Integer.MIN_VALUE;
Message Maxfamale = null;
//统计每一个男生给女生打分,并记录出最高分
for (int j = 0; j < femaleSize; j++) {
Message female = females.get(j);
int score = GetScore(male, female);
if (score > max) {
max = score;
Maxfamale = female;
}
}
//用hashmap存放每一个女生备选到的男生,
if (!femaleScore.containsKey(Maxfamale)){
ArrayList<Message> people = new ArrayList<Message>();
people.add(male);
femaleScore.put(Maxfamale,people);
}else{
ArrayList<Message> people = femaleScore.get(Maxfamale);
people.add(male);
femaleScore.put(Maxfamale,people);
}
}
int maxFemaleNum = 0;
ArrayList<Message> maxFemaleList = null;
Message maxFemale = null;
//找到最受欢迎的女生
for (int i = 0; i < femaleSize; i++) {
Message person = females.get(i);
ArrayList<Message> people = femaleScore.get(person);
if (people != null) {
if (people.size() == maxFemaleNum) {
if (Select(person, maxFemale)) {
maxFemaleNum = people.size();
maxFemale = person;
maxFemaleList = people;
}
}
if (people.size() > maxFemaleNum) {
maxFemaleNum = people.size();
maxFemale = person;
maxFemaleList = people;
}
}
}
//最喜欢的女生挑选男生
if (maxFemaleList != null) {
int maxFemaleListSize = maxFemaleList.size();
int maxScore = 0;
Message maxMale = null;
for (int i = 0; i < maxFemaleListSize; i++) {
Message person = maxFemaleList.get(i);
int score = GetScore(maxFemale, person);
if (score == maxScore) {
if (Select(person, maxMale)) {
maxScore = score;
maxMale = person;
}
}
if (score > maxScore) {
maxScore = score;
maxMale = person;
}
}
//将结果放入,并且删除掉这两个人
maleFemale.put(maxMale, maxFemale);
Femalemale.put(maxFemale, maxMale);
males.remove(maxMale);
females.remove(maxFemale);
}
}
//根据主角的性别进行判断输出
if (sex == 0) {
if (Femalemale.get(player) != null) {
Message person = Femalemale.get(player);
print1(player,person);
}else {
print2();
}
} else {
if(maleFemale.get(player)!=null) {
Message person = maleFemale.get(player);
print1(player,person);
}else{
print2();
}
}
}
/**
* 打印无结果的数据
*/
private static void print2() {
System.out.println("第" + (x++) + "组主角: 无结果");
}
/**
* 打印有结果的数据
* @param person
* @param player :主角
*/
private static void print1(Message person, Message player) {
System.out.println("第" + (x++) + "组主角加入" + person.getID() + ":" + player.getID());
}
/**
*得到每一个异性的分数
* @return
*/
public static int GetScore(Message one ,Message two)
{
return one.getRequireAppearance()*two.getAppearance()+
one.getRequireCharacter()*two.getCharacter()+
one.getRequireTreasure()*two.getTreasure();
}
/**
*如果分数相同进行选择
* @return
*/
private static boolean Select(Message one, Message two)
{
int sumOne = one.getAppearance()+one.getCharacter()+one.getTreasure();
int sumTwo = two.getAppearance()+two.getCharacter()+two.getTreasure();
if(sumOne>sumTwo) {
return true;
}
else if(sumOne<sumTwo) {
return false;
}
else {
return one.getID() <= two.getID();
}
}
}
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Scanner;
/**
* 描述:将信息类的格式转化为集合
*
* @Author administrator{GINO ZHANG}
* @Date2018/11/2
*/
public class Until {
/**
* 将Person文件转换为一个集合
* @param filePath 文件路径
* @param sex 性别
* @return ArrayList集合
*/
public static ArrayList<Message> FIleTrasPersonClassList(String filePath,int sex)
{ Scanner in = null;
ArrayList<Message> people = new ArrayList<Message>();
try {
in = new Scanner(new File(filePath));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
while (in.hasNextLine()) {
String i = in.nextLine();
String[] split = i.split(",");
people.add(new Message(Integer.parseInt(split[0]),
Integer.parseInt(split[1]),
Integer.parseInt(split[2]),
Integer.parseInt(split[3]),
Integer.parseInt(split[4]),
Integer.parseInt(split[5]),
Integer.parseInt(split[6]),
sex
));
}
return people;
}
/**
* 将主角文件转化为 ArrayLis
* @param filePath 文件路径
* @return ArrayList集合
*/
public static ArrayList<Message> FIleTrasPlayerClassList(String filePath)
{
Scanner in = null;
ArrayList<Message> people = new ArrayList<Message>();
try {
in = new Scanner(new File(filePath));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
while (in.hasNextLine()) {
String i = in.nextLine();
String[] split = i.split(",");
people.add(new Message(-1,
Integer.parseInt(split[1]),
Integer.parseInt(split[2]),
Integer.parseInt(split[3]),
Integer.parseInt(split[4]),
Integer.parseInt(split[5]),
Integer.parseInt(split[6]),
Integer.parseInt(split[0])
));
}
return people;
}
}
/**
* 描述:创建信息类,创建每个人的基本属性
*
* @Author administrator{GINO ZHANG}
* @Date2018/11/2
*/
class Message {
private int ID;
private int appearance;
private int character;
private int treasure;
private int requireAppearance;
private int requireCharacter;
private int requireTreasure;
private int sex;
public Message(int ID,int appearance,int character,int treasure,int requireAppearance,int requireCharacter,int requireTreasure,int sex){
this.ID = ID;
this.appearance = appearance;
this.character = character;
this.treasure = treasure;
this.requireAppearance = requireAppearance;
this.requireCharacter = requireCharacter;
this.requireTreasure = requireTreasure;
this.sex = sex;
}
@Override
public String toString() {
return "Message{" +
"ID=" + ID +
", treasure=" + treasure +
", appearance=" + appearance +
", character=" + character +
", requireTreasure=" + requireTreasure +
", requireAppearance=" + requireAppearance +
", requireCharacter=" + requireCharacter +
", sex=" + sex +
'}';
}
public int getSex() {
return sex;
}
public void setSex(int sex) {
this.sex = sex;
}
public int getRequireCharacter() {
return requireCharacter;
}
public void setRequireCharacter(int requireCharacter) {
this.requireCharacter = requireCharacter;
}
public int getID() {
return ID;
}
public int getRequireAppearance() {
return requireAppearance;
}
public void setRequireAppearance(int requireAppearance) {
this.requireAppearance = requireAppearance;
}
public int getRequireTreasure() {
return requireTreasure;
}
public void setRequireTreasure(int requireTreasure) {
this.requireTreasure = requireTreasure;
}
public int getCharacter() {
return character;
}
public void setCharacter(int character) {
this.character = character;
}
public int getAppearance() {
return appearance;
}
public void setAppearance(int appearance) {
this.appearance = appearance;
}
public int getTreasure() {
return treasure;
}
public void setTreasure(int treasure) {
this.treasure = treasure;
}
public void setID(int ID) {
this.ID = ID;
}
}
100组数据运行结果:
C:\java\java7\jdk1.7.0_80\bin\java.exe -javaagent:D:\ideaIU-2018.1.5.win\lib\idea_rt.jar=2797:D:\ideaIU-2018.1.5.win\bin -
第1组主角加入-1:28
第2组主角加入-1:33
第3组主角加入-1:4
第4组主角加入-1:11
第5组主角加入-1:46
第6组主角加入-1:65
第7组主角加入-1:39
第8组主角加入-1:41
第9组主角加入-1:49
第10组主角加入-1:80
第11组主角加入-1:36
第12组主角加入-1:23
第13组主角加入-1:29
第14组主角加入-1:86
第15组主角加入-1:36
第16组主角加入-1:98
第17组主角加入-1:11
第18组主角加入-1:76
第19组主角加入-1:20
第20组主角加入-1:47
第21组主角加入-1:77
第22组主角加入-1:41
第23组主角加入-1:20
第24组主角加入-1:57
第25组主角加入-1:45
第26组主角加入-1:39
第27组主角加入-1:36
第28组主角加入-1:9
第29组主角加入-1:22
第30组主角加入-1:79
第31组主角加入-1:45
第32组主角加入-1:86
第33组主角加入-1:22
第34组主角加入-1:34
第35组主角加入-1:45
第36组主角加入-1:97
第37组主角加入-1:67
第38组主角加入-1:13
第39组主角加入-1:39
第40组主角加入-1:60
第41组主角加入-1:15
第42组主角加入-1:56
第43组主角加入-1:97
第44组主角加入-1:26
第45组主角加入-1:71
第46组主角加入-1:27
第47组主角: 无结果
第48组主角加入-1:85
第49组主角加入-1:97
第50组主角加入-1:46
第51组主角加入-1:49
第52组主角加入-1:4
第53组主角加入-1:35
第54组主角加入-1:27
第55组主角加入-1:65
第56组主角加入-1:77
第57组主角加入-1:73
第58组主角加入-1:94
第59组主角加入-1:83
第60组主角加入-1:52
第61组主角加入-1:48
第62组主角加入-1:53
第63组主角加入-1:2
第64组主角加入-1:12
第65组主角加入-1:78
第66组主角加入-1:84
第67组主角加入-1:69
第68组主角加入-1:97
第69组主角加入-1:26
第70组主角加入-1:97
第71组主角加入-1:71
第72组主角加入-1:78
第73组主角加入-1:1
第74组主角加入-1:28
第75组主角加入-1:55
第76组主角加入-1:28
第77组主角加入-1:10
第78组主角加入-1:81
第79组主角加入-1:87
第80组主角加入-1:74
第81组主角加入-1:63
第82组主角加入-1:33
第83组主角: 无结果
第84组主角加入-1:79
第85组主角加入-1:66
第86组主角加入-1:9
第87组主角加入-1:66
第88组主角加入-1:58
第89组主角加入-1:37
第90组主角加入-1:14
第91组主角加入-1:21
第92组主角加入-1:54
第93组主角加入-1:78
第94组主角加入-1:77
第95组主角加入-1:78
第96组主角加入-1:94
第97组主角加入-1:53
第98组主角加入-1:56
第99组主角加入-1:45
第100组主角加入-1:14
Process finished with exit code 0