-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathmain.cpp
189 lines (164 loc) · 5.01 KB
/
main.cpp
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
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
/*
* Uğur Ali Kaplan
* Student ID: 150170042
*/
#include <iostream>
#include <cmath>
#include <fstream>
#include <cstdlib>
#include <vector>
/*
* Input format : EVENT-NAME START-TIME END-TIME
* How to read input: Read a list of events from a binary file, file name is supplied as commandline argument
* Create a MIN-HEAP PRIORITY QUEUE
* Each event creates two entries in the min-heap -> (Event Start, Key = Start_time) and (Event End, Key = End_time)
* So, heap nodes should include event name and event type(i.e. start or end)
*
* Virtual clock in the system starting from T = 0
* At each tick, check the root of the min heap. If T = Key value of the root, Call Min-remove and print the name
* and type of the event.
*
* There might be multiple keys with the same value.
*/
using namespace std;
class Node{
private:
string name;
bool start; // If true, this is a "START" node, else this is an "END" node
unsigned int time;
public:
Node(string name, bool start, unsigned int time);
unsigned int getTime() {
return time;
}
void printNode();
};
void Node::printNode() {
/*
* Prints the name of the event and type of the event (e.g. EVENT-A STARTED, EVENT-B ENDED ...)
*/
cout << name << " ";
if (start) cout << "STARTED";
else cout << "ENDED";
cout << endl;
}
Node::Node(string name, bool start, unsigned int time) {
this->name = name;
this->start = start;
this->time = time;
}
class Scheduler{
private:
Node *heap; // Hold an array of nodes, called heap
int heap_size; // How many elements do we have?
unsigned int T; // Timer
public:
Scheduler(Node *heap, int size);
unsigned int heapMinimum();
void heapExtractMin();
void minHeapify(int index);
void buildMinHeap();
void printHeap();
void tickTock();
};
Scheduler::Scheduler(Node *heap, int size) : T(1){
this->heap = heap;
this->heap_size = size;
buildMinHeap();
}
unsigned int Scheduler::heapMinimum() {
/*
* Returns the key of the minimum element
*/
return heap[0].getTime();
}
void Scheduler::heapExtractMin() {
/*
* Prints the minimum element and discards it out of the heap.
*/
Node value = heap[0];
Node temp = heap[heap_size - 1];
heap[heap_size - 1] = heap[0];
heap[0] = temp;
heap_size -= 1;
minHeapify(0);
value.printNode();
}
void Scheduler::minHeapify(int index) {
/*
* Changes the heap so that index it is called on satisfies the min-heap property.
*/
int left = (2 * (index + 1)) - 1;
int right = left + 1;
int min = index;
if (left <= (heap_size - 1))
{if (heap[left].getTime() < heap[min].getTime()) min = left;}
if (right <= (heap_size - 1))
{if (heap[right].getTime() < heap[min].getTime()) min = right;}
if(min != index){
Node temp = heap[index];
heap[index] = heap[min];
heap[min] = temp;
minHeapify(min);
}
}
void Scheduler::buildMinHeap() {
/*
* Builds a min-heap out of the unordered array it is given.
*/
int start_index = floor(heap_size - 1 / 2.0);
for(int i = start_index; i >= 0; i--){
minHeapify(i);
}
}
void Scheduler::printHeap() {
/*
* Prints all elements of the heap, can be used for debugging purposes.
*/
for(int i = 0; i < heap_size; i++){
heap[i].printNode();
}
}
void Scheduler::tickTock() {
/*
* Runs the timer, prints the events that are happening.
* Stops the timer if there are no more events.
*/
while (heap_size > 0){
if (T != heapMinimum()) cout << "TIME " << T << ": NO EVENT" << endl;
while (T == heapMinimum() && heap_size > 0){
cout << "TIME " << T << ": ";
heapExtractMin();
}
T++;
}
T--;
cout << "TIME " << T << ": NO MORE EVENTS, SCHEDULER EXITS" << endl;
}
int main(int argc, char * argv[]) {
ifstream in_file(argv[1]); // Open the input file
int size = 0; // Heap Size
if(!in_file) { // If were unable to open the file
cerr << "File could not be read" << endl;
exit(1);
}
vector<Node> nodeList; // Number of events is unknown, therefore we use vectors
string name; // name will hold the name of the event
while(in_file >> name){ // Read lines from the file
int start, end; // Start and end times
in_file >> start;
in_file >> end;
if(start < 1 || end < 1 || start > end){
cerr << name << " cannot be used, times are incorrect" << endl;
continue;
}
nodeList.push_back(Node(name, true, start)); // Append a start node
nodeList.push_back(Node(name, false, end)); // Append an end node
size += 2; // Keep track of how many nodes we have added
}
in_file.close(); // Clean after yourself
if (size == 0) {cerr << "File is empty!" << endl; exit(1);} // If there are no nodes, exit
Scheduler schedule(&nodeList[0], size); // Initialize the scheduler object
schedule.tickTock(); // Run the timer
return 0;
}