add utilization
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user