第六次作业--结队编程第二次

1、结队信息

学号 姓名 博客链接
618 炜坤(po主) 链接
616 语恳 链接

2、gayhub地址

传送门

3、设计说明

  • 接口设计(API)

void Generate_JSON(int N,int M); //随机产生需要输入的数据(需要部门数和学生数)
void ReadJson(Department* &department, Student* &student,int N,int M);  //读入json文件
void match(Department* &department,Student* &student,int N,int M);  //部门匹配学生
void output(Department* department, Student* student, int N, int M) //输出匹配结果
  • 内部实现设计(类图)

学生类属性包括:学号、姓名、性别、绩点、兴趣标签、空闲时间表、部门志愿表、选中部门数量、选中部门表。
部门类属性包括:部门编号、部门名称、人数限制、活动时间表、部门标签、绩点限制、报名学生权值表、报名学生数量、报名学生表

  • 匹配算法设计

    • 以部门为视角,最外层循环为部门遍历,内层循环为每个部门从全体学生筛选出有填报该部门志愿的学生,先将其招进部门学生表,计算每个申请者的权值(兴趣标签匹配一个加4分,空闲时间匹配一个加4分,高于绩点要求加10分,低于绩点要求不加分),并更新部门的学生选中个数。
    • 若超出人数限制,在新学生加进表之前遍历部门学生表,比较其权值,将权值较大的选中,表中权值较低的淘汰。
    • 在一个部门筛选完所有学生后,将选中信息更新到学生的选中部门表内,并更新学生的部门选中个数。
  • 测试数据生成

创建一个数据生成器的头文件DataGenerator.h及类DataGenerator(包括各项属性的生成方式),分别定义定部门数据生成、学生数据生成(引用部门类和学生类)。
学生:学号(S0315xxxx),姓名(AZxxx),性别(female/male),绩点(15分),兴趣标签(25个),空闲时间(210个),部门志愿(2~5个)。
部门:编号(AZx),部门名称(同学生),人数限制(015人),活动时间(15个),标签(35个),绩点限制(1~3分)。
有关字符串方面的数据均通过定义固定的string数组,随机生成数组下标来达成随机字符串的目的。
基于最大数据(100,5000),学号和部门号均不重复,现阶段的随机形式也够用了,但这些数据离现实还是有很多差距,有待改进。

  • 如何评价自己的匹配算法?

在权值计算方面还不够完善,只是通过简单的符合度累加,虽然能够做到让部门招满的地步,但离真正最优分配还有很大一段距离。
本程序的匹配算法有待优化,部门遍历学生太多,存在冗余代码,性能不佳。

4、关键代码解释

志愿匹配函数:

  • 用于将学生与部门进行匹配的函数,函数中包含对学生评分的筛选。
  • 该函数针对单个单个部门和单个学生,具体要求多个部门对多个学生可在外部加入双重循环。部门根据当前学生的志愿进行查找,寻找是否有本部门的部门号,如果有则匹配,没有则跳出。匹配到学生时,首先判断本部门是否已达到人满,如果人未满,则直接将其放入预选名单中,并记录其评分,如果人满,则需要将该学生的评分算出,与预选名单中的学生评分进行比较,若发现该学生评分大于预选表中某学生的评分则将其放入预选表中,并将评分较低的学生淘汰。
void Department::willmatching(Student &s)
{
	if (D_Limit != 0)
	{
		for (int i = 0; i < 5; i++)
		{
			if (s.S_Choice[i] == D_No)
			{			
				if (numofstu < D_Limit)
				{
					student[numofstu] = s.S_No;
					m[numofstu] = cmp(s.GPA, s.S_Schedules, s.S_Tags, GPA_Limit, D_Schedules, D_Tags);
					numofstu++;
				}
				else if (numofstu > D_Limit)
				{
					m[numofstu] = cmp(s.GPA, s.S_Schedules, s.S_Tags, GPA_Limit, D_Schedules, D_Tags);
					for (int u = 0; u < D_Limit; u++)
					{
						if (m[numofstu] > m[u])
						{							
							m[u] = m[numofstu];
							student[u] = student[numofstu];
							break;
						}
					}
				}
			}
		}
	}
}

评分计算函数

  • 用于计算各学生的评分,根据不同的条件要求,对学生进行评分,算出部们对学生的总评分。
  • 对于学生的兴趣条目与部门的兴趣要求进行匹配,发现一个相同的对该学生评分加4分,两个加8分,一次类推。同理对时间表也是发现一个相同的加4分,对于绩点要求,学生绩点高于部门要求绩点,评分加十分。
