[关闭]
@thousfeet 2017-10-09T22:03:54.000000Z 字数 2932 阅读 960

《软工实践》结对项目 - 部门纳新智能匹配

软工实践


结对成员

郑浩晖 031502442
刘晨瑶 031502522


项目Github链接

https://github.com/TheSkyFucker/DepartmentSelector


数据的生成

一个样例(给链接,贴出关键数据)

程序中考虑的因素

对于学生:

对于部门:


匹配程序

数据建模

思路(分配原则)

假设每名学生都是理性填报。

我们以尽量迎合意愿相对公平的原则为前提,采用类似高考志愿模式来设计匹配算法。

考虑到,部门意愿的优先级排序,是学生有根据多方综合考虑的(包括兴趣爱好、特长以及空闲时间等)。因此我们不首先去做标签或时间匹配,而是以学生的意愿列表为依据去投报部门。

并且,假设“学生空余时间”满足每周一致,没有单双周的问题,且“部门活动时间”是常规活动,而非临时活动。那么,只要某部门和某学生的空闲时间有冲突,也就代表着每次该部门在该时段举行活动,此同学都无法参加。为满足第一次作业中“如果一个学生常规部门活动时间请假超过6次,将面临被淘汰”的条件,我们直接将空闲时间冲突的学生筛去

算法流程如下:

对于每名同学,有如下步骤:

(1)投到下一轮志愿的部门;
(2)为每个部门执行淘汰算法;
(3)若中选,从空闲时间中扣去花在该部门的时间,回到(1)

其中,淘汰算法步骤如下:

(1)筛选掉时间冲突的
(2)若剩余人数不超过部门人数限制,则全部中选,退出
(3)为每个学生根据“兴趣标签”计算一个排序权值 = 标签匹配数 * 中选价值。定义中选价值为:(已中选部门数量+1)的倒数
(4)匹配值从高到低排序,淘汰多余的人数

我们认为,对于学生选择部门这件事而言,是符合意愿宁缺毋滥、而非类似选导那样非要匹配一个不可的。
因此有如下可能的“异常”状态:

  1. 即使与某部门的标签再匹配,但只要不在学生的意愿列表中就绝不会中选。
  2. 多数人投报极个别部门,然后几乎全部落选。

对于此类“异常”我们的解释:

对于1) 高达5个的志愿数量几乎是可以避免“还有想去的部门但不够填”的状况,因此,把一个学生强制塞到不想去的部门是不可取的方案。
对于2) 这种情况发生的可能性是满足约定的一部分,完全取决于输入的数据的“好坏”,想要避免就应该在学生填报的时候,说明一下不要一个篮子装全部的鸡蛋的道理。

架构设计图


代码规范

https://github.com/TheSkyFucker/DepartmentSelector/blob/master/Docs/Coding%20Standard.md

代码体现

  1. std::string m_id; //部门编号
  2. std::vector<Student *> m_students; //部门正式成员
  3. int m_memberLimit; //学生上限
  4. std::vector<TimeSegment> m_schedules; //活动时间
  5. std::vector<std::string> m_tags; //兴趣标签
  6. std::vector<Student *> m_tempStudents; //部门候选成员
  1. void Student::DeleteFreeTimes(TimeSegment aSegment) throw()
  2. {
  3. std::vector<TimeSegment> result;
  4. for (auto m_freeTime : m_freeTimes)
  5. {
  6. auto tmpSegs = m_freeTime.Cut(aSegment);
  7. for (auto aSeg : tmpSegs)
  8. {
  9. result.push_back(aSeg);
  10. }
  11. }
  12. m_freeTimes = result;
  13. }


结果评估

指标条件

考虑到的指标条件有如下几条:

1.学生中选率——中选/总人数
2.部门收获率——纳新不为0的部门数/总部门数
3.学生满意度——(5-i+1)/5 ,i为中选第几志愿部门。(如,中选第一志愿的满意度为5分,第二志愿4分...,没有中选则为0)
4. 部门满意度——标签的匹配数 * 中选价值

针对于我们的算法,第4点将不用于考量指标的优良,因为这正是分配算法的依据。而1、2点,根据之前的分析,用两个值做评定指标并不满足我们“符合意愿、宁缺毋滥”的原则。

因此,我们选择第3点的累加和作为评判指标,也即统计所有学生满意度的平均值。

分析自己的输出是否达到算法所达到的指标


结对小结

结对编码的感受

对友打代码手速爆炸快,打起来超有气势,因为作业正值国庆期间,隔着屏幕感觉仿佛是在看游戏主播打代码。全程可以说是肥肠的愉快了。(x

一个人打代码时常打着打着陷入脑子浆糊,能被及时点醒或者状态不好的时候换人其实效率很高。还没有哪次打代码有完整遵守过规范,因为背后还有人盯着……

对于代码能力阶梯级差距的结对来说,仅仅在观察的过程中就能学到很多东西。get到了很多之前没有见过的操作,比如看到对面一键生成函数注释十分惊奇,下线马上也给自己的VS安了AssistX(

一些分享

1.瓶颈的时候回去再翻一遍需求,能很快会有思路。(在和对友前期讨论的时候一字一字的看了不下五遍作业博客)
2.结对过程中一定时刻保持思路状态同步状态,因为即使实现讨论了再多,都会有不少问题在实现的过程中被一个个提出来,及时的交互解决比起一个人苦想会愉快很多(结对编程的迷之乐趣)XD

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注