Input Distributions

In this chapter, the default input distributions are presented. These are automatically seeded when a new database is created. They can be simply overwritten with your use-case specific assumptions.

First, the required modules are imported.

[1]:
import datetime
import itertools

import matplotlib
import matplotlib.pyplot as plt
import seaborn as sns

import conflowgen

Next, an in-memory SQLite database is opened. This is a fresh database without any content. While creating the database, it is automatically seeded with the default values.

[2]:
database_chooser = conflowgen.DatabaseChooser()
database_chooser.create_new_sqlite_database(":memory:")

If that was too fast, you can switch on logging to have a look behind the scenes.

[3]:
conflowgen.setup_logger(
    logging_directory="./data/logger",  # use data subdirectory relative to Jupyter Notebook
    format_string="%(message)s"  # only show log messages, no timestamps etc.
)
Creating log file at ./data/logger/2022-09-14--10-44-43.log
[3]:
<Logger conflowgen (DEBUG)>

Now you can see the same output like in the demo scripts.

[4]:
database_chooser.create_new_sqlite_database(":memory:")
Closing current database connection.
Opening file :memory:
journal_mode: memory
cache_size: -32768
page_size: 4096
foreign_keys: 1
Creating new database at :memory:
Creating all tables...
Seed with default values...

Once the database is set up, we can use the different distribution managers to have a look at the distributions which were automatically seeded.

Container Length Distribution

For each container length, the container length distribution determines its frequency among the containers. The numbers have been determined by the following reasoning:

Note

DEFAULT_CONTAINER_LENGTH_FREQUENCIES = {<ContainerLength.twenty_feet: 20>: 0.4, <ContainerLength.forty_feet: 40>: 0.57, <ContainerLength.forty_five_feet: 45>: 0.029, <ContainerLength.other: -1>: 0.001}

In general, most containerized goods are transported in 20’ and 40’ sea containers. In Germany in August 2021, only 1% of containerized goods (measured in weight) were transported in a container different from these two standard sizes [Statistisches Bundesamt (DESTATIS), 2021]. The same statistics says that approximately 30% of the goods (measured in weight again) are transported in 20’ containers, and 40’ containers make up 67%. For ConFlowGen, however, the fraction in numbers of containers is required instead of the fraction based on weight. In an expert interview it was said that the TEU factor in their case is approximately 1.6 and 45 foot containers made up less than 5%.

The numbers used here are inspired by the reported statistics and the expert interview. They are believed to be a reasonable first assumption if no data is available.

The container length distribution is obtained with the following lines of code:

[5]:
container_length_manager = conflowgen.ContainerLengthDistributionManager()

length_distribution = container_length_manager.get_container_length_distribution()

length_distribution
[5]:
{<ContainerLength.other: -1>: 0.001,
 <ContainerLength.twenty_feet: 20>: 0.4,
 <ContainerLength.forty_feet: 40>: 0.57,
 <ContainerLength.forty_five_feet: 45>: 0.029}

We can see that all the keys are enum values of the enum ContainerLength. For a nicer visualization, we can circumvent that by converting the enum values into strings.

[6]:
length_distribution_with_key_as_str = {
    str(key): value
    for (key, value) in length_distribution.items()
}

length_distribution_with_key_as_str
[6]:
{'other': 0.001, '20 feet': 0.4, '40 feet': 0.57, '45 feet': 0.029}

Now we can also plot the same information as a pie chart.

[7]:
length_distribution_with_key_as_str_without_zeros = {
    key: value
    for (key, value) in length_distribution_with_key_as_str.items()
    if value > 0
}

plt.title("Frequency of container lengths")
plt.pie(
    list(length_distribution_with_key_as_str_without_zeros.values()),
    labels=list(length_distribution_with_key_as_str_without_zeros.keys())
)
plt.gcf().set_size_inches(5, 5)
plt.show()
../_images/notebooks_input_distributions_17_0.svg

More information on setting and getting the distribution can be found at ContainerLengthDistributionManager.

Container Weight Distribution

The container weight of each container is drawn from a distribution. For each container length, a different weight distribution can be provided.

Note

DEFAULT_CONTAINER_WEIGHT_DISTRIBUTION = {<ContainerLength.twenty_feet: 20>: {2: 1, 4: 1, 6: 2, 8: 2.5, 10: 2.5, 12: 3, 14: 3, 16: 3, 18: 2.5, 20: 2.5, 22: 2, 24: 2, 26: 2, 28: 1, 30: 1}, <ContainerLength.forty_feet: 40>: {2: 0, 4: 2, 6: 5, 8: 6, 10: 9, 12: 11, 14: 11, 16: 9, 18: 4, 20: 3, 22: 3, 24: 3, 26: 1, 28: 1, 30: 1}, <ContainerLength.forty_five_feet: 45>: {2: 0, 4: 2, 6: 5, 8: 6, 10: 9, 12: 11, 14: 11, 16: 9, 18: 4, 20: 3, 22: 3, 24: 3, 26: 1, 28: 1, 30: 1}, <ContainerLength.other: -1>: {2: 0, 4: 0, 6: 0, 8: 0, 10: 0, 12: 0, 14: 0, 16: 0, 18: 0, 20: 0, 22: 0, 24: 0, 26: 0, 28: 0, 30: 0}}

The initially seeded weight distributions stem from the cargo profile of the brochure [MACGREGOR, 2016]. The key refers to the weight of the container in metric tonnes. The value describes the relative frequency.

[8]:
container_weight_distribution_manager = conflowgen.ContainerWeightDistributionManager()

weight_distribution = container_weight_distribution_manager.get_container_weight_distribution()

weight_distribution
[8]:
{<ContainerLength.twenty_feet: 20>: {2: 0.03225806451612903,
  4: 0.03225806451612903,
  6: 0.06451612903225806,
  8: 0.08064516129032258,
  10: 0.08064516129032258,
  12: 0.0967741935483871,
  14: 0.0967741935483871,
  16: 0.0967741935483871,
  18: 0.08064516129032258,
  20: 0.08064516129032258,
  22: 0.06451612903225806,
  24: 0.06451612903225806,
  26: 0.06451612903225806,
  28: 0.03225806451612903,
  30: 0.03225806451612903},
 <ContainerLength.forty_feet: 40>: {2: 0.0,
  4: 0.028985507246376812,
  6: 0.07246376811594203,
  8: 0.08695652173913043,
  10: 0.13043478260869565,
  12: 0.15942028985507245,
  14: 0.15942028985507245,
  16: 0.13043478260869565,
  18: 0.057971014492753624,
  20: 0.043478260869565216,
  22: 0.043478260869565216,
  24: 0.043478260869565216,
  26: 0.014492753623188406,
  28: 0.014492753623188406,
  30: 0.014492753623188406},
 <ContainerLength.forty_five_feet: 45>: {2: 0.0,
  4: 0.028985507246376812,
  6: 0.07246376811594203,
  8: 0.08695652173913043,
  10: 0.13043478260869565,
  12: 0.15942028985507245,
  14: 0.15942028985507245,
  16: 0.13043478260869565,
  18: 0.057971014492753624,
  20: 0.043478260869565216,
  22: 0.043478260869565216,
  24: 0.043478260869565216,
  26: 0.014492753623188406,
  28: 0.014492753623188406,
  30: 0.014492753623188406},
 <ContainerLength.other: -1>: {2: 0.06666666666666667,
  4: 0.06666666666666667,
  6: 0.06666666666666667,
  8: 0.06666666666666667,
  10: 0.06666666666666667,
  12: 0.06666666666666667,
  14: 0.06666666666666667,
  16: 0.06666666666666667,
  18: 0.06666666666666667,
  20: 0.06666666666666667,
  22: 0.06666666666666667,
  24: 0.06666666666666667,
  26: 0.06666666666666667,
  28: 0.06666666666666667,
  30: 0.06666666666666667}}

