食堂排队问题的一个实现

问题场景:食堂,11点到1点,整分钟时学生进入食堂,最后的1点0秒不算在内,所以共120个时间点,进入食堂的学生数按高斯分布N(0,1/2PI),即y=e- x*x*PI,即x=0时 y=1,12点对应x=0,11点对应-0.5,1点对应0.49...,对高斯分布等比例放大N倍,即12点到达N人,现规定窗口数为K,所有窗口的服务时间满足[4,5,6]的随机分布,单位为秒,要求实现函数接口getAveTime(N,K)

我的实现,英文比较差,但又不想中文注释,偶尔会有乱码问题。

/*this is a piece of code about time ofline up
  author: wzy
  IDE: VC6
*/
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<math.h>

#define PI 3.1415926
#define FALSE 0
#define TRUE 1
struct Student{
    int entry_time;
    int serve_time;
    struct Student *next;
};

typedef Student *Queueptr;

struct LinkQueue{
    Queueptr front;
    Queueptr rear;
    int last_leave_time;
};


void InitQueue(LinkQueue &Q);
void DestroyQueue(LinkQueue &Q);
void Enqueue(LinkQueue &Q, int start, int serve);
bool Dequeue(LinkQueue &Q);
bool IsEmpty(LinkQueue &Q);
int getQueueLen(LinkQueue &Q);
int findBestWin(LinkQueue win[], int len);
int getServeTime();
int getGaussianNum(int n, int time);
int getTotalPeople(int n);

float getAveTime(int n, int k);
/* define totaltime as global variable*/
int total_time = 0;

int main(){
    srand((int)time(0));

    float aveTime = 0.0;

    int n = 1;
    int k = 3;
/*
    printf("please input num of people:");
    scanf("%d", &n);
    printf("\nplease input num of window:");
    scanf("%d", &k);
*/
    aveTime = getAveTime(n , k);

    printf("num of people: %d\n", n);
    printf("num of window: %d\n", k);
    printf("total people: %d\n", getTotalPeople(n));
    printf("total time: %d\n", total_time);
    printf("aveTime: %f", aveTime);

    return 0;
}

float getAveTime(int n, int k){

    int people_index = 0;
    int total_people = 0;
    int win_index = 0;
    int win_num = k;
    int tick = 0;
    struct LinkQueue win[10];

    total_people = getTotalPeople(n);

    /* do initialization for every window*/
    for(win_index = 0; win_index < win_num; win_index++){
        InitQueue(win[win_index]);
    }

    for(tick = 0; people_index < total_people ; tick++){

        /*Enqueue when tick comes to minutes, tick(s) must less than 7200, when num of people equals to 
          total people, loop ends. when enqueue, if the window is empty, we must reset the last_leave_time
          which means the time of the second student becomes the first, and when enqueue, we choose the 
          shortest window, besides, we should set the entry_time and serve_time of students
        */
        if(tick%60 == 0 && tick < 7200){
            
            for(int j = 0; j < getGaussianNum(n, tick) ; j++){
                int choose = findBestWin(win, win_num);
                if(getQueueLen(win[choose]) == 0)
                    win[choose].last_leave_time = tick;
                Enqueue(win[choose], tick, getServeTime());             
            }
            //printf("\tenqueue people: %d\n", getGaussianNum(n, tick));
            printf("tick:%d\n",tick);
            for(win_index = 0; win_index < win_num; win_index++){
                printf("window%d num of people: %d\n", win_index, getQueueLen(win[win_index]));
            }
        }

    
        /*Dequeue when serve_time is satisfied, that is(last_leave_time - entry_time = serve_time)
          then we should add (current time(tick) - entry_time) to total_time as the wait_time, and 
          add people plus 1, set last_leave_time equals to current time
        */
        for(win_index = 0; win_index < win_num ; win_index++){
            if(IsEmpty(win[win_index])){
                continue;
            }
            //printf("window%d last_leave_time:%d  firstman serve_time:%d\n", win_index, win[win_index].last_leave_time, win[win_index].front->next->serve_time);
            if((tick - win[win_index].last_leave_time) == win[win_index].front->next->serve_time){
                //printf("window%d dequeue\n",win_index);
                total_time += (tick-win[win_index].front->next->entry_time);
                if(Dequeue(win[win_index]))
                    people_index += 1;
                win[win_index].last_leave_time = tick;
            }
        }
    

    }
/* not shure if we should free memory by self, when i do, error arise
    for(win_index = 0; win_index < win_num ; win_index++){
        DestroyQueue(win[win_index]);
    }
*/
    return float(total_time)/float(total_people);
}


void InitQueue(LinkQueue &Q)
{
    Q.front = Q.rear = new Student;
    Q.front->next = NULL;
    Q.last_leave_time = 0;
}

