diff --git a/assignment/TIPS.txt b/assignment/doc/TIPS.txt similarity index 100% rename from assignment/TIPS.txt rename to assignment/doc/TIPS.txt diff --git a/assignment/doc/assignment.html b/assignment/doc/assignment.html new file mode 100644 index 0000000..66132e2 --- /dev/null +++ b/assignment/doc/assignment.html @@ -0,0 +1,110 @@ + +DEVS Assignment + + +

Introduction

+

You will use (classic) DEVS to model a queueing and load balancing system for a set of waterway locks. A conceptual view of the system is shown here:

+ +

Ships move in the direction of the arrows. A generator generates ships at pseudo-random time intervals, which are added to a queue. Whenever the queue has a ship available, and one of the locks has enough remaining capacity for that ship, the load balancer pulls a ship from the queue and sends it to that lock. A lock may fit more than one ship, so as long as it is not filled up to full capacity, it may wait for more ships to arrive before the lock doors close and the ships can pass through to the other side of the lock. At the end of the system, we have a Sink, where all ships are collected, so we can extract statistics to analyse performance.

+ +

Ships can have different sizes. For simplicity, the size of a ship is a small integer (e.g., 1 or 2). Locks can have different capacities: for instance, a lock of capacity 3 will fit either: +

+

+ +

Specification

+ +

We now give an overview of the different DEVS components, and their behavior, and their parameters. Although many of the parameters are fixed, your solution must work with different parameters as well. In other words, don't hardcode the parameter values in your DEVS blocks!

+ +

Atomic DEVS blocks

+ + +The specification of the semantics of the Atomic DEVS blocks is entirely deterministic. If you implement everything correctly, the system as-a-whole will behave 100% identical to the teacher's solution. +

+ +

Coupled DEVS

+

The system as a whole is modeled as a Coupled DEVS block. Many of its parameters are passed as-is to the underlying Atomic DEVS blocks, such as: +

+

+ +

Goal: Performance Analysis

+

We will do performance analysis, comparing combinations of the following parameter values:

+ +

More specifically, we would like to know under which (combinations of) parameter values the (avg/min/max) duration that ships spend in the system is minimized. Also, we'd like to know if one choice (e.g., prioritize bigger) always better than another choice (e.g., prioritize smaller), or does it depend on the choices made for the other parameters?

+ + + \ No newline at end of file diff --git a/assignment/doc/concept.svg b/assignment/doc/concept.svg new file mode 100644 index 0000000..df2edf2 --- /dev/null +++ b/assignment/doc/concept.svg @@ -0,0 +1,3 @@ + + +
Generator
Queue
Load Balancer
Lock
Lock
Sink
\ No newline at end of file diff --git a/assignment/doc/figures.drawio b/assignment/doc/figures.drawio new file mode 100644 index 0000000..fd69eb1 --- /dev/null +++ b/assignment/doc/figures.drawio @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assignment/runner.py b/assignment/runner.py index fc4e524..0000641 100644 --- a/assignment/runner.py +++ b/assignment/runner.py @@ -31,9 +31,9 @@ strategies = { # The number of locks and their capacities lock_capacities=[3,2] # two locks, of capacity 3 and 2 -# The different parameters to try for lock_max_wait -lock_max_waits = [ 0.0+i*120.0 for i in range(5) ] # all these values will be attempted -# lock_max_waits = [ 15.0 ] # <-- uncomment if you only want to run an experiment with this value (useful for debugging) +# The different parameters to try for max_wait_duration +max_wait_durations = [ 0.0+i*120.0 for i in range(5) ] # all these values will be attempted +# max_wait_durations = [ 15.0 ] # <-- uncomment if you only want to run an experiment with this value (useful for debugging) # How long does it take for a ship to pass through a lock passthrough_duration = 60.0*15 # 15 minutes @@ -49,9 +49,9 @@ os.makedirs(outdir, exist_ok=True) for priority in priorities: for strategy in strategies: values = [] - # and in each experiment, try a bunch of different values for the 'lock_max_wait' parameter: - for lock_max_wait in lock_max_waits: - print("Run simulation:", priorities[priority], strategies[strategy], "max_wait =",lock_max_wait) + # and in each experiment, try a bunch of different values for the 'max_wait_duration' parameter: + for max_wait_duration in max_wait_durations: + print("Run simulation:", priorities[priority], strategies[strategy], "max_wait =",max_wait_duration) sys = LockQueueingSystem( # See system.py for explanation of these values: seed=0, @@ -61,7 +61,7 @@ for priority in priorities: load_balancer_strategy=strategy, lock_capacities=lock_capacities, priority=priority, - lock_max_wait=lock_max_wait, + max_wait_duration=max_wait_duration, passthrough_duration=passthrough_duration, ) sim = Simulator(sys) @@ -73,7 +73,7 @@ for priority in priorities: ships = sys.sink.state.ships values.append([ship.queueing_duration for ship in ships]) - # Write out all the ship queueuing durations for every 'lock_max_wait' parameter + # Write out all the ship queueuing durations for every 'max_wait_duration' parameter # for every ship, we write a line: # , time_max_wait0, time_max_wait1, time_max_wait2, ... time_max_wait10 filename = f'{outdir}/output_{strategies[strategy]}_{priorities[priority]}.csv' @@ -91,13 +91,13 @@ for priority in priorities: plots_ships.append(make_plot_ships_script( priority=priorities[priority], strategy=strategies[strategy], - max_waits=lock_max_waits, + max_waits=max_wait_durations, gen_num=gen_num, )) plots_box.append(make_plot_box_script( priority=priorities[priority], strategy=strategies[strategy], - max_waits=lock_max_waits, + max_waits=max_wait_durations, gen_num=gen_num, )) diff --git a/assignment/system.py b/assignment/system.py index f185371..f55d645 100644 --- a/assignment/system.py +++ b/assignment/system.py @@ -17,7 +17,7 @@ class LockQueueingSystem(CoupledDEVS): load_balancer_strategy, lock_capacities, priority, - lock_max_wait, + max_wait_duration, passthrough_duration, ): super().__init__("LockQueueingSystem") @@ -47,7 +47,7 @@ class LockQueueingSystem(CoupledDEVS): locks = [ self.addSubModel(Lock( capacity=lock_capacity, - max_wait_duration=lock_max_wait, + max_wait_duration=max_wait_duration, passthrough_duration=passthrough_duration)) for lock_capacity in lock_capacities ]