By visualizing the previous distribution with matplotlib, it is easier to make sense of it.

[9]:
fig, axes = plt.subplots(nrows=4, sharex=True, sharey=True, figsize=(5, 12))

for ax, container_length in zip(axes, list(conflowgen.ContainerLength)):
    x, y = zip(*weight_distribution[container_length].items())
    ax.title.set_text(str(container_length))
    ax.bar(x, [i * 100 for i in y])
    ax.set_ylabel("Share (in percentage)")

plt.xlabel("Weight (in metric tonnes)")
plt.show()
../_images/notebooks_input_distributions_23_0.svg

The container weight distributions can only be overwritten all at once. The values are automatically normalized by default.

[10]:
container_weight_distribution_manager.set_container_weight_distribution(
    {
        conflowgen.ContainerLength.twenty_feet: {
            10: 20,
            20: 50,
            30: 30
        },
        conflowgen.ContainerLength.forty_feet: {
            10: 15,
            20: 50,
            30: 35
        },
        conflowgen.ContainerLength.forty_five_feet: {
            10: 10,
            20: 5,
            30: 85
        },
        conflowgen.ContainerLength.other: {
            10: 1,
            20: 1,
            30: 1
        }
    }
)
Sum of fractions was not 1 for '20 feet' and was automatically normalized.
Sum of fractions was not 1 for '40 feet' and was automatically normalized.
Sum of fractions was not 1 for '45 feet' and was automatically normalized.
Sum of fractions was not 1 for 'other' and was automatically normalized.

From now on, ConFlowGen uses the new container weight distribution:

[11]:
container_weight_distribution_manager.get_container_weight_distribution()
[11]:
{<ContainerLength.twenty_feet: 20>: {10: 0.2, 20: 0.5, 30: 0.3},
 <ContainerLength.forty_feet: 40>: {10: 0.15, 20: 0.5, 30: 0.35},
 <ContainerLength.forty_five_feet: 45>: {10: 0.1, 20: 0.05, 30: 0.85},
 <ContainerLength.other: -1>: {10: 0.3333333333333333,
  20: 0.3333333333333333,
  30: 0.3333333333333333}}

More information on setting and getting the distribution can be found at ContainerWeightDistributionManager.

Container Storage Requirement Distribution

The storage requirement of each container is drawn from a distribution. For each container length, a different storage requirement distribution can be provided.

Note

DEFAULT_STORAGE_REQUIREMENT_DISTRIBUTION = {<ContainerLength.twenty_feet: 20>: {<StorageRequirement.standard: 'standard'>: 0.7290000000000001, <StorageRequirement.empty: 'empty'>: 0.12, <StorageRequirement.reefer: 'reefer'>: 0.07, <StorageRequirement.dangerous_goods: 'dangerous_goods'>: 0.08100000000000002}, <ContainerLength.forty_feet: 40>: {<StorageRequirement.standard: 'standard'>: 0.7290000000000001, <StorageRequirement.empty: 'empty'>: 0.12, <StorageRequirement.reefer: 'reefer'>: 0.07, <StorageRequirement.dangerous_goods: 'dangerous_goods'>: 0.08100000000000002}, <ContainerLength.forty_five_feet: 45>: {<StorageRequirement.standard: 'standard'>: 0.7290000000000001, <StorageRequirement.empty: 'empty'>: 0.12, <StorageRequirement.reefer: 'reefer'>: 0.07, <StorageRequirement.dangerous_goods: 'dangerous_goods'>: 0.08100000000000002}, <ContainerLength.other: -1>: {<StorageRequirement.standard: 'standard'>: 0.7290000000000001, <StorageRequirement.empty: 'empty'>: 0.12, <StorageRequirement.reefer: 'reefer'>: 0.07, <StorageRequirement.dangerous_goods: 'dangerous_goods'>: 0.08100000000000002}}

Containers come with different storage requirements. The given distribution is estimated based on the combination of several sources. Currently, no differentiation between the different container lengths exist.

The container storage requirement distribution is obtained with the following lines of code:

[12]:
container_storage_manager = conflowgen.ContainerStorageRequirementDistributionManager()

storage_requirement_distribution = container_storage_manager.get_storage_requirement_distribution()

storage_requirement_distribution
[12]:
{<ContainerLength.twenty_feet: 20>: {<StorageRequirement.empty: 'empty'>: 0.12,
  <StorageRequirement.standard: 'standard'>: 0.7290000000000001,
  <StorageRequirement.reefer: 'reefer'>: 0.07,
  <StorageRequirement.dangerous_goods: 'dangerous_goods'>: 0.08100000000000002},
 <ContainerLength.forty_feet: 40>: {<StorageRequirement.empty: 'empty'>: 0.12,
  <StorageRequirement.standard: 'standard'>: 0.7290000000000001,
  <StorageRequirement.reefer: 'reefer'>: 0.07,
  <StorageRequirement.dangerous_goods: 'dangerous_goods'>: 0.08100000000000002},
 <ContainerLength.forty_five_feet: 45>: {<StorageRequirement.empty: 'empty'>: 0.12,
  <StorageRequirement.standard: 'standard'>: 0.7290000000000001,
  <StorageRequirement.reefer: 'reefer'>: 0.07,
  <StorageRequirement.dangerous_goods: 'dangerous_goods'>: 0.08100000000000002},
 <ContainerLength.other: -1>: {<StorageRequirement.empty: 'empty'>: 0.12,
  <StorageRequirement.standard: 'standard'>: 0.7290000000000001,
  <StorageRequirement.reefer: 'reefer'>: 0.07,
  <StorageRequirement.dangerous_goods: 'dangerous_goods'>: 0.08100000000000002}}

This can be visualized e.g. with the help of one pie chart for each container length.

[13]:
fig, axes = plt.subplots(nrows=2, ncols=2, figsize=(8, 8))

axes = list(itertools.chain(*axes))

for ax, container_length in zip(axes, list(conflowgen.ContainerLength)):
    keys, values = zip(*storage_requirement_distribution[container_length].items())
    labels = list(map(lambda x: str(x).replace("_", "\n"), keys))
    ax.title.set_text(str(container_length))
    ax.pie(
        [i * 100 for i in values],
        labels=labels,
        autopct='%1.0f%%',
        pctdistance=0.7,
        labeldistance=1.18,
        colors=sns.color_palette('pastel', 4),
        startangle=45
    )

plt.tight_layout()
plt.show()
../_images/notebooks_input_distributions_35_0.svg

