코딩스터디

Queue를 이용한 미용사 서비스와 고객관리

애플앤마블 2019. 9. 9. 04:22
반응형
SMALL

1. 개요

  Queue를 이용하여 Server 3명인 경우 Customer에 대한 time number요소들을 출력한다.

 

2. Code에 대한 설명

 

  전체 서비스의 시간을 관장하는 Clock을 선언하고 이는 전체 시간을 담당한다.

Server 3명으로 설정하기 위해 Server가 가지는 service_time을 각각 1, 2, 3으로 선언하고 이 를 0으로 초기화 한다. , Server Customer를 받지 않을 경우 “잉여시간”으로 설정하기 위해 이를 service_idle_time으로 선언하고 초기화 한다.

모든 직원이 쉬고 있을 경우를 표현하기 위해 모든 Server service_time 0이 될 경우 “직원 이 모두 쉬고 있습니다.” 를 출력한다. , clock 1일 때부터 Customer가 들어오도록 설정된 환 경이므로 clock 0~1일 경우 모든 직원의 service_idle_time이 상승한다.

각 경우 모두 유의미한 값을 도출해내기 위해 초기 값들을 조정할 필요가 있다. 따라서duration = 100, arrival_prob = 0.7, max_serv_time = 9 로 설정했다.

If ( is_customer_arrived( ) )에서 0.7보다 작을 경우 Customer가 입장한 것으로 보고insert_customer 함수를 통해 enqueue(큐를 삽입)한다. 이 때 random함수를 이용하여 고객의service_time이 임의 배정되고 고객의 id, 도착시간, 서비스시간을 출력한다.

선입선출의 개념인 Queue이므로 먼저 들어온 고객부터 Server에 배정을 하며 각 Server가 모 두 Customer를 받고 있을 때 들어오는 Customer는 대기하며 Server Customer를 받고 있을 경 우 service_time이 전체 Clock에 반대하여 줄어들고 service_time 0일 경우 remove_customer()를 실행한다. 대기 시간은 전체 시간에서 도착시간을 뺀 시간에 더하여 표현한다

Insert_customer의 경우 선입선출에 의해 한 줄의 대기줄이 필요한 것 같이 하나의 함수만 필 요하지만, remove_customer의 경우 각 Server마다 개별로 각 하나씩 필요한 함수이므로 1, 2, 3의 함수를 삽입한다. 그리고 dequeue(큐를 삭제)하여 Customer의 서비스를 끝내고 삭제한다. 그 후 각 변수들을 return하고 각 요소들을 출력한다.

Service_idle_time에 대해서는 각 Server Customer에게 Service를 제공하지 않을 경우 잉여시 간으로 간주하여 service_idle_time을 증가시킨다. 만약 2명의 Server Service를 제공하지 않을 경우 잉여시간을 2 증가 시키고 마지막에 총 잉여시간을 출력한다.

 

3. Code

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

#define TRUE 1
#define FALSE 0
#define MAX_QUEUE_SIZE 100
typedef struct { …… } element;

typedef struct {    …… } QueueType;
QueueType queue;

void error(char *message) { …… }

void init(QueueType *q) { …… }

int is_empty(QueueType *q) { …… }

int is_full(QueueType *q) { …… }

void enqueue(QueueType *q, element item){ …… }

element dequeue(QueueType *q){ …… }

element peek(QueueType *q) { …… }

double random() { …… }

int duration = 100;
double arrival_prob = 0.7;
int max_serv_time = 9;
int clock;

int customers;
int served_customers;
int waited_time;

int is_customer_arrived()
{
    if (random() < arrival_prob)
        return TRUE;
    else return FALSE;
}

