您的位置:首页 > 其它

结对项目第二次作业

2017-10-09 21:55 260 查看

作者

011500908 陈裕鹏

结对队友

031502500 林炜鸿

Github链接

项目地址

输入数据

input_data.txt




这组数据从结果上看没有unlucky_department

我们先是随机了所有部门的tags和event schedule,

之后又随机了所有学生的tags和free time

之后对每一个学生,遍历所有部门,并设一个参数NegScore反映出学生对每一个部门的喜爱程度

NegScore越小,则表示该学生越喜欢这个部门

在寻找的过程中,不断将时间冲突的部门用NegScore较小的那一个替换

确保此学生申请的所有部门互不冲突

最后对所有部门的NegScore排序,取最小的不超过5个的部门


建模过程


两个人稍微讨论了一下觉得这是一个匹配的问题,然后就想了一些情况

比如说应该是最大人次优先呢还是最大人数优先?

还比如说如果一个人申请的两个部门时间上有冲突的话应该要怎么办呢?

等等之类。。。

最终我们选择了最大人次优先进行匹配。


问题建模


我们利用了最小费用最大流算法来解决此问题。

将所有学生和部门都抽象成图上的点。

流量即为通过部门申请的人次,费用即为所有学生的喜好程度的和。




算法实现


当A学生向B部门提出入部申请的时候,就从A向B连一条流量为1的边。

这条边容量为1,费用为这个B部门在A学生心目中的名次。

名次越高,费用越低,从而越可能选中这条边。

之后从源点向每个学生连一条流量为无穷,费用为0的边。

从每个部门向汇点连一条流量为该部门限定人数,费用为0的边。

之后在图上跑一遍费用流。

算法结束之后,如果A学生到B部门的边上有流量通过,则说明A加入了B部门。

所以只要遍历一下所有学生和部门之间的连边,检查边上的流量情况,就能获得所有部门的部员情况以及未能加入任一部门的学生和没有部员的部门。


代码规范

利用驼峰命名法来对变量,函数和对象进行命名。



将直接引用的最小费用最大流算法进行模板的封装。



利用C11新特性来简化对容器遍历的书写。



结果评估


此算法所能求出的最大人次,并非至少参与一个部门的学生的最大值(即unlucky_student的最小值),而是所有部门部员数总和的最大值。同时在此优化目标下,求出了全局权值最优的一个解。

这个算法的好处在于,能够简单地建立模型,实现算法,并且对问题得出一个合理的解。

这个算法的缺陷在于,不够贴近现实,我们并没有处理一些现实中会遇到的情况,如讨论中的内容,这里不再赘述。

同时这个算法能够再进行增强,比如可以再增加一些限制,可以更加的模拟现实情况


最后一点感想


炜鸿同学想法了得,一下子就提出了好几个方案,最终我们选定的也是他提出的方案,同时他又负责了数据生成器的代码,无论是想法还是动手能力都是属于比较厉害的那一部分人。

很高兴炜鸿同学也会c++11的一些特性,这让我们的代码规范很有效果,同时代码会相对的优雅。

在编程的过程中,炜鸿同学还展示了他灵活的编译技巧,让我很是佩服。

炜鸿同学不仅想法好代码能力强,同时也很有耐心能够跟我好好的解释他的思路,对于我的问题也能不吝啬回答,真是辛苦了。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: