C语言模拟加油站的工作情况

加油站有两台油泵;
每台油泵为一辆汽车加油的时间为d分钟
加油站的到车率为1辆/g分钟;
模拟时间长度为time分钟

该回答引用ChatGPT
以下是一个简单的C语言代码,用于模拟加油站的情况:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define MAX_QUEUE_SIZE 100

typedef struct {
    int arrival_time;
    int service_time;
} Customer;

typedef struct {
    int front;
    int rear;
    Customer data[MAX_QUEUE_SIZE];
} Queue;

void init_queue(Queue *q) {
    q->front = q->rear = 0;
}

int is_empty(Queue *q) {
    return q->front == q->rear;
}

int is_full(Queue *q) {
    return (q->rear + 1) % MAX_QUEUE_SIZE == q->front;
}

void enqueue(Queue *q, Customer c) {
    if (is_full(q)) {
        printf("Queue is full\n");
        exit(1);
    }
    q->data[q->rear] = c;
    q->rear = (q->rear + 1) % MAX_QUEUE_SIZE;
}

Customer dequeue(Queue *q) {
    if (is_empty(q)) {
        printf("Queue is empty\n");
        exit(1);
    }
    Customer c = q->data[q->front];
    q->front = (q->front + 1) % MAX_QUEUE_SIZE;
    return c;
}

int main() {
    int time, d;
    double g;
    printf("Enter simulation time (in minutes): ");
    scanf("%d", &time);
    printf("Enter service time (in minutes): ");
    scanf("%d", &d);
    printf("Enter arrival rate (in cars per minute): ");
    scanf("%lf", &g);

    srand(time(NULL));
    Queue q1, q2;
    init_queue(&q1);
    init_queue(&q2);
    int total_customers = 0, served_customers = 0;
    int busy1 = 0, busy2 = 0;
    int wait_time1 = 0, wait_time2 = 0;

    for (int t = 0; t < time; t++) {
        if ((double) rand() / RAND_MAX < g) {
            Customer c;
            c.arrival_time = t;
            c.service_time = d;
            enqueue(&q1, c);
            total_customers++;
        }

        if (busy1 == 0 && !is_empty(&q1)) {
            Customer c = dequeue(&q1);
            busy1 = c.service_time;
            wait_time1 += t - c.arrival_time;
        }

        if (busy2 == 0 && !is_empty(&q2)) {
            Customer c = dequeue(&q2);
            busy2 = c.service_time;
            wait_time2 += t - c.arrival_time;
        }

        if (busy1 > 0) {
            busy1--;
            if (busy1 == 0) {
                served_customers++;
                if (!is_empty(&q1)) {
                    Customer c = dequeue(&q1);
                    busy1 = c.service_time;
                    wait_time1 += t - c.arrival_time;
                }
            }
        }

        if (busy2 > 0) {
            busy2--;
            if (busy2 == 0) {
                served_customers++;
                if (!is_empty(&q2)) {
                    Customer c = dequeue(&q2);
                    busy2 = c.service_time;
                    wait_time2 += t - c.arrival_time;
                }
            }
        }
    }

    printf("Total customers served: %d\n", served_customers);
    printf("Average wait time at pump 1: %.2f minutes\n", (double) wait_time1 / served_customers);
    printf("Average wait time at pump 2: %.2f minutes\n", (double) wait_time2 / served_customers);
    printf("Average wait time overall: %.2f minutes\n", (double) (wait_time1 + wait_time2) / (2 * served_customers));
    printf("Percentage of customers who had to wait: %.2f%%\n", (double) (total_customers - served_customers) / total_customers * 100);

    return 0;
}

该代码使用了队列来模拟加油站的两台油泵,每次循环中会根据到车率随机生成一个顾客,并将其加入到队列中。如果油泵空闲,则从队列中取出一个顾客进行服务,服务完成后再从队列中取出下一个顾客进行服务。在服务过程中,会记录每个顾客等待的时间,并在循环结束后计算出平均等待时间、等待时间的百分比等信息。