The container storage distributions can only be overwritten all at once. The values are automatically normalized by default.

[14]:
container_storage_manager.set_storage_requirement_distribution(
    {
        conflowgen.ContainerLength.twenty_feet: {
            conflowgen.StorageRequirement.empty: 0.3,
            conflowgen.StorageRequirement.standard: 0.5,
            conflowgen.StorageRequirement.reefer: 0.1,
            conflowgen.StorageRequirement.dangerous_goods: 0.1
        },
        conflowgen.ContainerLength.forty_feet: {
            conflowgen.StorageRequirement.empty: 0.2,
            conflowgen.StorageRequirement.standard: 0.45,
            conflowgen.StorageRequirement.reefer: 0.2,
            conflowgen.StorageRequirement.dangerous_goods: 0.15
        },
        conflowgen.ContainerLength.forty_five_feet: {
            conflowgen.StorageRequirement.empty: 0.2,
            conflowgen.StorageRequirement.standard: 0.7,
            conflowgen.StorageRequirement.reefer: 0.05,
            conflowgen.StorageRequirement.dangerous_goods: 0.05
        },
        conflowgen.ContainerLength.other: {
            conflowgen.StorageRequirement.empty: 0.25,
            conflowgen.StorageRequirement.standard: 0.4,
            conflowgen.StorageRequirement.reefer: 0.25,
            conflowgen.StorageRequirement.dangerous_goods: 0.1
        }
    }
)

From now on, ConFlowGen uses the new distribution.

[15]:
container_storage_manager.get_storage_requirement_distribution()
[15]:
{<ContainerLength.twenty_feet: 20>: {<StorageRequirement.empty: 'empty'>: 0.3,
  <StorageRequirement.standard: 'standard'>: 0.5,
  <StorageRequirement.reefer: 'reefer'>: 0.1,
  <StorageRequirement.dangerous_goods: 'dangerous_goods'>: 0.1},
 <ContainerLength.forty_feet: 40>: {<StorageRequirement.empty: 'empty'>: 0.2,
  <StorageRequirement.standard: 'standard'>: 0.45,
  <StorageRequirement.reefer: 'reefer'>: 0.2,
  <StorageRequirement.dangerous_goods: 'dangerous_goods'>: 0.15},
 <ContainerLength.forty_five_feet: 45>: {<StorageRequirement.empty: 'empty'>: 0.2,
  <StorageRequirement.standard: 'standard'>: 0.7,
  <StorageRequirement.reefer: 'reefer'>: 0.05,
  <StorageRequirement.dangerous_goods: 'dangerous_goods'>: 0.05},
 <ContainerLength.other: -1>: {<StorageRequirement.empty: 'empty'>: 0.25,
  <StorageRequirement.standard: 'standard'>: 0.4,
  <StorageRequirement.reefer: 'reefer'>: 0.25,
  <StorageRequirement.dangerous_goods: 'dangerous_goods'>: 0.1}}

More information on setting and getting the distribution can be found at ContainerStorageRequirementDistributionManager.

Mode of Transport Distribution

The mode of transport for each container is drawn from a distribution.

Note

DEFAULT_MODE_OF_TRANSPORT_DISTRIBUTION = {<ModeOfTransport.truck: 'truck'>: {<ModeOfTransport.truck: 'truck'>: 0, <ModeOfTransport.train: 'train'>: 0, <ModeOfTransport.barge: 'barge'>: 0, <ModeOfTransport.feeder: 'feeder'>: 0.29814814814814816, <ModeOfTransport.deep_sea_vessel: 'deep_sea_vessel'>: 0.7018518518518518}, <ModeOfTransport.train: 'train'>: {<ModeOfTransport.truck: 'truck'>: 0, <ModeOfTransport.train: 'train'>: 0, <ModeOfTransport.barge: 'barge'>: 0, <ModeOfTransport.feeder: 'feeder'>: 0.29814814814814816, <ModeOfTransport.deep_sea_vessel: 'deep_sea_vessel'>: 0.7018518518518518}, <ModeOfTransport.barge: 'barge'>: {<ModeOfTransport.truck: 'truck'>: 0, <ModeOfTransport.train: 'train'>: 0, <ModeOfTransport.barge: 'barge'>: 0, <ModeOfTransport.feeder: 'feeder'>: 0.14814814814814817, <ModeOfTransport.deep_sea_vessel: 'deep_sea_vessel'>: 0.8518518518518519}, <ModeOfTransport.feeder: 'feeder'>: {<ModeOfTransport.truck: 'truck'>: 0.14874074074074073, <ModeOfTransport.train: 'train'>: 0.13925925925925925, <ModeOfTransport.barge: 'barge'>: 0.0008296296296296296, <ModeOfTransport.feeder: 'feeder'>: 0, <ModeOfTransport.deep_sea_vessel: 'deep_sea_vessel'>: 0.7037037037037036}, <ModeOfTransport.deep_sea_vessel: 'deep_sea_vessel'>: {<ModeOfTransport.truck: 'truck'>: 0.3552615384615384, <ModeOfTransport.train: 'train'>: 0.3326153846153846, <ModeOfTransport.barge: 'barge'>: 0.0019815384615384612, <ModeOfTransport.feeder: 'feeder'>: 0.29230769230769227, <ModeOfTransport.deep_sea_vessel: 'deep_sea_vessel'>: 0}}

This mode of transport distribution is based on the report [Institut für Seeverkehrswirtschaft und Logistik, 2015]. The exact data for transshipment and hinterland share is taken from page 22, Figure 12 “Containerumschlag des Hafens Hamburg in TEU / Marktsegment 2013”. The modal split of the hinterland is updated based on the figures presented by Hafen Hamburg [2021]. After those adaptions, still there were several imbalances. Thus, some traffic was shifted from deep sea vessels to feeders by adding/subtracting some constants. In summary, this is an educated guess based on several sources.

The mode of transport distribution is obtained by the following code:

[16]:
mode_of_transport = conflowgen.ModeOfTransportDistributionManager()

mode_of_transport_distribution = mode_of_transport.get_mode_of_transport_distribution()

