Github链接

结对成员:

031502308 付逸豪

031502113 胡俊钦



数据生成

样例链接: 来点我啊

由于在生成数据的时候做了很多符合实际情况的限制,所以生成的数据都挺好的,就随便选了一组。

提供输入包括:

20个部门
部门编号(唯一确定值),字符;
各部门需要学生数的要求的上限,单个,数值,在[10,15]内;
各部门的特点标签,多个(两个以上),字符;
各部门的常规活动时间段,多个(两个以上),字符。

300个学生
学生编号(唯一确定值),字符;
学生空闲时间段,多个(两个以上),字符;
兴趣标签,多个(两个以上),字符(学生的兴趣标签一定是所有部门特点标签其中的一个)
每个学生有不多于5个的部门意愿(助教测试时测试数据中部门意愿可能会出现空缺,非空缺的部分一定是部门编号中的一个,并按照优先级从高到底的顺序排序)。

数据生成就是根据上面的要求一个个生成,具体如下:

  • 部门部分

部门编号:部门编号先事先设定好,考虑到现实中的部门是固定的,就把部门编号固定为D001~D020,下面学生的意愿还要用到,所以用一个字符串数组存起来;

部门需要的学生数上限:由于限定范围在10~15,所以就是直接随机产生10~15的一个随机数;

部门的特点标签:事先设定21个标签,用数组存起来。要求至少输出两个标签,同时自己设定每个部门标签上限为4个,这是因为学生的平均兴趣标签一般是在5个以内,为了和学生标签数量相近,设定上限为4。输出时,先产生一个2~4的随机数,限定该部门标签数量,然后根据数量,随机产生标签的下标,根据下标到标签数组里面找到该标签并输出。同时,考虑到随机产生的下表可能重复,导致输出重复标签,又加了去重判断。

部门常规活动时间:这个的处理方式跟标签类似。考虑到实际情况,部门的活动时间大多是在“10:30~11:30”,“16:30~18:00”,“20:00~21:30”三个时间段,所以我们先预设了21个时间段,一周7天,每天三个,共21个,并用数组存起来。而部门的活动时间一周也是在5个以内,所以设定部门的活动时间数为2~5。一样的,先产生一个随机数限定数量,然后随机产生下标,再输出随机的时间段。为避免重复,增加重复判断。

  • 学生部分

学生编号: 300个学生数量多,而且现实中报名部门的学生本来就不是固定的,所以上面实现设定并存到数组的方式不再可取,就直接随机生成学生的编号。

学生空闲时间段:根据自己的课表预设“10:00~12:00”,“16:00~18:00”,“20:00~22:00”三个空闲时间段,加上星期,一共也是21个时间段。学生的空闲时间段比部门活动时间多半个小时,这也比较符合实际情况,毕竟不可能所有空闲时间都在部门活动。然后就跟产生部门活动时间一样的方式随机产生学生的空闲时间段。至于每个学生的空闲时间段数量,上限定为21(平均水平是这样,至于胆大一周七天假的不在考虑范围内~)。

学生标签:学生标签一定是部门标签里面的,所以直接用刚才的那个数组就好了,操作也一样,复制粘贴就搞定了。

部门意愿:每个学生有1~5个意愿,生成方法也大同小异。生成1~5的一个随机数限定数量,然后随机生成下标,到部门编号数组里面去找对应的部门编号进行输出。为了避免重复,加上重复判断。

  • 输出格式

说到这个输出格式,简直了。一开始并不知道json,作业上的样例旁边的小小“json”字眼并没有引起我的注意,一直以为那是助教不小心写上去的。所以就简单粗暴的手动空格换行加引号。小心翼翼的写,就怕格式不对。后来看到隔壁班群有个人一直在问json的问题,我就想是不是作业有要求,点上去又看了一下作业,没看到json
的字眼(博客上面的作业没有,班级博客上的作业有“json”的字眼,orz),就理所当然的认为是隔壁班的特殊要求。同时,自己班群很安静,根本没人提到json这个词,也就心安了。直到后来,终于有人提到了,我又看了一眼作业(这回点开的是班级博客上的),终于找到了那个不起眼的“json”,就发现事情不太对。百度了一下json,才知道是怎么回事。我就觉得奇怪,这回的作业为什么输出都加了引号,顿时整个容恩都不好了。后来在群里问,说是这样手动加并不犯法,才安心了一点。(本来想改来着,但是C++好像还要加第三方库啊什么的,试了几遍失败了,时间又不是很够了,就放弃了。手动输出格式的渣渣向json大佬致敬~)

匹配算法

  • 数据建模过程

