-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsimulation.py
101 lines (75 loc) · 2.92 KB
/
simulation.py
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
import numpy as np
from customer import Customer
from distributions import customer_entry
from mqueue import MQueue
from system import System
CLOCK_STEP = 0.01
def run_simulation(
server_count: int, customer_count: int, priority_chance=0.1, logging=True
):
system = System(server_count)
queue = MQueue()
customer_arrival_times = customer_entry(customer_count)
queued_customers = 0
# Each tick of the clock is 0.01 seconds
clock = 0
finish_events = []
finished_customers = []
waiting_count = {}
busy_servers_count = {}
customer_id = 0
log_text = []
while ( not queue.is_empty() or len(finish_events) > 0 or queued_customers != customer_count):
if queued_customers < customer_count and customer_arrival_times[0] == clock:
customer_id += 1
# Customer entry
new_customer_arrival_time = customer_arrival_times.pop(0)
new_customer_priority_state = np.random.uniform() < priority_chance
queued_customers += 1
customer = Customer(
arrival_time=new_customer_arrival_time,
priority=new_customer_priority_state,
)
if customer.priority:
queue.enqueue_priority(customer)
else:
queue.enqueue(customer)
log = f"{clock} \t # \t New customer arrived and queued.\n"
log_text.append(log)
elif not queue.is_empty() and system.can_serve():
# Job assignment
customer = queue.dequeue()
server, service_time = system.serve()
customer.start_service(clock, server)
finish_events.append(
{
"server": server,
"time": round(clock + service_time, 2),
"customer": customer,
}
)
finish_events = sorted(finish_events, key=lambda e: e["time"])
log = f"{clock} \t @ \t Customer assigned to server {server+1} and is set to finish in {round(clock+service_time, 2)}\n"
log_text.append(log)
elif len(finish_events) > 0 and clock == finish_events[0]["time"]:
# Customer served
event = finish_events.pop(0)
event["customer"].end_service(clock)
system.free_server(event["server"])
finished_customers.append(event["customer"])
log = f"{clock} \t * \t Server {event['server']+1} finished proccessing and is free.\n"
log_text.extend(log)
else:
waiting_count[clock] = len(queue)
busy_servers_count[clock] = system.busy_servers()
clock = round(clock + CLOCK_STEP, 2)
if logging:
with open("out.txt", "w") as wf:
wf.writelines(log_text)
return (
finished_customers,
system.server_stats,
clock,
waiting_count,
busy_servers_count,
)