void insert_customer(int arrival_time, FILE *fp)
{
    element customer;
    
    customer.id = customers++;
    customer.arrival_time = arrival_time;
    customer.service_time = (int)(max_serv_time*random()) + 1;
    enqueue(&queue, customer);
    fprintf_s(fp,"고객 %d이 %d분에 들어옵니다. 서비스의 시간은 %d분입니다.\n", customer.id, customer.arrival_time, customer.service_time);
}
int remove_customer1(FILE *fp)
{
    element customer;
    int service_time1 = 0;
    
    if (is_empty(&queue)) return 0;
    customer = dequeue(&queue);
    service_time1 = customer.service_time - 1;
    served_customers++;
    waited_time += clock - customer.arrival_time;
    fprintf_s(fp,"고객 %d이 %d분에 서비스를 시작합니다. 대기시간은 %d분이었습니다.\n", customer.id, clock, clock - customer.arrival_time);
    return service_time1;
}

int remove_customer2(FILE *fp)
{
    element customer;
    int service_time2 = 0;
    
    if (is_empty(&queue)) return 0;
    customer = dequeue(&queue);
    service_time2 = customer.service_time - 1;
    served_customers++;
    waited_time += clock - customer.arrival_time;
    fprintf_s(fp,"고객 %d이 %d분에 서비스를 시작합니다. 대기시간은 %d분이었습니다.\n", customer.id, clock, clock - customer.arrival_time);
    return service_time2;
}
int remove_customer3(FILE *fp) { …… }
print_stat(FILE *fp)
{
    fprintf_s(fp,"서비스받은 고객수 = %d\n", served_customers);
    fprintf_s(fp,"전체 대기 시간 = %d분\n", waited_time);
    fprintf_s(fp,"1인당 평균 대기 시간 = %f분\n", (double)waited_time / served_customers);
    fprintf_s(fp,"아직 대기중인 고객수 = %d\n", customers - served_customers);
    
}
void main()
{
    FILE* fp = NULL;
    errno_t err;
    
    if ((err = fopen_s(&fp, "serviceRusult.txt", "w")) != 0) {
        printf("File open error!");
        exit(0);
    }
    
    int service_time1 = 0;
    int service_time2 = 0;
    int service_time3 = 0;
    int service_idle_time = 0;
    clock = 0;
    
    while (clock < duration) {
        if (service_time1 == 0 && service_time2 == 0 && service_time3 == 0)
            fprintf_s(fp, "직원이 모두 쉬고 있습니다.");//clock이 0~1일 때는 모든 직원이 쉬고 있다. 그 후 clock++
        clock++;
        fprintf_s(fp, "현재시각 = %d\n", clock);
        if (is_customer_arrived()) {
            insert_customer(clock, fp);
        }
        if (service_time1 > 0)
            service_time1--;
        else {
            service_time1 = remove_customer1(fp);
            service_idle_time++;
        }
        if (service_time2 > 0)
            service_time2--;
        else {
            service_time2 = remove_customer2(fp);
            service_idle_time++;
        }
        if (service_time3 > 0)
            service_time3--;
        else {
            service_time3 = remove_customer3(fp);
            service_idle_time++;
        }
        
    }
    print_stat(fp);
    fprintf_s(fp, "총 잉여시간 = %d\n", service_idle_time);
    fclose(fp);
}

  기본적 큐를 구현하기 위한 큐 함수들 { ...... }로 생략하였다. 아이디어를 포함하는 is_ customer_arrived(), insert_customer(intarrival_time, FILE*fp), print_stat(FILE*fp), main()은 생략하지 않았고 remove_customer(FILE*fp) 같은 경우는 1,2는 생략하지 않았으며 3은 생략했다.

 

4. 결과

결과는 serviceResult.txt의 텍스트 파일로 저장하여 출력하였다.

100분의 Clock동안 서비스하였으며 중간의 시간은 중략하였다.

첫번째 좌측 결과 사진은 Server가 모두 쉬었을 때부터 다음 모두 쉴 때까지의 결과창이며Clock마다 쉬는 Server수 만큼 잉여시간이 증가한다. 두번째 우측 결과 사진은 Clock 100이 된 후 서비스 받은 고객 수와, 전체 대기 시간, 1인당 평균 대기 시간, 아직 대기 중인 고객 수, 직원 의 총 잉여시간을 계산하여 출력한 값이다.

반응형
LIST