-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathSimulation.cpp
95 lines (74 loc) · 2.6 KB
/
Simulation.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
#include <iostream>
#include "utils.h"
#include "Simulation.h"
Simulation::Simulation(double lambda, double mu, unsigned int capacity) {
this->lambda = lambda;
this->mu = mu;
this->system_capacity = capacity;
}
double Simulation::generate_interarrival() {
return get_exponential_random_value(this->lambda);
}
double Simulation::generate_service() {
return get_exponential_random_value(this->mu);
}
bool Simulation::is_queue_full() {
return this->packets.size() >= this->system_capacity;
}
bool Simulation::is_arrival() {
return this->time_arrival < get_time_departure();
}
double Simulation::get_time_departure() {
double time_departure = (!this->packets.empty()) ? this->packets.front().get_time_departure() : this->time_total;
return time_departure;
}
void Simulation::update_time_current() {
this->time_current = std::min(this->time_arrival, get_time_departure());
}
void Simulation::add_packet(double time) {
Packet packet(time);
this->packets.push(packet);
}
void Simulation::handle_arrival_event(double time) {
++this->n_pkt_total;
if (!is_queue_full()) {
add_packet(time);
if (this->packets.size() == 1) {
set_next_departure();
}
} else {
++this->n_pkt_dropped;
}
this->time_arrival += generate_interarrival();
}
void Simulation::set_next_departure() {
if (!this->packets.empty()) {
this->time_pkts_queue_total += this->time_current - this->packets.front().get_time_arrival();
double next_departure = this->time_current + generate_service();
this->packets.front().set_time_departure(next_departure);
}
}
void Simulation::handle_depart_event() {
if (!this->packets.empty()) {
this->time_pkts_system_total += this->packets.front().get_time_in_system();
this->packets.pop();
set_next_departure();
}
}
void Simulation::simulate() {
double time_last_event;
while (this->time_current < this->time_total) {
time_last_event = this->time_current;
update_time_current();
this->sum_n_pkt_system += this->packets.size() * (this->time_current - time_last_event);
if (is_arrival()) {
handle_arrival_event(this->time_current);
} else {
handle_depart_event();
}
}
this->probability_dropped_pkt = (double)this->n_pkt_dropped / this->n_pkt_total;
this->avg_n_pkt_system = this->sum_n_pkt_system / this->time_total;
this->avg_time_pkt_system = this->time_pkts_system_total / this->n_pkt_total;
this->avg_time_pkt_queue = this->time_pkts_queue_total / this->n_pkt_total;
}