Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Принцип работы программы ??? не совсем понятен 
:(
    Опции темы
sgrey
Дата 13.8.2006, 03:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 265
Регистрация: 15.4.2006

Репутация: нет
Всего: 4



Писал я прогу, и взял из книжки приёмчик один. Суть проги такая - она считает среднее время ожидания клиента в очереди в банке. Оперции:
1) Постатистическим данным из файла читается время прибытия и заносится в лист событий,  время ожидания и время непосредственно которое кассир делал что там нужно с клиентом - это хранится в пямяти.
2) Во время прибытия клиента смотрится есть ли кто-то в очереди и занят ли кассир.
3) Если Кассир свободен - считается время когда клиент уедет и записывается в лист событый.
4) Если кассир несвбоден - человек заносится в очередь
5) таким образом решаются все остальные клиенты до конца дня.
Вопрос как раз при проверке. В коде когда первый клиент заходит в банк, то стоит проверка очереди. Мне кажется что это только для первого клиента, потому как для следующих это уже всегда будет ложно, но препод сказал что это для всех и вроде как работает всё время... вобщем вод код, я обозначил это место с вопросом. Это только исполняемый скрипт, к нему ещё 2 класса описаны и файл с данными. если надо могу дать весь архив.
Объяснил коряво, что непонятно - спрашивайте

Код
#include"QueueS.h"
#include<fstream>
#include<cstdlib>

void dysplayQueue(Queue& S); //display the line of the customers
//for tracing the algorithm
ifstream read;

