Skip to content

Commit f85fe9b

Browse files
committed
Server utilisation works across server schedules
1 parent 9f1ccf1 commit f85fe9b

5 files changed

Lines changed: 50 additions & 14 deletions

File tree

ciw/exactnode.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,20 @@
11
from .node import Node
22
from .arrival_node import ArrivalNode
33
from decimal import Decimal, getcontext
4+
from .server import Server
45

56
class ExactNode(Node):
67
"""
78
Inherits from the Node class, implements a more
89
precise version of addition to fix discrepencies
910
with floating point numbers.
1011
"""
12+
def create_starting_servers(self):
13+
"""
14+
Initialise the servers
15+
"""
16+
return [Server(self, i + 1, Decimal('0.0')) for i in range(self.c)]
17+
1118
def increment_time(self, original, increment):
1219
"""
1320
Increments the original time by the increment

ciw/node.py

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ def __init__(self, id_, simulation):
5252
self.next_event_date = float("Inf")
5353
self.blocked_queue = []
5454
if self.c < float('Inf'):
55-
self.servers = [Server(self, i + 1) for i in range(self.c)]
55+
self.servers = self.create_starting_servers()
5656
self.highest_id = self.c
5757
self.simulation.deadlock_detector.initialise_at_node(self)
5858
self.preempt = node.preempt
@@ -96,7 +96,7 @@ def add_new_servers(self, shift_indx):
9696
num_servers = self.schedule[shift_indx][1]
9797
for i in range(num_servers):
9898
self.highest_id += 1
99-
self.servers.append(Server(self, self.highest_id))
99+
self.servers.append(Server(self, self.highest_id, self.next_event_date))
100100

101101
def attach_server(self, server, individual):
102102
"""
@@ -218,7 +218,6 @@ def change_shift(self):
218218
self.begin_service_if_possible_change_shift(
219219
self.next_event_date)
220220

221-
222221
def check_if_shiftchange(self):
223222
"""
224223
Check whether current time is a shift change.
@@ -227,6 +226,12 @@ def check_if_shiftchange(self):
227226
return self.next_event_date == self.next_shift_change
228227
return False
229228

229+
def create_starting_servers(self):
230+
"""
231+
Initialise the servers
232+
"""
233+
return [Server(self, i + 1, 0.0) for i in range(self.c)]
234+
230235
def detatch_server(self, server, individual):
231236
"""
232237
Detatches a server from an individual, and vice versa
@@ -240,7 +245,7 @@ def detatch_server(self, server, individual):
240245
server.busy_time = (individual.exit_date - individual.service_start_date)
241246
else:
242247
server.busy_time += (individual.exit_date - individual.service_start_date)
243-
server.total_time = individual.exit_date
248+
server.total_time = self.increment_time(individual.exit_date, -server.start_date)
244249
if server.offduty:
245250
self.kill_server(server)
246251

@@ -320,10 +325,13 @@ def increment_time(self, original, increment):
320325
"""
321326
return original + increment
322327

323-
def kill_server(self,srvr):
328+
def kill_server(self, srvr):
324329
"""
325330
Kills server.
326331
"""
332+
srvr.total_time = self.increment_time(self.next_event_date, -srvr.start_date)
333+
self.all_servers_busy.append(srvr.busy_time)
334+
self.all_servers_total.append(srvr.total_time)
327335
indx = self.servers.index(srvr)
328336
del self.servers[indx]
329337

@@ -417,6 +425,18 @@ def update_next_event_date(self, current_time):
417425
else:
418426
self.next_event_date = next_end_service
419427

428+
def wrap_up_servers(self, current_time):
429+
"""
430+
Updates the servers' total_time and busy_time
431+
as the end of the simulation run.
432+
"""
433+
if self.c != float('Inf'):
434+
for srvr in self.servers:
435+
srvr.total_time = current_time - srvr.start_date
436+
if srvr.busy:
437+
srvr.busy_time += (current_time - srvr.cust.arrival_date)
438+
439+
420440
def write_individual_record(self, individual):
421441
"""
422442
Write a data record for an individual:

ciw/server.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ class Server(object):
44
"""
55
A class to contain server information
66
"""
7-
def __init__(self, node, id_number):
7+
def __init__(self, node, id_number, start_date=0.0):
88
"""
99
Initialise the server object
1010
"""
@@ -14,6 +14,7 @@ def __init__(self, node, id_number):
1414
self.busy = False
1515
self.offduty = False
1616
self.all_time = False
17+
self.start_date = start_date
1718
self.busy_time = False
1819
self.total_time = False
1920

ciw/simulation.py

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -351,15 +351,12 @@ def simulate_until_max_customers(self, max_customers,
351351

352352
def wrap_up_servers(self, current_time):
353353
"""
354-
Updates the servers' total_time and busy_time
355-
as the end of the simulation run.
354+
Updates the servers' total_time and busy_time as
355+
the end of the simulation run. Finds the overall
356+
server utilisation for each node.
356357
"""
357358
for nd in self.transitive_nodes:
358-
if nd.c != float('Inf'):
359-
for srvr in nd.servers:
360-
srvr.total_time = current_time
361-
if srvr.busy:
362-
srvr.busy_time += (current_time - srvr.cust.arrival_date)
359+
nd.wrap_up_servers(current_time)
363360
nd.find_server_utilisation()
364361

365362
def source(self, c, n, kind):

ciw/tests/test_node.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -599,4 +599,15 @@ def test_server_utilisation(self):
599599
)
600600
Q = ciw.Simulation(N)
601601
Q.simulate_until_max_time(20.0)
602-
self.assertEqual(Q.transitive_nodes[0].server_utilisation, 4.0/15.0)
602+
self.assertEqual(Q.transitive_nodes[0].server_utilisation, 4.0/15.0)
603+
604+
def test_server_utilisation_with_schedules(self):
605+
N = ciw.create_network(
606+
Arrival_distributions=[['Sequential', [2.0, 4.0, 4.0, 0.0, 7.0, 1000.0]]],
607+
Service_distributions=[['Sequential', [4.0, 2.0, 6.0, 6.0, 3.0]]],
608+
Number_of_servers=[[[1, 9], [2, 23]]]
609+
)
610+
Q = ciw.Simulation(N)
611+
Q.simulate_until_max_time(23)
612+
recs = Q.get_all_records()
613+
self.assertEqual(Q.transitive_nodes[0].server_utilisation, 21.0/37.0)

0 commit comments

Comments
 (0)