Compare commits
2 Commits
a4004fc6f7
...
4a5ced1172
| Author | SHA1 | Date | |
|---|---|---|---|
| 4a5ced1172 | |||
| ed876c9f91 |
@@ -1,4 +1,4 @@
|
|||||||
from dataclasses import asdict, dataclass
|
from dataclasses import dataclass
|
||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
import polars as pl
|
import polars as pl
|
||||||
@@ -39,23 +39,37 @@ 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 = pl.DataFrame([asdict(customer) for customer in customers_handled]).with_columns(
|
df_customers = pl.DataFrame(
|
||||||
queue_time=pl.col('started_at') - pl.col('arrived_at')
|
[customer.__dict__ for customer in customers_handled]
|
||||||
)
|
).with_columns(queue_time=pl.col("started_at") - pl.col("arrived_at"))
|
||||||
|
|
||||||
print(f"\nservers: {len(servers)}")
|
df_servers = pl.DataFrame([server.__dict__ for server in servers])
|
||||||
print(df[["queue_time", "handling_time"]].mean())
|
|
||||||
|
# print(f"\nservers: {len(servers)}")
|
||||||
|
print("\ncustomers", df_customers[["queue_time", "handling_time"]].mean())
|
||||||
|
print("\nservers", df_servers[["id", "utilization"]])
|
||||||
|
|
||||||
|
|
||||||
|
run_simulation(n_servers=3)
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user