int  cminterests(string* s_interest, string* d_interest)
{
	int i, j, n = 0, n1 = 0, mark = 0;
	for (i = 0; i < n; i++)
	{
		for (j = 0; j < n1; j++)
		{
			if (s_interest[i] == d_interest[j])
			{
				mark = mark + 1;
			}
		}
	}
	mark = mark * 4;
	return mark;
}
int  cmschedual(string* s_che, string* d_che)
{
	int i, j, n = 0, n1 = 0, mark = 0;
	for (i = 0; i < 10; i++)
	{
		if (s_che[i] == "")break;
		for (j = 0; j < 5; j++)
		{
			if (d_che[j] == "")break;
			if (s_che[i] == d_che[j])
			{
				mark = mark + 1;
			}
		}
	}
	mark = mark * 4;
	return mark;
}
int	 cmpoint(float p1, float p2)
{
	int mark = 0;
	if (p1 >= p2)
	{
		mark = mark + 10;
	}
	return mark;
}
int  cmp(float point, string* schedual, string* interests, float point1, string* schedual1, string* interests1)
{
	int mark;
	mark = cminterests(interests, interests1) + cmschedual(schedual, schedual1) + cmpoint(point, point1);
	return mark;
}

5、运行及测试结果展示

  • 测试200位同学,20个部门的情况

输入数据
完整数据点此

