23 : floorButtons(new
FloorButtons(numberOfFloors)), queue(new
Queue(numberOfFloors)), time(0)
26 elevators.emplace_back(
new Elevator(numberOfFloors, capacityOfElevator,
id));
35 void Control::TimeIncrement()
41 void Control::FindAppearingPassengers()
43 auto newEnd = std::partition(queue->passengers.begin(), queue->passengers.end(), \
46 for (
auto it = newEnd; it != queue->passengers.end(); ++it)
48 queue->passOnFloor[it->getFloorDeparture()].push_back(*it);
49 passStatBuffer.push_back(
"time = " + std::to_string(
getCurrentTime()) \
50 +
"\tPassenger #" + std::to_string(it->id) \
51 +
"\tappeared on floor #" + std::to_string(it->getFloorDeparture()) \
52 +
", goes to floor #" + std::to_string(it->getFloorDestination()));
55 queue->passengers.erase(newEnd, queue->passengers.end());
59 void Control::PressingFloorButtons()
61 for (
size_t floor = 0; floor < queue->passOnFloor.size(); ++floor)
63 for (
auto& p : queue->passOnFloor[floor])
64 if (!isElevatorOnFloor(floor))
66 if (p.getFloorDestination() > p.getFloorDeparture())
67 floorButtons->setUpButton(p.getFloorDeparture());
69 floorButtons->setDnButton(p.getFloorDeparture());
75 void Control::LeavingFloors()
77 for (
size_t floor = 0; floor < queue->passOnFloor.size(); ++floor)
79 std::vector<Passenger> continueWaiting;
81 for (
auto& p : queue->passOnFloor[floor])
83 if (
getCurrentTime() - p.getTimeInit() < p.properties.criticalWaitTime)
84 continueWaiting.push_back(p);
88 queue->finished.push_back(p);
89 passStatBuffer.push_back(\
91 +
"\tPassenger #" + std::to_string(p.id) \
92 +
"\tfrom floor #" + std::to_string(p.getFloorDeparture()) \
93 +
" to floor #" + std::to_string(p.getFloorDestination()) \
94 +
"\tleaved the floor (waiting time = " + std::to_string(
getCurrentTime() - p.getTimeInit()) +
")");
97 queue->passOnFloor[floor] = std::move(continueWaiting);
104 passStatBuffer.resize(0);
110 FindAppearingPassengers();
113 PressingFloorButtons();
120 for (
size_t pos = 0; pos < floorButtons->dnButtons.size(); ++pos)
126 std::vector<Elevator*> elevOnFloor;
127 for (
auto& e : elevators)
130 if (e->getNumberOfPassengers() < e->capacity)
131 elevOnFloor.push_back(e.get());
134 if (e->timeToSelfProgramme == 0)
142 if (elevOnFloor.size() > 1)
143 for (
auto& pe : elevOnFloor)
144 pe->timeToSelfProgramme = elevOnFloor[0]->timeToSelfProgramme;
146 if (elevOnFloor.size() > 0)
147 if (elevOnFloor[0]->timeToSelfProgramme == 0)
149 auto& pass = queue->passOnFloor[pos];
151 size_t passToUp = 0, passToDn = 0;
154 if (p.getFloorDestination() > pos)
161 for (
auto& e : elevOnFloor)
169 for (
auto& e : elevOnFloor)
176 if ((passToUp == 0) && (passToDn == 0))
177 for (
auto& e : elevOnFloor)
185 std::vector<Passenger> stillWaiting;
190 std::vector<Elevator*> elevAppropriate;
191 bool inverseWay =
false;
195 for (
auto& e : elevOnFloor)
199 e->lastChechedPassenger = std::max(p.id, e->lastChechedPassenger);
201 if (e->getNumberOfPassengers() < e->capacity)
202 elevAppropriate.push_back(e);
212 e->lastChechedPassenger = std::max(p.id, e->lastChechedPassenger);
214 if (e->getNumberOfPassengers() < e->capacity)
215 elevAppropriate.push_back(e);
225 if ((elevAppropriate.size() == 0) && (inv))
228 for (
auto& e : elevOnFloor)
232 e->lastChechedPassenger = std::max(p.id, e->lastChechedPassenger);
234 if (e->lastChechedPassenger <= p.id)
236 if (e->getNumberOfPassengers() < e->capacity)
238 elevAppropriate.push_back(e);
252 if (elevAppropriate.size() > 0)
254 size_t elevWithSmallestPass = 0;
255 size_t smallestPass = elevAppropriate[0]->getNumberOfPassengers();
257 for (
size_t numb = 1; numb < elevAppropriate.size(); ++numb)
258 if (elevAppropriate[numb]->getNumberOfPassengers() < smallestPass)
260 elevWithSmallestPass = numb;
261 smallestPass = elevAppropriate[numb]->getNumberOfPassengers();
265 Elevator* e = elevAppropriate[elevWithSmallestPass];
267 e->passengers.push_back(p);
270 passStatBuffer.push_back(
"time = " + std::to_string(
getCurrentTime()) \
271 +
"\tPassenger #" + std::to_string(e->passengers.back().id) \
272 +
"\tfrom floor #" + std::to_string(e->passengers.back().getFloorDeparture()) \
273 +
" to floor #" + std::to_string(e->passengers.back().getFloorDestination()) \
274 + (inverseWay ?
"*" :
"") \
275 +
"\tentered the elevator #" + std::to_string(e->myid));
277 e->buttons[e->passengers.back().getFloorDestination()] =
true;
280 if (e->passengers.back().properties.floorDestination > pos)
288 stillWaiting.push_back(p);
293 pass = std::move(stillWaiting);
301 for (
auto& e : elevators)
304 if (e->isGoingButtonPressed() && (e->timeToSelfProgramme > 1))
306 e->timeToSelfProgramme = 1;
311 for (
auto& e : elevators)
313 if (e->timeToSelfProgramme == 0)
315 auto pos = e->position / 100;
316 auto& pass = queue->passOnFloor[pos];
323 switch (e->doorsStatus)
328 auto it = std::find_if(e->passengers.begin(), e->passengers.end(), \
329 [=](
const Passenger& p) {
return p.getFloorDestination() == pos; });
330 if (it != e->passengers.end())
334 queue->finished.push_back(*it);
335 passStatBuffer.push_back(
"time = " + std::to_string(
getCurrentTime()) \
336 +
"\tPassenger #" + std::to_string(it->id) \
337 +
"\tfrom floor #" + std::to_string(it->getFloorDeparture()) \
338 +
" to floor #" + std::to_string(it->getFloorDestination()) \
339 +
"\tgot off the elevator #" + std::to_string(e->myid) \
340 +
" (appeared t = " + std::to_string(it->properties.timeInit) \
341 +
", in elevator t = " + std::to_string(it->timeStart) +
")");
342 e->passengers.erase(it);
347 e->lastChechedPassenger = 0;
369 if ( ((e->position % 100) == 0 ) && (e->isEmpty()) )
371 if (queue->passOnFloor[e->position / 100].size() > 0)
373 bool isPassUp =
false, isPassDn =
false;
374 for (
auto& p : queue->passOnFloor[e->position / 100])
376 if (p.getFloorDestination() > pos)
378 if (p.getFloorDestination() < pos)
387 e->buttons[pos] =
false;
398 if ((e->position / 100) < e->destinationFloor)
406 if (((e->position + 99) / 100) > e->destinationFloor)
414 if (((e->position / 100) == e->destinationFloor) &&
415 ((e->position % 100) == 0))
418 if ((e->getNumberOfPassengers() > 0) ||
419 (floorButtons->getDnButton(e->destinationFloor)) ||
420 (floorButtons->getUpButton(e->destinationFloor)))
423 e->buttons[pos] =
false;
426 if ((floorButtons->getDnButton(e->destinationFloor)) &&
428 floorButtons->unsetDnButton(e->destinationFloor);
430 if ((floorButtons->getUpButton(e->destinationFloor)) &&
432 floorButtons->unsetUpButton(e->destinationFloor);
457 switch (e->acceleration)
478 bool critDir = ((100 * (int)e->destinationFloor - (
int)e->position) * sign) > 0;
481 if (abs((
int)((e->position - 100 * e->destinationFloor))) != (
int)(100 *
veloUniform))
487 e->position += sign * 12;
494 e->position += sign * 12;
517 switch (e->timeToSelfProgramme)
520 e->position += sign * 5;
524 e->position += sign * 8;
528 e->position += sign * 12;
535 switch (e->timeToSelfProgramme)
538 e->position += sign * 8;
542 e->position += sign * 5;
548 --(e->timeToSelfProgramme);
556 queue->addPassenger(passProp_);
561 std::ifstream fi(fileName_);
564 fi.getline(str, 100,
'\n');
587 queue->addPassenger(passProp);
603 fout.open(fname, std::ios_base::app);
606 std::ostream& str = (fname ==
"") ? std::cout : fout;
611 printf(
"\033[01;37m");
614 case 0: printf(
"\033[01;34m");
break;
615 case 1: printf(
"\033[01;32m");
break;
616 case 2: printf(
"\033[22;31m");
break;
617 case 3: printf(
"\033[01;35m");
break;
618 default: printf(
"\033[22;33m");
621 printf(
"\033[01;37m");
630 str << std::to_string(elevators[i]->position / 100);
632 if ((elevators[i]->position % 100) < 10)
634 str << std::to_string(elevators[i]->position % 100);
638 switch (elevators[i]->status)
641 printf(
"\033[01;32m");
645 printf(
"\033[01;34m");
649 printf(
"\033[01;33m");
654 printf(
"\033[01;37m");
658 switch (elevators[i]->indicator)
661 printf(
"\033[01;32m");
665 printf(
"\033[01;34m");
669 printf(
"\033[01;33m");
674 printf(
"\033[01;37m");
675 str <<
" acceler. = ";
678 switch (elevators[i]->acceleration)
681 printf(
"\033[22;32m");
685 printf(
"\033[22;31m");
689 printf(
"\033[22;33m");
694 printf(
"\033[01;37m");
698 switch (elevators[i]->doorsStatus)
701 printf(
"\033[01;31m");
702 str <<
"unloading...";
705 printf(
"\033[01;31m");
706 str <<
"loading... ";
709 printf(
"\033[01;33m");
710 str <<
"opening... ";
713 printf(
"\033[01;33m");
714 str <<
"closing... ";
717 printf(
"\033[22;36m");
721 printf(
"\033[01;31m");
722 str <<
"waiting... ";
726 printf(
"\033[01;37m");
728 for (
auto& p : elevators[i]->passengers)
730 str << std::to_string(p.id);
733 str <<
")" << std::endl;
750 fout.open(fname, std::ios_base::app);
753 std::ostream& str = (fname ==
"") ? std::cout : fout;
756 for (
auto& e : elevators)
758 str <<
" in elevator #" << e->myid <<
": ";
759 for (
size_t i = 0; i < e->buttons.size(); ++i)
764 str <<
" on floors: ";
765 for (
size_t i = 0; i < floorButtons->upButtons.size(); ++i)
767 if (floorButtons->getUpButton(i) || floorButtons->getDnButton(i))
769 str <<
"#" << i <<
"(";
770 if (floorButtons->getUpButton(i)) {
771 printf(
"\033[01;32m");
774 if (floorButtons->getDnButton(i)) {
775 printf(
"\033[01;34m");
778 printf(
"\033[01;37m");
782 str << std::endl << std::endl;
797 fout.open(fname, std::ios_base::app);
800 std::ostream& str = (fname ==
"") ? std::cout : fout;
801 printf(
"\033[01;33m");
802 if (passStatBuffer.size() > 0)
803 for (
auto& st : passStatBuffer)
804 str << st << std::endl;
808 printf(
"\033[01;37m");
812 bool Control::isElevatorOnFloor(
size_t stage)
const 814 for (
auto& e : elevators)
815 if ((e->position / 100.0 == stage) && (e->position % 100 == 0))
827 std::ostream& str = (fname ==
"") ? std::cout : fout;
829 std::vector<Passenger> allPass(queue->passengers);
830 for (
auto& pf : queue->passOnFloor)
831 std::copy(pf.begin(), pf.end(), std::back_inserter(allPass));
832 for (
auto& e : elevators)
833 std::copy(e->passengers.begin(), e->passengers.end(), std::back_inserter(allPass));
834 std::copy(queue->finished.begin(), queue->finished.end(), std::back_inserter(allPass));
836 std::sort(allPass.begin(), allPass.end());
838 size_t numInElevetor = 0, numOnFloors = 0, numLeaved = 0;
839 size_t penaltyFinished = 0, penaltyInElevetor = 0, penaltyOnFloors = 0, penaltyLeaved = 0;
841 if (passengersDetails)
842 str <<
"Passangers:" << std::endl;
844 for (
auto& p : allPass)
850 penaltyFinished += p.timeFinish - p.getTimeInit();
851 if (passengersDetails)
852 str <<
"#" << p.id <<
", penalty = " << p.timeFinish - p.getTimeInit() \
853 <<
" (init = " << p.getTimeInit() <<
", started = " << p.timeStart <<
", finished = " << p.timeFinish <<
")" \
862 if (passengersDetails)
863 str <<
"#" << p.id <<
", penalty = " <<
getCurrentTime() - p.getTimeInit() \
864 <<
" (init = " << p.getTimeInit() <<
", started = " << p.timeStart <<
", STILL IN ELEVATOR!!!" <<
")" \
873 if (passengersDetails)
874 str <<
"#" << p.id <<
", penalty = " <<
getCurrentTime() - p.getTimeInit() \
875 <<
" (init = " << p.getTimeInit() <<
", STILL WAITING FOR ELEVATOR!!!" <<
")" \
883 penaltyLeaved += p.properties.criticalWaitTime * 5;
884 if (passengersDetails)
885 str <<
"#" << p.id <<
", penalty = " << p.properties.criticalWaitTime * 5 \
886 <<
" (init = " << p.getTimeInit() <<
", LEAVED THE FLOOR!!!" <<
")" \
893 if (passengersDetails)
896 size_t waitingTime = 0, goingTime = 0, totalTime = 0;
897 size_t num_finished_notLeaved = 0;
898 for (
auto& p : queue->finished)
902 ++num_finished_notLeaved;
903 waitingTime += p.timeStart - p.getTimeInit();
904 goingTime += p.timeFinish - p.timeStart;
905 totalTime += p.timeFinish - p.getTimeInit();
914 str <<
"Number of passengers, that have finished the trip: " << num_finished_notLeaved << std::endl;
915 if (num_finished_notLeaved > 0)
917 str <<
" average waiting time = " << 1.0 * waitingTime / num_finished_notLeaved << std::endl;
918 str <<
" average going time = " << 1.0 * goingTime / num_finished_notLeaved << std::endl;
919 str <<
" average total time = " << 1.0 * totalTime / num_finished_notLeaved << std::endl;
921 str <<
"Penalty for them = " << penaltyFinished << std::endl;
925 str <<
"Still waiting on floors = " << numOnFloors << std::endl;
926 str <<
"Penalty for them = " << penaltyOnFloors << std::endl;
929 str <<
"Still in elevator = " << numInElevetor << std::endl;
930 str <<
"Penalty for them = " << penaltyInElevetor << std::endl;
933 str <<
"Leaved the floors, because of too large waiting time = " << numLeaved << std::endl;
934 str <<
"Penalty for them = " << penaltyLeaved << std::endl;
937 str <<
"TOTAL PENALTY = " << penaltyFinished + penaltyInElevetor + penaltyOnFloors + penaltyLeaved << std::endl;
стрелочки в обоих направлениях
double pStartGoing
Вероятность нажать кнопку "ход", не дожидаясь закрытия дверей
const double veloUniform
Скорость равномерно движения лифта (в долях этажа)
const size_t timeLeaving
Время между выходами двух пассажиров в лифт
const size_t numberOfFloors
Общее число этажей
void PrintPassengerState(const std::string &fname="") const
Функция печати в файл или на экран событий, произошедших с пассажирами за последний шаг (последнюю се...
Пассажир не дождался лифта и ушел
size_t timeInit
Время появления пассажира на этаже
движется равномерно или стоит
Пассажир ждет лифта на этаже отправления
const size_t waitingTime
Время ожидания до закрытия дверей (если только кто-то не нажмет кнопку "ход" раньше) ...
void AddPassengerToQueue(const PassengerProperties &passProp_)
Функция добавления пассажира в очередь
const size_t timeOpening
Время открывания дверей
size_t criticalWaitTime
Время ожидания, после которого пассажир уходит
const size_t timeBreaking
Время торможения лифта
size_t floorDestination
Этаж, на который пассажир едет
size_t getCurrentTime() const
Функция запроса текущего времени
const size_t numberOfElevators
Число лифтов
Заголовочный файл с описанием класса Queue.
Пассажир успешно прибыл на нужный этаж
size_t floorDeparture
Этаж, с которого пассажир отправляется
const size_t timeAccelerating
Время разгона лифта
открыты (идет посадка пассажиров)
открыты (лифт ожидает отправления)
double pInverseStopWaiting
Вероятность сесть в лифт, едущий в неверном направлении в конце ожидания
const size_t timeClosing
Время закрывания дверей
открыты (идет высадка пассажиров)
double pInverseStartWaiting
Вероятность сесть в лифт, едущий в неверном направлении в начале ожидания
void PrintElevatorState(size_t elevatorNumber, const std::string &fname="") const
Функция печати в файл или на экран состояния лифта в текущий момент времени
const size_t timeEntering
Время между входами двух пассажиров в лифт
Control(size_t numberOfFloors, size_t numberOfElevators, size_t capacityOfElevator)
Инициализирующий конструктор
Класс — очередь пассажиров
void PrintButtonsState(const std::string &fname="") const
Функция печати в файл или на экран состояния кнопок в кабинах и на этажах в текущий момент времени ...
Заголовочный файл с описанием основного класса Control.
Пассажир нажодится в лифте
void MakeStep()
Функция выполнения шага моделирования по времени
void PrintStatistics(bool passengersDetails, const std::string &fname="") const
Функция печати в файл или на экран итоговой статистики, включая итоговый "рейтинг" (чем меньше - тем ...
void ReadTimeTable(const std::string &fileName_)
Функция чтения расписания появления пассажиров на этажах