mode_of_transport_distribution
[16]:
{<ModeOfTransport.truck: 'truck'>: {<ModeOfTransport.truck: 'truck'>: 0,
  <ModeOfTransport.train: 'train'>: 0,
  <ModeOfTransport.feeder: 'feeder'>: 0.29814814814814816,
  <ModeOfTransport.deep_sea_vessel: 'deep_sea_vessel'>: 0.7018518518518518,
  <ModeOfTransport.barge: 'barge'>: 0},
 <ModeOfTransport.train: 'train'>: {<ModeOfTransport.truck: 'truck'>: 0,
  <ModeOfTransport.train: 'train'>: 0,
  <ModeOfTransport.feeder: 'feeder'>: 0.29814814814814816,
  <ModeOfTransport.deep_sea_vessel: 'deep_sea_vessel'>: 0.7018518518518518,
  <ModeOfTransport.barge: 'barge'>: 0},
 <ModeOfTransport.feeder: 'feeder'>: {<ModeOfTransport.truck: 'truck'>: 0.14985969311600694,
  <ModeOfTransport.train: 'train'>: 0.14030688399307423,
  <ModeOfTransport.feeder: 'feeder'>: 0,
  <ModeOfTransport.deep_sea_vessel: 'deep_sea_vessel'>: 0.7089975520926622,
  <ModeOfTransport.barge: 'barge'>: 0.0008358707982566125},
 <ModeOfTransport.deep_sea_vessel: 'deep_sea_vessel'>: {<ModeOfTransport.truck: 'truck'>: 0.3617122592448716,
  <ModeOfTransport.train: 'train'>: 0.33865490407388377,
  <ModeOfTransport.feeder: 'feeder'>: 0.2976153181037831,
  <ModeOfTransport.deep_sea_vessel: 'deep_sea_vessel'>: 0,
  <ModeOfTransport.barge: 'barge'>: 0.0020175185774614353},
 <ModeOfTransport.barge: 'barge'>: {<ModeOfTransport.truck: 'truck'>: 0,
  <ModeOfTransport.train: 'train'>: 0,
  <ModeOfTransport.feeder: 'feeder'>: 0.14814814814814817,
  <ModeOfTransport.deep_sea_vessel: 'deep_sea_vessel'>: 0.8518518518518519,
  <ModeOfTransport.barge: 'barge'>: 0}}

The mode of transport distributions can only be overwritten all at once. The values are automatically normalized by default.

[17]:
mode_of_transport.set_mode_of_transport_distribution(
    {
        conflowgen.ModeOfTransport.feeder: {
            conflowgen.ModeOfTransport.train: 0.2,
            conflowgen.ModeOfTransport.truck: 0.1,
            conflowgen.ModeOfTransport.barge: 0.1,
            conflowgen.ModeOfTransport.feeder: 0.4,
            conflowgen.ModeOfTransport.deep_sea_vessel: 0.2
        },
        conflowgen.ModeOfTransport.truck: {
            conflowgen.ModeOfTransport.train: 0.15,
            conflowgen.ModeOfTransport.truck: 0.45,
            conflowgen.ModeOfTransport.barge: 0.1,
            conflowgen.ModeOfTransport.feeder: 0.2,
            conflowgen.ModeOfTransport.deep_sea_vessel: 0.1
        },
        conflowgen.ModeOfTransport.barge: {
            conflowgen.ModeOfTransport.train: 0.2,
            conflowgen.ModeOfTransport.truck: 0.15,
            conflowgen.ModeOfTransport.barge: 0.25,
            conflowgen.ModeOfTransport.feeder: 0.1,
            conflowgen.ModeOfTransport.deep_sea_vessel: 0.3
        },
        conflowgen.ModeOfTransport.deep_sea_vessel: {
            conflowgen.ModeOfTransport.train: 0.25,
            conflowgen.ModeOfTransport.truck: 0.1,
            conflowgen.ModeOfTransport.barge: 0.2,
            conflowgen.ModeOfTransport.feeder: 0.15,
            conflowgen.ModeOfTransport.deep_sea_vessel: 0.3
        },
        conflowgen.ModeOfTransport.train: {
            conflowgen.ModeOfTransport.train: 0.3,
            conflowgen.ModeOfTransport.truck: 0.1,
            conflowgen.ModeOfTransport.barge: 0.15,
            conflowgen.ModeOfTransport.feeder: 0.2,
            conflowgen.ModeOfTransport.deep_sea_vessel: 0.25
        }
    }
)

From now on, ConFlowGen uses the new distribution.

[18]:
mode_of_transport.get_mode_of_transport_distribution()
[18]:
{<ModeOfTransport.truck: 'truck'>: {<ModeOfTransport.truck: 'truck'>: 0.45,
  <ModeOfTransport.train: 'train'>: 0.15,
  <ModeOfTransport.feeder: 'feeder'>: 0.2,
  <ModeOfTransport.deep_sea_vessel: 'deep_sea_vessel'>: 0.1,
  <ModeOfTransport.barge: 'barge'>: 0.1},
 <ModeOfTransport.train: 'train'>: {<ModeOfTransport.truck: 'truck'>: 0.1,
  <ModeOfTransport.train: 'train'>: 0.3,
  <ModeOfTransport.feeder: 'feeder'>: 0.2,
  <ModeOfTransport.deep_sea_vessel: 'deep_sea_vessel'>: 0.25,
  <ModeOfTransport.barge: 'barge'>: 0.15},
 <ModeOfTransport.feeder: 'feeder'>: {<ModeOfTransport.truck: 'truck'>: 0.09999999999999998,
  <ModeOfTransport.train: 'train'>: 0.19999999999999996,
  <ModeOfTransport.feeder: 'feeder'>: 0.3999999999999999,
  <ModeOfTransport.deep_sea_vessel: 'deep_sea_vessel'>: 0.19999999999999996,
  <ModeOfTransport.barge: 'barge'>: 0.09999999999999998},
 <ModeOfTransport.deep_sea_vessel: 'deep_sea_vessel'>: {<ModeOfTransport.truck: 'truck'>: 0.1,
  <ModeOfTransport.train: 'train'>: 0.25,
  <ModeOfTransport.feeder: 'feeder'>: 0.15,
  <ModeOfTransport.deep_sea_vessel: 'deep_sea_vessel'>: 0.3,
  <ModeOfTransport.barge: 'barge'>: 0.2},
 <ModeOfTransport.barge: 'barge'>: {<ModeOfTransport.truck: 'truck'>: 0.15,
  <ModeOfTransport.train: 'train'>: 0.2,
  <ModeOfTransport.feeder: 'feeder'>: 0.1,
  <ModeOfTransport.deep_sea_vessel: 'deep_sea_vessel'>: 0.3,
  <ModeOfTransport.barge: 'barge'>: 0.25}}

More information on setting and getting the distribution can be found at ModeOfTransportDistributionManager.

Truck Arrival Distribution Manager

Each truck arrival time is drawn from a distribution.

Note

