队列模拟(简单链表数据结构的处理)

来源:互联网 发布:ubuntu创建c文件 编辑:程序博客网 时间:2024/05/23 01:12

模拟ATM机为客户队列提供服务。

用户输入队列最大人数、持续模拟时间、平均人流量。

程序采用随机方式自然模拟,最后得出统计数据:客户数、遗失的客户数、客户平均等待时间等。

(这里默认假设每位用户操作ATM的时间为1到3分钟,可以修改set()函数来自设定时间。)

 


 

//头文件 queue.h

#ifndef QUEUE_H_
#define QUEUE_H_
class Customer
{
public:
 Customer(){arrive = processtime = 0;}
 void set (long when);
 long when ()const {return arrive;}
 int ptime()const {return processtime;}
private:
 long arrive;
 int processtime;
};

 

typedef Customer Item;

 

class Queue
{
public:
 Queue(int qs = Q_SIZE);
 ~Queue();
 bool isempty()const;
 bool isfull()const;
 int queuecount()const;
 bool enqueue(const Item &item);
 bool dequeue(Item &item);
private:
 Queue(const Queue & q):qsize (0){}                   
//禁止传递类引用的构造函数(默认复制构造函数)
 Queue & operator=(const Queue & q){return *this;}     //禁止默认赋值操作符
 struct Node{Item item;struct Node * next;};           //类嵌套结构,结构嵌套类
 enum{Q_SIZE = 10};
 Node * front;
 Node * rear;
 int items;
 const int qsize;
};
#endif

 


 

//类方法文件 queue.cpp

#include "queue.h"
#include <cstdlib>

Queue::Queue(int qs):qsize(qs)
{
 front = rear = NULL;
 items = 0;
}

Queue::~Queue()
{
 Node * temp;
 while (front != NULL)
 {
  temp = front;
  front = front->next;
  delete temp;
 }
}

 

bool Queue::isempty()const
{
 return items == 0;
}
bool Queue::isfull()const
{
 return items == qsize;
}

 

int Queue::queuecount()const
{
 return items;
}

 

bool Queue::enqueue(const Item & item) //将新数据加入链表尾
{
 if(isfull())
  return false;
 Node * add = new Node;
 if(add == NULL)
  return false;
 add->item = item;
 add->next = NULL;
 items++;
 if(front==NULL)
  front = add;
 else
  rear->next = add;
 rear = add;
 return true;
}

 

bool Queue::dequeue(Item & item)  //删除链表中首位单元
{
 if(front == NULL)
    return false;
 item = front->item;         //这里很巧妙,先删除队首客户,再在外部调用中等待该客户需要的服务时间。
 items--;
 Node * temp = front;
 front = front->next;
 delete temp;
 if(items == 0)
  rear = NULL;
 return true;
}

 

void Customer::set(long when)
{
 processtime = std::rand()%3+1;
//需要停留的分钟数(这里是1到3分钟)
 arrive = when;                            //客户到达的时间(开始模拟后的第几分钟)
}

 

 


 

//main.cpp

#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));  //为随机函数提供种子

 

 cout<<"案例研究:银行自动取款/n/n";
 cout<<"输入队列的最大人数: ";
 int qs;
 cin>>qs;
 Queue line(qs);

 

 cout<<"输入需要模拟的时间(小时): ";
 int hours;
 cin>>hours;

 long cyclelimit = MIN_PER_HR * hours;

 

 cout<<"输入平均每小时用户人数: ";
 double perhour;
 cin>>perhour;
 double min_per_cust;
 min_per_cust = MIN_PER_HR / perhour;
           //60分钟除以每小时人数,得到客户到达的间隔时间。
 cout<<endl;

 

 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++) //cyclelimit(总模拟分钟数)。
 {
  if (
newcustomer(min_per_cust))  //判断是否来人。
  {
      if (line.
isfull()) //判断队列是否满了。
         turnaways++;  //丢失的客户数。
      else
      {
         customers++;
        //加入队列的客户数。
         temp.set(cycle);    //设置并记录客户信息。
         line.enqueue(temp); //将客户加入队列。
      }
  }


  if (wait_time <= 0 && !line.isempty()) //line.isempty()判断队列是否为空,wait_time判断客户是否处理完毕。
  {
   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<<endl;
  cout<<"成功提供服务数: "<<served<<endl;
  cout<<
"因队列满而遗失的客户: "<<turnaways<<endl;
  cout<<
"平均每分钟队列中人数: ";
  cout.
precision(2);
  cout.
setf(ios_base::fixed,ios_base::floatfield);
  cout.
setf(ios_base::showpoint);
  cout<<(double)sum_line / cyclelimit<<endl;
    //每分钟队列人数的累加 除以 总分钟数 得到平均队列人数。
  cout<<"得到服务的客户平均等待时间: "
   <<(double)line_wait / served<<" 分钟/n";

  //得到服务的每位客户的总等待时间 除以 成功提供服务的客户总数 得到 平均每位得到服务的客户等待时间。
 }
 else
  cout<<
"没有客户!/n";


 cout<<endl;
 cout<<
"银行自动取款,模拟结束!/n";


 return 0;
}

 

bool newcustomer(double x)
{
 return (std::rand()* x/RAND_MAX < 1);
//随机数 * 客户到达的间隔时间 / 随机最大数(得到0到X之间)
 //平均每隔X次,这个值会有1次小于1.不过如果客户到达的平均时间间隔少于1分钟,则该方法无效。解决办法,提高时间分辨率,比如每次循环代表10秒。
}

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 天猫超市多发货怎么办 天猫中不小心取消退款了怎么办 天猫超市写错了怎么办 二维码收付款不到红包怎么办 天猫优惠劵过期了怎么办 天猫购物津贴用不完怎么办 天猫上买的大件东西实物不符怎么办 天猫上面料成分与实物不符怎么办 闲鱼发货与实物不符怎么办 天猫超市买贵了怎么办 天猫超市里购买的东西退货怎么办 淘宝店上传的图片不清楚怎么办 微信图片打印出来不清楚怎么办 微信图片打印不清楚怎么办 淘宝上传商品视频不清楚怎么办 手机安装器没了怎么办 我不做直播换工作怎么办 天猫发票被投诉怎么办 天猫机顶盒闪退怎么办 苹果8红色掉漆怎么办 毛坯房验房房及厅试水时漏水怎么办 淘宝退货赠品被拆了怎么办 如果淘宝买家说赠品不好怎么办 淘宝顾客反应没赠品怎么办 淘宝上买东西赠品不给怎么办 天猫店关了质量有问题怎么办 蘑菇街开店被骗了怎么办 百视通网络机顶盒恢复出厂后怎么办 王牌电视出现无信号怎么办 联通电视串台了怎么办 电视上出现系统更新怎么办 电视开机一直在更新怎么办 云视听极光闪退怎么办 不小心打错电话怎么办 相亲发信息不回怎么办 如果一个人微信不回电话不接怎么办 跟老公吵架打电话不接怎么办 起诉离婚对方不接电话怎么办 苹果手机接电话声音小怎么办 老公不回你微信怎么办 工地欠货款不给怎么办