处理顾客离开事件
处理“顾客离开事件”的逻辑:
1.顾客所在服务窗口置为空闲,统计顾客信息;
2.出队事件队列;
3.若顾客队列不为空且有空闲的服务窗口,生成“顾客离开事件”。
下面是代码:
void Manager::customer_departure() {
int current_time = _current_event->occur_time;
int service_index = _current_event->service_index;//顾客离开的服务窗口
_customer_stay_time += current_time -
_services[service_index].get_customer_arrive_time();//统计顾客在银行的滞留时间
++_total_served_customer_num;//接受服务的顾客数目加1
_services[service_index].set_idle();
_event_queue.dequeue();
if(_customer_queue.size() > 0) {
service_index = get_idle_service_index();//有顾客离开,必然可以获得1个空闲服务窗口,这里获取最小序号的服务窗口
generate_departure_event(service_index, current_time);
}
}
清理工作:
1.寻找仍在接受服务的顾客并统计他们的信息;
2.释放动态申请的内存。
下面是代码:
void Manager::end() {
for (int i = 0; i < _service_num; i++) {
if (!_services[i].is_idle()) {//统计正在接受服务的顾客的信息
int service_start_time = _services[i].get_service_start_time();
int arrive_time = _services[i].get_customer_arrive_time();
int duration = _services[i].get_customer_duration();
_customer_stay_time += service_start_time + duration - arrive_time;
++_total_served_customer_num;
}
}
//释放动态申请的内存
_customer_queue.clear();
_event_queue.clear();
delete[] _services;
}
关于队列的说明
程序中使用的是自定义的队列,根据需求,可以使用STL中的优先队列和队列,前者用于事件队列,后者用于顾客队列。
优先队列的头部总是优先级最高的节点,对于事件来说,就是发生的时间越早,事件优先级越高,所以这是一个最小堆——时间发生的时间最小(最早)的位于堆顶。这涉及到对Event类型的比较,使用STL的greater<Event>(需要重载operator>)或是自定义的函数对象来比较2个Event对象:
(1)重载operator>运算符
//声明使用greater<Event>作为比较函数的优先队列
std::priority_queue<Event, std::vector<Event>, std::greater<Event>> _event_queue; //event_queue.h
#ifndef BANKQUEUE_EVENT_QUEUE_H
#define BANKQUEUE_EVENT_QUEUE_H
#include "random.h"
enum class EventType : int {
ARRIVIED,
DEPARTURE
};
class Event {
public:
Event():occur_time(Random::uniform(RANDOM_PARAMETER)),
event_type(EventType::ARRIVIED),
service_index(-1),
next(nullptr){}
Event(int occur_time):occur_time(occur_time),
event_type(EventType::ARRIVIED),
service_index(-1),
next(nullptr){}
Event(int occur_time, EventType event_type, int service_index):
occur_time(occur_time),
event_type(event_type),
service_index(service_index),
next(nullptr) {}
friend bool operator< (const Event& event1, const Event& event2);//模仿STL的实现,都是通过'<'来完成余下的比较操作符
friend bool operator> (const Event& event1, const Event& event2);//供`greater<Event>`使用
public:
int occur_time;
int service_index;
EventType event_type;
Event *next;
};
inline bool operator< (const Event& event1, const Event& event2) {
return event1.occur_time < event2.occur_time;
}
inline bool operator> (const Event& event1, const Event& event2) {
return event2 < event1;//通过'<'实现'>'的功能
}
#endif //BANKQUEUE_EVENT_QUEUE_H