int main()
{
    Queue line; //the line in the bank
    List events; //the list of the events
    ListItem event; //structure of the events
    int currenttime = 0, arrivetime, duration, departure = 0, averagetime = 0,
        totaltime = 0, waittime = 0, customer = 0; 
    const char arrive = 'A', dep = 'D'; //event types - arrive or departure
    bool success, atFront; // success using in the list functions, 
    //atFront checks if the customer first in the line

    read.open("line.txt");
    if (read.fail()) //if file cannot open -> show mistake
    {
        cerr << "Cannot open file!!!\n\n";
        //cerr output text without buffering, so it takes less resourses
        exit(1);
    }
    
    read >> arrivetime;//read time and duration of the first event
    read >> duration;
    
    event.eventType = arrive;//assing data for the first event
    event.eventTime = arrivetime;
    event.duration = duration;
    events.insert(1, event, success);
    currenttime = event.eventTime;
    //first event is arrival, enters it into event list
        
    while(!events.isEmpty())//proccess the line until there are
        //events in the list
    {
        events.retrieve(1, event, success);//retrieve first event in the eventlist
        //if it arraival event, proccess an arrival, orthewise proccess a departure
        //currenttime = event.eventTime;
        if (event.eventType == arrive)
        {
            customer++;



            atFront = line.isEmpty();//check if the customer was first in the line <- здесь идёт первая проверка по которой вопрос        //then create departure event for him



            cout << "Proccessing an arravial event at time " << event.eventTime << endl;
            currenttime = event.eventTime;
            duration = event.duration;

            cout << "The list of the events before removing arraival "; 
            events.display();//display the list of the events
            //for tracing the algorithm before remove first event and after
            events.remove(1, success);
                    //remove proccessed event from the eventlist
            cout << "The list of the events after removing arraival ";
            events.display();
            cout << "The line of customers before inserting new one\n";
            dysplayQueue(line);//display the list of the events
            //for tracing the algorithm before remove first event and after
            
            line.insert(currenttime, duration);
            //insert custumer in the line

        cout << "The line of customers after inserting new one\n";
                dysplayQueue(line);




            if (atFront) //if the customer begins transaction, create 
                //departure event for him здесь где функция вступает в работу. больше нигде не применеятся



            {
                departure = currenttime + duration;
                event.eventType = dep;
                event.eventTime = departure;
                event.duration = 0;
                events.insert(1, event, success);
                //create a departure event for the customer
                
            }
        
            if (!read.eof())//if there are more events in the file, 
            {
                read >> arrivetime;//read file for next event
                read >> duration;
                event.eventType = arrive;
                event.eventTime = arrivetime;
                event.duration = duration;
                if (arrivetime <= departure) //if time of next event is less
                    //then time of the event in eventlist, then
                    //insert it in first position, otherwise insert in a second
                {
                    events.insert(1, event, success);
                }
                else
                {
                    events.insert(2, event, success);
                }
            }
        }
        else if (event.eventType == dep) //proccess departure event
        {
            currenttime = event.eventTime;//assing the time of the current event 
            //to currenttime for computing waittime
                                    
            cout << "\tProccessing a departure event at time " << currenttime << endl;
        
            cout << "The list of the events before removing departure ";
            //display the list of the events before departure
            events.display();
            events.remove(1, success);

        cout << "The list of the events after removing departure ";
        events.display();
        //display list after customer left 
            
            line.getFront(arrivetime, duration);//read arrive time to
            //compute wait time
            waittime = currenttime - arrivetime;
            //computing waittime of the current customer
            totaltime += waittime; //total waittime of all customers
            
            cout << "The line of the customers before departure\n";
                dysplayQueue(line);//display the line of the customers
                //to trace the algorithm before customer depart
            line.remove();
            cout << "The line of the customers after departure\n";
                dysplayQueue(line);//display the line of the customers
                //to trace the algorithm after customer depart

            if (!line.isEmpty())//if there are customers in the line, 
                //create departure event for them
            {
                line.getFront(arrivetime, duration);
                departure = currenttime + duration;
                if (!events.isEmpty())//determine if there are events 
                    //in the eventlist and if there is an event, then check
                    //time of the event in the eventlist and departure event
                    //that was just created for the customer
                {    
                    events.retrieve(1, event, success);
                    
                    if(departure > event.eventTime)//if departure time is
                        //grater then time of the event in the event list,
                        //place departure as a second event in the list,
                        //otherwise, place as firs event
                    {
                        event.eventType = dep;
                        event.eventTime = departure;
                        event.duration = 0;
                        events.insert(2, event, success);
                    }
                    else
                    {
                        event.eventType = dep;
                        event.eventTime = departure;
                        event.duration = 0;
                        events.insert(1, event, success);
                    }//end if
                }
                else
                {
                    event.eventType = dep; //if there are no events 
                    //in the list, place departure in the first position
                    event.eventTime = departure;
                    event.duration = 0;
                    events.insert(1, event, success);
                }//end if
            }//end if
        }//end if            
    }//end loop

    averagetime = totaltime / customer;//show statics for the customers
    cout << endl << endl;
    cout << "Avarege wait time for the customers is " << averagetime << endl;
    cout << "Total wait time is " << totaltime << endl;
    cout << customer << " customers were served today\n\n";

    read.close();

    return 0;
}
void dysplayQueue(Queue& S)
{
    Queue T;
    int time = 0, dur = 0;
    while (!S.isEmpty())
    {
        S.getFront(time, dur);
        cout << "Time " << time << " Duration " << dur << endl;
        T.insert(time, dur);
        S.remove();
    }
    while (!T.isEmpty())
    {
        T.getFront(time, dur);
        S.insert(time, dur);
        T.remove();
    }
    cout << endl;
}


PM MAIL   Вверх
Pilligrim
Дата 13.8.2006, 17:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 65
Регистрация: 9.6.2006

Репутация: 1
Всего: 1



А я думаю, что когда заходит первый клиент проверку на очередь не надо, т.к. он - первый, и соответственно очереди быть не может. А потом, для следующих клиентов, проверка нужна,т.к. она не всегда будет сообщать, что очередь есть, ведь он может зайти к вечеру, когда очереди уже нет.
PM MAIL   Вверх
sgrey
Дата 13.8.2006, 21:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 265
Регистрация: 15.4.2006

Репутация: нет
Всего: 4



