2022-03-16-DataStructure-Week10-실습2
priority_queue_simulation
- Priority_queue_simulation의 구현
- Min heap
key 값(duration)이 작을수록 우선 순위가 높음
자료구조 및 함수 구성
typedef struct {
int key; // Priority queue 의 키 값(duration)
...
} Job;
typedef Job Element;
Element PQ[MAX_PQ_SIZE]; //min heap
int PQ_size = 0;
- void insert_PQ(Element item)
PQ 에 job 삽입
- Element delete_PQ()
PQ 에서 min item(루트) 삭제 및 반환
- void PQ_show()
PQ 의 job 들의 key와 id를 차례로 출력
- boolean is_PQ_empty()
실행 예
Source
- 실습2.h
#pragma once
#define MAX_SIMUL_TIME 20
#define MAX_PRINTING_TIME 10
#define JOB_ARRIVAL_PROB 0.5
#define boolean unsigned char
#define true 1
#define false 0
#define MAX_PQ_SIZE 1000
int current_time = 0;
int new_job_id = 0;
int current_job_id;
int remaining_time;
int total_wait_time;
int num_printed_jobs;
//Job
typedef struct {
int key; //Priority queue의 키 값(duration을 키로 설정)
int id; //Job id;
int arrival_time; //Job이 요청된 시간
int duration; //Job의 프린트 시간
}Job;
typedef Job Element;
//Global PQ(priority queue): min heap - key값(duration)이 작을수록 우선순위가 높음
Element PQ[MAX_PQ_SIZE];
int PQ_size = 0;
void insert_job(int id, int arrival_time, int duration);
void process_next_job();
boolean is_job_arrived();
boolean is_printer_idle();
double random();
int get_random_duration();
void insert_PQ(Element item);
Element delete_PQ();
void PQ_show();
boolean is_PQ_empty();
- 실습2.cpp
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include"실습2.h"
void insert_job(int id, int arrival_time, int duration) {
Job p;
p.key = duration;
p.id = id;
p.arrival_time = arrival_time;
p.duration = duration;
insert_PQ(p);
printf("새 job <%d>이 들어 왔습니다. 프린트 시간은 %d 입니다.\n", id, duration);
}
void process_next_job() {
Job p;
p = delete_PQ();
current_job_id = p.id;
remaining_time = p.duration - 1;
total_wait_time += current_time - p.arrival_time;
++num_printed_jobs;
printf("프린트를 시작합니다 = job<%d>...\n", current_job_id);
}
boolean is_job_arrived() {
if (random() < JOB_ARRIVAL_PROB)
return true;
else
return false;
}
boolean is_printer_idle() {
if (remaining_time <= 0)
return true;
else
return false;
}
double random() {
return rand() / (double)RAND_MAX;
}
int get_random_duration() {
return (int)(MAX_PRINTING_TIME * random()) + 1;
}
void insert_PQ(Element item) {
int i = ++PQ_size;
while ((i != 1) && (item.key > PQ[i / 2].key)) {
PQ[i] = PQ[i / 2];
i = i / 2;
}
PQ[i] = item;
}
Element delete_PQ() {
Element max = PQ[1];
Element tmp = PQ[PQ_size--];
int p = 1, c = 2;
while (c <= PQ_size) {
if ((c < PQ_size) && (PQ[c].key < PQ[c + 1].key))
c++;
if (tmp.key >= PQ[c].key)
break;
PQ[p] = PQ[c];
p = c;
c = c * 2;
}
PQ[p] = tmp;
return max;
}
void PQ_show() {
printf("현재 프린터 큐: [ ");
for (int i = 0; i < PQ_size; i++)
printf("<%d %d> ", PQ[i + 1].id, PQ[i + 1].key);
printf("]\n");
}
boolean is_PQ_empty() {
if (PQ_size == 0)
return true;
else
return false;
}
void main() {
int duration;
srand(time(NULL));
while (current_time < MAX_SIMUL_TIME) {
printf("\n----- time %d -----\n", current_time);
if (is_job_arrived()) {
++new_job_id;
duration = get_random_duration();
insert_job(new_job_id, current_time, duration);
}
if (is_printer_idle()) {
if (!is_PQ_empty())
process_next_job();
}
else {
printf("아직 Job <%d>을 프린트하고 있습니다...\n", current_job_id);
--remaining_time;
}
PQ_show();
++current_time;
}
printf("\n완료된 프린트 job = %d개 \n", num_printed_jobs);
printf("평균 지연 시간 = %f 단위시간 \n\n", (double)total_wait_time / num_printed_jobs);
}