DEFAULT_TRUCK_ARRIVAL_DISTRIBUTION_WITH_NO_ARRIVAL_MANAGEMENT = {0: 0.0, 1: 0.0, 2: 0.0, 3: 0.0, 4: 0.0, 5: 0.0039591265543534575, 6: 0.008280755354708402, 7: 0.00787052138708076, 8: 0.009048448164603814, 9: 0.010653252222483504, 10: 0.012752141622641803, 11: 0.016642037255734387, 12: 0.014028517880762, 13: 0.014804115031537253, 14: 0.014974413128949352, 15: 0.011139325718994135, 16: 0.013892795598075644, 17: 0.01082340227148447, 18: 0.008328057746798652, 19: 0.006987426702627708, 20: 0.005148702946956847, 21: 0.0030022110241690898, 22: 0.0022556664886468924, 23: 0.002490824815783658, 24: 0.001903829363512033, 25: 0.0021963463393818504, 26: 0.001702371138626582, 27: 0.0021438383478597847, 28: 0.0024202228363111615, 29: 0.006458109051981418, 30: 0.009296920847765565, 31: 0.008129901930327036, 32: 0.009348584294496615, 33: 0.011340930095712323, 34: 0.013698448606867216, 35: 0.01296799663104594, 36: 0.015331193639106963, 37: 0.014188986240397503, 38: 0.014878231656167027, 39: 0.01218616653188358, 40: 0.012107579394020204, 41: 0.010917000115475164, 42: 0.006806732487834122, 43: 0.005802918750649381, 44: 0.005287802279192979, 45: 0.0028202830127811215, 46: 0.0019358005313836828, 47: 0.0024196460473237236, 48: 0.0016307576755443523, 49: 0.0019988666796929904, 50: 0.001446034417884346, 51: 0.0010097489273788896, 52: 0.0022229861377374384, 53: 0.008228976109664983, 54: 0.00916729394725238, 55: 0.008981193048564363, 56: 0.010437595120044508, 57: 0.011883447250428468, 58: 0.013126241314098189, 59: 0.0140232137102564, 60: 0.014067510063763042, 61: 0.017925057408950704, 62: 0.014893617277832918, 63: 0.01301145426124103, 64: 0.012079362990869175, 65: 0.010112961782918234, 66: 0.00893673181616467, 67: 0.006631710275002562, 68: 0.004326674554006004, 69: 0.004305598082248182, 70: 0.0022903162137174965, 71: 0.0024661555911701296, 72: 0.0011415664927662006, 73: 0.0012494109397148158, 74: 0.0009989509275061823, 75: 0.0009419532259761962, 76: 0.002040252335905318, 77: 0.00518431625514197, 78: 0.009913000508486947, 79: 0.010654141394182583, 80: 0.010344655620812727, 81: 0.012472178423578372, 82: 0.015253769000857457, 83: 0.015313545656682602, 84: 0.01971921057376204, 85: 0.016488565599922105, 86: 0.016894274684674377, 87: 0.015499123208186931, 88: 0.01478237177250456, 89: 0.012150479118805851, 90: 0.008135216144988145, 91: 0.006333340451456769, 92: 0.006095849295750999, 93: 0.004708883365054937, 94: 0.003413326087863949, 95: 0.0017118289895981984, 96: 0.0026912758548089605, 97: 0.0021584624941145677, 98: 0.0023228922170533146, 99: 0.001604168692757123, 100: 0.0027305554397402476, 101: 0.0065523938632102915, 102: 0.009520380832912196, 103: 0.010997001773196237, 104: 0.010602136875550094, 105: 0.015899660970804596, 106: 0.018083220148664984, 107: 0.0163816471763427, 108: 0.01629007302430533, 109: 0.019168920074881534, 110: 0.01646589595887871, 111: 0.013656904790633789, 112: 0.012617169136636602, 113: 0.009685606800402495, 114: 0.009069337128450136, 115: 0.004422493262915178, 116: 0.0042658850465993456, 117: 0.0030436628208826318, 118: 0.0016924428501923685, 119: 0.002152265219068244, 120: 0.0028091995053135693, 121: 0.0022128380816916287, 122: 0.0020158483718963533, 123: 0.0010395871009478725, 124: 0.0009474696390102265, 125: 0.0011628071003245448, 126: 0.001418797422137764, 127: 0.0016522620284370162, 128: 0.0015376248047583672, 129: 0.0014253278743416424, 130: 0.0007202777097896012, 131: 0.0005074102872076632, 132: 0.0004608008040356385, 133: 0.0, 134: 0.0, 135: 0.0, 136: 0.0, 137: 0.0, 138: 0.0, 139: 0.0, 140: 0.0, 141: 0.0, 142: 0.0, 143: 0.0, 144: 0, 145: 0, 146: 0, 147: 0, 148: 0, 149: 0, 150: 0, 151: 0, 152: 0, 153: 0, 154: 0, 155: 0, 156: 0, 157: 0, 158: 0, 159: 0, 160: 0, 161: 0, 162: 0, 163: 0, 164: 0, 165: 0, 166: 0, 167: 0}

This distribution assigns each hour of the week to the fraction of trucks that arrive during this time window. The distribution is based on real data of a project that took place approximately between 2013 and 2017. To ensure confidentiality, the distribution has been slightly distorted.

Truck arrival distribution is obtained by the following code:

[19]:
truck_arrival_distribution_manager = conflowgen.TruckArrivalDistributionManager()

truck_arrival_distribution = truck_arrival_distribution_manager.get_truck_arrival_distribution()

truck_arrival_distribution
[19]:
{0: 0.0,
 1: 0.0,
 2: 0.0,
 3: 0.0,
 4: 0.0,
 5: 0.0039591265543534575,
 6: 0.008280755354708402,
 7: 0.00787052138708076,
 8: 0.009048448164603814,
 9: 0.010653252222483504,
 10: 0.012752141622641803,
 11: 0.016642037255734387,
 12: 0.014028517880762,
 13: 0.014804115031537253,
 14: 0.014974413128949352,
 15: 0.011139325718994135,
 16: 0.013892795598075644,
 17: 0.01082340227148447,
 18: 0.008328057746798652,
 19: 0.006987426702627708,
 20: 0.005148702946956847,
 21: 0.0030022110241690898,
 22: 0.0022556664886468924,
 23: 0.002490824815783658,
 24: 0.001903829363512033,
 25: 0.0021963463393818504,
 26: 0.001702371138626582,
 27: 0.0021438383478597847,
 28: 0.0024202228363111615,
 29: 0.006458109051981418,
 30: 0.009296920847765565,
 31: 0.008129901930327036,
 32: 0.009348584294496615,
 33: 0.011340930095712323,
 34: 0.013698448606867216,
 35: 0.01296799663104594,
 36: 0.015331193639106963,
 37: 0.014188986240397503,
 38: 0.014878231656167027,
 39: 0.01218616653188358,
 40: 0.012107579394020204,
 41: 0.010917000115475164,
 42: 0.006806732487834122,
 43: 0.005802918750649381,
 44: 0.005287802279192979,
 45: 0.0028202830127811215,
 46: 0.0019358005313836828,
 47: 0.0024196460473237236,
 48: 0.0016307576755443523,
 49: 0.0019988666796929904,
 50: 0.001446034417884346,
 51: 0.0010097489273788896,
 52: 0.0022229861377374384,
 53: 0.008228976109664983,
 54: 0.00916729394725238,
 55: 0.008981193048564363,
 56: 0.010437595120044508,
 57: 0.011883447250428468,
 58: 0.013126241314098189,
 59: 0.0140232137102564,
 60: 0.014067510063763042,
 61: 0.017925057408950704,
 62: 0.014893617277832918,
 63: 0.01301145426124103,
 64: 0.012079362990869175,
 65: 0.010112961782918234,
 66: 0.00893673181616467,
 67: 0.006631710275002562,
 68: 0.004326674554006004,
 69: 0.004305598082248182,
 70: 0.0022903162137174965,
 71: 0.0024661555911701296,
 72: 0.0011415664927662006,
 73: 0.0012494109397148158,
 74: 0.0009989509275061823,
 75: 0.0009419532259761962,
 76: 0.002040252335905318,
 77: 0.00518431625514197,
 78: 0.009913000508486947,
 79: 0.010654141394182583,
 80: 0.010344655620812727,
 81: 0.012472178423578372,
 82: 0.015253769000857457,
 83: 0.015313545656682602,
 84: 0.01971921057376204,
 85: 0.016488565599922105,
 86: 0.016894274684674377,
 87: 0.015499123208186931,
 88: 0.01478237177250456,
 89: 0.012150479118805851,
 90: 0.008135216144988145,
 91: 0.006333340451456769,
 92: 0.006095849295750999,
 93: 0.004708883365054937,
 94: 0.003413326087863949,
 95: 0.0017118289895981984,
 96: 0.0026912758548089605,
 97: 0.0021584624941145677,
 98: 0.0023228922170533146,
 99: 0.001604168692757123,
 100: 0.0027305554397402476,
 101: 0.0065523938632102915,
 102: 0.009520380832912196,
 103: 0.010997001773196237,
 104: 0.010602136875550094,
 105: 0.015899660970804596,
 106: 0.018083220148664984,
 107: 0.0163816471763427,
 108: 0.01629007302430533,
 109: 0.019168920074881534,
 110: 0.01646589595887871,
 111: 0.013656904790633789,
 112: 0.012617169136636602,
 113: 0.009685606800402495,
 114: 0.009069337128450136,
 115: 0.004422493262915178,
 116: 0.0042658850465993456,
 117: 0.0030436628208826318,
 118: 0.0016924428501923685,
 119: 0.002152265219068244,
 120: 0.0028091995053135693,
 121: 0.0022128380816916287,
 122: 0.0020158483718963533,
 123: 0.0010395871009478725,
 124: 0.0009474696390102265,
 125: 0.0011628071003245448,
 126: 0.001418797422137764,
 127: 0.0016522620284370162,
 128: 0.0015376248047583672,
 129: 0.0014253278743416424,
 130: 0.0007202777097896012,
 131: 0.0005074102872076632,
 132: 0.0004608008040356385,
 133: 0.0,
 134: 0.0,
 135: 0.0,
 136: 0.0,
 137: 0.0,
 138: 0.0,
 139: 0.0,
 140: 0.0,
 141: 0.0,
 142: 0.0,
 143: 0.0,
 144: 0.0,
 145: 0.0,
 146: 0.0,
 147: 0.0,
 148: 0.0,
 149: 0.0,
 150: 0.0,
 151: 0.0,
 152: 0.0,
 153: 0.0,
 154: 0.0,
 155: 0.0,
 156: 0.0,
 157: 0.0,
 158: 0.0,
 159: 0.0,
 160: 0.0,
 161: 0.0,
 162: 0.0,
 163: 0.0,
 164: 0.0,
 165: 0.0,
 166: 0.0,
 167: 0.0}

