Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Scan

  • Loading branch information...
commit e2e9c299cc5f6a833d51b561b4c0d36e9ca92c7e 0 parents
elvin authored
9 .gitignore
@@ -0,0 +1,9 @@
+emu
+thor
+ascii
+*~
+
+*.app
+*.plist
+*.pro
+*.xcodproj/*
103 Docs/API-шп┤цШО.md
@@ -0,0 +1,103 @@
+经过不懈的努力,终于将框架和具体实现区分开来了。从此算法的设计者不需要再考虑底层模型的实现和整个机制的运行细节。为了更方便的设计算法,在此详细地介绍设计算法可能用到的 API,如果觉得 API 有任何不足和需要改进的地方,一定提出修改,提高整体的工作效率。
+
+###1. 嵌入算法
+
+在此,用我的写的 FCFS(First Come First Service)做例子,FCFS 算法是一种优先处理请求队列头的算法,也就是“先按电梯的楼层先服务”,为了嵌入这一种算法:
+
+1 在 **Headers/controller.h** 中声明新的算法函数 **static void Fcfs()**, 务必声明为静态函数
+
+```
+class Controller
+{
+public:
+ static void Fcfs();
+ /* 在这里补充更多算法 */
+};
+```
+
+2 在 **Sources** 目录下创建算法的实现 fcfs.cpp
+
+```
+#include "../Headers/models.h"
+
+/* 找到最为空闲的电梯 */
+Elevator* Idlest() {
+ /* SOME CODE */
+}
+
+/* 调度 */
+void Controller::Fcfs() {
+ while(Idlest() != NULL) {
+ if (Emulator::orders.empty()) return;
+ Elevator* idle = Idlest();
+ Order* order = Emulator::orders.front();
+ Emulator::orders.pop_front();
+ idle->PushInst(new Instruction(order->from, 1));
+ }
+}
+```
+
+在这个文件里,首先包含了 models.h 这个文件,这个文件包含了所有的基本的类,所谓基本类就是指除了特种电梯意外的所有类,如果算法对数据结构没有特殊的要求(比如要求改写 Elevator 类),那么这个头文件就足够了。
+
+接下来我写了一个叫 Idlest 的 helper 函数,在接下来就是刚才在 controller.h 里声明的调度函数。
+
+至此,嵌入算法的基本流程就结束了。
+
+###2. 算法设计的输入与输出
+
+
+仍然是一 Fcfs 为例子,在刚才的 fcfs.cpp 中,实现了这样一个函数
+
+```
+/* 调度 */
+void Controller::Fcfs() {
+ while(Idlest() != NULL) {
+ if (Emulator::orders.empty()) return;
+ Elevator* idle = Idlest();
+ Order* order = Emulator::orders.front();
+ Emulator::orders.pop_front();
+ idle->PushInst(new Instruction(order->from, 1));
+ }
+}
+```
+整个代码的大意是:有空闲的电梯时,并且有未处理的 order 时,把请求队列的 front 弹出,根据这个order 的信息向空闲的电梯发送一条指令,这条指令指定电梯去 order 发出的地方,行进的方向是上下两个方向皆可(行进方向待会讨论)。
+
+从这个算法的实现过程中,可以看出算法实现是基于 Emulator::orders 和 Emulator::elevators 的,并且在最后向某一台电梯推送了一条指令。简要的说:
+
+输入 = 当前情况,这些情况由 Emulator 中的静态成员(类似于全局变量)表现
+输出 = 向某台电梯推送一条或多条 Instruction
+
+附
+
+```
+/* instruction.h */
+class Instruction
+{
+public:
+ Instruction(int dest_, int dirCode_) : dest(dest_), dirCode(dirCode_){};
+ int dest; // 目的地
+ int dirCode; // 电梯行进过程中可接受请求的方向
+};
+```
+###3. 程序运行的流程
+
+* Born( ), 产生新的乘客和新的请求
+* Control( ), 执行 Controller 中不同的算法
+* Move( ), 每个电梯依据指令移动
+* Update( ), 更新统计数据,绘制图形界面等
+
+
+###3. 一些需要注意的细节说明
+
+* 电梯会优先依据给定的指令(Instruction, 下用 inst 代替一个实例)工作,朝着 inst.dest 前进。
+* 电梯运行途中如果开门的话,会把本层楼 inst.dirCode 对应的上、下请求接受,并且从全局请求序列中去除掉对应的请求。
+* inst.dirCode == 1, 电梯开门会接受本层上下两个方向的请求; inst.dirCode == 2,电梯开门会接受向上的请求; inst.dirCode == 3,电梯开门会本层接受向下的请求; inst.dirCode == 0, 电梯开门不会再接受请求,停在原地直到 controller 调度。
+* 如果电梯没有得到指令的话,会将楼层里的人按照从 0 层到顶层的顺序送达。
+* 假设乘客是知道电梯运行的方向的,比如当 dirCode == 2 时,只有向上走的乘客会进入电梯。
+* 当一台电梯要去的目的地中途被另一座电梯通过 dirCode 给取消的时候,这台电梯会 pop 掉现有的以该层楼为 dest,dirCode 比取消请求的 dirCode 小的指令。
+* Emulator 保证,只要楼层有人,那么这层楼一定会有请求,所以如果电梯来却没有装完所有人的时候,这层楼的人会重新请求电梯。
+
+###4. API 细节
+
+请大家在设计算法的时候参考 emulator.h 中的 static member,值得注意的几个是 elevators(所有电梯), floors(所有楼层), orders(所有请求,动态更新),一些对象的细节可以去对应的头文件中去看,更实用简明的文档会被不断的更新补充。
+
44 Docs/ASCIIчХМщЭвшп┤цШО.md
@@ -0,0 +1,44 @@
+为了方便大家编译和调试,推出了 ascii 版的模拟系统,该系统与 Qt 界面的系统类似,每 1 单位时间刷新一场景,
+现在的单位时间是 0.2 秒。由于调用的是 Linux/Gnu 系操作系统的 clear 和 sleep 函数,因此 windows 系统
+下无法正常的工作,见谅(或者谁有空写一下。。)。
+
+在此将关于 ascii 界面程序的编译和算法设计相关事项阐述一下:
+
+###编译和运行
+
+编译直接在根目录下 `$ make` 就行了,会生成一个叫做 `ascii` 的可执行文件。这个程序的主函数在 Sources/ascii.cpp 中,从主函数中可以见到,为了方便,楼层数固定为 10,电梯固定为 4 架,泊松参数为 0.02, 程序持续 100 个单位时间,在没有命令行参数的情况下,运行程序还要求输入算法的名字。如果需要指定参数可以用命令行参数指定 `./ascii 10 4 0.02 100 FCFS`。不过。。。这个功能还没做。。先忍一忍或者谁写一下。。
+
+###插入算法
+插入算法的顺序的基本方法还是和本目录下的《API-说明》中叙述的一样,只是为了配合 main 函数,需要在 Sources/ascii.cpp 中添加一个分支。
+
+具体的步骤是
+
+* 按照《API-说明》完成算法设计
+*`Sources/ascii.cpp` 中的 `Control()` 函数中增添分支,代码片段如下,相信看注释就懂了
+
+```
+void Control() {
+ if (Emulator::elevatorType == "PFCFS") {
+ Controller::Fcfs();
+ } /* else if (Emulator::elevatorType == "costflow") {
+ /* Controller::costflow();
+ /*
+ /* } */
+}
+```
+* 更新 Makefile
+
+打开根目录下的 Makefile
+
+```
+ascii: Sources/ascii.cpp Sources/elevator.cpp Sources/emulator.cpp Sources/fcfs.cpp Sources/passenger.cpp \
+ Sources/floor.cpp Sources/PoissRand.cpp Headers/controller.h Headers/elevator.h \
+ Headers/emulator.h Headers/fcfs.h Headers/floor.h Headers/instruction.h Headers/models.h Headers/internlib.h \
+ Headers/passenger.h Headers/PoissRand.h Sources/order.cpp Sources/Print.cpp /* 在这里添加新创建的文件, 如 xx_algorithm.cpp */
+
+ $(CC) $(CFLAGS) $(LIBS) -o ascii Sources/ascii.cpp Sources/elevator.cpp Sources/emulator.cpp Sources/fcfs.cpp Sources/passenger.cpp \
+ Sources/floor.cpp Sources/PoissRand.cpp Sources/order.cpp Sources/Print.cpp
+ /* 在这里添加新创建的需要编译和链接的文件, 如 xx_algorithm.cpp */
+```
+
+* `$ make`, 执行,就能够看见输出了~
8 Headers/PoissRand.h
@@ -0,0 +1,8 @@
+/*
+ * PARAMS:
+ * Emulator::lambda: the parameter Emulator::lambda in a Poiss Distribution(the average occurance of a event)
+ * RETURN:
+ * generates one ramdom number, and the sequence of these numbers is obay Poiss Distribution
+ */
+int PoissRand(double lambda);
+double Rand(double a, double b);
17 Headers/controller.h
@@ -0,0 +1,17 @@
+#ifndef __EleEmu__controller__
+#define __EleEmu__controller__
+/* 电梯调度器,每一个静态函数是一个调度算法 */
+class Controller
+{
+public:
+ static void Fcfs(); /* FCFS 算法 */
+
+ static void Scan();
+
+ static void CostFLow();
+
+ static void PickUp();
+
+ /* 在这里补充更多算法 */
+};
+#endif /* defined(__EleEmu__controller__) */
14 Headers/costflow.h
@@ -0,0 +1,14 @@
+#ifndef EleEmu_costflow_h
+#define EleEmu_costflow_h
+
+/*
+ * 称某电梯对某order顺路,如果该电梯开往的方向刚好可以到达order,或者该电梯闲置
+ * 电梯到达order的经过的楼层数目是电梯i到达楼层j的代价
+ * 构图做最小费用最大流,以保证在当前情况下满足最多数量的order并且总代价最小
+ */
+
+int spfa();
+void addEdge(int, int, int, int);
+int BytheWay(Elevator *, Order *);
+
+#endif
74 Headers/elevator.h
@@ -0,0 +1,74 @@
+#ifndef ELEVATOR_H
+#define ELEVATOR_H
+#include <vector>
+#include <list>
+#include "passenger.h"
+#include "instruction.h"
+/* 电梯基类 */
+class Elevator
+{
+ friend class Controller;
+ friend class Emulator;
+protected:
+ int pos;
+ bool doorStatus; /* 0: close, 1: open, 2: in toggle door */
+
+ int toggleDoorCounter; /* 计算开/关门已花费时间,用以控制门的状态过渡 */
+
+ static int timeToggleDoor; /* 开/关门所需时间 */
+
+ static int timeMove; /* 电梯移动所需时间 */
+
+ static int capacity; /* 电梯最大容量 */
+
+ static int throughput; /* 所有电梯总吞吐量 */
+
+ char dir; /* 电梯运动方向 */
+
+ int defaultDir; /* 电梯默认接客方向 */
+
+ static double acceleration; /* 电梯加速度 */
+
+ std::list<Passenger*> passengers; /* 电梯内乘客 */
+
+ std::list<Instruction*> instructions; /* 电梯现有指令栈 */
+
+ int speed;
+
+ void Letout();
+
+ void Letin(int cancelCode);
+
+ void OpenDoor();
+
+ void CloseDoor();
+public:
+ void LetThemMove();
+
+ Elevator(); /* Constructor */
+
+ int Get_pos(); /* Get current position */
+
+ int Get_nPassenger(); /* Get current passenger number */
+
+ char Dir(); /* Get current direction. ^: upwards, v: downwards, -: stopping */
+
+ void ToggleDoor(); /* Toggle door's status, open if closed, close if opened */
+
+ virtual void Move(); /* 继承具有不同算法的电梯,添加所需的成员及方法,实现自己的 Move, Move 将在主函数中被调用 */
+
+ void PushInst(Instruction*); /* 添加指令 */
+
+ std::list<Instruction*> *Get_inst();/* 得到指令栈的指针 */
+
+ static int AverThrput(); /* Calculate and return AverThrput */
+
+ static int Get_capacity(); /* Get method for static member capacity */
+
+ void Set_defaultDir(int dir);
+
+ int Get_defaultDir();
+};
+
+typedef std::vector<Elevator*>::iterator EleIter;
+#endif
35 Headers/emulator.h
@@ -0,0 +1,35 @@
+/* Emulator is a class like a controller(engine) manage all the logic */
+#ifndef __AsciiEleEmu__emulator__
+#define __AsciiEleEmu__emulator__
+
+#include <vector>
+#include <string>
+#include "models.h"
+#include "internlib.h"
+
+class Emulator
+{
+
+public:
+ Emulator();
+
+ static int dual; /* dual: Time consumed with the whole duration */
+
+ static int nElevator; /* Total number of all elevators */
+
+ static int UNIT_TIME; /* Unit time is set to time consumed by moving elevator up or down a floor */
+
+ static vector<Elevator*> elevators; /* All the elevators functioning */
+
+ static double lambda; /* Poiss process parameter lambda */
+
+ static Floor floors[30]; /* Floors */
+
+ static int nFloor; /* Total number of all floors */
+
+ static string elevatorType;
+
+ static list<Order*> orders;
+};
+
+#endif
43 Headers/floor.h
@@ -0,0 +1,43 @@
+#ifndef FLOOR_H
+#define FLOOR_H
+#include <list>
+using namespace std;
+
+class Passenger;
+class Order;
+class Floor
+{
+private:
+ list<Passenger*> passengers;
+ Order* upOrder;
+ Order* downOrder;
+public:
+ Floor(); /* Construct funtion */
+
+ void PushPassenger(Passenger *p); /* Let a new passenger p comes in */
+
+ int Get_nPassenger(); /* Get totalnum of passengers on a floor */
+
+ Passenger *PopPassenger(); /* Pop and return the frontest passenger from queue */
+
+ Passenger *FrontPassenger(); /* Get passenger at the front of the queue(list) */
+
+ void LetThemWait(); /* Let passengers wait for one unit time */
+
+ bool Ordered(); /* Return true if floor has order an elevator */
+
+ void Set_downOrder(Order* order);
+
+ void Set_upOrder(Order* order);
+
+ bool UpOrdered();
+
+ bool DownOrdered();
+
+ void CancelOrder(char dir);
+
+ friend class Passenger;
+
+ void CheckOrder();
+};
+#endif
17 Headers/instruction.h
@@ -0,0 +1,17 @@
+#ifndef EleEmu_instruction_h
+#define EleEmu_instruction_h
+
+/* 电梯指令,算法的输出 */
+class Instruction
+{
+public:
+ Instruction(int dest_, int dirCode_) : dest(dest_), dirCode(dirCode_){};
+ int dest; /* 指令目的地 */
+ int dirCode; /* 指令的载人方向
+ 1: 中途开门接受上、下两个方向乘客
+ 2: 中途开门只接受向上的乘客
+ 3: 中途开门只接受向下的乘客
+ */
+};
+
+#endif
12 Headers/internlib.h
@@ -0,0 +1,12 @@
+/* A lib file with lots of include */
+#include <iostream>
+#include <cstdlib>
+#include <ctime>
+#include <cmath>
+#include <queue>
+#include <cstdio>
+#include <vector>
+#include <climits>
+#include <list>
+#include <algorithm>
+#include <stack>
8 Headers/models.h
@@ -0,0 +1,8 @@
+/* 此头文件包含所有模型和 Controller 类 */
+
+#include "controller.h"
+#include "elevator.h"
+#include "floor.h"
+#include "instruction.h"
+#include "order.h"
+#include "passenger.h"
19 Headers/order.h
@@ -0,0 +1,19 @@
+#ifndef ORDER_H
+#define ORDER_H
+
+#include "passenger.h"
+
+class Order
+{
+public:
+ Order(Passenger* pass);
+
+ Floor *floor; /* From which floor the order comes */
+
+ int from; /* 请求发出的楼层 */
+
+ char dir; /* 请求希望去的方向, 'v': 向下, '^': 向上 */
+
+ int OrderId(); /* 当前请求是所有未接收请求中的第几个 */
+};
+#endif
54 Headers/passenger.h
@@ -0,0 +1,54 @@
+#ifndef PASSENGER_H
+#define PASSENGER_H
+
+#include <algorithm>
+#include <climits>
+
+class Passenger
+{
+private:
+ int timeWait;
+ int timeMove;
+ int from;
+ int to;
+ static int total;
+ static int maxWaitTime;
+ static int minWaitTime;
+ static int totalWaitTime;
+ static int maxDuration;
+ static int minDuration;
+ static int totalDuration;
+ static int nCompleteDuration;
+
+public:
+
+ Passenger(int from_, int to_); /* Construct a passenfer from `from_` to `to_` */
+
+ int Get_from(); /* Where the passenger from */
+
+ int Get_to(); /* Where the passenger goes to */
+
+ void Wait(int t = 1); /* Wait for t unit time */
+
+ void Move(int t = 1); /* Move for t unit time */
+
+ static int Total(); /* Total number of all passengers */
+
+ static int MaxWaitTime(); /* Max wait time of all passengers */
+
+ static int MinWaitTime(); /* Min wait time of all passengers */
+
+ static int AverWaitTime(); /* Average wait time for all passengers */
+
+ static int MaxDuration(); /* Max Duration of all passengers */
+
+ static int MinDuration(); /* Min Duration of all passengers */
+
+ static int AverDuration(); /* Average Duration of all passengers */
+
+ void Arrive(); /* Function to be called when passenger arrive dest */
+
+ void MakeAnOrder(); /* 乘客按下电梯按钮,每层楼有两个按钮,乘客将根据目的地选择,以按下了乘客所需
+ * 按钮时乘客不会再按 */
+};
+#endif
15 Makefile
@@ -0,0 +1,15 @@
+CC = g++
+CFLAGS = -O1 -Wall
+
+all: ascii
+
+ascii: Sources/ascii.cpp Sources/elevator.cpp Sources/emulator.cpp Sources/fcfs.cpp Sources/passenger.cpp \
+ Sources/floor.cpp Sources/PoissRand.cpp Headers/controller.h Headers/elevator.h \
+ Sources/Scan.cpp \
+ Headers/emulator.h Headers/floor.h Headers/instruction.h Headers/models.h Headers/internlib.h \
+ Headers/passenger.h Headers/PoissRand.h Sources/order.cpp Sources/Print.cpp Sources/costflow.cpp \
+ Headers/costflow.h Sources/pickup.cpp
+
+ $(CC) $(CFLAGS) $(LIBS) -o ascii Sources/ascii.cpp Sources/elevator.cpp Sources/emulator.cpp Sources/fcfs.cpp Sources/passenger.cpp \
+ Sources/floor.cpp Sources/PoissRand.cpp Sources/pickup.cpp Sources/order.cpp Sources/Print.cpp Sources/costflow.cpp \
+ Sources/Scan.cpp
6 README.md
@@ -0,0 +1,6 @@
+##Elevator Emulator
+
+
+----
+本项目是北京大学信息科学技术学院数据《结构与算法实习课》综合实验题《电梯模拟器》的完成。采用面向对象的设计模式,由 鲜染(1100012783) & 潘晨毅 & 单旭东 & 朱凯凯合作开发完成.
+
26 Sources/PoissRand.cpp
@@ -0,0 +1,26 @@
+#include "../Headers/internlib.h"
+
+/* Private function: Generates random float number between a and b */
+double Rand(double a, double b)
+{
+ return a + (b - a)*rand()/(RAND_MAX + 1.0);
+}
+
+/*
+ * PARAMS:
+ * lambda: the parameter lambda in a Poiss Distribution(the average occurance of a event)
+ * RETURN:
+ * generates one ramdom number, and the sequence of these numbers is obay Poiss Distribution
+ */
+int PoissRand(double lambda) {
+ int x = -1;
+ double logNegLamb = -lambda;
+ double logRand = 0;
+
+ do {
+ logRand += log(Rand(0, 1));
+ x++;
+ } while (logRand >= logNegLamb);
+
+ return x;
+}
34 Sources/Print.cpp
@@ -0,0 +1,34 @@
+#include "../Headers/internlib.h"
+#include "../Headers/passenger.h"
+#include "../Headers/emulator.h"
+
+using namespace std;
+
+void Print() {
+ cout << "Number of elevator: " << Emulator::nElevator << endl
+ << "Total Passenger: " << Passenger::Total() << endl
+ << "Average waiting time: " << Passenger::AverWaitTime() << endl
+ << "Maximum waiting time: " << Passenger::MaxWaitTime() << endl
+ << "Average duration: " << Passenger::AverDuration() << endl
+ << "Maximum duration: " << Passenger::MaxDuration() << endl
+ << "Minimum duration: " << Passenger::MinDuration() << endl
+ << "Average Throughput: " << Elevator::AverThrput() << " pass/hour" << endl << endl;
+
+ cout << " Floor Passenger ";
+ for(int i = 0; i < Emulator::nElevator; i++) {
+ cout << "elevator" << i << " ";
+ }
+ cout << endl;
+
+ for(int i = 0; i < Emulator::nFloor; i++) {
+ printf(" %2d %2d ", i+1, Emulator::floors[i].Get_nPassenger());
+ EleIter iter;
+ for(iter = Emulator::elevators.begin(); iter != Emulator::elevators.end(); iter++) {
+ if((*iter)->Get_pos() == i)
+ printf(" \033[32m[%2d]%c\033[0m ", (*iter)->Get_nPassenger(), (*iter)->Dir());
+ else
+ printf(" ");
+ }
+ printf("\n");
+ }
+}
68 Sources/Scan.cpp
@@ -0,0 +1,68 @@
+#include "../Headers/models.h"
+#include "../Headers/emulator.h"
+Elevator* Idlest()
+{
+ EleIter iter;
+
+ for(iter = Emulator::elevators.begin(); iter != Emulator::elevators.end(); iter++)
+ {
+ if((*iter)->Dir() == '-' && (*iter)->Get_nPassenger() == 0 && (*iter)->Get_inst()->size() == 0) return *iter;
+ }
+ return NULL;
+}
+Elevator* Lowest()
+{
+ EleIter iter;
+ int low=1000000;
+ for(iter = Emulator::elevators.begin(); iter != Emulator::elevators.end(); iter++)
+ {
+ if(low>(*iter)->Get_nPassenger()) low=(*iter)->Get_nPassenger();
+ }
+ for(iter = Emulator::elevators.begin(); iter != Emulator::elevators.end(); iter++)
+ {
+ if(low==(*iter)->Get_nPassenger()) return *iter;
+ }
+}
+void Controller::Scan()
+{
+ while(Idlest() != NULL)
+ {
+ Elevator* idle = Idlest();
+ if(idle->Get_pos()==0)
+ idle->PushInst(new Instruction(Emulator::nFloor-1, 2));
+ else
+ idle->PushInst(new Instruction(0, 3));
+ break;
+ }
+ EleIter iter = Emulator::elevators.begin();
+ int k=Emulator::orders.size();
+ while(k)
+ {
+ Order* order = Emulator::orders.front();
+ if(Lowest()->Dir()==order->dir)
+ {
+ if(Lowest()->Dir()=='^')
+ Lowest()->PushInst(new Instruction(order->from,2));
+ else if(Lowest()->Dir()=='v')
+ Lowest()->PushInst(new Instruction(order->from,3));
+ Emulator::orders.pop_front();
+ continue;
+ }
+ if(iter == Emulator::elevators.end())
+ iter = Emulator::elevators.begin();
+ for(; iter != Emulator::elevators.end(); iter++)
+ {
+ if((*iter)->Dir()==order->dir)
+ {
+ if((*iter)->Dir()=='^')
+ (*iter)->PushInst(new Instruction(order->from,2));
+ else if(Lowest()->Dir()=='v')
+ (*iter)->PushInst(new Instruction(order->from,3));
+ Emulator::orders.pop_front();
+ break;
+ }
+ }
+
+ k--;
+ }
+}
108 Sources/ascii.cpp
@@ -0,0 +1,108 @@
+#include "../Headers/internlib.h"
+#include "../Headers/PoissRand.h"
+#include "../Headers/models.h"
+#include "../Headers/emulator.h"
+
+using namespace std;
+
+/* Declaration of Passenger static member */
+int Elevator::capacity = 20;
+int Elevator::throughput = 0;
+int Passenger::maxWaitTime = 0;
+int Passenger::minWaitTime = INT_MAX;
+int Passenger::total = 0;
+int Passenger::totalWaitTime = 0;
+int Passenger::maxDuration = 0;
+int Passenger::minDuration = INT_MAX;
+int Passenger::nCompleteDuration = 0;
+int Passenger::totalDuration = 0;
+
+/* Declaration of Emulator static member, similar to glable variable */
+int Emulator::dual = 0;
+int Emulator::nElevator ;
+int Emulator::UNIT_TIME = 2;
+int Emulator::nFloor;
+list<Order*> Emulator::orders;
+vector<Elevator*> Emulator::elevators;
+double Emulator::lambda;
+string Emulator::elevatorType;
+Floor Emulator::floors[30];
+
+double Elevator::acceleration = 1;
+
+void Born() {
+ for(int i = 0; i < Emulator::nFloor; i++) {
+ int nPassenger = PoissRand(Emulator::lambda);
+ for(int j = 0; j < nPassenger; j++) {
+ Passenger *pass = new Passenger(i, floor(Rand(0, Emulator::nFloor)));
+
+ Emulator::floors[i].PushPassenger(pass);
+
+ pass->MakeAnOrder();
+ }
+ }
+}
+
+void Control() {
+ if (Emulator::elevatorType == "PFCFS") {
+ Controller::Fcfs();
+ } else if (Emulator::elevatorType == "costflow") {
+ Controller::CostFLow();
+ } else if (Emulator::elevatorType == "pickup") {
+ Controller::PickUp();
+ }else if (Emulator::elevatorType == "scan") {
+ Controller::Scan();
+ }
+ /* else if (Emulator::elevatorType == "costflow") {
+ * Controller::costflow();
+ *
+ * } */
+}
+
+void Move() {
+ EleIter iter;
+ for(iter = Emulator::elevators.begin(); iter != Emulator::elevators.end(); iter++) {
+ (*iter)->Move();
+ }
+}
+
+void Update() {
+ EleIter iter;
+ for (int i = 0; i < Emulator::nFloor; i++) {
+ Emulator::floors[i].LetThemWait();
+ }
+ for (iter = Emulator::elevators.begin(); iter != Emulator::elevators.end(); iter++) {
+ (*iter)->LetThemMove();
+ }
+}
+
+void Print();
+
+int main(int argc, char *argv[])
+{
+ /* Generate random number seed with current time */
+ srand(time(NULL));
+
+ /* Set runtime parameters */
+ Emulator::nFloor = 10;
+ Emulator::lambda = 0.02;
+ Emulator::nElevator = 4;
+ cin >> Emulator::elevatorType;
+
+ /* Initialize elevators */
+ for(int i = 0; i < Emulator::nElevator; i++) {
+ Elevator* ele = new Elevator();
+ Emulator::elevators.push_back(ele);
+ }
+
+ for (Emulator::dual = 1; Emulator::dual <= 100; Emulator::dual++) {
+ system("clear");
+ Born();
+ Control();
+ Move();
+ Update();
+ Print();
+ system("sleep 0.2");
+ }
+ return 0;
+}
126 Sources/costflow.cpp
@@ -0,0 +1,126 @@
+#include "../Headers/models.h"
+
+#include "../Headers/order.h"
+#include "../Headers/elevator.h"
+#include "../Headers/emulator.h"
+#include <cstring>
+
+typedef list<Order*>::iterator OrderIter;
+
+#define MAXN 500 /* 最大点的个数 */
+#define order_s Emulator::orders.begin()
+#define order_e Emulator::orders.end()
+#define ele_s Emulator::elevators.begin()
+#define ele_e Emulator::elevators.end()
+
+int S, T; /* 源点和汇点 */
+int flow[MAXN][MAXN], cost[MAXN][MAXN];
+int path[MAXN];
+int inq[MAXN], Q[MAXN], dist[MAXN];
+/*
+ * 称某电梯对某order顺路,当且仅当该电梯闲置 (如果我们的电梯知道更加多的事情,可以有更加多的算法)
+ * 电梯到达order的经过的楼层数目是电梯i到达楼层j的代价
+ * 构图做最小费用最大流,以保证在当前情况下满足最多数量的order并且总代价最小
+ */
+
+void addEdge(int a, int b, int f, int c)
+{
+ flow[a][b] = f, flow[b][a] = 0;
+ cost[a][b] = c, cost[b][a] = -c;
+}
+
+int BytheWay(Elevator *ele, Order *order)
+{
+ if (ele->Get_nPassenger() == Elevator::Get_capacity())
+ return 0;
+ if (ele->Dir() == '-' && ele->Get_nPassenger() == 0 && ele->Get_inst()->size() == 0)
+ return 1;
+ else return 0;
+}
+
+int spfa()
+{
+ memset(dist, -1, sizeof(dist));
+ memset(inq, 0, sizeof(inq));
+ inq[S] = 1;
+ dist[S] = 0;
+ memset(path, -1, sizeof(path));
+ Q[0] = S;
+ for (int h = 0, t = 0; h <= t; ++ h)
+ {
+ int cur = Q[h];
+ for (int nxt = S; nxt <= T; ++ nxt)
+ if (flow[cur][nxt] == 1 && (dist[nxt] == -1 || dist[nxt] > dist[cur] + cost[cur][nxt]))
+ {
+ dist[nxt] = dist[cur] + cost[cur][nxt];
+ path[nxt] = cur;
+ if (inq[nxt]) continue;
+ inq[Q[++ t] = nxt] = 1;
+ }
+ inq[cur] = 0;
+ }
+ return path[T] != -1;
+}
+
+void Controller::CostFLow()
+{
+ memset(flow, 0, sizeof(flow));
+ memset(cost, 0, sizeof(cost));
+ S = 0, T = Emulator::orders.size() + Emulator::elevators.size() + 1;
+ int idx_order, idx_ele;
+ idx_order = 0;
+ for (OrderIter iter = order_s; iter != order_e; ++ iter)
+ addEdge(S, ++ idx_order, 1, 0);
+ idx_order = 0;
+ for (OrderIter iter = order_s; iter != order_e; ++ iter)
+ {
+ ++ idx_order;
+ idx_ele = Emulator::orders.size();
+ for (EleIter jter = ele_s; jter != ele_e; ++ jter)
+ {
+ ++ idx_ele;
+
+ if (BytheWay(*jter, *iter))
+ addEdge(idx_order, idx_ele, 1, abs((*jter)->Get_pos() - (*iter)->from));
+
+ //addEdge(idx_order, idx_ele, 1, estimate(*jter, *iter));
+ }
+ }
+ idx_ele = Emulator::orders.size();
+ for (EleIter iter = ele_s; iter != ele_e; ++ iter)
+ addEdge(++ idx_ele, T, 1, 0);
+
+ int tt = 0;
+ while (spfa())
+ {
+ ++ tt;
+ /* Every path flow could only be one */
+ for (int i = T; i != S; i = path[i])
+ flow[path[i]][i] = 0, flow[i][path[i]] = 1;
+ /* No need to calc the mincost */
+ }
+ printf("%u %u\n", Emulator::orders.size(), tt);
+ //if (! tt) return;
+
+ //memset(toDel, 0, sizeof(toDel));
+ idx_order = 0;
+ for (OrderIter iter = order_s; iter != order_e; )
+ {
+ ++ idx_order;
+ int flag = 0;
+ idx_ele = Emulator::orders.size();
+ for (EleIter jter = ele_s; jter != ele_e; ++ jter)
+ {
+ ++ idx_ele;
+ if (flow[idx_ele][idx_order] == 1)
+ {
+ (*jter)->PushInst(new Instruction((*iter)->from, 1));
+ flag = 1;
+ break;
+ }
+ }
+ OrderIter temp = iter ++;
+ if (flag)
+ Emulator::orders.erase(temp);
+ }
+}
152 Sources/elevator.cpp
@@ -0,0 +1,152 @@
+#include "../Headers/elevator.h"
+#include "../Headers/emulator.h"
+
+Elevator::Elevator() {
+ pos = 0;
+ doorStatus = 0;
+ speed = 1;
+ toggleDoorCounter = 1;
+ dir = '-';
+}
+
+int Elevator::Get_pos() {
+ return pos;
+}
+
+int Elevator::Get_nPassenger() {
+ return passengers.size();
+}
+
+char Elevator::Dir() {
+ return dir;
+}
+
+void Elevator::OpenDoor() {
+ toggleDoorCounter++;
+ if (toggleDoorCounter == 2)
+ doorStatus = 1;
+}
+
+void Elevator::CloseDoor() {
+ toggleDoorCounter--;
+ if (toggleDoorCounter == 0)
+ doorStatus = 0;
+}
+void Elevator::Move() {
+ int inst = 0;
+ if (instructions.empty()) {
+ if (!passengers.empty()) {
+ inst = passengers.front()->Get_to();
+ } else return;
+ } else {
+ inst = instructions.back()->dest;
+ }
+ if (pos == inst) {
+ dir = '-';
+ if (doorStatus == 0) OpenDoor();
+ else {
+ int dirCode = defaultDir;
+ if (!instructions.empty()) {
+ dirCode = instructions.back()->dirCode;
+ instructions.pop_back();
+ }
+ Letout();
+ Letin(dirCode);
+ }
+ } else {
+ if (doorStatus == 1) CloseDoor();
+ else {
+ if (pos > inst) {
+ pos -= speed;
+ dir = '^';
+ } else {
+ dir = 'v';
+ pos += speed;
+ }
+ }
+ }
+}
+
+/*
+ * Function template, provides assertion to passgers->remove_if() function.
+ * Return:
+ * true: passenger destination is at pos
+ * false: anything else.
+ */
+struct to_is_pos
+{
+ int pos;
+ to_is_pos(int pos_) : pos(pos_){};
+ bool operator () (Passenger *p) {
+ return p->Get_to() == pos;
+ }
+};
+
+/* Let out all passengers whoes destination is at pos, update throughput */
+void Elevator::Letout() {
+ for(list<Passenger*>::iterator iter = passengers.begin(); iter != passengers.end(); iter++) {
+ if((*iter)->Get_to() == pos) {
+ throughput++;
+ (*iter)->Arrive();
+ }
+ }
+ passengers.remove_if( to_is_pos(pos) );
+}
+
+void Elevator::Letin(int dirCode) {
+ Floor* floor = &Emulator::floors[pos];
+
+ while (floor->Get_nPassenger() && passengers.size() < unsigned(capacity)) {
+ Passenger *pass = floor->PopPassenger();
+ if (pass) passengers.push_back(pass);
+ }
+
+ switch(dirCode) {
+ case 1:
+ floor->CancelOrder('^');
+ floor->CancelOrder('v');
+ break;
+ case 2:
+ floor->CancelOrder('^');
+ break;
+ case 3:
+ floor->CancelOrder('v');
+ break;
+ default:
+ break;
+ };
+
+ floor->CheckOrder();
+}
+
+int Elevator::AverThrput() {
+ if (Emulator::dual == 0) return -1;
+ return (throughput * 3600) / (Emulator::dual * Emulator::UNIT_TIME);
+}
+
+int Elevator::Get_capacity() {
+ return capacity;
+}
+
+void Elevator::LetThemMove() {
+ list<Passenger*>::iterator iter;
+ for(iter = passengers.begin(); iter != passengers.end(); iter++) {
+ (*iter)->Move();
+ }
+}
+
+void Elevator::PushInst(Instruction* inst) {
+ instructions.push_back(inst);
+}
+
+list<Instruction*> *Elevator::Get_inst() {
+ return &instructions;
+}
+
+int Elevator::Get_defaultDir() {
+ return defaultDir;
+}
+
+void Elevator::Set_defaultDir(int dir) {
+ defaultDir = dir;
+}
7 Sources/emulator.cpp
@@ -0,0 +1,7 @@
+#include "../Headers/emulator.h"
+#include "../Headers/PoissRand.h"
+#include "../Headers/internlib.h"
+#include "../Headers/controller.h"
+
+Emulator::Emulator() {
+}
14 Sources/fcfs.cpp
@@ -0,0 +1,14 @@
+#include "../Headers/models.h"
+#include "../Headers/emulator.h"
+
+
+Elevator* Idlest();
+void Controller::Fcfs() {
+ while(Idlest() != NULL) {
+ if (Emulator::orders.empty()) return;
+ Elevator* idle = Idlest();
+ Order* order = Emulator::orders.front();
+ Emulator::orders.pop_front();
+ idle->PushInst(new Instruction(order->from, 1));
+ }
+}
89 Sources/floor.cpp
@@ -0,0 +1,89 @@
+#include "../Headers/floor.h"
+#include "../Headers/passenger.h"
+#include "../Headers/order.h"
+#include "../Headers/emulator.h"
+
+Floor::Floor() {
+ downOrder = NULL;
+ upOrder = NULL;
+}
+
+void Floor::PushPassenger(Passenger *p) {
+ passengers.push_back(p);
+
+}
+
+Passenger *Floor::PopPassenger() {
+ Passenger *p = NULL;
+ if(!passengers.empty()) {
+ p = passengers.front();
+ passengers.pop_front();
+ }
+ return p;
+}
+
+int Floor::Get_nPassenger() {
+ return passengers.size();
+}
+
+void Floor::LetThemWait() {
+ list<Passenger*>::iterator iter;
+ for(iter = passengers.begin(); iter != passengers.end(); iter++) {
+ (*iter)->Wait();
+ }
+}
+
+Passenger* Floor::FrontPassenger() {
+ if(passengers.empty()) {
+ return NULL;
+ } else {
+ return passengers.front();
+ }
+}
+
+bool Floor::Ordered() {
+ return UpOrdered() || DownOrdered();
+}
+
+
+void Floor::Set_upOrder(Order* order) {
+ upOrder = order;
+}
+
+void Floor::Set_downOrder(Order* order) {
+ downOrder = order;
+}
+
+bool Floor::UpOrdered() {
+ return upOrder != NULL;
+}
+
+bool Floor::DownOrdered() {
+ return downOrder != NULL;
+}
+
+void Floor::CancelOrder(char dir) {
+ list<Order*>::iterator iter;
+ Order* order;
+ if (dir == '^') {
+ order = upOrder;
+ upOrder = NULL;
+ } else {
+ order = downOrder;
+ downOrder = NULL;
+ }
+ for(iter = Emulator::orders.begin(); iter != Emulator::orders.end(); iter++)
+ {
+ if (*iter == order) {
+ Emulator::orders.erase(iter);
+ return;
+ }
+ }
+}
+
+void Floor::CheckOrder() {
+ list<Passenger*>::iterator iter;
+ for (iter = passengers.begin(); iter != passengers.end(); iter++) {
+ (*iter)->MakeAnOrder();
+ }
+}
68 Sources/main.cpp
@@ -0,0 +1,68 @@
+#include "../Headers/internlib.h"
+#include "../Headers/PoissRand.h"
+#include "../Headers/passenger.h"
+#include "../Headers/floor.h"
+#include "../Headers/qt/emulator.h"
+#include <QApplication>
+
+using namespace std;
+
+/* FcfsElevator's flash process, P means premium */
+int PFcfsFlash();
+
+/* Declaration of Passenger static member */
+int Elevator::capacity = 20;
+int Elevator::throughput = 0;
+int Passenger::maxWaitTime = 0;
+int Passenger::minWaitTime = INT_MAX;
+int Passenger::total = 0;
+int Passenger::totalWaitTime = 0;
+int Passenger::maxDuration = 0;
+int Passenger::minDuration = INT_MAX;
+int Passenger::nCompleteDuration = 0;
+int Passenger::totalDuration = 0;
+
+/* Declaration of Emulator static member, similar to glable variable */
+int Emulator::dual = 0;
+int Emulator::nElevator ;
+int Emulator::UNIT_TIME = 2;
+int Emulator::nFloor;
+list<Order*> Emulator::orders;
+vector<Elevator*> Emulator::elevators;
+double Emulator::lambda;
+string Emulator::elevatorType;
+Floor Emulator::floors[30];
+
+double Elevator::acceleration = 1;
+
+int main(int argc, char *argv[])
+{
+ QApplication app(argc, argv);
+
+ /* Generate random number seed with current time */
+ srand(time(NULL));
+
+ /* Set runtime parameters */
+ Emulator::nFloor = 10;
+ Emulator::lambda = 0.1;
+ Emulator::nElevator = 10;
+ Emulator::elevatorType = "PFCFS";
+
+ /* Initialize elevators */
+ for(int i = 0; i < Emulator::nElevator; i++) {
+ Elevator *ele;
+ if (Emulator::elevatorType == "PFCFS") {
+ Elevator* elev = new Elevator();
+ ele = elev;
+ }
+ Emulator::elevators.push_back(ele);
+ }
+
+ Emulator window;
+
+ window.resize(800, 600);
+ window.show();
+ window.setWindowTitle("Elevator Emulator");
+
+ return app.exec();
+}
94 Sources/moc_emulator.cpp
@@ -0,0 +1,94 @@
+/****************************************************************************
+** Meta object code from reading C++ file 'emulator.h'
+**
+** Created: Thu Oct 11 11:46:20 2012
+** by: The Qt Meta Object Compiler version 63 (Qt 4.8.3)
+**
+** WARNING! All changes made in this file will be lost!
+*****************************************************************************/
+
+#include "emulator.h"
+#if !defined(Q_MOC_OUTPUT_REVISION)
+#error "The header file 'emulator.h' doesn't include <QObject>."
+#elif Q_MOC_OUTPUT_REVISION != 63
+#error "This file was generated using the moc from 4.8.3. It"
+#error "cannot be used with the include files from this version of Qt."
+#error "(The moc has changed too much.)"
+#endif
+
+QT_BEGIN_MOC_NAMESPACE
+static const uint qt_meta_data_Emulator[] = {
+
+ // content:
+ 6, // revision
+ 0, // classname
+ 0, 0, // classinfo
+ 1, 14, // methods
+ 0, 0, // properties
+ 0, 0, // enums/sets
+ 0, 0, // constructors
+ 0, // flags
+ 0, // signalCount
+
+ // slots: signature, parameters, type, tag, flags
+ 10, 9, 9, 9, 0x08,
+
+ 0 // eod
+};
+
+static const char qt_meta_stringdata_Emulator[] = {
+ "Emulator\0\0startEmulationSlots()\0"
+};
+
+void Emulator::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
+{
+ if (_c == QMetaObject::InvokeMetaMethod) {
+ Q_ASSERT(staticMetaObject.cast(_o));
+ Emulator *_t = static_cast<Emulator *>(_o);
+ switch (_id) {
+ case 0: _t->startEmulationSlots(); break;
+ default: ;
+ }
+ }
+ Q_UNUSED(_a);
+}
+
+const QMetaObjectExtraData Emulator::staticMetaObjectExtraData = {
+ 0, qt_static_metacall
+};
+
+const QMetaObject Emulator::staticMetaObject = {
+ { &QWidget::staticMetaObject, qt_meta_stringdata_Emulator,
+ qt_meta_data_Emulator, &staticMetaObjectExtraData }
+};
+
+#ifdef Q_NO_DATA_RELOCATION
+const QMetaObject &Emulator::getStaticMetaObject() { return staticMetaObject; }
+#endif //Q_NO_DATA_RELOCATION
+
+const QMetaObject *Emulator::metaObject() const
+{
+ return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject;
+}
+
+void *Emulator::qt_metacast(const char *_clname)
+{
+ if (!_clname) return 0;
+ if (!strcmp(_clname, qt_meta_stringdata_Emulator))
+ return static_cast<void*>(const_cast< Emulator*>(this));
+ return QWidget::qt_metacast(_clname);
+}
+
+int Emulator::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
+{
+ _id = QWidget::qt_metacall(_c, _id, _a);
+ if (_id < 0)
+ return _id;
+ if (_c == QMetaObject::InvokeMetaMethod) {
+ if (_id < 1)
+ qt_static_metacall(this, _c, _id, _a);
+ _id -= 1;
+ }
+ return _id;
+}
+QT_END_MOC_NAMESPACE
19 Sources/order.cpp
@@ -0,0 +1,19 @@
+#include "../Headers/emulator.h"
+#include "../Headers/order.h"
+
+Order::Order(Passenger* pass) : from(pass->Get_from()) {
+ int to = pass->Get_to();
+ if(to >= from) dir = '^';
+ else dir = 'v';
+ floor = &(Emulator::floors[from]);
+};
+
+int Order::OrderId() {
+ std::list<Order*>::iterator iter;
+ int cnt = 0;
+ for (iter = Emulator::orders.begin(); iter != Emulator::orders.end(); iter++, cnt++) {
+ if (*iter == this)
+ return cnt;
+ }
+ return -1;
+};
85 Sources/passenger.cpp
@@ -0,0 +1,85 @@
+#include "../Headers/passenger.h"
+#include "../Headers/floor.h"
+#include "../Headers/emulator.h"
+#include "../Headers/order.h"
+
+Passenger::Passenger(int from_, int to_): from(from_), to(to_) {
+ total += 1;
+ timeWait = 0;
+ timeMove = 0;
+}
+
+int Passenger::Total() {
+ return total;
+}
+
+int Passenger::MaxWaitTime() {
+ return maxWaitTime;
+}
+
+int Passenger::MinWaitTime() {
+ if (minWaitTime == INT_MAX) return -1;
+ return minWaitTime;
+}
+
+int Passenger::AverWaitTime() {
+ if(total == 0) return 0;
+ else return totalWaitTime / total;
+}
+
+int Passenger::MaxDuration() {
+ return maxDuration;
+}
+
+int Passenger::MinDuration() {
+ if(minDuration == INT_MAX) return -1;
+ else return minDuration;
+}
+
+int Passenger::AverDuration() {
+ if(nCompleteDuration == 0) return 0;
+ else return totalDuration / nCompleteDuration;
+}
+
+int Passenger::Get_from() {
+ return from;
+}
+
+int Passenger::Get_to() {
+ return to;
+}
+
+void Passenger::Wait(int t) {
+ totalWaitTime += t;
+ timeWait += t;
+ minWaitTime = std::min(minWaitTime, timeWait);
+ maxWaitTime = std::max(maxWaitTime, timeWait);
+}
+
+void Passenger::Move(int t) {
+ timeMove += t;
+}
+
+void Passenger::Arrive() {
+ int duration = timeMove + timeWait;
+
+ totalDuration += duration;
+ nCompleteDuration += 1;
+ minDuration = std::min(minDuration, duration);
+ maxDuration = std::max(maxDuration, duration);
+}
+
+void Passenger::MakeAnOrder() {
+ Floor *floor = &Emulator::floors[from];
+ if(to > from) {
+ if (floor->UpOrdered()) return;
+ Order *order = new Order(this);
+ Emulator::orders.push_back(order);
+ floor->Set_upOrder(order);
+ } else {
+ if (floor->DownOrdered()) return;
+ Order *order = new Order(this);
+ floor->Set_downOrder(order);
+ Emulator::orders.push_back(order);
+ }
+}
40 Sources/pickup.cpp
@@ -0,0 +1,40 @@
+#include "../Headers/models.h"
+#include "../Headers/emulator.h"
+Elevator* Available(Order* order)
+{
+ EleIter iter;
+ Elevator *ans=NULL,*idle=NULL;
+ int dist=999999999;
+ for(iter = Emulator::elevators.begin(); iter != Emulator::elevators.end(); iter++)
+ {
+ if ((*iter)->Dir()==order->dir)
+ {
+ if ((*iter)->Dir()=='^' && (*iter)->Get_pos()<=order->from)
+ ans=*iter;
+ else if ((*iter)->Dir()=='v' && (*iter)->Get_pos()>=order->from)
+ ans=*iter;
+ }
+ else if ((*iter)->Dir()=='-' && (*iter)->Get_nPassenger() == 0 && (*iter)->Get_inst()->size() == 0 && dist>abs((*iter)->Get_pos()-order->from))
+ {
+ dist=abs((*iter)->Get_pos()-order->from);
+ idle=*iter;
+ }
+ if (ans==NULL && idle!=NULL) ans=idle;
+ }
+ return ans;
+}
+void Controller::PickUp()
+{
+ while(!Emulator::orders.empty())
+ {
+ Order* order = Emulator::orders.front();
+ Emulator::orders.pop_front();
+ Elevator* chosenone = Available(order);
+ if (chosenone==NULL) return;
+ if (chosenone->Dir()=='^')
+ chosenone->PushInst(new Instruction(order->from,2));
+ else if (chosenone->Dir()=='v')
+ chosenone->PushInst(new Instruction(order->from,3));
+ else chosenone->PushInst(new Instruction(order->from,1));
+ }
+}
117 Sources/stillworkingon.cpp
@@ -0,0 +1,117 @@
+
+#include <iostream>
+#include <cstdlib>
+#include <ctime>
+#include <queue>
+#include "../Headers/PoissRand.h"
+using namespace std;
+int max_people=0,ele_num=0,Floor=0,people[100]={0};
+
+class PASS_FLOW
+{
+public:
+ int num;
+ int target,begin;
+ PASS_FLOW(int a,int b,int c):num(a),begin(b),target(c){};
+ PASS_FLOW(){num=begin=target=0;};
+ int dir()
+ {
+ if(target>begin) return 1;
+ else return -1;
+ }
+};queue<PASS_FLOW*> q[100];
+
+class ELE_VATOR
+{
+public:
+ int mov_status;
+ int passanger_num;
+ int target_floor,present_floor,up,flownum;
+ queue<PASS_FLOW*> pas;
+ ELE_VATOR():mov_status(1),passanger_num(0),up(Floor),present_floor(1){flownum=0;}
+ void mov()
+ {
+ if(present_floor+mov_status>=1 && present_floor+mov_status<=up)present_floor +=mov_status;
+
+ }
+ void turn()
+ {
+ if(present_floor <=1 || present_floor == up) mov_status = -mov_status;
+ }
+ void pick()
+ {
+ cout<<"yes";
+ while(!q[present_floor].empty())
+ {
+ PASS_FLOW *s=q[present_floor].front();
+ if(s->num+passanger_num>max_people) break;
+ pas.push(s);
+ passanger_num+=s->num;
+ q[present_floor].pop();
+ people[present_floor]-=q[present_floor].front()->num;
+ flownum++;
+ }
+ }
+ void drop()
+ {
+ int round=0,f=flownum;
+ while(!pas.empty()&&round<f)
+ {
+ if(pas.front()->target==present_floor)
+ {
+ passanger_num-=pas.front()->num;
+ pas.pop();
+ flownum--;
+ }
+ else
+ {
+ pas.push(pas.front());
+ pas.pop();
+ }
+ round++;
+ }
+ }
+};
+
+int main(int argc, const char * argv[])
+{
+ int Emulator::lambda = atoi(argv[1]),total_person = 0,tim = 0, wait_sum = 0, on_sum = 0 ;
+ int
+ srand(time(NULL));
+ /* receive input */
+ char ele_direction[3]={'^','-','V'};
+ cin>>max_people>>ele_num>>Floor;
+ ELE_VATOR elevator;
+ while(1)
+ {
+ tim++;
+ int a=rand()%Floor+1,b=rand()%Floor+1;
+ if(b==a) b=a+1;
+ /* random floor of begin and target*/
+ PASS_FLOW *tmp=new PASS_FLOW(PoissRand(Emulator::lambda), a, b);
+ people[a]+=tmp->num;
+ total_person+=tmp->num;
+ q[a].push(tmp);
+ for(int i=Floor;i>=1;i--)
+ {
+ cout<<"Floor "<<i<<":"<<people[i]<<" ";
+ if(i==elevator.present_floor)
+ {
+ cout<<elevator.passanger_num;
+ }
+ cout<<endl;
+ }
+ elevator.mov();
+ cout<<"move"<<endl;
+ elevator.pick();
+ cout<<"pick"<<endl;
+ elevator.drop();
+ cout<<"drop"<<endl;
+ elevator.turn();
+ cin.get();
+ system("clear");
+ }
+ cout << endl;
+ return 0;
+}
+
Please sign in to comment.
Something went wrong with that request. Please try again.