Basic Example Tutorial
This tutorial demonstrates how to create and solve a simple transportation planning problem from scratch using TransportationPlanningOptimization.jl.
Problem Setup
We'll build a small network with:
- 2 origin nodes (A1, A2)
- 4 intermediate nodes (B1, B2, B3, B4)
- 2 destination nodes (C1, C2)
The network topology looks like this:
┌──→ B1 ──→ B3 ───┐
│ ↓
A1 ─┤ ┌─→ C1
│ │
└──→ B2 ──┬───→┘
│
┌──→ B4 ──┘ ┌─→ C2
│ │
A2 ─┴──────────────┘Load the Package
using TransportationPlanningOptimization
using DatesDefine Network Nodes
Create nodes with unique IDs and appropriate node types:
nodes = [
NetworkNode(; id="A1", node_type=:origin),
NetworkNode(; id="A2", node_type=:origin),
NetworkNode(; id="B1", node_type=:other),
NetworkNode(; id="B2", node_type=:other),
NetworkNode(; id="B3", node_type=:other),
NetworkNode(; id="B4", node_type=:other),
NetworkNode(; id="C1", node_type=:destination),
NetworkNode(; id="C2", node_type=:destination),
]8-element Vector{NetworkNode{Nothing}}:
NetworkNode(id=A1, node_type=origin, cost=0.0, capacity=∞, info=nothing)
NetworkNode(id=A2, node_type=origin, cost=0.0, capacity=∞, info=nothing)
NetworkNode(id=B1, node_type=other, cost=0.0, capacity=∞, info=nothing)
NetworkNode(id=B2, node_type=other, cost=0.0, capacity=∞, info=nothing)
NetworkNode(id=B3, node_type=other, cost=0.0, capacity=∞, info=nothing)
NetworkNode(id=B4, node_type=other, cost=0.0, capacity=∞, info=nothing)
NetworkNode(id=C1, node_type=destination, cost=0.0, capacity=∞, info=nothing)
NetworkNode(id=C2, node_type=destination, cost=0.0, capacity=∞, info=nothing)Define Transportation Arcs
Create arcs with linear costs (proportional to volume transported):
arcs = [
Arc(; origin_id="A1", destination_id="B1", cost=LinearArcCost(5.0), travel_time=Day(1)),
Arc(; origin_id="A1", destination_id="B2", cost=LinearArcCost(7.0), travel_time=Day(1)),
Arc(; origin_id="A2", destination_id="B4", cost=LinearArcCost(6.0), travel_time=Day(1)),
Arc(;
origin_id="A2", destination_id="C2", cost=LinearArcCost(12.0), travel_time=Day(2)
),
Arc(; origin_id="B1", destination_id="B3", cost=LinearArcCost(3.0), travel_time=Day(1)),
Arc(; origin_id="B2", destination_id="C1", cost=LinearArcCost(4.0), travel_time=Day(1)),
Arc(; origin_id="B2", destination_id="B4", cost=LinearArcCost(2.0), travel_time=Day(1)),
Arc(; origin_id="B3", destination_id="C1", cost=LinearArcCost(5.0), travel_time=Day(1)),
Arc(; origin_id="B4", destination_id="C1", cost=LinearArcCost(4.0), travel_time=Day(1)),
Arc(; origin_id="B4", destination_id="C2", cost=LinearArcCost(6.0), travel_time=Day(1)),
]10-element Vector{Arc{LinearArcCost, Nothing, Dates.Day}}:
Arc(origin_id=A1, destination_id=B1, capacity=∞, cost=LinearArcCost(5.0), info=nothing)
Arc(origin_id=A1, destination_id=B2, capacity=∞, cost=LinearArcCost(7.0), info=nothing)
Arc(origin_id=A2, destination_id=B4, capacity=∞, cost=LinearArcCost(6.0), info=nothing)
Arc(origin_id=A2, destination_id=C2, capacity=∞, cost=LinearArcCost(12.0), info=nothing)
Arc(origin_id=B1, destination_id=B3, capacity=∞, cost=LinearArcCost(3.0), info=nothing)
Arc(origin_id=B2, destination_id=C1, capacity=∞, cost=LinearArcCost(4.0), info=nothing)
Arc(origin_id=B2, destination_id=B4, capacity=∞, cost=LinearArcCost(2.0), info=nothing)
Arc(origin_id=B3, destination_id=C1, capacity=∞, cost=LinearArcCost(5.0), info=nothing)
Arc(origin_id=B4, destination_id=C1, capacity=∞, cost=LinearArcCost(4.0), info=nothing)
Arc(origin_id=B4, destination_id=C2, capacity=∞, cost=LinearArcCost(6.0), info=nothing)Define Commodities
Create commodities to transport through the network:
base_date = DateTime(2025, 1, 1)
commodities = [
Commodity(; #src From A1 to C1, size 10, must arrive by day 3
origin_id="A1",
destination_id="C1",
arrival_date=base_date + Day(3),
max_delivery_time=Day(3),
size=10.0,
),
Commodity(; #src From A1 to C1, size 5, must arrive by day 3 (same bundle as above)
origin_id="A1",
destination_id="C1",
arrival_date=base_date + Day(3),
max_delivery_time=Day(3),
size=5.0,
),
Commodity(; #src From A2 to C2, size 8, must arrive by day 2
origin_id="A2",
destination_id="C2",
arrival_date=base_date + Day(2),
max_delivery_time=Day(2),
size=8.0,
),
]3-element Vector{Commodity{true, String, Nothing}}:
Commodity{is_date_arrival=true}:
Origin ID: A1
Destination ID: C1
Arrival Date: 2025-01-04T00:00:00
Quantity: 1
Size: 10.0
Max Delivery Time: 3 days
Forbidden Node IDs: String[]
Forbidden Arcs: Tuple{String, String}[]
Info: nothing
Commodity{is_date_arrival=true}:
Origin ID: A1
Destination ID: C1
Arrival Date: 2025-01-04T00:00:00
Quantity: 1
Size: 5.0
Max Delivery Time: 3 days
Forbidden Node IDs: String[]
Forbidden Arcs: Tuple{String, String}[]
Info: nothing
Commodity{is_date_arrival=true}:
Origin ID: A2
Destination ID: C2
Arrival Date: 2025-01-03T00:00:00
Quantity: 1
Size: 8.0
Max Delivery Time: 2 days
Forbidden Node IDs: String[]
Forbidden Arcs: Tuple{String, String}[]
Info: nothing
Create the Instance
Build the complete optimization instance with daily time steps:
instance = Instance(nodes, arcs, commodities, Day(1))Instance Summary:
• Horizon: 4 time steps (1 day per step)
• Commodities: 3
• Orders: 2
• Bundles: 2
• Network Graph with 8 nodes and 10 arcs
• Time-Space Graph with 32 nodes and 29 arcs
• Travel-Time Graph with 25 nodes and 24 arcs
Solve with Greedy Heuristic
Apply the greedy insertion heuristic to find a solution:
solution = greedy_heuristic(instance)Solution(num_trucks=0, bin_assignments=Dict{Tuple{Int64, Int64}, Vector{Bin{LightCommodity{true, Nothing}}}}())Validate and Evaluate the Solution
Check if the solution is feasible:
is_feasible(solution, instance; verbose=true)trueCalculate the total cost:
cost(solution)261.0The solution routes commodities through the network to minimize transportation costs while respecting delivery deadlines and network capacity constraints.
This page was generated using Literate.jl.