add utilization

This commit is contained in:
2024-08-31 12:03:17 +02:00
parent 719f7d4c24
commit ed876c9f91
2 changed files with 46 additions and 16 deletions

View File

@@ -1,4 +1,4 @@
from dataclasses import asdict, dataclass from dataclasses import dataclass
import numpy as np import numpy as np
import pandas as pd import pandas as pd
@@ -39,22 +39,36 @@ class Server(Process):
class CustomerGenerator(Process): class CustomerGenerator(Process):
def __init__(self, lam=40, servers=[]):
self.lam = lam
self.servers = servers
super().__init__()
def run(self): def run(self):
while True: while True:
wait_for = float(max(0, (np.random.poisson(lam=40, size=1) / 10)[0])) wait_for = float(max(0, (np.random.poisson(lam=self.lam, size=1) / 10)[0]))
customer = Customer(arrived_at=self.simulation.clock) customer = Customer(arrived_at=self.simulation.clock)
customers_unhandled.append(customer) customers_unhandled.append(customer)
for server in servers: for server in self.servers:
server.resume() server.resume()
yield from self.hold(wait_for) yield from self.hold(wait_for)
servers = [Server() for _ in range(2)] def run_simulation(n_servers=2, lam=40):
simulation = Simulation(processes=[CustomerGenerator(), *servers]) servers = [Server() for _ in range(n_servers)]
simulation.start() simulation = Simulation(
processes=[CustomerGenerator(servers=servers, lam=lam), *servers]
)
simulation.start()
df = pd.DataFrame([asdict(customer) for customer in customers_handled]).assign( df_customers = pd.DataFrame(
queue_time=lambda row: row["started_at"] - row["arrived_at"] [customer.__dict__ for customer in customers_handled]
) ).assign(queue_time=lambda row: row["started_at"] - row["arrived_at"])
print(f"\nservers: {len(servers)}") df_servers = pd.DataFrame([server.__dict__ for server in servers]).set_index("id")
print(df[["queue_time", "handling_time"]].mean()) print("\n")
print(df_customers[["queue_time", "handling_time"]].mean())
print(f"\nservers: {len(servers)}")
print(df_servers[["utilization"]])
run_simulation(n_servers=2, lam=30)

View File

@@ -17,19 +17,32 @@ class Process(BaseProcess):
def __init__(self): def __init__(self):
self.id: int = 1 self.id: int = 1
self.simulation = BaseSimulation() self.simulation = BaseSimulation()
self.started_at: float = 0
self.resume_at: float = 0 self.resume_at: float = 0
self.time_active: float = 0
self.utilization: float = 0
self.suspended = False self.suspended = False
self._gen = self.run() self._gen = self.run()
@property def start(self, simulation, id):
def name(self): self.id = id
return f"{self.__class__.__name__} {self.id}" self.started_at = simulation.clock
self.simulation = simulation
def hold(self, hold_for: float): def hold(self, hold_for: float):
hold_for_formatted = "{:.2f}".format(hold_for) hold_for_formatted = "{:.2f}".format(hold_for)
self.simulation.log(f"holding {self.name} for {hold_for_formatted} seconds") self.simulation.log(f"holding {self.name} for {hold_for_formatted} seconds")
self.resume_at = self.simulation.clock + hold_for self.resume_at = self.simulation.clock + hold_for
t_start = self.simulation.clock
yield yield
t_end = self.simulation.clock
self.time_active += t_end - t_start
try:
self.utilization = self.time_active / (
self.simulation.clock - self.started_at
)
except Exception as e:
print(e)
def suspend(self): def suspend(self):
self.suspended = True self.suspended = True
@@ -42,6 +55,10 @@ class Process(BaseProcess):
self.suspended = False self.suspended = False
next(self._gen) next(self._gen)
@property
def name(self):
return f"{self.__class__.__name__} {self.id}"
class Simulation(BaseSimulation): class Simulation(BaseSimulation):
def __init__(self, processes: list[Process]): def __init__(self, processes: list[Process]):
@@ -56,8 +73,7 @@ class Simulation(BaseSimulation):
for p in self.processes for p in self.processes
if p.__class__.__name__ == process.__class__.__name__ if p.__class__.__name__ == process.__class__.__name__
] ]
process.id = 1 + len(processes_with_same_class) process.start(simulation=self, id=1 + len(processes_with_same_class))
process.simulation = self
self.processes.append(process) self.processes.append(process)
@property @property