With a few lines of matplotlib code, the truck arrival pattern is visualized.

[20]:
hour_in_week, fraction = zip(*list(sorted(truck_arrival_distribution.items())))
weekday_in_week = [x / 24 + 1 for x in hour_in_week]
percentage = [x * 100 for x in fraction]

fig, ax = plt.subplots(figsize=(15, 3))
plt.plot(weekday_in_week, percentage)
plt.xlim([1, 7])  # plot from Monday to Sunday
ax.xaxis.grid(True, which='minor', color='lightgray')  # every hour
ax.xaxis.grid(True, which='major', color='k')  # every day
ax.xaxis.set_minor_locator(matplotlib.ticker.MultipleLocator(1 / 24))  # every hour

plt.title("Truck arrival distribution")
ax.set_xticks([i for i in range(1, 8)])  # every day
ax.set_xticklabels(["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"])
plt.xlabel("Week day")
plt.ylabel("Share (as percentage overall)")

plt.show()
../_images/notebooks_input_distributions_57_0.svg

A second default distribution exists. You need to provide the corresponding keyword when creating the new SQLite database to use it.

Note

DEFAULT_TRUCK_ARRIVAL_DISTRIBUTION_WITH_SLOT_BOOKING = {0: 0.0, 1: 0.0, 2: 0.0, 3: 0.001568627450980392, 4: 0.001568627450980392, 5: 0.001568627450980392, 6: 0.009411764705882352, 7: 0.011764705882352941, 8: 0.013333333333333334, 9: 0.01411764705882353, 10: 0.014509803921568627, 11: 0.014901960784313726, 12: 0.014509803921568627, 13: 0.01411764705882353, 14: 0.014901960784313726, 15: 0.01568627450980392, 16: 0.01568627450980392, 17: 0.011764705882352941, 18: 0.00784313725490196, 19: 0.005490196078431373, 20: 0.004705882352941176, 21: 0.002352941176470588, 22: 0.00196078431372549, 23: 0.001568627450980392, 24: 0.001176470588235294, 25: 0.001176470588235294, 26: 0.001568627450980392, 27: 0.001568627450980392, 28: 0.001568627450980392, 29: 0.001568627450980392, 30: 0.009411764705882352, 31: 0.011764705882352941, 32: 0.013333333333333334, 33: 0.01411764705882353, 34: 0.014509803921568627, 35: 0.014901960784313726, 36: 0.014509803921568627, 37: 0.01411764705882353, 38: 0.014901960784313726, 39: 0.01568627450980392, 40: 0.01568627450980392, 41: 0.011764705882352941, 42: 0.00784313725490196, 43: 0.005490196078431373, 44: 0.004705882352941176, 45: 0.002352941176470588, 46: 0.00196078431372549, 47: 0.001568627450980392, 48: 0.001176470588235294, 49: 0.001176470588235294, 50: 0.001568627450980392, 51: 0.001568627450980392, 52: 0.001568627450980392, 53: 0.001568627450980392, 54: 0.009411764705882352, 55: 0.011764705882352941, 56: 0.013333333333333334, 57: 0.01411764705882353, 58: 0.014509803921568627, 59: 0.014901960784313726, 60: 0.014509803921568627, 61: 0.01411764705882353, 62: 0.014901960784313726, 63: 0.01568627450980392, 64: 0.01568627450980392, 65: 0.011764705882352941, 66: 0.00784313725490196, 67: 0.005490196078431373, 68: 0.004705882352941176, 69: 0.002352941176470588, 70: 0.00196078431372549, 71: 0.001568627450980392, 72: 0.001176470588235294, 73: 0.001176470588235294, 74: 0.001568627450980392, 75: 0.001568627450980392, 76: 0.001568627450980392, 77: 0.001568627450980392, 78: 0.009411764705882352, 79: 0.011764705882352941, 80: 0.013333333333333334, 81: 0.01411764705882353, 82: 0.014509803921568627, 83: 0.014901960784313726, 84: 0.014509803921568627, 85: 0.01411764705882353, 86: 0.014901960784313726, 87: 0.01568627450980392, 88: 0.01568627450980392, 89: 0.011764705882352941, 90: 0.00784313725490196, 91: 0.005490196078431373, 92: 0.004705882352941176, 93: 0.002352941176470588, 94: 0.00196078431372549, 95: 0.001568627450980392, 96: 0.001176470588235294, 97: 0.001176470588235294, 98: 0.001568627450980392, 99: 0.001568627450980392, 100: 0.001568627450980392, 101: 0.001568627450980392, 102: 0.009411764705882352, 103: 0.011764705882352941, 104: 0.013333333333333334, 105: 0.01411764705882353, 106: 0.014509803921568627, 107: 0.014901960784313726, 108: 0.014509803921568627, 109: 0.01411764705882353, 110: 0.014901960784313726, 111: 0.01568627450980392, 112: 0.01568627450980392, 113: 0.011764705882352941, 114: 0.00784313725490196, 115: 0.005490196078431373, 116: 0.004705882352941176, 117: 0.002352941176470588, 118: 0.00196078431372549, 119: 0.001568627450980392, 120: 0.001176470588235294, 121: 0.001176470588235294, 122: 0.001568627450980392, 123: 0.001568627450980392, 124: 0.001568627450980392, 125: 0.001568627450980392, 126: 0.001568627450980392, 127: 0.001568627450980392, 128: 0.001568627450980392, 129: 0.001568627450980392, 130: 0.001568627450980392, 131: 0.001176470588235294, 132: 0.0, 133: 0.0, 134: 0.0, 135: 0.0, 136: 0.0, 137: 0.0, 138: 0.0, 139: 0.0, 140: 0.0, 141: 0.0, 142: 0.0, 143: 0.0, 144: 0.0, 145: 0.0, 146: 0.0, 147: 0.0, 148: 0.0, 149: 0.0, 150: 0.0, 151: 0.0, 152: 0.0, 153: 0.0, 154: 0.0, 155: 0.0, 156: 0.0, 157: 0.0, 158: 0.0, 159: 0.0, 160: 0.0, 161: 0.0, 162: 0.0, 163: 0.0, 164: 0.0, 165: 0.0, 166: 0.0, 167: 0.0}