如果说这是一种食品,我可以打包票,“纯手工制作,不添加任何防腐剂”。我们一开始并没有注意到json,是纯手工空格和缩进,所以数据建模过程也是纯手工模拟字符串读入。就是照着那个样例,一个个的模拟,简直是做到怀疑人生,动不动就缺点什么而导致出错,虽然耗了很多时间,但是不管怎样,最后还是完成了(都亏队友给力,orz)。实现的过程就是每次读入一个字符串,然后按照格式,去处理这个字符串,把它“剥离”出来,得到我们想要的数据。然后把部门和学生相关的信息用分别存在两个结构体中。总之就像剥茧抽丝那样,一点点抽出来然后存起来。

  • 匹配过程

我们的匹配模式大体是参照高校招生的模式。我们匹配的优先顺序是:志愿、时间、兴趣标签、已经参加的部门个数、学号(学好小的人优先)。制定优先顺序解释如下:首先,部门要选学生,显然要学生有报这个部门,又要尽可能的满足学生的意愿,所以就第一志愿优先;然后,尽管学生报名了,但是时间不允许,部门的活动时间都不能参加,那也不能收。第三个考虑的就是学生本身的兴趣,最后最后就直接以学号录取(这个是考虑到到后面有一些同等条件的少数同学,以学号录取,运气也是实力的一部分\偷笑)。
匹配的过程是:先一层循环,一个个部门扫过去,把第一志愿报这个部门的学生挑出来,删除其中没时间的人。关于是否有时间,经过讨论,我们最终采取的策略是,只要该同学能够参加一半以上的活动就好,而且时间段不一定是要完全对的上,允许一点偏差。比如说,活动时间是10:00~12:00,并不是说学生的空闲时间段一定要完全包含这个时间段,如果空闲时间段是在10:00~11:40,也是允许的,毕竟部门活动有事提前走也是允许的,同理,适当的迟到也是允许的。当然,时间能够完全匹配显然会优先录取。然后就是把这些学生根据标签和学号(从小到大)进行排序,最后按优先级一个个录取,人满为止,不满就全部录取。但是这样会有一种情况,那就是学生空闲时间满足,但是他加入的部门之间存在相同的活动时间,一个人显然不可能在同一时间参加两个不同的活动,但是他也会被两个部门全部录取。所以后来就采取学生的时间设为动态的策略,就是学生被一个部门录取后,这个学生的空闲时间要减掉部门中的活动时间段,这样就避免了这种情况的发生。对于unlucky的学生和部门,就是排除法,先各自存在一个set里,学生被选了或部门加入了一个学生,就把他们删除,最后剩下的就输出为unlucky的。至此,整个过程就结束了。

结果评估

样例链接: 你再点一次试试

从数据结果来看,一共300个学生,20个部门,其中101个学生没有被部门选上,199个人加入了部门,部门总容量251,实际收人251,部门全部收满人,三分之二的学生被录取,达到所有部门全部收满人的预期,这也符合实际情况,对匹配的结果还是较满意的。

代码规范

对于代码规范,我们主要做了如下约定:

  • 花括号另起一行,不要接在if和for语句后面。

  • if和for逻辑块只有一个语句也要花括号括起来。

  • 变量及函数命名采用小驼峰命名方式,除了第一个单词外,所有单词首字母大写。

  • 类名采用大驼峰方式,所有单词首字母大写。

  • 命名尽量能够见名知意,杜绝拼音。

  • 除了临时变量外,不出现单字符变量。

  • 不同逻辑块之间,函数与函数之间要留空行。

  • 对函数功能和重要变量以及复杂的逻辑代码块要有注释