{
    "department": [
        {
            "Department_No": "D087",
            "Department_Name": "H867",
            "Limit": 3,
            "GPA_Limit": 1.1069999933242798,
            "Tags": [
                "programing",
                "basketball",
                "film",
                "dancing",
                "running"
            ],
            "Schedules": [
                "Sat.9: 00~10: 00",
                "Fri.13: 00~14: 00",
                "Wed.13: 00~14: 00",
                "Tue.19: 00~20: 00",
                "Wed.9: 00~10: 00"
            ]
        },
        ...
        "student": [
        {
            "Student_No": "S031500435",
            "Student_Name": "B107",
            "Sex": "male",
            "GPA": 4.166130065917969,
            "Tags": [
                "running",
                "travelling",
                "swimming"
            ],
            "Free_Time": [
                "Thu.9: 00~10: 00",
                "Mon.10: 00~11: 00",
                "Sat.16: 00~17: 00"
            ],
            "Choice": [
                "D087",
                "D042"
            ]
        },
        ...
  }

输出数据
完整数据点此

  {
    "matched_department_view": [
        {
            "department_no": "D010",
            "chosen_students": ["S031507426","S031504905"]
        },
        ...
   "matched_student_view": [
        ...
        {
          "department_no": "S031507426",
          "chosen_department": ["D010","D086","D075"]
        },
        ...
   "standalone_departments": [
       "D004",
       "D034"
   ],
   "standalone_students": [
        "S031507932","S031500103","S031504247",
       ...
  }
  • 测试500位同学,30个部门的情况

输入数据
完整数据点此

{
    "department": [
        {
            "Department_No": "D042",
            "Department_Name": "S141",
            "Limit": 1,
            "GPA_Limit": 1.8980000019073487,
            "Tags": ["film","math","sports","swimming","travelling"],
            ...
    "student":  [
            ...
            {
              "Student_No": "S031502129",
              "Student_Name": "H840",
              "Sex": "female",
              "GPA": 4.138800144195557,
              "Tags": [
              "math",
              "music"
              ],
              "Free_Time": [
              "Mon.9: 00~10: 00","Thu.15: 00~16: 00","Wed.10:
00~11: 00","Fri.19: 00~20: 00","Sun.20: 00~21: 00","Fri.21: 00~22: 00","Thu.10: 00~11: 00","Sat.19: 00~20: 00","Tue.14: 00~15: 00","Fri.13: 00~14: 00"],
              "Choice": ["D041","D031"]
            }
          ]
}

输出数据
完整数据点此

{
    "matched_department_view": [
        {
            "department_no": "D042",
            "chosen_students": [
                "S031505929"
            ]
        },
        ...
        ]
   "matched_student_view": [
            {
                "department_no": "S031504618",
                "chosen_department": [
                    "D048"
                ]
            },
            ...
            ]

   "standalone_departments": [
               "D057",
               "D031",
               "D040",
               "D070",
               "D058"
           ],
   "standalone_students": [
               "S031506502",
               "S031502946",
               "S031507815",
               "S031507228",
               ...
            ]
}
  • 测试1000位同学,50个部门的情况

输入数据
完整数据点此

{
    "department": [
        {
            "Department_No": "D066",
            "Department_Name": "X990",
            "Limit": 3,
            "GPA_Limit": 2.5360000133514406,
            "Tags": [
                "hiking",
                "dancing",
                "English",
                "swimming",
                "reading"
            ],
            ...
     "student":[
            ...
            {
            "Student_No": "S031504847",
            "Student_Name": "W893",
            "Sex": "male",
            "GPA": 3.1907501220703127,
            "Tags": [
                "game",
                "music"
            ],
            "Free_Time": [
            "Sat.9: 00~10: 00","Sat.14: 00~15:00","Mon.9: 00~10:00","Tue.20: 00~21: 00","Sun.20:00~21: 00","Sat.21: 00~22: 00","Tue.10: 00~11: 00","Sat.10: 00~11: 00"],
            "Choice": [
                "D078",
                "D091",
                "D041"
            ]
        },
        ...
     ]
}

输出数据
完整数据点此

{
    "matched_department_view": [
        {
            "department_no": "D066",
            "chosen_students": [
                "S031500428",
                "S031505147",
                "S031501728"
            ]
        },
        ...
      ]
    "matched_student_view": [
            {
                "department_no": "S031501327",
                "chosen_department": [
                    "D098",
                    "D037"
                ]
            },    
            ...
        ]
   "standalone_departments": [
           "D075",
           "D056",
           "D093",
           "D038"
       ],
   "standalone_students": [
           "S031508339",
           "S031501654",
           "S031503336",    
           ...
      ]
}
  • 测试5000位同学,100个部门的情况

输入数据
完整数据点此

{
    "department": [
        {
            "Department_No": "D066",
            "Department_Name": "A948",
            "Limit": 14,
            "GPA_Limit": 1.600000023841858,
            "Tags": [
                "music",
                "document",
                "travelling",
                "programing",
                "game"
            ],
            "Schedules": [
                "Mon.14: 00~15: 00",
                "Mon.21: 00~22: 00",
                "Thu.14: 00~15: 00",
                "Sun.10: 00~11: 00",
                "Tue.14: 00~15: 00"
            ]
        },
        ...
      ]
    "student": [
       {
           "Student_No": "S031504233",
           "Student_Name": "M553",
           "Sex": "male",
           "GPA": 3.126610040664673,
           "Tags": [
               "dancing",
               "running"
           ],
           "Free_Time": [
               "Wed.9: 00~10: 00",
               "Wed.10: 00~11: 00",
               "Tue.9: 00~10: 00",
               "Fri.16: 00~17: 00",
               "Thu.16: 00~17: 00",
               "Wed.19: 00~20: 00",
               "Thu.14: 00~15: 00",
               "Fri.19: 00~20: 00",
               "Mon.10: 00~11: 00"
           ],
           "Choice": [
               "D053",
               "D056",
               "D075",
               "D026"
           ]
       },
       ...
      ]
}

输出数据
完整数据点此

{
    "matched_department_view": [
        {
            "department_no": "D066",
            "chosen_students": [
                "S031500428",
                "S031505147",
                "S031501728"
            ]
        },
        ...
        ]
    "matched_student_view": [
        {
            "department_no": "S031500428",
            "chosen_department": [
                "D066",
                "D090"
            ]
        },
        ...
       ]
    "standalone_departments": [
       "D075",
       "D056",
       "D093",
       "D038"
   ],
    "standalone_students": [
    "S031508339",
    "S031501654",
    "S031503336",
    ...
    ]
}
  • 效能分析报告
    测试数据(100,5000)

在此前读json花费了巨大时间(超过一分钟),后来改进读取方式耗时不到四秒,主要耗时在matching匹配函数,另外读取json占一部分。

5、遇到的困难及解决方法

  • 困难描述

1.对于采用c++读取和写入json文件完全陌生。
2.每次操作部门都需要遍历所有学生,导致性能不佳。

  • 做过哪些尝试

1.在网络上寻找有效的解决方案和相关代码。
2.寻求队友的帮助。

  • 是否解决

采用较为流行的腾讯开源库rapidjson来读取和写入json,至少解决了输入输出问题。
匹配算法性能目前还处于较差的阶段,5000-100运行超过一分钟(汗颜)

  • 有何收获

get到json的相关姿势

6、对队友的评价

  • 有哪些好的地方值得学习

编码效率高,沟通能力良好!给五星好评,下次我再来。

  • 有哪些不好或者需要改进的地方

代码风格太过随意,函数和变量命名往往都看不懂还需他解释(可能我水平太菜了吧),缺少注释。

7、PSP

PSP2.1 Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟)
Planning 计划 60 60
· Estimate · 估计这个任务需要多少时间 60 60
Development 开发 1330 1430
· Analysis · 需求分析 (包括学习新技术) 120 60
· Design Spec · 生成设计文档 100 60
· Design Review · 设计复审 (和同事审核设计文档) 60 30
· Coding Standard · 代码规范 (为目前的开发制定合适的规范) 100 0
· Design · 具体设计 100 100
· Coding · 具体编码 650 800
· Code Review · 代码复审 100 150
· Test · 测试(自我测试,修改代码,提交修改) 100 150
Reporting 报告 150 250
· Test Report · 测试报告 135 100
· Size Measurement · 计算工作量 30 25
· Postmortem & Process Improvement Plan · 事后总结, 并提出过程改进计划 30 10
合计 1450 1625

8、学习进度表

1、结队信息

第N周 新增代码(行) 累计代码(行) 本周学习耗时(小时) 累计学习耗时(小时) 重要成长
1 300 300 6 6 重拾C++,初学PHP
2 15 21 学习了原型设计软件的操作及NABCD概念
3 600 900 24 45 学习json的读写,C++ level up
posted @ 2017-10-15 20:19  微困  阅读(248)  评论(6编辑  收藏  举报