Pilligrim, прога просто читает данные из файла и не знает первый он или не первый, поэтому ей нужно указать. вопрос в том - работает ли эта проверка для последующих клиентов, или она только первого проверяет? мне кажется только первого
PM MAIL   Вверх
ptr
Дата 14.8.2006, 05:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 661
Регистрация: 31.5.2006
Где: Новосибирск

Репутация: 1
Всего: 14



sgrey, что-то я не понял вопроса. Если у тебя выполнится условие if (event.eventType == arrive), то в любом случае будет произведена проверка на пустоту очереди.

Цитата(sgrey @  13.8.2006,  07:33 Найти цитируемый пост)
Мне кажется что это только для первого клиента, потому как для следующих это уже всегда будет ложно,

А если очередь полностью освободится?

Это сообщение отредактировал(а) ptr - 14.8.2006, 10:52


--------------------
Единственный способ определить границы возможного - это выйти за эти границы, в невозможное.
Артур Кларк.
PM MAIL ICQ   Вверх
MAKCim
Дата 14.8.2006, 10:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 52
Всего: 207



а зачем в этой задаче вообще очередь использовать
ради интереса набрал решение (если правильно понял условие)
Код

#include <iostream>
#include <fstream>

struct statistic
{
    statistic()
        : totaltime(0), custumers(0),
            averagetime(0.0) {}
    int totaltime, custumers;
    double averagetime;
};

statistic work(std::ifstream& stream, int day_end)
{
    bool flag, first=true;
    int previos_duration=0, beg_of;
    statistic stat;
    do
    {
        int a, b;
        stream>>a>>b;
        if (first) 
        {
            beg_of=a;
            first=false;
        }
        flag=!stream.eof() && (b+(previos_duration+beg_of)<=day_end);
        if (flag)
        {
            int c;
            if ((c=previos_duration+beg_of-a)<=0)
                beg_of=a;
            else 
            {
                beg_of=previos_duration+beg_of;
                stat.totaltime+=c;
            }
            ++stat.custumers;
            previos_duration=b;
        }
    }
    while (flag);
    stat.averagetime=static_cast<double>(stat.totaltime)/stat.custumers;
    return stat;
}

для файла
Код

0600 0005
0603 0007
0901 0025
0910 0014
0915 0016
0919 0001
1218 0007
1219 0006
1220 0010

выдает
totaltime=97
custumers=9
averagetime=10.7778

Это сообщение отредактировал(а) MAKCim - 14.8.2006, 10:50


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
sgrey
Дата 16.8.2006, 03:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 265
Регистрация: 15.4.2006

Репутация: нет
Всего: 4



Цитата(MAKCim @ 14.8.2006,  10:47)
а зачем в этой задаче вообще очередь использовать

потому что по заданию надо было использовать очередь )

Цитата

А если очередь полностью освободится?


если она осводится полностью, но в файле останутся клиенты, то прога запишет событие прибытия в лист событий и в нужное время процесс пойдёт опять до тех пор пока в файле не останется записей

Цитата

sgrey, что-то я не понял вопроса. Если у тебя выполнится условие if (event.eventType == arrive), то в любом случае будет произведена проверка на пустоту очереди.


это проверка события - если событием является прибытие, то идёт проверка на время. Если это время - сейчас, то проверяется есть ли очередь. Если очереди нет - сразу начинается работа банкира с клиентом, если есть - он становится последним в очередь. Также для него создаётся время ухода из банка. 

а если подробно всё описать, то вот лист событий в файле
Код

Время события
(прихода клиента)               Время операции
20                                         5
22                                         4
23                                         2
30                                         30


когда программа запускается, она генерирует следующий лист
Код

Время       Событие

20               Первый клиент вошёл
22               Второй вошёл
23               Третий вошёл
25               Первый ушёл, второй начинает операцию
29               Второй ушёл, третий начинает оперцию
30               Четвертый вошёл
31                Третий ушёл, четвертый начал операцию
34                Ушёл четвертый, день окончен


