ATM Queue模拟
#include <iostream>
#include <cstdlib>
#include <ctime>
#include "queue.h"
const int MIN_PER_HR = 60;
bool newcustomer(double x);
int main(){
using std::cin;
using std::cout;
using std::endl;
using std::ios_base;
std::srand(std::time(0)); //srand(time(0)),初始化时间种子
cout << "Case Study: Bank of Heather Automatic Teller\n";
cout << "Enter maximum size of queue: ";
int qs; //qs队列的最大长度
cin >> qs;
Queue line(qs);
cout << "Enter the number of simulation hours: ";
int hours; //模拟时间 h
cin >> hours;
long cyclelimit = MIN_PER_HR * hours; //模拟时间min
cout << "Enter the average number of customers per hour: ";
double perhour; //每小时来多少人
cin >> perhour;
double min_per_cust;
min_per_cust = MIN_PER_HR / perhour;
Item temp; //新顾客信息
long turnaways = 0;
long customers = 0;
long served = 0;
long sum_line = 0;
int wait_time = 0;
long line_wait = 0;
//开始模拟
for(int cycle = 0; cycle < cyclelimit; cycle++){
if(newcustomer(min_per_cust)){
if(line.isfull())
turnaways++;
else{
customers++;
temp.set(cycle);
line.enqueue(temp);
}
}
if(wait_time <= 0 && !line.isempty()){
line.dequeue(temp);
wait_time = temp.ptime();
line_wait += cycle - temp.when();
served++;
}
if(wait_time > 0)
wait_time--;
sum_line += line.queuecount();
}
if(customers > 0){
cout << "customers accepted: " << customers << endl;
cout << " customers served: " << served << endl;
cout << " turnaways: " << turnaways << endl;
cout << "average queue size: ";
cout.precision(2);
cout.setf(ios_base::fixed, ios_base::floatfield);
cout << (double) sum_line / cyclelimit << endl;
cout << " average wait time: " << (double) line_wait / served
<< " minutes\n";
}
else
cout << "No customers!\n";
cout << "Done!\n";
return 0;
}
bool newcustomer(double x)
{
return (std::rand() * x / RAND_MAX < 1);
}
#ifndef QUEUE_H_
#define QUEUE_H
class Customer{
private:
long arrive;
int processtime;
public:
Customer(){
arrive = processtime = 0;
}
void set(long when);
long when() const { return arrive;}
int ptime() const { return processtime;}
};
typedef Customer Item;
class Queue{
private:
//private representation to be developed later
struct Node { //链表更适合用于描述队列
//C++特性:在类中嵌套结构(或类声明),Node作用域为整个类
Item item;
struct Node * next;
};
enum {Q_SIZE = 10
};
Node * front;
Node * rear;
int items;
const int qsize; //qsize是常量,可以对它进行初始化,但不能给它赋值(初始化之后不变)
Queue(const Queue & q): qsize(0){}
Queue & operator=(const Queue & q) { return *this;} //赋值运算符重载
public:
Queue(int qs = Q_SIZE); //constructor
~Queue();
bool isempty() const;
bool isfull() const;
int queuecount() const;
bool enqueue(const Item &item);
bool dequeue(Item &item);
};
#endif
#include "queue.h"
#include <cstdlib>
Queue::Queue(int qs) : qsize(qs) //初始化类成员默认值,可用列表初始化,也可以函数体初始化。
//列表初始化效率更高,但是不能初始化const变量
{
front = rear = NULL;
items = 0;
}
Queue::~Queue()
{
Node * temp;
while(front != NULL){
temp = front;
front = front->next; //front是一个指向Node结构的指针,Node里又定义了一个指向Node的指针next
delete temp; //队列从前往后删除
}
}
bool Queue::isempty() const //判断队列是否为空,如果是空items为0(两个等号),没人,等价于true
{
return items == 0;
}
bool Queue::isfull() const //判断队列是否为full,如果是qsize,返回true
{
return items == qsize;
}
int Queue::queuecount() const
{
return items;
}
bool Queue::enqueue(const Item & item) //从后面添加元素
{
if(isfull())
return false; //如果队列满了,返回false
Node * add = new Node; //创建add指针,这个指针指向一个动态分配的Node空间
add->item = item; //向add指针指向的结构里的item添加customer
add->next = NULL; //把add指针指向的结构里的结构指针next置为NULL,标志着队列的结尾,
//如果向队列中添加元素(customer),就再新建一个“add”指针,链式赋值
items++; //更新全局变量items,这是当前队列的customer
if(front == NULL) //向指针front添加元素(customer),如果front是NULL,add就是front的地址
front = add;
else //如果front不为空,则把add的地址添加到rear指针
rear->next = add; //指针rear指向next的地址,rear是队列中最后一个元素,
//这里就是在队列的最后面添加元素,rear和rear->next都指向新加入元素的地址
rear = add; //把指针rear也指向add的地址
return true;
}
bool Queue::dequeue(Item & item)//这是从前向后删除队列中的元素
{
if(front == NULL) //如果队列为空,返回false
return false;
item = front->item; //队列不为空(返回true),让item指向front的首个元素
items--;
Node * temp = front; //把front地址赋给temp
front = front->next; //把front的next地址赋值给front
delete temp; //删除front,就是删除了队列的前端数据
if(items == 0) //如果队列为空,把rear置为NULL
rear = NULL;
return true;
}
void Customer::set(long when)
{
processtime = std::rand() % 3 + 1;
arrive = when;
}