好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

轮渡模拟

轮渡模拟

一、简单介绍

    这是在博客园潜水几个月第一次开始想要写点东西,一是记录自己的学习过程,二是和大家分享同时接受大家的指正,再者可以多交一些朋友,我微博地址在公告栏里,互粉哦。。。。这是最近上数据结构时的练习题,首先是队列的实现,再用队列去模拟解决一个实际问题——轮渡模拟。

二、问题分析    

2.1 问题描述:

轮渡模拟:有一个渡口,每条渡船能一次性装载10辆汽车过河,车辆分为客车和货车两类。 上渡轮有如下规定:同类汽车先到先上船,客车先于货车上船,轮渡每10分钟一班。 模拟一小时内汽车上渡轮的过程。 汽车:包含一个汽车类型属性,一个到达时间属性,到达时间随机产生。 轮渡:包含一个装车情况的属性,一个出发时间的属性。 输出:1小时内六班轮渡的装车情况。

2.2 实现说明:

轮渡不管是否装满10秒钟一班,一共进行6班共一分钟; 期间的汽车到来时间及类型是随机的; 初始当前已有一班渡轮停靠在渡口;

    当拿到这个问题时,分析问题后觉得要比较好的使各个事件不相互影响地模拟轮渡情况,需要用到多线程,但因为以前都是在Linux环境下编程,没有在Windows上实现过多线程编程,所以也不知道在具体实现中是否会存在什么问题。实现时在主函数中创建了三个线程:其中两个 线程 分别是客车和货车随机产生(到达),并携带时间信息进入到相应的队列;还有一个是用于做计数器用。

三、实现代码

3.1测试

#include <iostream> 
#include  <ctime> 
#include  <cstdlib> 
#include  <windows.h> 
#include  <process.h> 
#include   "  sqQueue.h  "                               //  包含自定义队列类 
 using   namespace   std;

  #define  MAX_NUM 10                                //  渡轮最大装载数量  
typedef   enum {PassengerCar, FreightCar}CarType;    //  汽车类型 
typedef  struct    
{
    CarType type;                                  //  汽车类型 
    time_t arriveTime;                            //  汽车到达时间 
 }Car;

typedef   struct    
{
      int  size;                                     //  渡轮当前装载汽车数量 
    time_t startTime;                             //  渡轮出发时间 
 }Ferry;

SqQueue <Car> pCarQueue( 61 );                       //  定义队列,用于存放客车的队列,模拟一分钟最多60辆汽车 
SqQueue<Car> fCarQueue( 61 );                       //  定义队列,用于存放货车的队列 
 int  startTimeFlag =  0 ;                            //  定义渡轮出发标志 
 int  countLength =  6 ;                              //  计数长度 
unsigned _stdcall threadCountFun( void *  pArguments)
{
      while  (countLength >  0  )
    {
        Sleep(  10000 );                             //  计数10秒 
        startTimeFlag =  1  ;
        countLength -- ;
    }
      return   0  ;
}
bool ferryFun() // 函数:处理渡轮到达,装载,出发等 { int count = 1 ; // 渡轮计数 while (count< 7 ) { Ferry ferry; ferry.size = 0 ; // 初始轮渡装载汽车数量 while ( 1 ) { if (ferry.size < 10 ) // 轮渡未满 { if (!pCarQueue.isEmpty_SqQueue() && ! fCarQueue.isEmpty_SqQueue() && pCarQueue.top_SqQueue().arriveTime == fCarQueue.top_SqQueue().arriveTime) { // 当两队列对头汽车到达时间相同时,客车先上船 cout<< " 一辆客车上船...其到达渡口时间: " ; cout <<ctime(& pCarQueue.top_SqQueue().arriveTime); pCarQueue.pop_SqQueue(); ferry.size ++ ; }
          else if (!pCarQueue.isEmpty_SqQueue() && ! fCarQueue.isEmpty_SqQueue() && pCarQueue.top_SqQueue().arriveTime < fCarQueue.top_SqQueue().arriveTime) { // 客车先到 cout<< " 一辆客车上船...其到达渡口时间: " ; cout <<ctime(& pCarQueue.top_SqQueue().arriveTime); pCarQueue.pop_SqQueue(); ferry.size ++ ; }
          else if (!fCarQueue.isEmpty_SqQueue()) // 货车先到 { cout << " 一辆货车上船...其到达渡口时间: " ; cout <<ctime(& fCarQueue.top_SqQueue().arriveTime); fCarQueue.pop_SqQueue(); ferry.size ++ ; } }
if ( 1 == startTimeFlag) { time( & ferry.startTime); cout << " 时间过去 " << 10 *count<< " 分钟 " ; cout << " 第 " <<count<< " 条渡轮开走, " << " 装有汽车 " ; cout <<ferry.size<< " 辆 " << " ,出发时间: " <<ctime(& ferry.startTime); count ++ ; startTimeFlag = 0 ; break ; }
} }
return true ; } unsigned _stdcall threadPCarFun( void * pArguments) // 客车处理函数 { srand(time( 0 )); while (! pCarQueue.isFull_SqQueue()) { Car car; if ( 1 == rand()% 14 ) // 1(客车) { car.type = PassengerCar; time( &car.arriveTime); // 记录到达时间 pCarQueue.push_SqQueue(car); // cout<<"P: "<<car.arriveTime<<endl; } Sleep( 200 ); // 200和10意义:每2毫秒中有十分之一概率产生(到达)一辆汽车(客车和货车) } return 0 ; } unsigned _stdcall threadFCarFun( void * pArguments) // 货车处理函数 { srand(time( 0 )); while (! fCarQueue.isFull_SqQueue()) { Car car; if ( 2 == rand()% 14 ) // 2(货车) { car.type = FreightCar; time( &car.arriveTime); // 记录到达时间 fCarQueue.push_SqQueue(car); // cout<<"H: "<<car.arriveTime<<endl; } Sleep( 200 ); // 200和14意义:每1毫秒中有十分之一概率产生(到达)一辆汽车 } // 测试这个频率能看到装满和没装满的情况 return 0 ; } int main( int argc, char ** argv) { HANDLE hThread_P, hThread_F, hThread_Count; unsigned int threadID_P, threadID_F, threadID_Count; hThread_P = (HANDLE) _beginthreadex(NULL, 0 , &threadPCarFun, NULL, 0 , & threadID_P); hThread_F = (HANDLE) _beginthreadex(NULL, 0 , &threadFCarFun, NULL, 0 , & threadID_F); hThread_Count = (HANDLE) _beginthreadex(NULL, 0 , &threadCountFun, NULL, 0 , & threadID_Count); ferryFun(); cout << " \n汽车排队中....直至队满... " << endl; WaitForSingleObject(hThread_P, INFINITE ); WaitForSingleObject(hThread_F, INFINITE ); WaitForSingleObject(hThread_Count, INFINITE );
CloseHandle(hThread_P); CloseHandle(hThread_F); CloseHandle(hThread_Count); return 0 ; }

