//Name: XXXXXXXXXXXXXXX //ID: XXXXXXXXXXXXXXX //Date: Dec 1, 2017 #include #include #include #include #include #include #include using namespace std; //START: Init values #define startTime 0.0 #define totalAllowedArrivals 20000 #define numOfFloors 7 #define timeStep 10.0 //This would be the speed of the elevators #define numOfElevators 1 #define maxPassengers 10 #define modeOfElevators 0 //0 - SSFT, 1 - Linear Scan #define idleModeOfElevators 0 //0 - Bottom, 1 - Middle #define arrivalRate 120.0 #define workAverage 60.0 #define randomSeed 121 //Poisson, aggregate arrival rate //END: Init values //START: Vars int count = 0; float currentTime = startTime; float totalWaitTime = 0; //EMD: Vars //START: My structs struct people { int floor = 0; int waiting = 0;//0 means not waiting, 1 means waiting float waitingTime = 0; int goingTo = 0; }; struct elevators { vector passengers; int rate = 0; int floor= 0; int mode = 0; //0 means shortest seek time first int idleMode = 0; int direction = 0; //-1 means down, 0 not moving, 1 means up }; //END: My structs //START: WorkTime //NOTE: Currently uses exponential float getWorkTime() { //No seed return -1*(workAverage)*log(1-((double) rand() / (double) (RAND_MAX))) + currentTime; } //END: workTime //START: arrival //NOTE: Currently uses exponential float arrivalTime() { //No seed return -1*(arrivalRate)*log(1-((double) rand() / (double) (RAND_MAX))) + currentTime; } //END: arrival //START: arrival //NOTE: Currently uses exponential struct people newPerson(float workTime, int floor) { //No seed struct people newPerson; newPerson.waitingTime = workTime; newPerson.floor = floor; return newPerson; } //END: arrival //START: arrival //NOTE: Currently uses exponential struct elevators newElevator(int rate, int floor, int mode, int idleMode) { //No seed struct elevators newE; newE.rate = rate; newE.floor = floor; newE.mode = mode; newE.idleMode = idleMode; return newE; } //END: arrival //START: Elevator modes void SSTF(struct elevators *elevator, vector *working) { int distance = numOfFloors + 1; int goTo = distance; if((elevator->passengers).size() == maxPassengers) { //START: Cycling through passengers to find closest location for(uint i = 0; i < (elevator->passengers).size(); i++) { if(abs((elevator->passengers)[i].goingTo-elevator->floor) < distance) { distance = abs((elevator->passengers)[i].goingTo-elevator->floor); goTo = (elevator->passengers)[i].goingTo; } } //END: Cycling through passengers to find closest location //START: Idle if(goTo == numOfFloors + 1) { if(idleModeOfElevators == 0) { if(elevator->floor != 1) { elevator->floor--; } } else if(idleModeOfElevators == 1) { if(elevator->floor > numOfFloors/2) { elevator->floor--; } else if(elevator->floor < numOfFloors/2) { elevator->floor++; } } return; } //END: idle //START: Update floor number if(elevator->floor > goTo) { elevator->floor--; } else if(elevator->floor < goTo) { elevator->floor++; } //END: Update floor number } else { //START: Check to see which is closer of floors calling and floors //to go to for(uint i = 0; i < (elevator->passengers).size(); i++) { if(abs((elevator->passengers)[i].goingTo-elevator->floor) < distance) { distance = abs((elevator->passengers)[i].goingTo-elevator->floor); goTo = (elevator->passengers)[i].goingTo; } } for(uint i = 0; i < (*working).size(); i++) { if((*working)[i].waiting == 1) { if(abs((*working)[i].floor-elevator->floor) < distance) { distance = abs((*working)[i].floor-elevator->floor); goTo = (*working)[i].floor; } } } //END: Check to see which is closer of floors calling and floors //to go to //START: Idle if(goTo == numOfFloors + 1) { if(idleModeOfElevators == 0) { if(elevator->floor != 1) { elevator->floor--; } } else if(idleModeOfElevators == 1) { if(elevator->floor > numOfFloors/2) { elevator->floor--; } else if(elevator->floor < numOfFloors/2) { elevator->floor++; } } return; } //END: idle //START: Update floor number if(elevator->floor > goTo) { elevator->floor--; } else if(elevator->floor < goTo) { elevator->floor++; } //END: Update floor number } //START: If you are on the desired floor, shuffle the passengers if(goTo == elevator->floor) { //START: get customers off elevator for(uint i = 0; i < (elevator->passengers).size(); i++) { if((elevator->passengers)[i].goingTo == goTo) { totalWaitTime += currentTime - ((elevator->passengers)[i]).waitingTime; if(goTo != 1) { (*working).push_back((elevator->passengers)[i]); ((*working).back()).waitingTime = getWorkTime(); ((*working).back()).floor = goTo; ((*working).back()).goingTo = 1; ((*working).back()).waiting = 0; } else { count++; } (elevator->passengers).erase((elevator->passengers).begin() + i); } } //END: get customers off elevator //START: Get customers on elevator if((elevator->passengers).size() < maxPassengers) { for(uint i = 0; i < (*working).size(); i++) { if((*working)[i].floor == goTo) { if((*working)[i].waiting == 1) { (elevator->passengers).push_back((*working)[i]); (*working).erase((*working).begin() + i); } } if((elevator->passengers).size() == maxPassengers) { i = (*working).size(); } } } //END: Get customers on elevator } //END: If you are on the desired floor, shuffle the passengers } void LRSN(struct elevators *elevator, vector *working) { int distance = numOfFloors + 1; int goTo = distance; //START: Check to see which is closer of floors calling and floors //to go to for(uint i = 0; i < (elevator->passengers).size(); i++) { if(abs((elevator->passengers)[i].goingTo-elevator->floor) < distance) { distance = abs((elevator->passengers)[i].goingTo-elevator->floor); goTo = (elevator->passengers)[i].goingTo; } } for(uint i = 0; i < (*working).size(); i++) { if((*working)[i].waiting == 1) { if(abs((*working)[i].floor-elevator->floor) < distance) { distance = abs((*working)[i].floor-elevator->floor); goTo = (*working)[i].floor; } } } //END: Check to see which is closer of floors calling and floors //to go to //START: Idle if(goTo == numOfFloors + 1) { if(idleModeOfElevators == 0) { if(elevator->floor != 1) { elevator->floor--; } } else if(idleModeOfElevators == 1) { if(elevator->floor > numOfFloors/2) { elevator->floor--; } else if(elevator->floor < numOfFloors/2) { elevator->floor++; } } elevator->direction = 0; return; } //END: idle //START: Update floor number if((elevator->floor == numOfFloors)||(elevator->floor == 1)) { elevator->direction = 0; } if(elevator->direction == -1) { elevator->floor--; } else if(elevator->direction == 1) { elevator->floor++; } else { if(elevator->floor > goTo) { elevator->floor--; elevator->direction = -1; } else if(elevator->floor < goTo) { elevator->floor++; elevator->direction = 1; } } //END: Update floor number //START: If you are on the desired floor, shuffle the passengers if(goTo == elevator->floor) { //START: get customers off elevator for(uint i = 0; i < (elevator->passengers).size(); i++) { if((elevator->passengers)[i].goingTo == goTo) { totalWaitTime += currentTime - ((elevator->passengers)[i]).waitingTime; if(goTo != 1) { (*working).push_back((elevator->passengers)[i]); ((*working).back()).waitingTime = getWorkTime(); ((*working).back()).floor = goTo; ((*working).back()).goingTo = 1; ((*working).back()).waiting = 0; } else { count++; } (elevator->passengers).erase((elevator->passengers).begin() + i); } } //END: get customers off elevator //START: Get customers on elevator if((elevator->passengers).size() < maxPassengers) { for(uint i = 0; i < (*working).size(); i++) { if((*working)[i].floor == goTo) { if((*working)[i].waiting == 1) { (elevator->passengers).push_back((*working)[i]); (*working).erase((*working).begin() + i); } } if((elevator->passengers).size() == maxPassengers) { i = (*working).size(); } } } //END: Get customers on elevator } //END: If you are on the desired floor, shuffle the passengers } //END: Elevator modes //START: Simulation Main function void discreteEventSim() { vector working; vector elevator; //START: Sim loop working.push_back(newPerson(arrivalTime(),1)); for(int i = 0; i < numOfElevators; i++) { elevator.push_back(newElevator(10,1,modeOfElevators,idleModeOfElevators)); } while(count < totalAllowedArrivals) { //START: Loop for checking each floor arrival for(uint i = 0; i < working.size(); i++) { if(working[i].waitingTime <= currentTime) { if(working[i].waiting == 0) { working[i].waiting = 1; if(working[i].floor == 1) { working[i].goingTo = rand()%(numOfFloors-1) + 2; working.push_back(newPerson(arrivalTime(),1)); } else { working[i].goingTo = 1; } } } } //END: Loop for checking each floor arrival //START: Loop for checking each elevator for(uint i = 0; i < elevator.size(); i++) { if(elevator[i].mode == 0) { SSTF(&elevator[i],&working); } else if(elevator[i].mode == 1) { LRSN(&elevator[i],&working); } } //END: Loop for checking each elevator currentTime += timeStep; } cout << "Elevator Mode: " << modeOfElevators << "\n"; cout << "Idle Mode: " << idleModeOfElevators << "\n"; cout << "Total Time: " << currentTime << "\n"; cout << "Total Average Wait Time: " << totalWaitTime/(float)totalAllowedArrivals << "\n"; //END: Sim loop } //END: Simulation Main function int main() { srand(randomSeed); discreteEventSim(); return 0; }