银行模拟的无限循环

Endless loop with Bank Simulation

本文关键字:无限循环 模拟      更新时间:2023-10-16

嗨,当我运行银行模拟时,它在最后一个客户上陷入了无限循环 无法从列表中删除事件 我不知道如何重新设计逻辑来解决此问题。 MY 当前函数保护在处理第一个事件之前删除第一个事件,但也会导致循环被捕获到最后一个事件

事件列表类方法删除事件((中的问题代码

Event* EventList::removeEvent()
{
if (isEmpty())
cout << "Cannot remove event from empty list" << endl;
Event* tmp = front;
if (tmp->next != NULL)
{
tmp = tmp->next;
deleteFront();
front = tmp;
}
return tmp;
}
#include "Bank.h"
#include <stdlib.h>
#include <time.h>
using namespace std;
Bank::Bank()
{
totalCustomers = 0;
totalTime = 0;
currentTime = 0;
closingTime = 60 * 60;//(60 * 60 * 8);
list = new EventList();
win1 = new Queue();
win2 = new Queue();
win3 = new Queue();
win4 = new Queue();
}
Bank::Bank(Event* event)
{
totalCustomers = 0;
totalTime = 0;
currentTime = event->occurTime;
closingTime = (60 * 60 * 8);
list = new EventList();
list->insertEnd(event);
win1 = new Queue();
win2 = new Queue();
win3 = new Queue();
win4 = new Queue();
}
Bank::~Bank()
{
win1->clear();
win2->clear();
win3->clear();
win4->clear();
list->clearList();
}
int Bank::avgTime()
{
int avg = totalTime / totalCustomers;
return avg;
}
int Bank::genService()
{
srand(time(NULL));
int time = rand() % 20 + 1;
time *= 60;
return time;
}
int Bank::genArrival(Customer* customer)
{
srand(time(NULL));
int time = rand() % 5 + 1;
time *= 60;
time += customer->arrivalTime;
return time;
}
int Bank::departTime(Customer* tmp)
{
int depart;
depart = tmp->arrivalTime + tmp->serviceTime;
return depart;
}
bool Bank::emptyWindows()
{
if (win1->isEmpty() || win2->isEmpty() || win3->isEmpty() || win4->isEmpty())
return true;
return false;
}
int Bank::checkType(int eventType)
{
switch (eventType)
{
case 1: return 1; break;
case 2: return 2; break;
case 3: return 3; break;
case 4: return 4; break;
default: return 0; break;
}
}
void Bank::customerArrival(Event* event)
{
Customer* customer = new Customer;
customer->arrivalTime = event->occurTime;
int time = genService();
customer->serviceTime = time;
customer->nextCustomer = NULL;
int nxtArrival = genArrival(customer);
if (nxtArrival < closingTime)
{
Event* arriveEvent = new Event;
arriveEvent->occurTime = nxtArrival;
arriveEvent->type = 0;
arriveEvent->next = NULL;
Event* p = list->getFront();
if (list->isEmpty())
list->frontInsert(arriveEvent);
else {
while (p->occurTime < nxtArrival && p->next != NULL)
p = p->next;
if (nxtArrival > p->occurTime)
list->insertEnd(arriveEvent);
else
list->midInsert(arriveEvent, p);
}
}
int num1, num2, num3, num4;
if (!emptyWindows())
{
num1 = win1->getSize();
num2 = win2->getSize();
num3 = win3->getSize();
num4 = win4->getSize();
if (num1 < num2 && num1 < num3 && num1 < num4)
win1->enQueue(customer);
else if (num2 < num3 && num2 < num4)
win2->enQueue(customer);
else if (num3 < num4)
win3->enQueue(customer);
else
win4->enQueue(customer);
}
if (win1->isEmpty())
{
Event* depart = new Event;
depart->occurTime = customer->arrivalTime + customer->serviceTime;
depart->type = 1;
depart->next = NULL;
win1->enQueue(customer);
Event* p = list->getFront();
while (p->occurTime < depart->occurTime && p->next != NULL)
p = p->next;
if (depart->occurTime > p->occurTime)
list->insertEnd(depart);
else
list->midInsert(depart, p);
}
else if (win2->isEmpty())
{
Event* depart = new Event;
depart->occurTime = customer->arrivalTime + customer->serviceTime;
depart->type = 2;
depart->next = NULL;
win2->enQueue(customer);
Event* p = list->getFront();
while (p->occurTime < depart->occurTime && p->next != NULL)
p = p->next;
if (depart->occurTime > p->occurTime)
list->insertEnd(depart);
else
list->midInsert(depart, p);
}
else if (win3->isEmpty())
{
Event* depart = new Event;
depart->occurTime = departTime(customer);
depart->type = 3;
depart->next = NULL;
win3->enQueue(customer);
Event* p = list->getFront();
while (p->occurTime < depart->occurTime && p->next != NULL)
p = p->next;
if (depart->occurTime > p->occurTime)
list->insertEnd(depart);
else
list->midInsert(depart, p);
}
else if (win4->isEmpty())
{
Event* depart = new Event;
depart->occurTime = departTime(customer);
depart->type = 4;
depart->next = NULL;
win4->enQueue(customer);
Event* p = list->getFront();
while (p->occurTime < depart->occurTime && p->next != NULL)
p = p->next;
if (depart->occurTime > p->occurTime)
list->insertEnd(depart);
else
list->midInsert(depart, p);
}
totalCustomers++;
}
int Bank::customerDepart(Event* event)
{
int tmpType = checkType(event->type);
Customer* nxt;
int stayingTime = 0;
if (tmpType == 1)
{
Customer* tmp = win1->getHead();
if (tmp != NULL)
{
stayingTime += event->occurTime - tmp->arrivalTime;
win1->dlQueue();
}
if (!win1->isEmpty())
{
nxt = win1->getHead();
Event* depart = new Event;
depart->occurTime = event->occurTime + nxt->serviceTime;
depart->type = 1;
depart->next = NULL;
Event* p = list->getFront();
while (p->occurTime < depart->occurTime && p->next != NULL)
p = p->next;
if (depart->occurTime > p->occurTime)
list->insertEnd(depart);
else
list->midInsert(depart, p);
}
}
else if (tmpType == 2)
{
Customer* tmp = win2->getHead();
if (tmp != NULL)
{
stayingTime += event->occurTime - tmp->arrivalTime;
win2->dlQueue();
}
if (!win2->isEmpty())
{
nxt = win2->getHead();
Event* depart = new Event;
depart->occurTime = event->occurTime + nxt->serviceTime;
depart->type = 2;
depart->next = NULL;
Event* p = list->getFront();
while (p->occurTime < depart->occurTime && p->next != NULL)
p = p->next;
if (depart->occurTime > p->occurTime)
list->insertEnd(depart);
else
list->midInsert(depart, p);
}
}
else if (tmpType == 3)
{
Customer* tmp = win3->getHead();
if (tmp != NULL)
{
stayingTime += event->occurTime - tmp->arrivalTime;
win3->dlQueue();
}
if (!win3->isEmpty())
{
nxt = win3->getHead();
Event* depart = new Event;
depart->occurTime = event->occurTime + nxt->serviceTime;
depart->type = 3;
depart->next = NULL;
Event* p = list->getFront();
while (p->occurTime < depart->occurTime && p->next != NULL)
p = p->next;
if (depart->occurTime > p->occurTime)
list->insertEnd(depart);
else
list->midInsert(depart, p);
}
}
else if (tmpType == 4)
{
Customer* tmp = win4->getHead();
if (tmp != NULL)
{
stayingTime += event->occurTime - tmp->arrivalTime;
win4->dlQueue();
}
if (!win4->isEmpty())
{
nxt = win4->getHead();
Event* depart = new Event;
depart->occurTime = event->occurTime + nxt->serviceTime;
depart->type = 4;
depart->next = NULL;
Event* p = list->getFront();
while (p->occurTime < depart->occurTime && p->next != NULL)
p = p->next;
if (depart->occurTime > p->occurTime)
list->insertEnd(depart);
else
list->midInsert(depart, p);
}
}
return stayingTime;
}
void Bank::runSimulation() //caught in endless loop
{
if (currentTime == 0)
{
list->addNode(currentTime, 0);
}
Event* currentEvent;
while (!list->isEmpty())
{
currentEvent = list->removeEvent();
if (currentEvent->type == 0)
{
customerArrival(currentEvent);
currentTime = currentEvent->occurTime;
}
else
{
customerDepart(currentEvent);
currentTime = currentEvent->occurTime;
}
}
int avg = avgTime();
printResults(avg);
}
void Bank::printResults(int avg)
{
cout << "Total Customers:" << totalCustomers << endl;
cout << "Total Time:" << totalTime << endl;
cout << "Avg Staying Time:" << avg << endl;
}

想通了,只是在列表的前面返回了事件,然后在执行后删除了前面作为循环重启前的最后一部分

removeEvent(( 方法确实存在问题。当队列只有一个元素时,您无法正确处理这种情况。这会导致无限循环。

Event* EventList::removeEvent()
{
if (isEmpty())
cout << "Cannot remove event from empty list" << endl;
Event* tmp = front;
if (tmp != NULL) {
tmp = (tmp->next != NULL) ? tmp->next : null;
deleteFront();
front = tmp;
}
return tmp;
}

也许与其创建自己的队列类,不如考虑从标准库中开始使用 std::queue 模板。