总结&感受

  • 结对作业的感受

  上一次的结对作业仅仅只是设计,并没有打代码,所以体验就是分工省时省事高效。这一次的结对需要编程实现,也就是需要打代码。那就产生了很多的不同,特别是当结对遇到国庆,就只能叫伪结对,并不是栋哥所说的那样。像栋哥说的那样,一个人在打,另一个人在旁边看着,过一段时间交换着来,这种方式没有试过,不好说感受,但我觉得打代码的时候旁边有一个人盯着应该会很尴尬吧,我怕是一个字也打不出来。就说说我们国庆的伪结对的感受吧。
  遇到国庆,不知道别人怎么样,反正我是回家了,作业只能线上交流了(给QQ点个赞)。这便有一个问题,那就是可能队友发的消息,我一段时间后才能回复,然后他等回复没等到就继续做别的事情去了,等我回复的时候他也没有马上看到,如此这般,拖得时间就会比较久。按道理来说放假期间,时间会更多才对,但是回家就会完全打乱这一定律。不过还好,争做一名合格的夜猫子是我们都已经具备的良好品质,所以,晚上是讨论的好时机(白天琐事真的多,而且我在家很少把手机带在身上,经常看不到消息\流汗),但终究还是会对进度有所影响。如果是独立项目,显然就不存在这种问题。此外,结对作业还有一点很重要,那就是代码规范。这个跟独立项目很是不一样。独立项目可以随心所欲,开心就好。当然也要注意规范,但是不规范的话对于作业来说影响不大。这个就不一样了,这个没有事先商量好规范的话,就会有种两个人在对话,但是一个讲日语,一个讲韩语的感觉,影响就比较大了。总之,结对作业我觉得缺陷就是没有做独立项目来的自由,不管是时间上还是代码风格上。当然,这都是小问题,相比于结对带来的好处,简直是微不知足道。
  这次的结对编程,对于“双拳难敌四手”、“三个臭皮匠顶个诸葛亮”之类的俗语,有了刻骨铭心的认识。独立项目是自由一点,但是,终究还是只有一个人,不管从量上还是质上,都处于劣势。就说找bug吧,四只眼睛总比两只看得容易吧,更何况找自己的bug更是难,特别是那些打错了之类的,更是找到怀疑人生。比如我把星期三的英文写成“wen.”,让我自己找,永远也看不出来,但是付少火眼金睛就看出啦。同时,两个人的思维肯定比一个人要严密,特别是经过讨论,这绝不是1+1=2,思维的碰撞产生的是很多小火花,特别是跟大佬合作,简直是烟花啊(先偷偷开心一下,下面再开心好几下\嘚瑟)。在匹配算法这一块,讨论出来的情况比一个人单独想要严密得多,这就是结对的好处。我想结对作业想让我们体会到的应该也是1+1>>2吧。上面讲的是结对作业的感受,但是结对作业不同的人会有不同的感受,跟不同的人结对也会有不同的感受,下面我就讲讲自己跟付少结对的感受。

  • 跟大佬结对的感受

  大家好,给大家介绍一下,这是我的结对队友@付逸豪
  付少,在结对过程中,给我的感觉就是一个字——稳,那种感觉就是打英雄联盟的时候眼看自己的塔就要被推掉了,但是队友就只是一句“稳住,我们能赢,”给人的感觉就是那种特别可靠特别厉害特别稳的那种。在讨论过程中,他的思维和考虑问题的角度以及严谨性,都是非常非常的棒。每一次我都觉得这应该够全面了,但是一会他就又会提出新的情况,或许,这就是大佬。打代码的时候,他惊人的手速就像是一位钢琴大师在弹奏绝世佳曲,配合着键盘的敲击声,一股大佬的气场悄然形成。从付少身上,我学到了很多。他会在代码中加入很多的测试函数,用以调试输出,这是个好习惯,我也要向他学习。想自己以前都是一股脑把整个程序写下来,然后运行时出现了bug,要回去找bug修改,却发现代码太长,以至于根本不知道从何找起,简直是大海捞针,甚是痛苦。然后我还学到了一点,就是在freopen之后,cin就是从文件中读取,并不需要用键盘输入。除此之外,还get到了“由面到点”的思想。就是说,在程序设计时,可以先把一个大的框架想好,具体细节再慢慢一点一点的去完善,并不需要一步到位,直接就从细节开始处理,这也是我以前做的不好的地方。以前,对于整个程序缺少一个大局观,都是“以点成面”,上来就直接写细节,然后拼成一个面,往往会出现很多的问题。还有就是,前面有说到,我们的输出格式不是用json库,是手动加空格。生成数据的时候还好,但是到了要建模读入数据的时候,就很麻烦,什么都要手工去做,需要极大的耐心和细心,要是没有付少,我基本是要多花好几倍的时间。当然,作为一个大佬,付少还是很接地气的,这也使合作进行得非常顺利(听到同学说自己的结对作业基本是一个人在做,就为自己感到庆幸,让我再开心好几下\调皮)。总之我给付少5星好评,这次真是捡到宝了。



