zoukankan      html  css  js  c++  java
  • 食堂排队问题的一个实现

    问题场景:食堂,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("
    please input num of window:");
        scanf("%d", &k);
    */
        aveTime = getAveTime(n , k);
    
        printf("num of people: %d
    ", n);
        printf("num of window: %d
    ", k);
        printf("total people: %d
    ", getTotalPeople(n));
        printf("total time: %d
    ", 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("	enqueue people: %d
    ", getGaussianNum(n, tick));
                printf("tick:%d
    ",tick);
                for(win_index = 0; win_index < win_num; win_index++){
                    printf("window%d num of people: %d
    ", 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
    ", 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
    ",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!!!
    ");
        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;
    }
  • 相关阅读:
    为Android系统内置Java应用程序测试Application Frameworks层的硬件服务
    为Android系统的Application Frameworks层增加硬件访问服务
    为Android硬件抽象层(HAL)模块编写JNI方法提供Java访问硬件服务接口
    为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序
    为Android系统内置C可执行程序测试Linux内核驱动程序
    Android内核驱动程序的编写和编译过程
    添加一个Application Framework Service
    getopt()函数
    Google推Android新开发语言Sky:流畅度 秒iOS
    开发人员要避免的七个心态问题
  • 原文地址:https://www.cnblogs.com/wzyuan/p/9768957.html
Copyright © 2011-2022 走看看