자료구조

자료구조) Queue를 이용한 은행 시뮬레이션 프로그램

쫑드기 2020. 5. 4. 22:01

<들어가기에 앞서>

c언어로 작성된 코드입니다.

 

<큐를 이용한 Server가 두 개인 은행 시뮬레이션>

Server가 한 개인 은행 시뮬레이션을 자료구조에서 배웠는데 만약 Sever가 두 개라면 어떻게 할까 고민해보다가 만들게 되었다. 한참을 고민하다가 결국 혼자 해냈다!! 짜릿

 

<프로그램 개요>

- 은행 시뮬레이션 프로그램이다.

- 은행에서 업무를 보는 것처럼 랜덤으로 고객이 들어와 고객 업무처리 시간(랜덤)에 맞게 업무 처리하고 나간다.

- 이를 60분까지 반복한다.

 

<문제 해결에 어려웠던 점>

Server를 두 개(a창구, b창구)로 만들어야 했는데 어떤 식으로 구성할지 한참을 고민하였다.

 

<문제 해결 방법>

- bool 자료형을 사용했다. 각 Sever마다 출입 여부를 임의로 정하여 업무 중에는 들어오지 못하게끔 코드를 짰다.

- 만약 은행에 두 개의 창구가 있다면 어떤 식으로 서비스가 진행될까 생각해보고 A4용지에 글로 옮겨 구체적으로 하나하나 코드를 작성해 보았다.

 

<느낀 점>

정말 많이 고민했던 문제였다. 문제 해결에 밤까지 새웠었던 적이 있었다.. 결국은 밤을 새우고도 해결하지 못했는데 그땐 내가 바보인가 하며 좌절감까지 들었었다. 그래도 끈기 하나로 계속해서 풀어보았다. 어느새 시간이 지나고 보니 문제를 해결한 나를 볼 수 있었다. 그 기쁨은 어느 때보다 즐겁고 짜릿했다. 앞으로도 쉽게 해결되지 않는 문제들을 맞닥뜨릴 텐데 뚝심 하나로 계속해서 도전해봐야겠다. 스스로가 뿌듯하고 대견했다!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#define MAX_QUEUE_SIZE 100
//고객 정보
typedef struct
{
    int id; 
    int arrival_time; 
    int service_time; 
} element;
// 원형 큐
/*=================================================================================*/
typedef struct
{
    element data[MAX_QUEUE_SIZE]; //element 타입으로 배열선언
    int front,rear; 
} QueueType;
//에러 출력
void error(char *message)
{
    fprintf(stderr,"%s\n",message);
    exit(1);
}
//front, rear 초기화
void init_queue(QueueType *q)
{
    q->front = q->rear = 0;
}
//비어있는지 확인
int is_empty(QueueType *q)
{
    return (q->front == q->rear);
}
//가득차있는 확인
int is_full(QueueType *q)
{
    return ((q->rear + 1) % MAX_QUEUE_SIZE == q->front);
}
//삽입 큐
void enqueue(QueueType *q,element item)
{
    if (is_full(q))
    {
        error("포화상태입니다.\n");
    }
    q->rear = (q->rear + 1) % MAX_QUEUE_SIZE;
    q->data[q->rear] = item;
}
//삭제 큐
element dequeue(QueueType *q)
{
    if (is_empty(q))
    {
        error("공백상태입니다.\n");
    }
    q->front = (q->front + 1) % MAX_QUEUE_SIZE;
    return q->data[q->front]; 
}
/*=================================================================================*/
int main(void)
{
    int minutes = 60//60분을 담기 위한 변수
    int total_wait = 0//총 대기시간을 담기 위한 변수
    int total_customers = 0//고객번호를 담기 위한 변수
    int a_service_time = 0
        b_service_time = 0//a창구, b창구 손님 서비스 시간을 담기 위한 변수
    int a_service_customer, //a창구 손님 고객번호를 담기 위한 변수
        b_service_customer; //b창구 손님 고객번호를 담기 위한 변수
    bool aCounter = true//a창구 서비스 여부
    bool bCounter = true//b창구 서비스 여부
    QueueType q;
    init_queue(&q); 
    srand(time(NULL)); //rand()를 초기화해주는 역할
    for (int clock = 0; clock < minutes; clock++)
    {
        
        printf("\n====================================현재시각=%d분======================================\n",clock);
        printf("<현재> A창고 출입여부 %d, B창고 출입여부 %d (0: 닫힘, 1: 열림)\n",aCounter,bCounter);
        if ((rand() % 10< 3)
        {
            element customer;
            customer.id = total_customers++//고객을 숫자로 지칭함. ex) 고객 1, 고객 2
            customer.arrival_time = clock;
            customer.service_time = rand() % 3 + 1;  //업무시간을 랜덤으로  조정
            enqueue(&q,customer);
            printf("고객 %d이 %d분에 들어옵니다. 고객 업무처리시간=%d\n",customer.id,customer.arrival_time,customer.service_time);
        }
 
        if (a_service_time > 0//a창구 고객의 서비스 시간이 0보다 클 경우
        {
            printf("고객 %d이 A창구에서 업무처리중입니다.\n",a_service_customer);
            a_service_time--;
            
            if (a_service_time == 0)
            {
                printf("(A창구가 %d분부터 열립니다.)\n",clock+1);
                aCounter = true;
            }
        }
        else if(aCounter) //a창구 서비스가 열려있을 경우
        {
            if (!is_empty(&q))
            {
                element customer = dequeue(&q); 
                a_service_customer = customer.id;
                a_service_time = customer.service_time; 
                
                printf("고객 %d이 %d분에 A창구에서 업무를 시작합니다. 대기시간은 %d분이었습니다.\n",customer.id,clock,clock - customer.arrival_time);  
                aCounter = false;                                                                                
                total_wait += clock - customer.arrival_time;
            }
        }
 
        if (b_service_time > 0//b창구 고객의 서비스 시간이 0보다 클 경우
        {
            printf("고객 %d이 B창구에서 업무처리중입니다.\n",b_service_customer);
            b_service_time--;
            
            if (b_service_time == 0)
            {
                printf("(B창구가 %d분부터 열립니다.)\n",clock + 1);
                bCounter = true;
            }
        }
        else if (bCounter) //b창구 서비스가 열려있을 경우
        {
            if (!is_empty(&q))
            {
                element customer = dequeue(&q); 
                b_service_customer = customer.id;
                b_service_time = customer.service_time;  
                printf("고객 %d이 %d분에 B창구에서 업무를 시작합니다. 대기시간은 %d분이었습니다.\n",customer.id,clock,clock - customer.arrival_time);  
                bCounter = false;                                                                                                                
                total_wait += clock - customer.arrival_time;
            }
        }
        
    }
    printf("전체 대기 시간 = %d분 \n",total_wait);
    return 0;
}
http://colorscripter.com/info#e" target="_blank" style="color:#e5e5e5text-decoration:none">Colored by Color Scripter
http://colorscripter.com/info#e" target="_blank" style="text-decoration:none;color:white">cs

 

결과 화면

 

감사합니다. 틀린 점 있으면 피드백 부탁드립니다. 

좋은 하루 되세요~!