学生&部门智能匹配程序的更多相关文章

  1. perl智能匹配

    1.perl中~~为智能匹配,它能够智能地依据符号两側的操作数来确定操作. 如要推断某个元素是否存在于数组中,不使用智能匹配,程序像这样: my $x=2; my @array=(1,2,3); my ...

  2. 百度智能小程序弹窗组件wcPop|智能小程序自定义model弹窗模板

    百度智能小程序自定义弹窗组件wcPop|百度小程序model对话框|智能小程序弹窗界面模板 最近百度也推出了自己的智能小程序,如是就赶紧去试了下,官方提供的api还不是狠完整.而且官方提供的弹窗组件也 ...

  3. Perl语言学习笔记 15 智能匹配与give-when结构

    1.智能匹配操作符 替代绑定操作符: 在哈希中查找某一个键: 比較两个数组是否全然同样: 查找列表中是否存在某个元素: 智能匹配操作符与顺序无关.~~ 左右元素能够互换 2.智能操作符优先级 3.gi ...

  4. android音乐播放器开发 SweetMusicPlayer 智能匹配本地歌词

    上一篇写了使用MediaPlayer播放音乐,http://blog.csdn.net/huweigoodboy/article/details/39861539. 代码地址:https://gith ...

  5. 如何快速将百度大脑AI技术内置智能小程序中

    实现效果: 该AI智能小程序目前集成了百度AI开放平台数十个AI服务产品功能,包括人脸识别.文字识别.表格识别.红酒识别.货币识别.地标识别.手势识别.商标识别.果蔬识别.菜品识别等图片识别功能,以及 ...

  6. fastjson简单使用demo,@JSONField注解属性字段上与set、get方法上。实体类toString(),实体类转json的区别;_下划线-减号大小写智能匹配

    一.demo代码 @JSONField注解属性字段上与set.get方法上.使用@Data注解(lombok插件安装最下方),对属性“笔名”[pseudonym]手动重写setter/getter方法 ...

  7. Apache Mahout 简介 通过可伸缩、商业友好的机器学习来构建智能应用程序

    在信息时代,公司和个人的成功越来越依赖于迅速有效地将大量数据转化为可操作的信息.无论是每天处理数以千计的个人电子邮件消息,还是从海量博客文章中推测用户的意图,都需要使用一些工具来组织和增强数据. 这其 ...

  8. 第二篇:基于K-近邻分类算法的约会对象智能匹配系统

    前言 假如你想到某个在线约会网站寻找约会对象,那么你很可能将该约会网站的所有用户归为三类: 1. 不喜欢的 2. 有点魅力的 3. 很有魅力的 你如何决定某个用户属于上述的哪一类呢?想必你会分析用户的 ...

  9. vue过滤器微信小程序过滤器和百度智能小程序过滤器

    因为最近写了微信小程序和百度小程序,用到了过滤器,感觉还挺好用的,所以就来总结一下,希望能帮到你们. 1. 微信小程序过滤器: 1.1:首先建一个单独的wxs后缀的文件,一般放在utils文件夹里面. ...

随机推荐

  1. Hadoop2源码分析-YARN 的服务库和事件库

    1.概述 在<Hadoop2源码分析-YARN RPC 示例介绍>一文当中,给大家介绍了YARN 的 RPC 机制,以及相关代码的演示,今天我们继续去学习 YARN 的服务库和事件库,分享 ...

  2. Maven_3 如何从Maven远程存储库下载

    如果在你的项目中,需要使用到的jar包. 如果使用build path的话,你把你的项目给别人运行的时候,别人还需要去build path,如果要换jar包的版本,这些都是比较麻烦的,所以我们使用ma ...

  3. 深入理解JavaScript的事件循环(Event Loop)

    一.什么是事件循环 JS的代码执行是基于一种事件循环的机制,之所以称作事件循环,MDN给出的解释为 因为它经常被用于类似如下的方式来实现 while (queue.waitForMessage()) ...

  4. asp.net mvc之自定义WebViewPage

    采用Razor引擎的View文件最终都会编译成一个WebViewPage类型, 通过自定义WebViewPage,添加相应的属性和方法,你可以很方便的在View里调用, 自定义WebViewPage只 ...

  5. angularjs学习第七天笔记(系统指令学习)

    您好,接着在昨天对简单指令学习了解以后,今天开始学习了解angularjs中的系统指令 系统指令大部分都是以ng开始,这也是为什么在自定义指令命名时不要以ng开始的原因所在 系统指令在学习了分成两个部 ...

  6. IQuerable与IEnumable的区别

    核心区别: IQueryable该接口会把查询表达式先缓存到表达式树Expression 中,只有当真正用到数据的时候(例如 遍历 ),才会由IQueryProvider解析表达式树,生成sql语句执 ...

  7. 使用iconv进行编码gb2312转utf8 转码失败的坑

    iconv 编码gb2312转utf8 转码失败的坑 使用背景 项目中使用thrift进行C#程序调用c++接口,其中的协议是通过json进行传输的,由于默认thrift使用utf8进行传输,而C#和 ...

  8. python爬虫简单代码爬取郭德纲单口相声

    搜索老郭的单口相声,打开检查模式,刷新 没有什么有价值的东东, 不过....清掉内容, 点击一个相声,再看看有些什么 是不是发现了些什么 我们来点击这个看看, 首先看一下headers, 这个url是 ...

  9. array.js

    // “最后加” concat 连接两个或更多的数组,并返回结果. var a = ['a','b','c']; var b = ['x','y','z']; var c = a.concat(b,t ...

  10. 原生js 对象深拷贝

    经常需要copy一个对象,又怕拷贝有问题,那下面这段就很方便啦,不用担心copy只是一个引用了. /** @ values 需要copy的变量 */ function deepClone(values ...