结对作业—电梯调度
现有一新建办公大厦,共有21层,共有四部电梯,所有电梯基本参数如下表所示:
电梯编号 |
可服务楼层 |
最大乘客数量 |
最大载重量 |
1 |
全部楼层 |
10 |
800 kg |
2 |
单层 |
10 |
800 kg |
3 |
双层 |
20 |
1600 kg |
4 |
全部楼层 |
20 |
2000 kg |
其使用规定如下:
1、楼层号为0~20,其中0号为地下一层;
2、有楼层限制的电梯不在响应楼层停靠,如单双层;
3、所有电梯采用统一按钮控制
上面是结对编程题目要求,我的小伙伴是白新宇:http://home.cnblogs.com/u/baiyinyu/,当结对编程开始时,我们就在开始准备了,最开始我们根据要求讨论到底用什么语言写,虽然Java能够更轻松的编写出界面,但是考虑到这是两个人第一次合作的,所以选择了C语言进行编写,虽然这样不好写界面,但是结对编程重要的是合作,这样,我们能够更好的共同讨论和研究编程过程中的问题。
程序分析:
首先我们选择电梯的存储,通过讨论决定用结构体数组进行存储,结构体里面分别存有电梯现在所在楼层,电梯目的楼层,所需要走的楼层数;然后通过结构体数组中的四个结构体分别存放电梯1到电梯4,代码如下:
struct elevator { int present;//电梯现在所在楼层 int aim;//电梯要到的楼层 int move;//电梯走的楼层数 }lift[4];
主函数中定义一个变量,用来判断是否结束电梯的使用,用while循环来进行电梯的显示和乘客的请求页面,代码如下:
void main() { int num = 1; while (num == 1) { show(); num=elevator_choice(); } }
乘客请求页面,会让用户填写想去的楼层和自己所在的楼层,因为电梯最高到20楼,所以当所填的楼层超过20的时候,系统自定义为20,然后调用elevator_panduan()函数,来进行电梯的选择,代码如下:
int elevator_choice() { int floors;//当前楼层数 int aim;//想到达的层数 int num; printf("0层是地下一层,顶层为20楼\n"); printf("请输入你所在的楼层数:"); scanf_s("%d", &floors); if (floors > 20) floors = 20; printf("请输入你想到达的层数:"); scanf_s("%d", &aim); if (aim > 20) aim = 20; printf("\n"); num=elevator_panduan(floors, aim); return num; }
电梯的选择,首先判断乘客所在楼层是奇数楼层还是偶数楼层,当是奇数楼层是调用Short2()函数,然后进行目的楼层的判定;如果是偶数楼层,调用Short1()函数,然后进行目的楼层的判定;最后得到一个电梯号,然后连同乘客所在楼层和目的楼层传递给elevator_run()函数来运行电梯。代码如下:
int elevator_panduan(int now, int future) { int i, a[3]; if (now % 2 == 0) { a[0] = 0; a[1] = 2; a[2] = 3; i = Short1(a, future, now);//偶数返回使用的电梯。 } else if (now % 2 == 1) { a[0] = 0; a[1] = 1; a[2] = 3; i = Short2(a, future, now);//奇数返回使用电梯号。 } printf("欢迎乘坐%d号电梯\n", i + 1); int num=elevator_run(i, now, future); return num; } int Short1(int ele[], int fu, int nw)//找出使用哪个电梯1 偶数楼层开始判断 { int min = ele[0]; int k = Diff(lift[min].present, nw); if (fu % 2 == 0) { for (int i = 1; i < 3; i++) { if (k > Diff(lift[ele[i]].present, nw)) { k = Diff(lift[ele[i]].present, nw); min = ele[i]; } } return min; } if (fu % 2 == 1) { int y = Diff(lift[3].present, nw); if (k > y) { return 3; } else { return 0; } } } int Short2(int ele[], int fu, int nw)//找出使用哪种电梯2 奇数楼层开始判断 { int min = ele[0]; int k = Diff(lift[min].present, nw); if (fu % 2 == 1) { for (int i = 1; i < 3; i++) { if (k > Diff(lift[ele[i]].present, nw)) { k = Diff(lift[ele[i]].present, nw); min = ele[i]; } } return min; } if (fu % 2 == 0) { int y = Diff(lift[3].present, nw); if (k > y) { return 3; } else { return 0; } } }
电梯运行函数,通过传递进来的电梯号来选择需要进行调整的电梯,首先将该电梯的目的楼层修改成乘客所在楼层,将电梯需要走的数进行运算,每刷新一次,电梯就行走一步,当电梯到达乘客所在楼层后将电梯的目的楼层修改成乘客的目的楼层,然后等待刷新,或者是进行其他用户的请求,代码如下:
int elevator_run(int i, int now, int aim1)//运行电梯 { lift[i].aim = now; lift[i].move = Diff(lift[i].present, lift[i].aim); int k = lift[i].move; if (k == 0) { lift[i].aim = aim1; lift[i].move = Diff(lift[i].present, lift[i].aim); int k = lift[i].move; } int m = 2; while (m == 2) { show(); shuaxin(); printf("乘坐电梯请按1,刷新请按2,退出请按任意键"); scanf_s("%d", &m); if (lift[i].move == 0) { if (lift[i].aim == aim1) lift[i].move = 0; else { lift[i].aim = aim1; lift[i].move = Diff(lift[i].present, lift[i].aim); } } } if (m == 1) return 1; else return 0; } void shuaxin() { for (int y = 0; y < 4; y++) { if (lift[y].aim > lift[y].present) { lift[y].present++; lift[y].move--; } else if (lift[y].aim < lift[y].present) { lift[y].present--; lift[y].move--; } } }
以上就是我们所写程序的大体流程。
遇到问题:
1.第一个问题是当一个乘客无论输入目的楼层和所在楼层是什么,最后运行的电梯都是1号电梯,然后我们俩又重新看了一下判断电梯函数,发现代码有点复杂,然后我们决定用通过输出语句来找到我们的问题所在,从函数的一开始当有变量改变时,就将变量进行输出,然后看是否与我们的想法一样,多次尝试后我们终于找到了问题所在,原来我们进行距离比较的地方有些问题,经过修改,最终能够正确的指出所用哪个电梯了。
2.第二个问题就是当我们完成一个乘客的请求后,开始第二个乘客的请求后,无论怎么刷新电梯显示的楼层数都不会发生改变,当我们遇到这个问题时,首相想到的是是不是电梯选择函数出错了,还是用上面那种方法,在电梯选择返回函数返回值后进行输出,发现选择的电梯并没有错,然后我们就去看电梯运行和刷新函数,发现运行函数中while循环里每一次循环电梯的目的楼层和所在楼层都没有发生变化,这种情况只有在刷新函数出错了才会出现,然后我们俩主要看刷新函数提出多种情况,然后在纸上写出函数运行的状况,然后对比我们需要的状况,发现在函数的判定后多写了一个break,所以当遇到目的楼层和所在楼层相等的电梯时,就返回函数,没有将剩下的电梯进行刷新。
感想:
在这次结对编程作业中,我学到了很多东西,原来的时候都是自己想,自己做程序,会有很多各种各样的问题,最后都要自己来一点一点的完成,很容易懈怠,但是结对编程中,虽然也会出现错误,但是有一个小伙伴后,他会在我编写代码的过程中就指出一些错误,然后我们进行讨论,找出一个最优的解决方案,当我们想要偷懒时,我们都会互相督促,这样我们就可以更快的完成任务,也能在讨论中了解到更多
下面我来评价一下我的小伙伴—白新宇,在我们结对编程以前,我们的关系挺不错的,在这次的结对编程中,发现他是一个非常认真和求知欲强的人,我们进行分工时,他总是尽力的完成自己的任务,有什么不懂的就进行询问与查询,当我们一起讨论时,总是能提出一些不错的建议;在我们遇到代码错误时,他更是一个非常细心的人,有时候我注意不到的问题,他能够注意到,在我进行代码修改与调试的过程中,他都在旁边耐心的观察现象,并没有表现出一点的不耐烦,希望我们在以后的过程中能够有机会再一起合作,共同的学习与成长。
我在这次结对编程中也学到了很多,无论是有关于代码的编写方面还是有关于与他人合作方面都有所进步,通过解决编程中遇到的问题,让我以后再运到问题不是去抱怨,而是去想办法解决问题,跟有信心面对接下来的挑战,希望在接下来的团队项目中做的更好。
附录:
1.工作照:
2.程序运行图:
3.源码:
#include<stdio.h> #include<math.h> #include<stdlib.h> #include<conio.h> struct elevator { int present;//电梯现在所在楼层 int aim;//电梯要到的楼层 int move;//电梯走的楼层数 }lift[4]; void show();//电梯目录显示 int elevator_choice();//乘客选择 int elevator_panduan(int now, int future);//判断电梯 int Short1(int ele[], int fu, int nw);//偶数层找出相差最小的电梯 int Short2(int ele[], int fu, int nw);//奇数层找出相差最小的电梯 int Diff(int a, int b);//求两个数的差值 int elevator_run(int i, int now, int aim1);//改变电梯运行 void shuaxin();//电梯行走 void main() { int num = 1; while (num == 1) { show(); num=elevator_choice(); } } int elevator_choice() { int floors;//当前楼层数 int aim;//想到达的层数 int num; printf("0层是地下一层,顶层为20楼\n"); printf("请输入你所在的楼层数:"); scanf_s("%d", &floors); if (floors > 20) floors = 20; printf("请输入你想到达的层数:"); scanf_s("%d", &aim); if (aim > 20) aim = 20; printf("\n"); num=elevator_panduan(floors, aim); return num; } int elevator_panduan(int now, int future) { int i, a[3]; if (now % 2 == 0) { a[0] = 0; a[1] = 2; a[2] = 3; i = Short1(a, future, now);//偶数返回使用的电梯。 } else if (now % 2 == 1) { a[0] = 0; a[1] = 1; a[2] = 3; i = Short2(a, future, now);//奇数返回使用电梯号。 } printf("欢迎乘坐%d号电梯\n", i + 1); int num=elevator_run(i, now, future); return num; } int Short1(int ele[], int fu, int nw)//找出使用哪个电梯1 偶数楼层开始判断 { int min = ele[0]; int k = Diff(lift[min].present, nw); if (fu % 2 == 0) { for (int i = 1; i < 3; i++) { if (k > Diff(lift[ele[i]].present, nw)) { k = Diff(lift[ele[i]].present, nw); min = ele[i]; } } return min; } if (fu % 2 == 1) { int y = Diff(lift[3].present, nw); if (k > y) { return 3; } else { return 0; } } } int Short2(int ele[], int fu, int nw)//找出使用哪种电梯2 奇数楼层开始判断 { int min = ele[0]; int k = Diff(lift[min].present, nw); if (fu % 2 == 1) { for (int i = 1; i < 3; i++) { if (k > Diff(lift[ele[i]].present, nw)) { k = Diff(lift[ele[i]].present, nw); min = ele[i]; } } return min; } if (fu % 2 == 0) { int y = Diff(lift[3].present, nw); if (k > y) { return 3; } else { return 0; } } } void show()//显示楼层 { system("cls"); printf("电梯\t当前楼层 \t状态\n"); for (int i = 0; i < 4; i++) { printf("%d\t",i+1); printf("%d\t\t", lift[i].present); if (lift[i].move>0) printf("↑\n"); else if (lift[i].move == 0) printf("--\n"); else printf("--\n"); } } int Diff(int a, int b)//求差 { if (a > b) { return a - b; } else { if (a < b) { return b - a; } } } int elevator_run(int i, int now, int aim1)//运行电梯 { lift[i].aim = now; lift[i].move = Diff(lift[i].present, lift[i].aim); int k = lift[i].move; if (k == 0) { lift[i].aim = aim1; lift[i].move = Diff(lift[i].present, lift[i].aim); int k = lift[i].move; } int m = 2; while (m == 2) { show(); shuaxin(); printf("乘坐电梯请按1,刷新请按2,退出请按任意键"); scanf_s("%d", &m); if (lift[i].move == 0) { if (lift[i].aim == aim1) lift[i].move = 0; else { lift[i].aim = aim1; lift[i].move = Diff(lift[i].present, lift[i].aim); } } } if (m == 1) return 1; else return 0; } void shuaxin() { for (int y = 0; y < 4; y++) { if (lift[y].aim > lift[y].present) { lift[y].present++; lift[y].move--; } else if (lift[y].aim < lift[y].present) { lift[y].present--; lift[y].move--; } } }