结对编程————电梯调度
作业内容:电梯调度
现有一新建办公大厦,共有21层,共有四部电梯,所有电梯基本参数如下表所示:
电梯编号 |
可服务楼层 |
最大乘客数量 |
最大载重量 |
1 |
全部楼层 |
10 |
800 kg |
2 |
单层 |
10 |
800 kg |
3 |
双层 |
20 |
1600 kg |
4 |
全部楼层 |
20 |
2000 kg |
其使用规定如下:
1、楼层号为0~20,其中0号为地下一层;
2、有楼层限制的电梯不在响应楼层停靠,如单双层;
3、所有电梯采用统一按钮控制
请根据上述要求设计并实现一个电梯控制程序,如果有图形显示就更好了。
这次作业是结对编程作业,结对编程能编写出质量更高的代码,而且编写效率较高。对于这次结对编程,我的队友是黎士达,恰好我们都在一个寝室,这样更方便我们的合作交流。进过两周多的努力,终于完成了,我们所用的是Java编写语音,对于Java我们并不陌生,因为这次作业要求要有图像显示效果,所用我们最后决定用Java编写。
一、 编写所遇到的问题已经解决思路:
因为有C/C++的基础,所以对于Java理解并不是很难,但是也存在一些疑难,首先如果对于单部电梯设计起来比较简单,而我们总共要编写四部电梯,必须创建类的设计,类的类型和属性过多,其主要属性有编号、单双层、所在楼层、目标楼层。所以编写稍微复杂了些,如果稍不专心,下一步又得重新编写,代码也一度出过问题,我俩通过反复编写调试,终于完成电梯的调度,最后就是图形化界面的编写以及实现。
我们设置了一个简易的图形界面,有两个输入框:一个输入框用来键入人所在的当前楼层,另一个用来表示目的楼层;上(下)按钮表示操作指令的上(下)电梯;四个显示表显示电梯的运转详情。
二、编程所涉及到的主要函数以及类如下:
1、主函数:整体界面操作
Main() { order = 0; init(); myRun(); }
2、电梯类:对电梯的描述以及使电梯操作运行
class Elevator { private int id;//电梯编号 private int maxLoadWeight;//最大载重 private int loadWeight;//当前重量 private int state;//0:全层 1:单层 2:双层 private int floor; //电梯当前楼层 private int runState;//电梯运行状态 0--不动 1--向上 -1--向下 private int[] toFloors;//电梯目标楼层 private int start,end; private String info;//电梯信息 Elevator(int id, int maxLoadWeight, int state){ this.id = id; this.maxLoadWeight = maxLoadWeight; this.loadWeight = 0; this.state = state; this.setFloor(1); this.setRunState(0); toFloors = new int[20]; this.start = 0; this.end = 0; }
3、控制类:对电梯进行控制操作,控制电梯的运行
class Controller implements Runnable { Elevator Elevator = null; String info = null; Controller(Elevator e) { this.Elevator = e; } public String getInfo(){ return info; } public void run()//控制器执行,调度电梯 { while(true)//里面保持每个电梯的运行 { try { Elevator.run(); info = Elevator.show(); } catch (Exception e1)
{ e1.printStackTrace(); } try { Thread.sleep(3000); } catch (InterruptedException e)
{ e.printStackTrace(); } } } }
三、合作总结
通过这次结对编程,收获很大,不但锻炼了自己的沟通交流能力而且还提高了自己编写代码能力以及不足之处,高兴之余,特意拍照留恋。
四、程序附录:
package cn.sau.homework;
import java.awt.*;
import java.awt.event.*;
public class Main {
// 定义图形化界面引用
private Frame f;
private Button butUp;//上升按钮
private Button butDown;//下降按钮
private Label lab1;//当前楼层说明
private Label lab2;//目的楼层说明
private TextField personFloor;//人所在楼层
private TextField personToFloor; //人的目标楼层
private TextArea screen1;//显示信息
private TextArea screen2;//显示信息
private TextArea screen3;//显示信息
private TextArea screen4;//显示信息
private static int order; //有无按钮提示 0:无 1:↑ -1:↓
Main()
{
order = 0;
init();
myRun();
}
public void init()//图形界面初始化
{
f = new Frame("Elevator dispatching");
f.setSize(400,400);
f.setLayout(new FlowLayout());
f.setResizable(false);//窗体固定
f.setLocationRelativeTo(null);//窗体居中
lab1 = new Label("当前楼层");
lab2 = new Label("目的楼层");
personFloor = new TextField("",10);
personToFloor = new TextField("",10);
butUp = new Button("↑");
butDown = new Button("↓");
screen1 = new TextArea("显示屏",5,10,TextArea.SCROLLBARS_NONE);
screen2 = new TextArea("显示屏",5,10,TextArea.SCROLLBARS_NONE);
screen3 = new TextArea("显示屏",5,10,TextArea.SCROLLBARS_NONE);
screen4 = new TextArea("显示屏",5,10,TextArea.SCROLLBARS_NONE);
screen1.setEditable(false);
screen2.setEditable(false);
screen3.setEditable(false);
screen4.setEditable(false);
f.add(lab1);
f.add(personFloor);
f.add(butUp);
f.add(butDown);
f.add(lab2);
f.add(personToFloor);
f.add(screen1);
f.add(screen2);
f.add(screen3);
f.add(screen4);
myEvent();//添加事件
f.setVisible(true);
}
public boolean isBetween20(int floor)
{
if(floor>=0 && floor <=20)
return true;
return false;
}
public boolean isCorrect(int order,int floor,int toFloor)//判断输入是否合法
{
if(1 == order){//电梯向上
if(!isBetween20(floor))
{
System.out.println("你在这?? "+floor+"");
return false;
}
if(!isBetween20(toFloor))
{
System.out.println("你要去这?? "+floor);
return false;
}
if(toFloor <= floor)
{
System.out.println("你确定是要上楼? 从 "+floor+"-> "+toFloor);
return false;
}
return true;
}
else
{//电梯向下
if(!isBetween20(floor))
{
System.out.println("你在这?? "+floor+"");
return false;
}
if(!isBetween20(toFloor))
{
System.out.println("你要去这? "+floor);
return false;
}
if(toFloor >= floor)
{
System.out.println("你确定是要下楼? from "+floor+" to "+toFloor);
return false;
}
return true;
}
}
public int WhoIsRun(int e1Distance,int e2Distance,int e3Distance,int e4Distance)
{//根据传入参数判断哪个电梯最优
int[] arr = new int[]{e1Distance,e2Distance,e3Distance,e4Distance};
int index=0;
for(int i=1;i<4;i++){
if(arr[index]>arr[i])
index = i;
}
return index+1;
}
private void myEvent(){//创建事件监听
f.addWindowListener(new WindowAdapter()
{
public void windowClosing(WindowEvent e)
{
System.exit(0);
}
});
personFloor.addKeyListener(new KeyAdapter()
{
public void keyPressed(KeyEvent e)
{
int code = e.getKeyCode();
if(!(code>=KeyEvent.VK_0 && code <= KeyEvent.VK_9 || code==8))
{
System.out.println(code+"... 是非法的");
e.consume();
}
}
});
personToFloor.addKeyListener(new KeyAdapter()
{
public void keyPressed(KeyEvent e)
{
int code = e.getKeyCode();
if(!(code>=KeyEvent.VK_0 && code <= KeyEvent.VK_9 || code==8))
{
System.out.println(code+"... 是非法的");
e.consume();
}
}
});
butUp.addActionListener(new ActionListener()
{//上升按钮
public void actionPerformed(ActionEvent e)
{
int personF = new Integer(personFloor.getText());
int personTF = new Integer(personToFloor.getText());
if(isCorrect(1,personF,personTF))
{
order = 1;
}
else
order = 0;
System.out.println("上升按钮按下");
}
});
butDown.addActionListener(new ActionListener()
{//下降按钮
public void actionPerformed(ActionEvent e)
{
int personF = new Integer(personFloor.getText());
int personTF = new Integer(personToFloor.getText());
if(isCorrect(-1,personF,personTF))
{
order = -1;
}
else
order = 0;
System.out.println("下降按钮按下");
}
});
}
public void myRun()//为了调用非静态方法自创的主函数~
{
Elevator e1 = new Elevator(1,800,0);
Elevator e2 = new Elevator(2,800,1);
Elevator e3 = new Elevator(3,1600,2);
Elevator e4 = new Elevator(4,2000,0);
Controller controller1 = new Controller(e1);
Controller controller2 = new Controller(e2);
Controller controller3 = new Controller(e3);
Controller controller4 = new Controller(e4);
Thread t1 = new Thread(controller1);
Thread t2 = new Thread(controller2);
Thread t3 = new Thread(controller3);
Thread t4 = new Thread(controller4);
//开启电梯控制器
t1.start();
t2.start();
t3.start();
t4.start();
while(true)//接收命令
{
try{Thread.sleep(2000);
}
catch (InterruptedException e)
{
// TODO 自动生成的 catch块
e.printStackTrace();
}
//逻辑判断,哪个电梯拥有最短路径哪个电梯去接人
if(1 == order){//上升按钮
int personF = new Integer(personFloor.getText());
int personTF = new Integer(personToFloor.getText());
//逻辑判断 电梯最优方案
int e1Distance = e1.countDistance(personF, order);
int e2Distance = e2.countDistance(personF, order);
int e3Distance = e3.countDistance(personF, order);
int e4Distance = e4.countDistance(personF, order);
int result = WhoIsRun(e1Distance,e2Distance,e3Distance,e4Distance);
switch(result)
{
case 1:e1.add(personF, order, personTF);break;
case 2:e2.add(personF, order, personTF);break;
case 3:e3.add(personF, order, personTF);break;
case 4:e4.add(personF, order, personTF);break;
}
order = 0;
}
else if(-1 == order)//下降按钮
{
int personF = new Integer(personFloor.getText());
int personTF = new Integer(personToFloor.getText());
//逻辑判断 电梯最优方案
int e1Distance = e1.countDistance(personF, order);
int e2Distance = e2.countDistance(personF, order);
int e3Distance = e3.countDistance(personF, order);
int e4Distance = e4.countDistance(personF, order);
int result = WhoIsRun(e1Distance,e2Distance,e3Distance,e4Distance);
switch(result)
{
case 1:e1.add(personF, order, personTF);break;
case 2:e2.add(personF, order, personTF);break;
case 3:e3.add(personF, order, personTF);break;
case 4:e4.add(personF, order, personTF);break;
}
order = 0;
}
//清理屏幕
screen1.setText(controller1.getInfo());
screen2.setText(controller2.getInfo());
screen3.setText(controller3.getInfo());
screen4.setText(controller4.getInfo());
}
}
public static void main(String[] args) {
new Main();
}
}
class Controller implements Runnable
{
Elevator Elevator = null;
String info = null;
Controller(Elevator e)
{
this.Elevator = e;
}
public String getInfo(){
return info;
}
public void run()//控制器执行,调度电梯
{
while(true)//里面保持每个电梯的运行
{
try {
Elevator.run();
info = Elevator.show();
} catch (Exception e1) {
// TODO 自动生成的 catch 块
e1.printStackTrace();
}
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
}
}
}
class Elevator
{
private int id;//电梯编号
private int maxLoadWeight;//最大载重
private int loadWeight;//当前重量
private int state;//0:全层 1:单层 2:双层
private int floor; //电梯当前楼层
private int runState;//电梯运行状态 0--不动 1--向上 -1--向下
private int[] toFloors;//电梯目标楼层
private int start,end;
private String info;//电梯信息
Elevator(int id, int maxLoadWeight, int state){
this.id = id;
this.maxLoadWeight = maxLoadWeight;
this.loadWeight = 0;
this.state = state;
this.setFloor(1);
this.setRunState(0);
toFloors = new int[20];
this.start = 0;
this.end = 0;
}
public int countDistance(int personFloor, int runDirection)//未完成函数
{
if(state ==1 && (personFloor%2)==0)
return 100;
if(state ==2 && (personFloor%2)==1)
return 100;
if(end == start)
return Math.abs(personFloor - floor);
else if(end-start ==1){//电梯目标值为1个
if(toFloors[end-1] > floor){//电梯上升
if(1 == runDirection){//人上升 三种情况
if(personFloor < floor){
return (toFloors[end-1]-floor)*2+(floor-personFloor);
}else{
return personFloor-floor;
}
}else{//人下降 三种情况
if(personFloor>toFloors[end-1]){
return personFloor-floor;
}else if(personFloor < floor){
return (toFloors[end-1]-floor)*2+(floor-personFloor);
}else{
return (toFloors[end-1]-floor)+(personFloor-floor);
}
}
}else{//电梯下降
if(1 == runDirection){//人上升
if(personFloor>floor){
return (floor-toFloors[end-1])*2+(personFloor-floor);
}else if(personFloor < toFloors[end-1]){
return floor-personFloor;
}else{
return (floor-toFloors[end-1])+(personFloor-toFloors[end-1]);
}
}else{//人下降
if(personFloor>floor){
return (floor-toFloors[end-1])*2+(personFloor-floor);
}else if(personFloor < toFloors[end-1]){
return floor-personFloor;
}
}
}
}else{//电梯目标值为两个以上
if(toFloors[end-1] >toFloors[end-2]){//电梯最终状态为上升
if(1 == runDirection){//人上升 三种情况
if(personFloor < toFloors[end-2]){
return (toFloors[end-1]-toFloors[end-2])*2+(toFloors[end-2]-personFloor);
}else{
return personFloor-toFloors[end-2];
}
}else{//人下降 三种情况
if(personFloor>toFloors[end-1]){
return personFloor-toFloors[end-2];
}else if(personFloor < toFloors[end-2]){
return (toFloors[end-1]-toFloors[end-2])*2+(toFloors[end-2]-personFloor);
}else{
return (toFloors[end-1]-toFloors[end-2])+(personFloor-toFloors[end-2]);
}
}
}else{//电梯最终状态为下降
if(1 == runDirection){//人上升
if(personFloor>toFloors[end-2]){
return (toFloors[end-2]-toFloors[end-1])*2+(personFloor-toFloors[end-2]);
}else if(personFloor < toFloors[end-1]){
return toFloors[end-2]-personFloor;
}else{
return (toFloors[end-2]-toFloors[end-1])+(personFloor-toFloors[end-1]);
}
}else{//人下降
if(personFloor>toFloors[end-2]){
return (floor-toFloors[end-1])*2+(personFloor-toFloors[end-2]);
}else if(personFloor < toFloors[end-1]){
return toFloors[end-2]-personFloor;
}
}
}
}
return -100;//防止出错判断
}
public void add(int personFloor, int runDirection,int toFloor)
{
if (end - start > 0)//电梯目标楼层大于0个
{
if ((toFloors[end-1] - toFloors[end - 2])*runDirection > 0) {//人和电梯同方向
if (1 == runDirection)//同向上
{
if (personFloor > toFloors[end - 1])//人所在楼层 高于 电梯去的最高楼层
{
toFloors[(end++) % 20] = personFloor;
toFloors[(end++) % 20] = toFloor;
}else {//人所在楼层 低于 电梯去的最高楼层
toFloors[end] = toFloors[(end++)%20 -1];
toFloors[end - 2] = personFloor;
if (toFloor > toFloors[end - 1])//人要去楼层高于电梯所在楼层
toFloors[(end++) % 20] = toFloor;
else{ //人要去楼层低于电梯所在楼层
toFloors[end] = toFloors[end - 1];
toFloors[end - 1] = toFloor;
end = (end++) % 20;
}
}
}
else {//同向下
if (personFloor < toFloors[end - 1])//人所在楼层 低于 电梯去的最高楼层
{
toFloors[(end++) % 20] = personFloor;
toFloors[(end++) % 20] = toFloor;
}
else {//人所在楼层 高于 电梯去的最低楼层
toFloors[end] = toFloors[end - 1];
toFloors[end - 1] = personFloor;
end = (end++)%20;
if (toFloor < toFloors[end - 1])//人要去楼层低于电梯所在楼层
toFloors[(end++) % 20] = toFloor;
else { //人要去楼层高于电梯所在楼层
toFloors[end] = toFloors[end - 1];
toFloors[end - 1] = toFloor;
end = (end++) % 20;
}
}
}
}
else {//反方向
toFloors[(end++) % 20] = personFloor;
toFloors[(end++) % 20] = toFloor;
}
}
else//电梯目标楼层数量为1或者0
{
toFloors[(end++) % 20] = personFloor;
toFloors[(end++) % 20] = toFloor;
}
}
public void run()throws Exception//电梯运行
{
if (start != end)//需要运行
{
if (floor < toFloors[start])//向上
{
runState = 1;
floor++;
}
else if (floor > toFloors[start])//向下
{
runState = -1;
floor--;
}
else//floor = toFloors[start] 到目的地
{
System.out.println("电梯"+id+" 已到达到达目的地:"+floor);
runState = 0;
start = (start+1)%20;
}
}
}
public String show(){
info = id+"'s Elevator \non "+floor+"'s floor\nis ";
if(1 == runState)
return info+" ↑";
if(-1 == runState)
return info+" ↓";
return info+" -- ";
}
public int getRunState() {
return runState;
}
public void setRunState(int runState) {
this.runState = runState;
}
public int getFloor() {
return floor;
}
public void setFloor(int floor) {
this.floor = floor;
}
运行结果: