zoukankan      html  css  js  c++  java
  • 结对第二次作业

    一、结对成员

    赖晓连 031502118
    林巧娜 031502125

    二、github链接

    github链接点这里

    三、数据模型

    认为最好的一组数据:https://github.com/sylviareset/clubProject/blob/master/clubProject/import.txt

    数据生成原理
    • 输入n和m,代表n个部门和m个学生,部门编号从1-n,学生编号从1-m;
    • 随机生成部门的所需学生人数上限,范围为[0,15],
    • 定义了十个标签:"programming","reading","film","music","dance","chess","handwriting","photograph","sports" ,"painting" ,从中随机选四个作为部门标签,选三个作为学生标签;
    • 部门活动时间段:在实际生活中,每个部门的常规活动时间都是一周一次,所以我们从周一到周天,时间在7:00-23:00之间任选一天以及其中的一个小时作为该部门的常规活动时间;
    • 学生空闲时间段:任选周一到周天五个天数(可重复),时间在7:00-23:00任意长度时间段,不可出现同一天的连续时间段分为两次出现的情况;
    • 学生志愿为5栏,从1-n个部门编号中挑选5个,考虑到实际情况,很多学生不一定对那么多部门感兴趣,只想加入少数部门,所以志愿可重复。
    • 学生绩点:生成1.00-5.00之间任意数,小数点保留两位。

    四、代码

    生成部门数据

    void department::DepartmentData(int n, int m)
    {
    	srand((unsigned)time(NULL));//随机化种子
    
    	for (int i = 0; i < n; i++)
    	{
    		depart[i].DepartmentNo = i + 1;//部门编号
    		depart[i].MemberLimit = (rand() % 15) + 1;//每个部门的限定人数
    												  //部门特点标签,每个部门4个
    		int count[9] = { 0 };
    		for (int j = 0; j < 4;)
    		{
    			int k = rand() % 9 + 1;
    			//解决部门特点标签重复问题
    			if (count[k] == 0)
    			{
    				count[k] = 1;
    				depart[i].DepartmentTags[j] = TotalTags[k];
    				j++;
    			}
    
    		}
    	}
    	for (int i = 0; i < n; i++)
    	{
    		//cout << "部门编号:" << depart[i].DepartmentNo << "  部门限定人数:" << depart[i].MemberLimit << endl;
    		cout << depart[i].DepartmentNo << " " << depart[i].MemberLimit << endl;
    		//cout << "部门特点:";
    
    		for (int j = 0; j < 4; j++)
    		{
    			cout << depart[i].DepartmentTags[j] << "  ";
    		}
    		cout << endl;
    		//cout << "部门常规活动时间段:";
    		int day = rand() % 7;
    		cout << week[day] << " ";
    		int hour1 = rand() % (15 + 1) + 7; //生成空余时间范围为7:00-22:00
    		int hour2 = hour1 + 1;
    
    		//int型转换为字符串,方便后面时间的表示
    		string str1 = std::to_string(hour2);
    		string str2 = std::to_string(hour1);
    		depart[i].Schedules = str2 + " :00- " + str1 + " :00";
    		cout << depart[i].Schedules << endl;
    	}
    }
    

    因为之前的作业有说到学生参加部门不能请假超过五次,所以我们觉得一个学生要是时间和部门常规时间不符合,那就不在考虑这位学生。因此我们是在时间已经符合的条件下,考虑志愿优先。
    而计算学生志愿的权重,首先考虑的是学生空余时间和部门常规时间是否匹配,没有匹配的学生加入该部门就没有意义了,只有匹配了才可以计算权重,参与到之后的选择中。对于权重中绩点和标签所占的比重,我们尝试过替换成其他的值,但是中选人数都很随机,不能直观的判断哪个更好,所以我们选择了一个比较好计算的比例。而计算权重时加入tidu是为了起到志愿优先的作用,不管你的成绩如何,只要你是优先选择该志愿的,那么你就会有更大的机会被选到。

    for (int j = 0; j < m; j++)
    {
    	
    	for (int k = 0; k < 5; k++)
    	{
    		//只有当学生时间与常规时间不冲突的时候才计算该志愿的权重
    		if (StuRank[st[j].StudentNo][st[j].aspiration[k]] == 1)
    		{
    			for (int f = 0; f < 3; f++)
    			{
    				for (int o = 0; o < 4; o++)
    				{
    					if ((q[st[j].aspiration[k]] != 1) && (st[j].StudentTags[f]
    						== dep[st[j].aspiration[k] - 1].DepartmentTags[o]))
    					{
    						num+=1;
    					}
    				}
    			}
    
    			if ((q[st[j].aspiration[k]] != 1))//第一次出现这个志愿
    			{
    				//志愿权重,梯度用来表示这个志愿是该学生的第几志愿,5K是第一志愿,4K是第二志愿,依次类推
    				StuRank[st[j].StudentNo][st[j].aspiration[k]] = (int)((st[j].Point*0.14 + num * 0.1 + tidu) * 1000);
    				
    				q[st[j].aspiration[k]] = 1;//将已经选择的部门编号置为1
    			}
    			num = 0;
    		}
    		tidu -= 1;//志愿梯度,第一志愿的梯度最大,之后逐级递减
    	}
    	for (int i = 1; i <= n; i++)
    	{
    		q[i] = 0;
    	}
    	memset(q, 0, sizeof(q));
    	tidu = 5;
    }
    

    对选择同一志愿的学生根据权重从大到小排序,部门选择时将根据权重选择

    void Function::sort()
    {
    	/*for (int i = 0; i < m; i++)
    	{
    		cout << "编号:" << i + 1 << endl;
    		for (int j = 0; j < 5; j++)
    		{
    			cout << "志愿 " << st[i].aspiration[j] << " 的分数为:" << StuRank[st[i].StudentNo][st[i].aspiration[j]] << endl;
    		}
    	}*/
    	for (int i = 0; i < n; i++)
    	{
    		for (int j = 0; j < m; j++)
    		{
    			if (StuRank[st[j].StudentNo][i + 1] != 0)
    			{
    				temp[i + 1][k[i + 1]] = st[j].StudentNo;//k[i+1]表示选了部门i+1的人一共有多少
    				k[i + 1]++;
    			}
    		}
    	}
    	for (int i = 0; i < n; i++)//i+1是部门编号
    	{
    		memset(s, 0, sizeof(s));
    		//将所有同学的该志愿权重存入一维数组
    		for (int j = 0; j < k[i + 1]; j++)
    		{
    			s[j] = StuRank[temp[i + 1][j]][i + 1];
    		}
    		for (int j = 0; j < k[i + 1] - 1; j++)//冒泡排序,按照权重从大到小排序
    		{
    			for (int p = 0; p < k[i + 1] - j - 1; p++)
    			{
    				if (s[p] <s[p + 1])
    				{
    					int t;
    					int t1;
    
    					//权重和学生编号同时替换
    					t1 = s[p];
    					s[p] = s[p + 1];
    					s[p + 1] = t1;
    
    					t = temp[i + 1][p]; //学生编号
    					temp[i + 1][p] = temp[i + 1][p + 1];
    					temp[i + 1][p + 1] = t;
    
    				}
    			}
    		}
    	}
    }
    

    五、代码规范

    1、使用驼峰式命名方法

        int DepartmentNo; //部门编号
    	int MemberLimit;//学生数上限
    	string DepartmentTags[20]; //特点标签,两个以上
    	string Schedules;//常规活动时间段
    

    2、每个功能封装成函数。

    六、结果分析评价

    时间符合的条件下考虑志愿优先:

    优先条件 学生总数 部门招收人数 匹配学生个数 未匹配学生个数 实际耗时(s) 输出文件路径
    志愿优先 300 183 136 164 0.998s output.txt

    七、结对感受

    laixl:这是第一次以结对编程的方式完成作业,感觉很神奇,感触也蛮多的。两个人编程和自己编程还是有很大差别的,在这次编程过程中,两个人的想法时常会撞出火花。而且两个人一起编程的时候有一些小的细节,小的错误,小伙伴也会立刻指出来,节省了很多时间。总之,这是一次奇妙的体验!
    reset-:本次的作业的完成时间正好是在国庆节,两个人不在一起,交流只通过网络就没有那么方便,虽然过程很无奈,但是在每次能够成功实现一块内容的时候激动心情也是加倍的。通过这次的结对编程作业,真正的体验了两人合作的编程感觉,可以互相讨论到底是什么地方出现了问题,一步步改正,也可以督促自己不要懒惰,遇到不会的及时询问,及时查资料,不会想着说先歇一会再来。

  • 相关阅读:
    react:如何创建一个新项目
    python3-多重继承
    Stylus-富有表现力的、动态的、健壮的CSS
    使用@property
    python3-使用__slots__
    python:实例属性和类属性
    java_day1
    学习笔记144—SPSS 重复测量方差分析【方法二】
    学习笔记143—SPSS 重复测量的多因素方差分析
    学习笔记142—Matlab如何读取Excel和写入Excel??
  • 原文地址:https://www.cnblogs.com/linqiaona/p/7643736.html
Copyright © 2011-2022 走看看