본문 바로가기

자료구조

큐(Queue)응용 은행 시뮬레이션

은행 시뮬레이션 프로그램

대기행렬은 큐로 구현하고, 큐에 들어있는 고객들은 순서대로 서비스를 받는다.

한 고객의 서비스가 끝나면 다음(가장 먼저 들어온) 고객이 서비스를 받는다.

단순화를 위해 은행 창구는 하나라고 가정한다.

시뮬레이션에서는 난수 발생이 많이 사용된다. 고객들이 은행에 오는 것이 일정하지 않고 서비스에 필요한 시간도 각기 다를 것이기 때문이다.

시뮬레이션에서는 이러한 이벤트 발생을 조절하기 위해 다양한 값(파라미터)들이 사용된다. 

여기서는 다음 세 값을 사용자가 입력하도록 한다.

1. 시뮬레이션 할 최대 시간(예: 10 [단위시간])

2. 단위시간에 도착하는 고객 수 (예: 0.5 [고객수/단위시간])

3. 한 고객에 대한 최대 서비스 시간 (예: 5 [단위시간/고객])

고객들은 단위시간에 도착하는 고객 수를 바탕으로 무작위로 발생되며, 서비스 시간도 최대 서비스 시간 내에서 무작위로 결정된다.

#include<stdio.h>
#include<stdlib.h>
#define MAX_QUEUE_SIZE 100

typedef struct BankCustomer {
	int id;
	int tArrival;
	int tService;
} Customer;

typedef Customer Element;

Element data[MAX_QUEUE_SIZE];

int front, rear;

void error(char str[])
{
	printf("%s\n", str);
	exit(1);
}

void init_queue() { front = rear = 0; ; }
int is_empty() { return front == rear; }
int is_full() { return front == (rear + 1) % MAX_QUEUE_SIZE; }
int size() { return (rear - front + MAX_QUEUE_SIZE) % MAX_QUEUE_SIZE; }

void enqueue(Element val)
{
	if (is_full())
		error("큐 포화 에러");
	rear = (rear + 1) % MAX_QUEUE_SIZE;
	data[rear] = val;
}

Element dequeue()
{
	if (is_empty())
		error("큐 공백 에러");
	front = (front + 1) % MAX_QUEUE_SIZE;
	return data[front];
}

Element peek()
{
	if (is_empty())
		error("큐 공백 에러");
	return data[(front + 1) % MAX_QUEUE_SIZE];
}

int nSimulation; // 시뮬레이션 시간
double probArrival; // 단위시간에 도착하는 평균 고객 수
int tMaxService; // 한 고객에 대한 최대 서비스 시간
int totalWaitTime; // 전체 대기 시간
int nCustomers; // 전체 고객의 수
int nServedCustomers; // 서비스를 받은 전체 고객 수

double rand0to1() { return rand() / (double)RAND_MAX; }

void insert_customer(int arrivalTime)
{
	Customer a;
	a.id = ++nCustomers;
	a.tArrival = arrivalTime;
	a.tService = (int)(tMaxService*rand0to1()) + 1;
	printf("% 고객 %d 방문 (서비스 시간:%d분)\n", a.id, a.tService);
	enqueue(a);
}

void read_sim_params()
{
	printf("시뮬레이션 할 최대 시간 (예:10) = ");
	scanf("%d", &nSimulation);
	printf("단위시간에 도착하는 고객 수 (예:0.5) = ");
	scanf("%lf", &probArrival);
	printf("한 고객에 대한 최대 서비스 시간 (예:5) = ");
	scanf("%d", &tMaxService);
	printf("============================================\n");
}

void run_simlation()
{
	Customer a;
	int clock = 0;
	int serviceTime = -1;

	init_queue();
	nCustomers = totalWaitTime = nServedCustomers = 0;
	
	while (clock < nSimulation) {
		clock++;
		printf("현재 시각 = %d\n", clock);

		if (rand0to1() > probArrival)
			insert_customer(clock);
		if (serviceTime > 0) serviceTime--;
		else {
			if (is_empty()) continue;
			a = dequeue();
			nServedCustomers++;
			totalWaitTime += clock - a.tArrival;
			printf(" 고개  %d 서비스 시작(대기시간:%d분)\n", a.id, clock - a.tArrival);
			serviceTime = a.tService - 1;
		}

	}

}

void print_result()
{
	printf("=====================================================\n");
	printf(" 서비스 받은 고객수         = %d\n", nServedCustomers);
	printf(" 전체 대기 시간             = %d분\n", totalWaitTime);
	printf(" 서비스고객 평균대기시간    = %-5.2f분\n", (double)totalWaitTime / nServedCustomers);
	printf(" 현재 대기 고객 수          = %d\n", nCustomers - nServedCustomers);

}

#include<time.h>
void main()
{
	srand((unsigned int)time(NULL));
	read_sim_params();
	run_simlation();
	print_result();
}

'자료구조' 카테고리의 다른 글

전역 변수와 객체지향 프로그래밍  (0) 2019.02.27
덱(Deque)응용 미로 탐색 프로그램  (0) 2019.02.27
스택(Stack) - 괄호  (0) 2019.02.25
스택(Stack)  (0) 2019.02.25
연결리스트(LinkedList)  (1) 2019.02.19