псевдокод событий

Код

while (настоящее время <= времени последнего события)
{
      if (событие является приходом)
    обработка прихода
     if(клиент уходит)
     обработка ухода
если события возникают одновременно,
сначала обрабатывается приход


псевдокод прихода
Код

while (есть события в листе)
{
         if(клиент начинает операцию немедленно)
         создаём для него событие ухода
           время ухода = текущее время + время оперции
         if(есть данные в файле)
         читаем следующее событие и заносим в лист событий


Обработка ухода псевдокод
Код

удаляем клиента который вышел\
 if(в очереди есть люди)
первый человек в очереди начинает операцию
удаляем событие ухода из листа
if(в очереди есть клиент)
создаём для первого в очереди событие ухода.


вобщем получается что мы вополняем всю проверку когда клиент уходит, и когда в конце остаются только события ухода - то программа даже не заходит в первый блок. 
поэтому проверка вначале она только для первого клиента... но мне утверждают обратное ) 
вот ссылка на архив со всей прогой и файлом событий написана на VC6. Там структура листа и очереди понятна будет думаю и логика самой программы) 
 http://rapidshare.de/files/29552379/bank.zip

Добавлено @ 03:53 
попробую ещё конкретизировать вопрос - там где применяется atFront, она работает только при первом цикле, или же она нужна до конца работы программы? 
Код


            atFront = line.isEmpty();//check if the customer was first in the line <- здесь идёт первая проверка по которой вопрос        //then create departure event for him



            cout << "Proccessing an arravial event at time " << event.eventTime << endl;
            currenttime = event.eventTime;
            duration = event.duration;

            cout << "The list of the events before removing arraival "; 
            events.display();//display the list of the events
            //for tracing the algorithm before remove first event and after
            events.remove(1, success);
                    //remove proccessed event from the eventlist
            cout << "The list of the events after removing arraival ";
            events.display();
            cout << "The line of customers before inserting new one\n";
            dysplayQueue(line);//display the list of the events
            //for tracing the algorithm before remove first event and after
            
            line.insert(currenttime, duration);
            //insert custumer in the line

        cout << "The line of customers after inserting new one\n";
                dysplayQueue(line);




            if (atFront) //if the customer begins transaction, create 
                //departure event for him здесь где функция вступает в работу. больше нигде не применеятся



            {
                departure = currenttime + duration;
                event.eventType = dep;
                event.eventTime = departure;
                event.duration = 0;
                events.insert(1, event, success);
                //create a departure event for the customer
                
            }


PM MAIL   Вверх
ptr
Дата 16.8.2006, 08:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 661
Регистрация: 31.5.2006
Где: Новосибирск

Репутация: 1
Всего: 14



Цитата(sgrey @  16.8.2006,  07:48 Найти цитируемый пост)
там где применяется atFront, она работает только при первом цикле, или же она нужна до конца работы программы? 

Вот так и надо было задавать вопрос. Как я понял у тебя line может очищаться и может возникнуть ситуация, когда она будет пуста, тогда данную проверку надо делать (я правда не понял смысла проверки).

Совет на будущее. Не стоит делать длинных функций, т.к. это ухудшает понимание кода.


--------------------
Единственный способ определить границы возможного - это выйти за эти границы, в невозможное.
Артур Кларк.
PM MAIL ICQ   Вверх
sgrey
Дата 16.8.2006, 23:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 265
Регистрация: 15.4.2006

Репутация: нет
Всего: 4



Цитата(ptr @ 16.8.2006,  08:05)
Вот так и надо было задавать вопрос. Как я понял у тебя line может очищаться и может возникнуть ситуация, когда она будет пуста, тогда данную проверку надо делать (я правда не понял смысла проверки).

Совет на будущее. Не стоит делать длинных функций, т.к. это ухудшает понимание кода.

ну не смог с самого начала сформулировать грамотно  smile 

спасибо ) теперь понятно )
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0531 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.