void DestroyQueue(LinkQueue &Q)
{
    while(Q.front){
        Q.rear = Q.front->next;
        delete Q.front;
        Q.front = Q.rear;
    }
}

void Enqueue(LinkQueue &Q, int start, int serve)
{
    Student *s = new Student;
    s->entry_time = start;
    s->serve_time = serve;
    Q.rear->next = s;
    Q.rear = s;
}

bool Dequeue(LinkQueue &Q)
{
    if(Q.front == Q.rear) 
        return FALSE;
    Student *p = new Student;
    p = Q.front->next;
    Q.front->next = p->next;
    if(Q.rear == p) //only one node
        Q.rear = Q.front;
    delete p; //release memory
    return TRUE;
}

bool IsEmpty(LinkQueue &Q)
{
    if(Q.front == Q.rear) 
        return TRUE;
    else
        return FALSE;
}
int findBestWin(LinkQueue win[], int len)
{
    if(len <= 0)
        printf("error: window num less than zero!!!\n");
    int index = 0;
    int shortest_len = getQueueLen(win[0]);
    for(int i = 1; i < len; i++){
        if(shortest_len == 0)
            return index;
        if(getQueueLen(win[i]) < shortest_len){
            shortest_len = getQueueLen(win[i]);
            index = i;
        }
    }
    return index;
}

int getQueueLen(LinkQueue &Q)
{
    if(Q.front == Q.rear)
        return 0;
    int len = 0;
    Student *p = new Student;
    p = Q.front;
    while(p != Q.rear){
        p = p->next;
        len++;
    }
    return len;
}

int getServeTime()
{
    return rand()%3 + 4;
}

int getGaussianNum(int n, int time)
{
    float x = float((time-3600))/7200;
    float num = n*exp(- x*x*PI);
    return int(num+0.5);
}

int getTotalPeople(int n)
{
    int count = 0;
    for(int i = 0; i < 120; i++)
        count += getGaussianNum(n,i*60);
    return count;
}

 

转载于:https://www.cnblogs.com/wzyuan/p/9768957.html

#include #include #include #include #include #include #include //请加入这个头文件 using namespace std; #include #define N 10 #define D 10 #define H 10 #define ASK (ORDER*)malloc(sizeof(ORDER)) #define MaxCapacity 4 //定义订单结构体 typedef struct Order{ int Table_ID; int Dish_ID[N]; struct Order *next; }ORDER; //定义餐桌信息 typedef struct Table{ int Table_ID; int Capacity; int Table_State; }TABLE; //定义菜的结构体 typedef struct dish{ int Dish_ID; int Dish_Name[10]; float Dish_Price; }DISH; TABLE tb[H]; DISH dish[D]; int PASSWORD=123; void LOAD_Dish(void);//从文件中读取菜谱; ORDER*CreateOne(int);//创建一个订单节点; void Dish_Menu(void);//显示菜谱 void Table_Init(void);//餐桌信息初始化 int search(void);//查找匹配的餐桌 ORDER* Dish_Order(ORDER *,ORDER *);//将节点插入到主链 void Display(int);//显示菜的信息; void saveInList(float);//将客户消费额写入账单 void Save_Inform(ORDER *,int);//将已结账订单信息写入历史记录 ORDER *Payment(ORDER *);//结账 void ModifyPW(int);//密码修改 int Pass_Word(void);//密码验证 void Observe(void);//账目查询 void ListMenu(void);//账单管理菜单 void List_Management(void);//账单管理 void Main_Menu(void);//主菜单 void Get_Rank(void);//统计 void Menu_select(void);//选择功能 //主函数 void main(){ Table_Init(); Menu_select(); } //系统主菜单 void Main_Menu(){ printf("\n*********************************\n"); printf("餐厅服务系统\n"); printf("\n*********************************\n"); printf("1.点菜\n"); printf("2.客户结账\n"); printf("3.账目管理\n"); printf("4.餐厅统计\n"); printf("5.退出系统\n"); } //选择功能 void Menu_select(void){ ORDER* head; int choose; int result; head=NULL; system("cls"); do{ LOAD_Dish(); Main_Menu(); printf("请选择:\n"); fflush(stdin); scanf("%d",&choose;); switch(choose){ case 1: result=search(); if(result==1) printf("您可以在%d号餐桌就餐\n",result); else printf("您和您的朋友可以在%d号餐桌就餐\n",result); Dish_Menu(); head=Dish_Order(head,CreateOne(result)); break; case 2: head=Payment(head); break; case 3: List_Management(); break; case 4: Get_Rank(); break; case 5: exit(1); break; } }while(1); } //从文件中读取菜谱 void LOAD_Dish(void){ FILE *fp
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值