This distribution assigns each hour of the week to the fraction of trucks that arrive during this time window. The distribution is based on an interview with the operational staff of a container terminal. To ensure confidentiality, the distribution has been slightly distorted.

Thee pattern looks slightly different - the peaks during lunch time are smoothened.

[21]:
database_chooser.close_current_connection()

database_chooser.create_new_sqlite_database(
    ":memory:",
    assume_tas=True
)

truck_arrival_distribution = truck_arrival_distribution_manager.get_truck_arrival_distribution()

hour_in_week, fraction = zip(*list(sorted(truck_arrival_distribution.items())))
weekday_in_week = [x / 24 + 1 for x in hour_in_week]
percentage = [x * 100 for x in fraction]

fig, ax = plt.subplots(figsize=(15, 3))
plt.plot(weekday_in_week, percentage)
plt.xlim([1, 7])  # plot from Monday to Sunday
ax.xaxis.grid(True, which='minor', color='lightgray')  # every hour
ax.xaxis.grid(True, which='major', color='k')  # every day
ax.xaxis.set_minor_locator(matplotlib.ticker.MultipleLocator(1 / 24))  # every hour

plt.title("Truck arrival distribution")
ax.set_xticks([i for i in range(1, 8)])  # every day
ax.set_xticklabels(["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"])
plt.xlabel("Week day")
plt.ylabel("Share (as percentage overall)")

plt.show()
Closing current database connection.
Opening file :memory:
journal_mode: memory
cache_size: -32768
page_size: 4096
foreign_keys: 1
Creating new database at :memory:
Creating all tables...
Seed with default values...
../_images/notebooks_input_distributions_61_1.svg

The truck arrival distributions can only be overwritten for the whole week at once. Each key represents the hour in the week and each value represents the probability of a truck to arrive between that hour and the start of the next time slot.

[22]:
truck_arrival_distribution_manager.set_truck_arrival_distribution(
    {
        0: 0.006944444444444444,
        1: 0.006944444444444444,
        2: 0.006944444444444444,
        3: 0.006944444444444444,
        4: 0.006944444444444444,
        5: 0.006944444444444444,
        6: 0.006944444444444444,
        7: 0.006944444444444444,
        8: 0.006944444444444444,
        9: 0.006944444444444444,
        10: 0.006944444444444444,
        11: 0.006944444444444444,
        12: 0.006944444444444444,
        13: 0.006944444444444444,
        14: 0.006944444444444444,
        15: 0.006944444444444444,
        16: 0.006944444444444444,
        17: 0.006944444444444444,
        18: 0.006944444444444444,
        19: 0.006944444444444444,
        20: 0.006944444444444444,
        21: 0.006944444444444444,
        22: 0.006944444444444444,
        23: 0.006944444444444444,
        24: 0.006944444444444444,
        25: 0.006944444444444444,
        26: 0.006944444444444444,
        27: 0.006944444444444444,
        28: 0.006944444444444444,
        29: 0.006944444444444444,
        30: 0.006944444444444444,
        31: 0.006944444444444444,
        32: 0.006944444444444444,
        33: 0.006944444444444444,
        34: 0.006944444444444444,
        35: 0.006944444444444444,
        36: 0.006944444444444444,
        37: 0.006944444444444444,
        38: 0.006944444444444444,
        39: 0.006944444444444444,
        40: 0.006944444444444444,
        41: 0.006944444444444444,
        42: 0.006944444444444444,
        43: 0.006944444444444444,
        44: 0.006944444444444444,
        45: 0.006944444444444444,
        46: 0.006944444444444444,
        47: 0.006944444444444444,
        48: 0.006944444444444444,
        49: 0.006944444444444444,
        50: 0.006944444444444444,
        51: 0.006944444444444444,
        52: 0.006944444444444444,
        53: 0.006944444444444444,
        54: 0.006944444444444444,
        55: 0.006944444444444444,
        56: 0.006944444444444444,
        57: 0.006944444444444444,
        58: 0.006944444444444444,
        59: 0.006944444444444444,
        60: 0.006944444444444444,
        61: 0.006944444444444444,
        62: 0.006944444444444444,
        63: 0.006944444444444444,
        64: 0.006944444444444444,
        65: 0.006944444444444444,
        66: 0.006944444444444444,
        67: 0.006944444444444444,
        68: 0.006944444444444444,
        69: 0.006944444444444444,
        70: 0.006944444444444444,
        71: 0.006944444444444444,
        72: 0.006944444444444444,
        73: 0.006944444444444444,
        74: 0.006944444444444444,
        75: 0.006944444444444444,
        76: 0.006944444444444444,
        77: 0.006944444444444444,
        78: 0.006944444444444444,
        79: 0.006944444444444444,
        80: 0.006944444444444444,
        81: 0.006944444444444444,
        82: 0.006944444444444444,
        83: 0.006944444444444444,
        84: 0.006944444444444444,
        85: 0.006944444444444444,
        86: 0.006944444444444444,
        87: 0.006944444444444444,
        88: 0.006944444444444444,
        89: 0.006944444444444444,
        90: 0.006944444444444444,
        91: 0.006944444444444444,
        92: 0.006944444444444444,
        93: 0.006944444444444444,
        94: 0.006944444444444444,
        95: 0.006944444444444444,
        96: 0.006944444444444444,
        97: 0.006944444444444444,
        98: 0.006944444444444444,
        99: 0.006944444444444444,
        100: 0.006944444444444444,
        101: 0.006944444444444444,
        102: 0.006944444444444444,
        103: 0.006944444444444444,
        104: 0.006944444444444444,
        105: 0.006944444444444444,
        106: 0.006944444444444444,
        107: 0.006944444444444444,
        108: 0.006944444444444444,
        109: 0.006944444444444444,
        110: 0.006944444444444444,
        111: 0.006944444444444444,
        112: 0.006944444444444444,
        113: 0.006944444444444444,
        114: 0.006944444444444444,
        115: 0.006944444444444444,
        116: 0.006944444444444444,
        117: 0.006944444444444444,
        118: 0.006944444444444444,
        119: 0.006944444444444444,
        120: 0.006944444444444444,
        121: 0.006944444444444444,
        122: 0.006944444444444444,
        123: 0.006944444444444444,
        124: 0.006944444444444444,
        125: 0.006944444444444444,
        126: 0.006944444444444444,
        127: 0.006944444444444444,
        128: 0.006944444444444444,
        129: 0.006944444444444444,
        130: 0.006944444444444444,
        131: 0.006944444444444444,
        132: 0.006944444444444444,
        133: 0.006944444444444444,
        134: 0.006944444444444444,
        135: 0.006944444444444444,
        136: 0.006944444444444444,
        137: 0.006944444444444444,
        138: 0.006944444444444444,
        139: 0.006944444444444444,
        140: 0.006944444444444444,
        141: 0.006944444444444444,
        142: 0.006944444444444444,
        143: 0.006944444444444444,
        144: 0.0,
        145: 0.0,
        146: 0.0,
        147: 0.0,
        148: 0.0,
        149: 0.0,
        150: 0.0,
        151: 0.0,
        152: 0.0,
        153: 0.0,
        154: 0.0,
        155: 0.0,
        156: 0.0,
        157: 0.0,
        158: 0.0,
        159: 0.0,
        160: 0.0,
        161: 0.0,
        162: 0.0,
        163: 0.0,
        164: 0.0,
        165: 0.0,
        166: 0.0,
        167: 0.0
    }
)