运行结果:

3.2以下是自己用模板类实现的循环队列:

自定义队列类(sqQueue.h)

 #ifndef SQQUEUE_H
  #define  SQQUEUE_H

 #define   Q_MAX_LENGTH 100 

template  <typename T>
 class   SqQueue
{
  public  :
    SqQueue(  int  length_SqQueue =  Q_MAX_LENGTH);
      virtual  ~ SqQueue();
      bool  push_SqQueue( const  T&  e);
      bool   pop_SqQueue();
      bool   isEmpty_SqQueue();
      bool   isFull_SqQueue();
    T &  top_SqQueue();
      const  T& top_SqQueue() const  ;
      int   size_SqQueue();
      void   display_SqQueue();
  private  :
    T *  data;
      int   front;
      int   rear;
      int   length;
};
  /*  构造函数,初始化队列  */  
template  <typename T> 
SqQueue <T>::SqQueue( int   length_SqQueue)
{
    data  =  new   T[length_SqQueue];
    front  = rear =  0  ;
    length  =  length_SqQueue;
}
  /*  析构函数  */  
template  <typename T> 
SqQueue <T>::~ SqQueue()
{
    delete []data;
}
  /*  判空操作   */  
template  <typename T>
 bool  SqQueue<T> ::isEmpty_SqQueue()
{
      if  (front ==  rear)
          return   true  ;
      else 
         return   false  ;
}
  /*  判满操作  */  
template  <typename T>
 bool  SqQueue<T> ::isFull_SqQueue()
{
      if  ((rear+ 1 )%length ==  front)
          return   true  ;
      else 
         return   false  ;
}
  /*  入队操作  */  
template  <typename T>
 bool  SqQueue<T>::push_SqQueue( const  T&  e)
{
      if  (! isFull_SqQueue())
    {
        data[rear]  =  e;
        rear  = (rear+ 1 )% length;
          return   true  ;
    }
      return   false  ;
}
  /*  出队操作  */  
template  <typename T>
 bool  SqQueue<T> ::pop_SqQueue()
{
      if  (! isEmpty_SqQueue())
    {
        front  = (front+ 1 )% length;
    }
      return   false  ;
}
  /*  得到对头元素  */  
template  <typename T> 
T & SqQueue<T> ::top_SqQueue()
{
      if  (! isEmpty_SqQueue())
    {
          return   data[front];
    }
  //      cout<<"队列空"<<endl; 
 }
  /*  得到对头元素, const版本  */  
template  <typename T>
 const  T& SqQueue<T>::top_SqQueue() const  
{
      if  (! isEmpty_SqQueue())
    {
          return   data[front];
    }
  //      cout<<"队列空"<<endl; 
 }
  /*  测队长  */  
template  <typename T>
 int  SqQueue<T> ::size_SqQueue()
{
      return  (rear-front+length)% length;
}
  /*  遍历打印操作  */  
template  <typename T>
 void  SqQueue<T> ::display_SqQueue()
{
      int  i =  front;
      while  (i !=  rear)
    {
        std::cout <<data[i]<< "   "  ;
        i  = (i+ 1 )% length;
    }
    std::cout << endl;
}

  #endif 

 

分类:  数据结构

标签:  数据结构

作者: Leo_wl

    

出处: http://www.cnblogs.com/Leo_wl/

    

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

版权信息

查看更多关于轮渡模拟的详细内容...

  阅读:27次