CriticalPath analysis#
This notebook provides an example of a simulation that takes a number of sub_processes, grouped in a SequentialActivity, that is executed in a WhileActivity while a stop condition is not yet met.
For this example we work with the following sub_processes:
sailing empty
loading
sailing full
unloading
After the simulation is run a gantt chart with the critical path is visualised. Note that the simulation is run with an environment within OpenClSim (which is designed for the purpose of extracting the critical path) and not with simpy.Environment.
0. Import libraries#
import datetime, time
import simpy
import shapely.geometry
import pandas as pd
import openclsim.core as core
import openclsim.model as model
import openclsim.plot as plot
from openclsim.critical_path.dependencies_from_simpy_step import DependenciesFromSimpy, CriticalPathEnvironment
1. Initialise simpy environment#
# setup environment
my_env = CriticalPathEnvironment(initial_time=0)
2. Define object classes#
# create a Site object based on desired mixin classes
Site = type(
"Site",
(
core.Identifiable,
core.Log,
core.Locatable,
core.HasContainer,
core.HasResource,
),
{},
)
# create a TransportProcessingResource object based on desired mixin classes
TransportProcessingResource = type(
"TransportProcessingResource",
(
core.ContainerDependentMovable,
core.Processor,
core.HasResource,
core.LoadingFunction,
core.UnloadingFunction,
core.Identifiable,
core.Log,
),
{},
)
3. Create objects#
3.1. Create site object(s)#
# prepare input data for from_site
location_from_site = shapely.geometry.Point(4.18055556, 52.18664444)
data_from_site = {"env": my_env,
"name": "from_site",
"geometry": location_from_site,
"capacity": 100,
"level": 100
}
# instantiate from_site
from_site = Site(**data_from_site)
# prepare input data for to_site
location_to_site = shapely.geometry.Point(4.25222222, 52.11428333)
data_to_site = {"env": my_env,
"name": "to_site",
"geometry": location_to_site,
"capacity": 100,
"level": 0
}
# instantiate to_site
to_site = Site(**data_to_site)
3.2. Create vessel object(s)#
# prepare input data for vessel_01
data_vessel01 = {"env": my_env,
"name": "vessel01",
"geometry": location_from_site,
"loading_rate": 0.0004,
"unloading_rate": 0.0004,
"capacity": 4,
"compute_v": lambda x: 10
}
# instantiate vessel_01
vessel01 = TransportProcessingResource(**data_vessel01)
3.3 Create activity/activities#
# initialise registry
registry = {}
# create a list of the sub processes
sub_processes = [
model.MoveActivity(
env=my_env,
name="sailing empty",
registry=registry,
mover=vessel01,
destination=from_site,
),
model.ShiftAmountActivity(
env=my_env,
name="loading",
registry=registry,
processor=vessel01,
origin=from_site,
destination=vessel01,
amount=4,
duration=1000,
),
model.MoveActivity(
env=my_env,
name="sailing full",
registry=registry,
mover=vessel01,
destination=to_site,
),
model.ShiftAmountActivity(
env=my_env,
name="unloading",
registry=registry,
processor=vessel01,
origin=vessel01,
destination=to_site,
amount=4,
duration=1000,
),
model.BasicActivity(
env=my_env,
name="basic activity",
registry=registry,
duration=0,
additional_logs=[vessel01],
),
]
# create a 'sequential activity' that is made up of the 'sub_processes'
sequential_activity = model.SequentialActivity(
env=my_env,
name="sequential",
registry=registry,
sub_processes=sub_processes,
)
# create a while activity that executes the 'sequential activity' while the stop condition is not triggered
while_activity = model.WhileActivity(
env=my_env,
name="while",
registry=registry,
sub_processes=[sequential_activity],
condition_event=[{"type": "container", "concept": to_site, "state": "full"}],
)
4. Register processes and run simpy#
# initate the simpy processes defined in the 'while activity' and run simpy
model.register_processes([while_activity])
my_env.run()
5. Inspect results#
5.1 Inspect logs#
plot.get_log_dataframe(vessel01, [while_activity])
Activity | Timestamp | ActivityState | container level | geometry | type | ref | |
---|---|---|---|---|---|---|---|
0 | sailing empty | 1970-01-01 00:00:00.000000 | START | 0.0 | POINT (4.18055556 52.18664444) | NaN | NaN |
1 | sailing empty | 1970-01-01 00:00:00.000000 | STOP | 0.0 | POINT (4.18055556 52.18664444) | NaN | NaN |
2 | loading | 1970-01-01 00:00:00.000000 | START | 0.0 | POINT (4.18055556 52.18664444) | NaN | NaN |
3 | loading | 1970-01-01 00:16:40.000000 | STOP | 4.0 | POINT (4.18055556 52.18664444) | NaN | NaN |
4 | sailing full | 1970-01-01 00:16:40.000000 | START | 4.0 | POINT (4.18055556 52.18664444) | NaN | NaN |
... | ... | ... | ... | ... | ... | ... | ... |
245 | sailing full | 1970-01-02 02:26:38.404972 | STOP | 4.0 | POINT (4.25222222 52.11428333) | NaN | NaN |
246 | unloading | 1970-01-02 02:26:38.404972 | START | 4.0 | POINT (4.25222222 52.11428333) | NaN | NaN |
247 | unloading | 1970-01-02 02:43:18.404972 | STOP | 0.0 | POINT (4.25222222 52.11428333) | NaN | NaN |
248 | basic activity | 1970-01-02 02:43:18.404972 | START | 0.0 | POINT (4.25222222 52.11428333) | additional log | 96f1d46a-a682-44eb-bbbd-5c51c62ea42f |
249 | basic activity | 1970-01-02 02:43:18.404972 | STOP | 0.0 | POINT (4.25222222 52.11428333) | additional log | 96f1d46a-a682-44eb-bbbd-5c51c62ea42f |
250 rows × 7 columns
5.2 Visualise gantt charts#
plot.get_gantt_chart([while_activity])
plot.get_gantt_chart([vessel01, from_site, to_site],id_map=[while_activity])
5.3 Visualise container volume developments#
fig = plot.get_step_chart([vessel01, from_site, to_site])
5.4 Visualise critical path#
Determine critical path with method ‘from simpy’. One can investigate the activities on the critical path through inspection of the dataframe with recorded activities or through a gannt chart.
my_cp_dependencies_from_simpy = DependenciesFromSimpy(env=my_env,
object_list=[vessel01, from_site, to_site],
activity_list=[while_activity])
critical_df = my_cp_dependencies_from_simpy.get_critical_path_df()
print("An overview of recorded activities, with an indication if activity is on critical path (column 'is_critical')")
critical_df
An overview of recorded activities, with an indication if activity is on critical path (column 'is_critical')
ActivityID | Activity | SimulationObject | start_time | end_time | duration | state | cp_activity_id | is_critical | |
---|---|---|---|---|---|---|---|---|---|
1 | f22afd72-13aa-4b38-8d1d-28c93acdc36f | loading | from_site | 1970-01-01 00:00:00.000000 | 1970-01-01 00:16:40.000000 | 0 days 00:16:40 | ACTIVE | 79239fec-36f8-4a3b-9069-67d099c1cabb | True |
2 | f22afd72-13aa-4b38-8d1d-28c93acdc36f | loading | vessel01 | 1970-01-01 00:00:00.000000 | 1970-01-01 00:16:40.000000 | 0 days 00:16:40 | ACTIVE | 79239fec-36f8-4a3b-9069-67d099c1cabb | True |
4 | 49eafd9c-23fe-43c3-8bbb-40923f84d8cd | sailing empty | vessel01 | 1970-01-01 00:00:00.000000 | 1970-01-01 00:00:00.000000 | 0 days 00:00:00 | ACTIVE | 0a37f983-626f-4cd1-9f96-1dbeb601d7eb | False |
11 | 16f6278f-7bb3-4299-b4b2-3742326cb0ed | sailing full | vessel01 | 1970-01-01 00:16:40.000000 | 1970-01-01 00:32:22.824591 | 0 days 00:15:42.824591 | ACTIVE | 056fc0f7-233b-4bf8-89ad-95b1944d09e6 | True |
15 | 8ad97efb-f073-4368-a54b-c4db7144e147 | unloading | to_site | 1970-01-01 00:32:22.824591 | 1970-01-01 00:49:02.824591 | 0 days 00:16:40 | ACTIVE | ea4ee3ce-26ef-4190-bac6-4d1603fcbd27 | True |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
464 | f22afd72-13aa-4b38-8d1d-28c93acdc36f | loading | vessel01 | 1970-01-02 01:54:15.580381 | 1970-01-02 02:10:55.580381 | 0 days 00:16:40 | ACTIVE | a13272f8-88ff-46ea-b60f-9cad1781ab71 | True |
467 | 16f6278f-7bb3-4299-b4b2-3742326cb0ed | sailing full | vessel01 | 1970-01-02 02:10:55.580381 | 1970-01-02 02:26:38.404972 | 0 days 00:15:42.824591 | ACTIVE | e8bb1673-2972-4284-a13b-97191c4baa24 | True |
471 | 8ad97efb-f073-4368-a54b-c4db7144e147 | unloading | to_site | 1970-01-02 02:26:38.404972 | 1970-01-02 02:43:18.404972 | 0 days 00:16:40 | ACTIVE | e077283c-f164-42aa-98f1-a3d925954772 | True |
472 | 8ad97efb-f073-4368-a54b-c4db7144e147 | unloading | vessel01 | 1970-01-02 02:26:38.404972 | 1970-01-02 02:43:18.404972 | 0 days 00:16:40 | ACTIVE | e077283c-f164-42aa-98f1-a3d925954772 | True |
474 | 96f1d46a-a682-44eb-bbbd-5c51c62ea42f | basic activity | vessel01 | 1970-01-02 02:43:18.404972 | 1970-01-02 02:43:18.404972 | 0 days 00:00:00 | ACTIVE | 52936c37-1578-4642-9426-8b2d88476dc8 | False |
175 rows × 9 columns
my_cp_dependencies_from_simpy.make_plotly_gantt_chart()