这个作业属于哪个课程 | https://bbs.csdn.net/forums/fzusdn |
---|---|
这个作业要求在哪里 | https://bbs.csdn.net/topics/608425848 |
这个作业的目标 | 设计一个点名算法 |
学号 | 072003403 |
队友学号 | 032002217 |
博客链接 | 链接 |
作业描述
栋哥对大家第一次结对编程作业的原型设计感到很满意,为了尽快让同学们使用上软件,于是栋哥花一晚上时间开发了一个点名小程序。但是在上线运行过后,发现了一些问题:大多数老师习惯在每次上课后或下课前的一小段时间内进行点名。如果采用全点的方式,在这段时间里,后端服务器需要处理大量的请求,拥塞导致响应速度变慢,给点名小程序带来极差的使用体验。采用随机抽点的方式,能够有效减少并发量,但是无法保证点名的质量,难以有效抓出没有到教室的同学。所以栋哥急需大家设计一个算法来解决这个问题,要求能够最小化向后端发送的请求次数,最大化抓出缺勤同学的数量。
具体要求
定义5门课程,每个课程班级人数为90人,一学期共20次课。每门课程均有5-8位同学缺席了该学期80%的课,此外每次课程均还有0-3位同学由于各种原因缺席。
参数定义
- 请求次数:定义在一次点名中,获取一位同学是否到达课堂的情况为一次请求。
- 有效点名:一位同学缺席该课程的一次课,算法在这次课上抽点到该同学,视为一次有效点名,一次课可包含多次有效点名。
评价标准
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-42Z1i6FM-1665580765480)(https://img-community.csdnimg.cn/images/a125a226e09e47b4bdca1b38ca3a44ab.png “#left”)]
重难点分析
怎么使用最少的点名次数进行最多次有效点名,重心在于检索经常缺课的58人,如果为了检索剩下的82到85个人中的三个人,这样耗费的时间必然是前者的几十倍。思路如下:既然已经不是全点,必然有缺漏,假设一个班级二十次点名全点,那么是100%的命中但E的大小是(511)/90 期望为0.089。当然也可以前几次全点,后几次用算法点名,但都达不到E的比较大的值(因为一个班级就20次点名),不妨就第一次全点,最大可能的找出经常缺课的那58人,并进行标记,当生成点名表(数据集)时被标记的有80%的概率缺课,同时缺课次数加一。58随机生成最为定值,不考虑第一次来了后面全不来等情况,如果要考虑,请采用全点方式。
// 定义学生类,id是唯一标识,absent是缺席次数,tag标记为经常迟到的5~8人
static class Student {
int id;
int absent;
int tag;
}
for (int i = 1; i <= 90; i++)
{
// 如果是被标记了的,会有一个大概率缺课
if(students[i].tag==1)
{
if(random.nextInt(1000)<800)
{
students[i].absent++;
// 每次点名都会排序,最经常迟到的会排在最前面,为了使E最大只点名最前面的十个人,点到没来次数加一
if(i<10) valid++;
}
}
// 否则只会有个小概率缺课(反正都会漏点,为了让E更大漏点无所谓
// (就像偶尔生病请假等小概率没必要浪费算法规模))
else {
int a= random.nextInt(1000);
// 随机数生成要对应概率生成,这是转换后a的动态区间(0~3缺课)也是动态的
while (a>((3.000/82)*1000))
{
a=random.nextInt(1000);
}
if(random.nextInt(1000)<a) students[i].absent++;
if(i<=10)
{
students[i].absent++;
valid++;
}
}
}
E的最终结果
0.5514285714285714
0.555
0.5614285714285714
0.56
0.5492857142857143
0.5528571428571428
0.5457142857142857
0.5571428571428572
0.5471428571428572
0.5485714285714286
结果趋近于0.55 稳定,且有一定效率,实际上因为第一次的全点拉低了概率,第二次开始的点名十次大约都有7~8次命中。
习进度条
PSP及学习进度条
PSP
PSP | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 40 | 50 |
Estimate | 估计这个任务需要多少时间 | 40 | 50 |
Development | 开发 | 650 | 720 |
Analysis | 需求分析 (包括学习新技术) | 150 | 160 |
Design Spec | 生成设计文档 | 30 | 30 |
Design Review | 设计复审 (和同事审核设计文档) | 30 | 40 |
Coding Standard | 代码规范 (为目前的开发制定合适的规范) | 20 | 25 |
Design | 具体设计 | 30 | 45 |
Coding | 具体编码 | 240 | 260 |
Code Review | 代码复审 | 60 | 60 |
Test | 测试(自我测试,修改代码,提交修改) | 90 | 100 |
Reporting | 报告 | 90 | 90 |
Test Report | 测试报告 | 30 | 25 |
Size Measurement | 计算工作量 | 20 | 30 |
Postmortem & Process Improvement Plan | 事后总结, 并提出过程改进计划 | 40 | 35 |
合计 | 820 | 910 |
学习进度条
第N周 | 本周学习耗时(小时) | 累计学习耗时 | 重要成长 |
---|---|---|---|
1 | 6 | 6 | 学习了有关流的相关概念,构思如何解决算法问题,设计算法思想,构建基本的数据参数模型 |
2 | 8 | 14 | 学习了流的具体操作,完善算法,确定算法结果,分析实际实现情况 |
代码仓库
-
github仓库链接
-
commit记录
结对照片
结对感受
有了上次的结对基础,我们对对方各自擅长的地方也有一定的了解,所以前期的分工安排上很快达成了一致。这次我们使用的语言是Java,两个人之前没有写过java,所以刚开始打代码感觉十分困难,但是通过不断的查阅资料,最终还算是顺利完成,并且也掌握了一定的java基础。
次结对作业较与第一次结对作业对我们来说难度不小,从设计算法到编写代码,我们都花费了不少时间去学习,学习如何创建数据集等等,而且通过本次实验,我我也更加深刻理解了结对的意义,与队友分工合作完成任务,不仅提高了效率,也从对方那里学习到了不少东西,得到了不少收获。