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 pandas as pd
@@ -39,22 +39,36 @@ class Server(Process):
class CustomerGenerator(Process):
def __init__(self, lam=40, servers=[]):
self.lam = lam
self.servers = servers
super().__init__()
def run(self):
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)
customers_unhandled.append(customer)
for server in servers:
for server in self.servers:
server.resume()
yield from self.hold(wait_for)
servers = [Server() for _ in range(2)]
simulation = Simulation(processes=[CustomerGenerator(), *servers])
def run_simulation(n_servers=2, lam=40):
servers = [Server() for _ in range(n_servers)]
simulation = Simulation(
processes=[CustomerGenerator(servers=servers, lam=lam), *servers]
)
simulation.start()
df = pd.DataFrame([asdict(customer) for customer in customers_handled]).assign(
queue_time=lambda row: row["started_at"] - row["arrived_at"]
)
df_customers = pd.DataFrame(
[customer.__dict__ for customer in customers_handled]
).assign(queue_time=lambda row: row["started_at"] - row["arrived_at"])
df_servers = pd.DataFrame([server.__dict__ for server in servers]).set_index("id")
print("\n")
print(df_customers[["queue_time", "handling_time"]].mean())
print(f"\nservers: {len(servers)}")
print(df[["queue_time", "handling_time"]].mean())
print(df_servers[["utilization"]])
run_simulation(n_servers=2, lam=30)

View File

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