银行业务模拟 离散事件模拟 数据结构 代码

2011.10.24

大二时候写的模拟银行的排队办理手续的程序。题目是严蔚敏的数据结构一书上忘了是哪一章的大练习了。

能够在VC++6.0下直接运行的。当然,这个题没有什么标准答案,我于是按照书中的要求和一些自己的理解写了。

对于排队办理业务中有个细节是,如果排上队了,但是银行下班了,银行是轰走人呢还是继续办理这些人的业务呢? 我这里选择的是继续办理,毕竟人家都排了好久了,很不容易的啊,呵呵,这里还有免费的空调^^

有什么问题可以留言^^

以下是源代码

/***
* Experiment of DataStructure file
*     Copyright (c) 2010-2011, htu zhuzhichao. All rights reserved.
*
*Purpose:
      实现了模拟银行的程序设计,并且包含每一个客户离开时间及统计,以及
      窗口排队的可视化模拟.运行测试通过.
*
      [Public]
      2010.10 朱智超 于河师大西区东一楼110宿舍
****/

# define OK 1

# define TRUE 1

# define FALSE 0

# define ERROR 0

# define INFEASIBLE -1

# define OVERFLOW -2

typedef int Status;

//-----------------银行排队模拟

//事件和事件表

typedef struct QCuEvent

{

    int OccurTime;
    
    int NType;
    
    struct QCuEvent *next;

}QCuEvent, *EventList;

//窗口前队列元素

typedef struct QCuElem

{

    int ArrivalTime;
    
    int Duration;
    
    struct QCuElem *next;

}QCuElem,*QEptr;

//窗口指针

typedef struct {

    QEptr front;
    
    QEptr rear;

}QCustomerp,*QCupp;

//主要操作函数

Status OpenForDay(EventList &ev, QCuEvent en, QCupp &q);//开门

Status CustomerArrived(EventList &ev, QCupp &q, QCuEvent en);//顾客到达

Status CustomerDeparture(EventList &ev, QCupp &q, QCuEvent en);//顾客离开

void CloseForDay();

//基本操作函数

Status OrderInser(EventList &ev, QCuEvent en);//按时间顺序插入事件到事件表

int QLength(QCustomerp qn);//求窗口队列长度

int MinCuQueue(QCupp q);//求队最短的窗口

Status DelFirstEvent(EventList &ev);//删除事件表中的第一个事件

Status InitCuQueue(QCustomerp &qn);//初始化窗口队列

Status EnCuQueue(QCustomerp &qn,QEptr Q);//进入队列

Status DeCuQueue(QCustomerp &qn,QCuElem &Q);//删除队列中的元素

Status GetQHead(QCustomerp qn,QCuElem &Q);//获得队列中的第一个元素

Status DestoryQueue(QCustomerp qn);//销毁队列

void Ptint_QStatus(QCustomerp QCu[]);//打印队列长度

void Bank_SimulationFunc();

void test(char str[]);

# include "stdio.h"

# include "stdlib.h"

# include "time.h"

int i=0,e=0,counter=0;

int TotalTime=0,CustomerNum=0;  //累计客户逗留时间,客户数

int CloseTime;  //关门时间

int windowsnum = 0;

//主函数

void main() {

    EventList ev;   // 事件表
    
    QCuEvent en;
    
    QCupp QCu = NULL;
    
    OpenForDay(ev, en, QCu);
    
    while (ev->next)
    
    {
    
        en.NType = ev->next->NType;
    
        en.OccurTime = ev->next->OccurTime;
    
        DelFirstEvent(ev);
    
        if (en.NType == 0)
    
            CustomerArrived(ev, QCu, en);
    
        else
    
            CustomerDeparture(ev, QCu, en);
    
        Ptint_QStatus(QCu);
    
    }
    
    CloseForDay();

}

//主要功能子函数

Status OpenForDay(EventList &ev, QCuEvent en, QCupp &q)

{

    int temp = 0;
    
    printf("请输入随机数种子(或输入0使用随机种子):");
    
    scanf("%d",&temp);
    
    if (temp==0) srand((unsigned)time(NULL));
    
    else srand(temp);
    
    printf("请输入营业时间(单位:分钟):");
    
    scanf("%d",&temp);
    
    CloseTime = temp;
    
    TotalTime = 0;
    
    CustomerNum = 0;
    
    en.OccurTime = 0;
    
    en.NType = 0;
    
    en.next = NULL;
    
    ev = (EventList) malloc(sizeof(QCuEvent));
    
    ev->next = NULL;
    
    OrderInser(ev, en);
    
    printf("请输入办理业务的窗口数(至少1个):");
    
    scanf("%d",&windowsnum);
    
    q = (QCustomerp *) malloc((windowsnum+1)*sizeof(QCustomerp));
    
    for (int i=1;i<=windowsnum;i++)
    
    {
    
        InitCuQueue(q[i]);
    
    }
    
    return OK;

}

Status CustomerArrived(EventList &ev, QCupp &q, QCuEvent en)