More information on setting and getting the distribution can be found at TruckArrivalDistributionManager.

Default Values

In addition to the input distributions, also some default values are defined. All of them are currently some kind of minimum or maximum value. Thus, they directly influence other distributions.

Note

DEFAULT_MAXIMUM_DWELL_TIME_OF_IMPORT_CONTAINERS_IN_HOURS = 72

The maximum dwell time for import containers is set by the container terminal operators. In practice, a later pickup would typically result in additional storage charges and is thus avoided by supply chain partners. The default value of 3 days is inspired by the pricing policy of HHLA as described in [HHLA, 2021]

DEFAULT_MINIMUM_DWELL_TIME_OF_IMPORT_CONTAINERS_IN_HOURS = 3

The minimum dwell time is the earliest time after the discharging and loading process has started that a truck tries to pick up the container. In practice, this is often determined by the IT system of the terminal operators which releases a container for being picked up once the container is on the terminal (it has been successfully been discharged). The actual earliest feasible point is determined in the subsequent model which consumes the generated data because here no sequence of discharge is determined, i.e. the container might be still on the vessel when the truck arrives. Thus, this value must be checked for when using the synthetic data in e.g. a simulation model or mathematical model.

DEFAULT_MAXIMUM_DWELL_TIME_OF_EXPORT_CONTAINERS_IN_HOURS = 120

The maximum dwell time for export containers is set by the container terminal. In practice, typically trucks are simply not allowed to deliver the container earlier than this. The default value of 5 days is inspired by the pricing policy of HHLA as described in [HHLA, 2021]

DEFAULT_MINIMUM_DWELL_TIME_OF_EXPORT_CONTAINERS_IN_HOURS = 12

The minimum dwell time is the minimum time a container must reside on the terminal before the vessel discharging and loading process starts. This time is needed for e.g. finalizing the stowage planning and avoiding that a container which is designated for a vessel arrives shortly before vessel departure. If the vehicle that delivers this container is waiting in a queue, actually the container might miss the vessel. This cut-off is typically defined by the shipping company. Here, as a simplification one cut-off period is used for all cases. Both the time intervall and the logic are inspired by expert interviews.

DEFAULT_MAXIMUM_DWELL_TIME_OF_TRANSSHIPMENT_CONTAINERS_IN_HOURS = 168

The maximum dwell time for transshipment is the maximum time difference of arrival between two vessels. The value of 7 days is inspired by [HHLA, 2021]

DEFAULT_MINIMUM_DWELL_TIME_OF_TRANSSHIPMENT_CONTAINERS_IN_HOURS = 3

The minimum dwell time for transshipment is the minimum time difference of arrival between two vessels. This means that one vessel can request a container from another vessel if and only if the previous vessel has arrived these k hours before the first one. For short transshipment dwell times, it might result in a direct transfer from one vessel to the other without any storage if the user decides to support such activities in their model (such as a simulation model or optimization model).

DEFAULT_TRANSPORTATION_BUFFER = 0.2

The export buffer describes how much more a vehicle typically takes from the terminal compared to the amount of containers in TEU which it delivers. The value .2 means that 20% more than the moved capacity (which determines the containers that are delivered to the terminal) is available for exporting containers as long as the maximum capacity of the vehicle is not exceeded. This concept has been first proposed by Hartmann [2004].

The default values can be overwritten with the help of ContainerFlowGenerationManager.set_properties().

[23]:
container_flow_generation_manager = conflowgen.ContainerFlowGenerationManager()
container_flow_generation_manager.get_properties()
Loading destination distribution...
[23]:
{'name': None,
 'start_date': None,
 'end_date': None,
 'transportation_buffer': 0.2,
 'minimum_dwell_time_of_import_containers_in_hours': 3,
 'minimum_dwell_time_of_export_containers_in_hours': 12,
 'minimum_dwell_time_of_transshipment_containers_in_hours': 3,
 'maximum_dwell_time_of_import_containers_in_hours': 72,
 'maximum_dwell_time_of_export_containers_in_hours': 120,
 'maximum_dwell_time_of_transshipment_containers_in_hours': 168}

All default values are optional. They are only overwritten if provided. The parameters start_date and end_date are obligatory though.

[24]:
container_flow_generation_manager.set_properties(
    start_date=datetime.date(2021, 1, 15),
    end_date=datetime.date(2021, 1, 31),
    maximum_dwell_time_of_export_containers_in_hours=10 * 24
)
container_flow_generation_manager.get_properties()
[24]:
{'name': None,
 'start_date': datetime.date(2021, 1, 15),
 'end_date': datetime.date(2021, 1, 31),
 'transportation_buffer': 0.2,
 'minimum_dwell_time_of_import_containers_in_hours': 3,
 'minimum_dwell_time_of_export_containers_in_hours': 12,
 'minimum_dwell_time_of_transshipment_containers_in_hours': 3,
 'maximum_dwell_time_of_import_containers_in_hours': 72,
 'maximum_dwell_time_of_export_containers_in_hours': 240,
 'maximum_dwell_time_of_transshipment_containers_in_hours': 168}

More information on setting and getting the values can be found at ContainerFlowGenerationManager.