Бесконечный цикл с Bank Simulation - PullRequest
0 голосов
/ 07 октября 2019

Привет, когда я запускаю симуляцию банка, он зацикливается на последнем клиенте, который не может удалить событие из списка. Я не знаю, как переработать логику, чтобы решить эту проблему. Моя текущая функция защищает удаление первого события до его обработки, но также заставляет цикл перехватывать последнее событие

код проблемы в методе класса EventList RemoveEvent ()

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;
}

Ответы [ 2 ]

1 голос
/ 08 октября 2019

понял, что только что возвратил событие в начале списка, затем удалил фронт после выполнения в качестве последней части цикла перед перезапуском цикла

0 голосов
/ 07 октября 2019

Действительно, есть проблема в методе 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 из стандартной библиотеки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...