From e72f7827b4b99467b5c54433d8cdb3aaf311a5b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=86=AF=E5=9B=BD=E5=B9=B3?= <@bzu.edu.cn> Date: Thu, 15 Jun 2023 18:57:54 +0800 Subject: [PATCH] 3 --- 代码 | 362 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 362 insertions(+) create mode 100644 代码 diff --git a/代码 b/代码 new file mode 100644 index 0000000..82fdc44 --- /dev/null +++ b/代码 @@ -0,0 +1,362 @@ +#define _CRT_SECURE_NO_WARNINGS + +#include + +#include + +#include + +#define TRUE 1 + +#define FALSE 0 + +#define OK 1 + +#define ERROR 0 + +#define INFEASIBLE -1 + +#define OVERFLOW -2 + +typedef int Status; + + + +typedef struct + +{ + +int OccurTime;//事件发生时刻 + +int NType;//事件类型,0表示到达事件,1-4表示四个窗口的离开事件 + +}Event, ElemType; + +typedef struct LNode + +{ + +ElemType data; + +struct LNode* next; + +}LNode, * LinkList; + +typedef LinkList EventList; + + + +typedef struct + +{ + +int ArrivalTime;//到达时刻 + +int Duration;//办理事务所需事件 + +}QElemType; + +typedef struct QNode + +{ + +QElemType data; + +struct QNode* next; + +}QNode, * QueuePtr; + +typedef struct + +{ + +QueuePtr front;//队头指针 + +QueuePtr rear;//队尾指针 + +}LinkQueue; + + + +EventList ev;//事件表 + +Event en;//事件 + +LinkQueue q[5];//四个客户队列 + +QElemType customer;//客户记录 + +int TotalTime, CustomerNum, CloseTime; + + + +void Bank_Simulation(int CloseTime);//银行业务模拟,统计一天内客户在银行逗留的平均时间 + +int cmp(Event a, Event b);//比较事件发生先后 + +void OpenForDay();//银行开门 + +void OrderInsert(EventList L, Event en, int(*cmp)(Event a, Event b));//插入事件 + +void CustomerArrived();//客户进门 + +void CustomerDepature();//客户离开 + +int Minimum(LinkQueue Q[5]);//求长度最短队列 + + + +Status InitList(LinkList& L);//链表初始化 + +Status ListInsert_L(LinkList& L, int i, ElemType e);//在第i个位置之前插入元素e + +Status ListEmpty(LinkList L);//判断链表是否为空 + +Status DelFirst(LinkList L, LNode*& q);//删除链表中第一个结点并以q返回 + +LNode* GetHead(LinkList L);//返回链表头结点 + +ElemType GetCurElem(LNode* p);//已知p指向线性链表中的一个结点,返回p所指结点中元素的值 + +void PrintEventList();//打印事件链表 + +Status ListTraverse(LinkList& L);//遍历链表  + + + +Status InitQueue(LinkQueue& Q);//链队列的初始化 + +Status EnQueue(LinkQueue& Q, QElemType e);//入队 + +Status DeQueue(LinkQueue& Q, QElemType& e);//出队 + +int QueueLength(LinkQueue Q);//返回队列的长度 + +Status GetHead(LinkQueue Q, QElemType& e);//获取队头元素 注:由于参数个数不同,发生函数重载 + +Status QueueEmpty(LinkQueue Q);//判断队列是否为空 + +void PrintQueue();//打印队列 + +Status QueueTraverse(LinkQueue Q);//遍历队列Q  + +int main() + +{ + +srand((unsigned)time(NULL));//设定随机数种子 + +printf("请输入银行的营业时间(min):"); + +scanf("%d", &CloseTime); + +Bank_Simulation(CloseTime); + +return 0; + +} + +void Bank_Simulation(int CloseTime)//银行业务模拟,统计一天内客户在银行逗留的平均时间 + +{ + +OpenForDay();//开始营业 + +LNode* p; + +while (!ListEmpty(ev)) + +{ + +DelFirst(GetHead(ev), p); + +printf("********action********\n"); + +en = GetCurElem(p); + +if (en.NType == 0) + +{ + +CustomerArrived(); + +} + +else + +{ + +CustomerDepature(); + +} + +PrintQueue(); + +PrintEventList(); + +} + +printf("The Average Time is %f\n", (float)TotalTime / CustomerNum); + +} + + + +int cmp(Event a, Event b)//比较事件发生先后 + +{ + +if (a.OccurTime > b.OccurTime) return 1; + +if (a.OccurTime = b.OccurTime) return 0; + +if (a.OccurTime < b.OccurTime) return -1; + +} + + + +void OpenForDay()//银行开门 + +//初始化操作 + +{ + +TotalTime = 0;//初始化累计时间为0 + +CustomerNum = 0;//初始化客户数为0 + +InitList(ev);//初始化事件链表为空表 + +en.OccurTime = 0; + +en.NType = 0;//设定第一个客户到达事件 + +OrderInsert(ev, en, cmp); + +for (int i = 1; i <= 4; i++) + +{ + +InitQueue(q[i]);//将四个银行窗口队列初始化 + +} + +} + + + +void OrderInsert(EventList L, Event en, int(*cmp)(Event a, Event b))//插入事件 + +//事件插入函数,将不同事件按发生时间递增排序 + +{ + +LNode* p = L; + +int i = 1; + +while (p->next && cmp(en, p->next->data) > 0)//找到事件发生时间所在事件链表中的位置 + +{ + +p = p->next; + +i++; + +} + +ListInsert_L(ev, i, en);//插入该事件 + +} + +void CustomerArrived()//客户进门 + +//处理客户到达事件,en.NType=0 + +{ + +CustomerNum++; + +int durtime = rand() % 30 + 1;//客户处理事务时间 + +int intertime = rand() % 8;//下一个客户到达的时间间隔 + +int t = en.OccurTime + intertime;//下一个客户到达的时刻 + +if (t < CloseTime)//如果他在营业时间内进来 + +{ + +printf("一个新客户在银行营业%2dmin后进来,办理业务花费了%2dmin,下一个客户过了%2dmin后进来\n", en.OccurTime, durtime, intertime); + +OrderInsert(ev, { t, 0 }, cmp);//插入客户进门事件,NType=0为到达事件 + +} + +int i = Minimum(q);//客户找最短队开始排队 + +EnQueue(q[i], { en.OccurTime, durtime }); + +if (QueueLength(q[i]) == 1) + +{ + +OrderInsert(ev, { en.OccurTime + durtime,i }, cmp);//队列长度为1时,设定一个离开事件 + +} + +} + + + +void CustomerDepature()//客户离开 + +{ + +int i = en.NType; + +DeQueue(q[i], customer);//删除第i队列的排头客户 + +TotalTime += en.OccurTime - customer.ArrivalTime;//累计客户逗留时间 + +if (!QueueEmpty(q[i])) { + +GetHead(q[i], customer); + +OrderInsert(ev, { en.OccurTime + customer.Duration, i }, cmp);//插入事件 + +} + +} + + + +int Minimum(LinkQueue Q[5])//求长度最短队列 + +{ + +int minLength = QueueLength(Q[1]); + +int i = 1; + +for (int j = 2; j < 5; j++) + +{ + +if (minLength > QueueLength(Q[j])) + +{ + +minLength = QueueLength(Q[j]); + +i = j; + +} + +} + +return i; + +} +