{

    test("顾客到达处理<<<<<<<<");
    
    CustomerNum ++;
    
    // 产生随机数
    
    //srand(54);
    
    int durtime = rand()%30+1;
    
    int intertime = rand()%5+1;
    
    // 插入到达事件表
    
    QCuEvent enTemp;
    
    int t = en.OccurTime + intertime;
    
    enTemp.OccurTime = t;
    
    enTemp.NType = 0;
    
    enTemp.next = NULL;
    
    if (t < CloseTime)   OrderInser(ev, enTemp);     printf("时间%d\n",t);   // 插入最短队  QEptr Q;    Q = (QEptr) malloc(sizeof(QCuElem));    Q->ArrivalTime = en.OccurTime;
    
    Q->Duration = durtime;
    
    Q->next = NULL;
    
    int i = MinCuQueue(q);
    
    EnCuQueue(q[i],Q);
    
    // 插入离开事件
    
    enTemp.OccurTime = en.OccurTime + durtime;
    
    enTemp.NType = i;
    
    enTemp.next = NULL;
    
    if(QLength(q[i]) == 1)  OrderInser(ev, enTemp);
    
    return OK;

}

Status CustomerDeparture(EventList &ev, QCupp &q, QCuEvent en)

{

    test(">>>>>>>>顾客离开处理");
    
    int i = en.NType;
    
    printf("离开时间%d\n",en.OccurTime);
    
    if(en.OccurTime>CloseTime)
    
    {
    
        DestoryQueue(q[i]);
    
    }
    
    else{
    
        QCuElem customer;
    
        DeCuQueue(q[i],customer);
    
        // 客户逗留时间
    
        TotalTime += en.OccurTime - customer.ArrivalTime;
    
        printf("总时间为%d\n",TotalTime);
    
        if (q[i].front->next)
    
        {
    
            GetQHead(q[i],customer);
    
            QCuEvent enTemp;
    
            enTemp.OccurTime = en.OccurTime + customer.Duration;
    
            enTemp.NType = i;
    
            OrderInser(ev, enTemp);
    
        }
    
    }
    
    return OK;

}

void CloseForDay()

{

    printf("***************************************\n");
    
    printf("*\n");
    
    printf("*  所有顾客业务办理总时间:%d分钟\n", TotalTime);
    
    printf("*  业务办理顾客数:%d\n", CustomerNum);
    
    printf("*  平均每人办理时间:%f\n",(float)TotalTime/(float)CustomerNum);
    
    printf("*\n");
    
    printf("***************************************\n");

}

//功能实现子函数

Status OrderInser(EventList &ev, QCuEvent en)

{

    EventList entemp,qtemp;
    
    entemp = (EventList) malloc(sizeof(QCuEvent));
    
    entemp->OccurTime = en.OccurTime;
    
    entemp->NType = en.NType;
    
    entemp->next = NULL;
    
    if (!ev->next)
    
    {
    
        ev->next = entemp;
    
        return OK;
    
    }
    
    qtemp = ev;
    
    while(qtemp->next&&qtemp->next->OccurTime < en.OccurTime)   {       qtemp = qtemp->next;
    
    }
    
    entemp->next = qtemp->next;
    
    qtemp->next = entemp;
    
    return OK;

}

int QLength(QCustomerp qn)

{

    QEptr qtemp;
    
    int i=0;
    
    qtemp = qn.front->next;
    
    while(qtemp)
    
    {
    
        qtemp = qtemp->next;
    
        i++;
    
    }
    
    return i;

}

int MinCuQueue(QCupp q)

{

    int i,min;
    
    for (i=1,min=1;i<=windowsnum;i++)
    
    {
    
        min = QLength(q[min])<=QLength(q[i]) ? min:i;    }   return min; } Status DelFirstEvent(EventList &ev) {     EventList p;    p = ev->next;
    
    ev->next = p->next;
    
    free(p);
    
    return OK;

}

Status InitCuQueue(QCustomerp &qn)

{

    qn.front = (QEptr) malloc(sizeof(QCuElem));
    
    qn.front->next = NULL;
    
    qn.rear = qn.front;
    
    return OK;

}

Status EnCuQueue(QCustomerp &qn,QEptr Q)

{

    qn.rear->next = Q;
    
    qn.rear = Q;
    
    return OK;

}

Status DeCuQueue(QCustomerp &qn,QCuElem &Q)

{

    QEptr qtemp;
    
    qtemp = qn.front->next;
    
    Q.ArrivalTime = qtemp->ArrivalTime;
    
    Q.Duration = qtemp->Duration;
    
    qn.front->next = qtemp->next;
    
    if(qn.rear == qtemp) qn.rear = qn.front;
    
    free(qtemp);
    
    return OK;

}

Status GetQHead(QCustomerp qn,QCuElem &Q)

{

    Q.ArrivalTime = qn.front->next->ArrivalTime;
    
    Q.Duration = qn.front->next->Duration;
    
    return OK;

}

Status DestoryQueue(QCustomerp qn)

{

    QEptr p;
    
    while(qn.front->next)
    
    {
    
        p = qn.front->next;
    
        qn.front->next = p->next;
    
        free(p);
    
    }
    
    qn.front->next =NULL;
    
    qn.rear = qn.front;
    
    return OK;

}

void Ptint_QStatus(QCustomerp QCu[])

{

    int l;
    
    for(int i=1;i<=windowsnum;i++)
    
    {
    
        l = QLength(QCu[i]);
    
        printf("队列%d:长%d:",i,l);
    
        for (int n=1;n<=l;n++)
    
        {
    
            printf("@");
    
        }
    
        printf("\n");
    
    }

}

//用于输出信息,帮助查看运行内容和调试以及显示结果

void test(char str[])

{

    printf("--%s--\n",str);

}
Comments
Write a Comment