轮渡模拟

一、简单介绍

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

二、问题分析   

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
复制代码
 
分类: 数据结构
标签: 数据结构
原文地址:https://www.cnblogs.com/Leo_wl/p/2714805.html