은행 서비스 시뮬레이션 프로그램
큐 데이터 원소를 고객 정보 구조체로 생성하고 큐 함수들을 가져다가 main함수만 바꿔주면 된다.
1.주어진 시간동안 고객은 랜덤한 간격으로 큐에 들어온다.
2.고객들의 서비스 시간도 한계값 안에서 랜덤하게 결정된다.
3.한 고객의 서비스가 끝나면 큐의 맨 앞에 있는 다른 고객이 서비스를 받기 시작한다.
4.정해진 시간동안의 시뮬레이션이 끝나면 고객들의 전체대기시간을 계산하여 출력한다.
#include <stdio.h>
#include <stdlib.h>
#define MAX_QUEUE_SIZE 5
typedef struct {
int id;
int arrival_time;
int service_time;
} element;
typedef struct {
int front;
int rear;
element data[MAX_QUEUE_SIZE];
} QueueType;
//오류 함수
void error(char *message)
{
fprintf(stderr, "%s\n", message);
exit(1);
}
//큐 초기화 함수
void init_queue(QueueType *q)
{
q->rear = 0;
q->front = 0;
}
//큐 상태 출력 함수
void queue_print(QueueType *q)
{
printf("QUEUE(front=%d rear=%d) = ", q->front, q->rear);
if( !is_empty(&q)) {
int i = q->front;
do{
i = (i+1) % (MAX_QUEUE_SIZE);
printf("%d | ", q->data[i]);
if(i == q->rear) // 공백 상태일때
break;
} while (i != q->front);
printf("\n");
}
// 큐 포화 확인 함수
int is_full(QueueType *q)
{
return(q->rear == q->front);
}
// 큐 공백 확인 함수
int is_empty(QueueType *q)
{
if((q->rear+1) % MAX_QUEUE_SIZE == q->front)
return 1;
else
return 0;
}
// 큐 삽입 함수
void enqueue(QueueType *q, int item)
{
if( is_full(q)){
error("큐가 포화상태입니다.");
return;
}
q->rear = (q->rear + 1) % MAX_QUEUE_SIZE; // 01234012....
q->data[(q->rear)] = item;
}
// 큐 삭제 함수
void dequeue(QueueType *q)
{
if( is_empty(q)){
error("큐가 공백상태입니다.");
return;
}
q->front = (q->front+1) % MAX_QUEUE_SIZE;
return q->data[q->front];
}
element peek(QueueType *q){
if(is_empty(&q))
error("큐가 공백상태입니다.");
return q->data[(q->front+1) % MAX_QUEUE_SIZE];
}
int main(void)
{
int minutes = 60;
int total_wait = 0;
int total_customer = 0;
int service_time;
int service_customer;
QueueType queue;
init_queue(&queue);
srand(time(NULL));// 난수 중복 없애기위해 선언
for(int clock = 0; clock < minutes; clock++) { // 총 60분동안 진행
printf("현재시각 = %d\n", clock);
if(rand()%10 < 3) { //30%확률로 고객이 들어옴
element customer; // 고객 정보 구조체 생성
customer.id = total_customer++; // 고객 id
customer.arrival_time = clock; // 고객 도착 시간
customer.service_time = rand()%3 + 1; // 고객 서비스 시간
enqueue(&queue, customer);// 고객 정보 큐에 삽입
printf("고객 %d이 %d분에 들어옵니다. 업무처리시간= %d분\n",
customer.id, customer.arrival_time, customer.service_time);
}
if(service_time > 0) {//서비스 시간 0이 아니면 고객이 서비스 받는중
printf("고객 %d 업무처리중입니다. \n", service_customer);
service_time--; //clock 하나 증가했으므로 서비스 타임 하나 감소
}
else { // 서비스 받는 고객이 없으므로 큐에서 고객 구조체 하나 꺼내어 서비스 시작
if( !is_empty(&queue)) {
element customer = dequeue(&queue);
service_customer = customer.id;
service_time = customer.service_time;
printf("고객 %d이 %d분에 업무를 시작합니다. 대긱시간은 %d분이었습니다.\n",
customer.id, clock, clock - customer.arrival_time);
total_wait += clock - coustomer.arrival_time;
}
}
}
printf("전체 대기 시간 = %d분 \n", total_wait);
return 0;
}
즉 service_time이 0이 아니냐 맞냐에 따라서 고객이 서비스를 받는중이냐 받지 않는중이냐를 판단할 수 있다. 그러나 30%의 확률로 고객이 들어오는것이(enqueue), 고객이 시간이 지남에 빠지는 것(dequeue)보다 많으면 큐는 포화 상태를 출력할 수 있다.