不知道你这个问题是否已经解决, 如果还没有解决的话:
  • 以下回答来自chatgpt:

    首先,我们可以将车辆统计的过程看作一个队列,每到达一个车辆就将其加入队列,每加油一次就将其从队列中移除。同时,我们需要记录每个油泵当前是否正在加油,以及当前加油的车辆编号。具体的实现方法如下:

    #include<stdio.h>
    #include<stdlib.h>
    
    #define MAX_QUEUE_SIZE 1000 //最大队列长度
    
    //定义车辆结构体
    typedef struct {
        int id; //编号
        int arrive; //到达时间
    } Car;
    
    Car queue[MAX_QUEUE_SIZE]; //车辆队列
    int front = 0; //队首指针
    int rear = 0; //队尾指针
    
    int pump1_busy = 0; //油泵1是否正在加油
    int pump1_car = -1; //油泵1当前加油的车辆编号
    int pump1_time_remaining = 0; //油泵1加油结束剩余时间
    
    int pump2_busy = 0; //油泵2是否正在加油
    int pump2_car = -1; //油泵2当前加油的车辆编号
    int pump2_time_remaining = 0; //油泵2加油结束剩余时间
    
    int count = 0; //车辆总数
    int sum_wait_time = 0; //总等待时间
    
    //模拟函数,输入加油时间d、模拟时间time
    void simulate(int d, int time) {
        int current_time; //当前时间
        Car current_car; //当前车辆
        int wait_time; //等待时间
    
        for(current_time = 0; current_time < time || front != rear; current_time++) {
            //新车辆到达
            if(current_time < time) {
                if(rand()%2 == 1) { //以等概率随机
                    current_car.id = ++count;
                    current_car.arrive = current_time;
                    queue[rear++] = current_car; //加入队列
                }
            }
    
            //油泵1没有占用,且队列不为空
            if(!pump1_busy && front != rear) {
                current_car = queue[front++]; //取出队首车辆
                wait_time = current_time - current_car.arrive;
                sum_wait_time += wait_time; //累计等待时间
                pump1_busy = 1; //占用油泵1
                pump1_car = current_car.id; //记录当前加油的车辆编号
                pump1_time_remaining = d; //设置加油结束剩余时间
            }
    
            //油泵2没有占用,且队列不为空
            if(!pump2_busy && front != rear) {
                current_car = queue[front++]; //取出队首车辆
                wait_time = current_time - current_car.arrive;
                sum_wait_time += wait_time; //累计等待时间
                pump2_busy = 1; //占用油泵2
                pump2_car = current_car.id; //记录当前加油的车辆编号
                pump2_time_remaining = d; //设置加油结束剩余时间
            }
    
            //油泵1正在占用,结束加油
            if(pump1_busy) {
                pump1_time_remaining--; //剩余时间减1
                if(pump1_time_remaining == 0) {
                    pump1_busy = 0; //释放油泵1
                    pump1_car = -1; //清除当前加油的车辆编号
                }
            }
    
            //油泵2正在占用,结束加油
            if(pump2_busy) {
                pump2_time_remaining--; //剩余时间减1
                if(pump2_time_remaining == 0) {
                    pump2_busy = 0; //释放油泵2
                    pump2_car = -1; //清除当前加油的车辆编号
                }
            }
        }
    }
    
    //主函数
    int main() {
        simulate(5, 100); //以5分钟为基准时间,模拟100分钟的加油站运行情况
        printf("Average waiting time: %.2f\n", (double)sum_wait_time/count); //输出平均等待时间
        return 0;
    }
    

    以上代码使用队列来统计每辆车到达的时间,使用两个整型变量记录每个油泵的运行情况,使用一个整型变量记录车辆总数和总等待时间。simulate函数为程序的核心部分,每个循环周期表示1分钟时间的流逝,具体执行流程如下:

    • 判断是否有新车辆到达,如有,则将其加入队列。
    • 检查油泵1是否空闲,如满足条件,则取出队首车辆,记录其等待时间和当前时间,设置油泵1的运行状态。
    • 检查油泵2是否空闲,如满足条件,则重复步骤2的操作,设置油泵2的运行状态。
    • 如果油泵1正在运行,且剩余加油时间为0,则释放油泵1。
    • 如果油泵2正在运行,且剩余加油时间为0,则释放油泵2。
    • 循环执行以上5个步骤,直到时间结束且队列为空,输出平均等待时间。

    实际运行效果如下:

    Average waiting time: 13.50
    

如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^