初始化事件队列:
_generate_arrived_time = 0;//依旧是以时间顺序生成顾客到达事件
while(_generate_arrived_time < INIT_ARRIVIED_EVENT_NUM) {//选择合适的值,使最初生成的顾客到达事件略多于服务窗口数量,保证服务窗口满载且有等待顾客即可
generate_arrived_event(_generate_arrived_time);
}
判断条件并生成到达事件:
if(_customer_queue.empty() && _event_queue.size() <= _service_num)
{
generate_arrived_event(_generate_arrived_time);
_current_event = &_event_queue.top();//update current event, deal it with order
}
由于顾客到达事件仍是以时间顺序从0到营业时间结束来生成的,之所以能够保证不会在处理了98分钟时的顾客离开事件(可能是5分钟时到达的顾客产生的)后再去处理新插入的10分钟时的顾客到达事件,就是初始化事件队列时选择合适的INIT_ARRIVIED_EVENT_NUM的意义所在:时刻保证事件队列的长度大于服务窗口的数量,新生成的顾客到达事件的时间若早于顾客离开事件的时间(以时间为顺序生成顾客到达事件就保证了新生成的顾客到达事件的时间不小于事件队列中已有的顾客到达事件,而顾客离开事件的时间是随机的,若提前于新生成的顾客到事件处理,可能会失序)也能被正确处理。
生成顾客离开事件
顾客队列头部顾客接受服务并出队,生成顾客离开事件并入队事件队列。顾客离开事件的发生时间 = 当前时间 + 顾客接受服务的时长。
void Manager::generate_departure_event(int service_index, int current_time) {
_services[service_index].serve_customer(*_customer_queue.front());
_services[service_index].set_busy();//服务窗口置为“忙”
_services[service_index].set_service_start_time(current_time);//服务开始时间
_customer_queue.dequeue();
int duration = _services[service_index].get_customer_duration();
Event* event = new Event(current_time + duration, EventType::DEPARTURE, service_index);//生成顾客离开事件
_event_queue.enqueue(event);
}
处理顾客到达事件
处理“顾客到达事件”的逻辑:
1.生成1个顾客,入队顾客队列;
2.出队事件队列;
3.若有空闲的服务窗口,则生成“顾客离开事件”。
下面是代码:
void Manager::customer_arrived() {
int idle_service_num = get_idle_service_index();//获取空闲的服务窗口,返回-1说明未找到
int current_time = _current_event->occur_time;
Customer* customer = new Customer(current_time);//顾客到达事件发生时间即为顾客到达时间, 顾客接受服务的时长随机
_customer_queue.enqueue(customer);
_event_queue.dequeue();
if (idle_service_num != -1)
generate_departure_event(idle_service_num, current_time);
}










