Skip to content
Last updated

What the Planner Decides

Most planning stacks split one decision over many tools: a route optimiser, a driving-time check, an ADR spreadsheet, a load planner, a dock booking screen, an empties desk, a carrier portal and an intermodal planner. Each one is right on its own, and the combined plan still fails at the dock, at the terminal or at the trailer door.

Transportial decides all of it together, in one search, so the plan it hands over can actually run. The same engine plans inside the product (the optimizer and map planning) and on the API (POST /vrp/solve).

This page lists what that one search decides, which rule guards each decision, and where you set it on the platform and in the API. The request fields are in the Multi-Modal VRP example.

Every resource per tour

A refrigerated consignment leaves Venlo at 06:00. The tractor is in Venlo, the only free reefer trailer stands in Tilburg, and the driver who is free has already driven 41 hours this week. One option is a carrier who serves Venlo to Lyon, but only if the order is in before 14:00.

What the planner decides. Each tour gets a vehicle, a driver and, when it needs one, a trailer or other equipment. Instead of your own fleet, a tour can also run on a carrier's capacity contract.

  • Drivers. Each driver has one EU 561/2006 driving-time clock across all their tours. The clock starts from what they have already driven, so breaks, daily and weekly rests and weekly limits are planned over the whole plan, not per tour. Availability, ADR certificate, licence, tacho card, certificates, bans and languages count as well.
  • Trailers. A trailer is picked from the pool by type, attributes, temperature and room, and the tour fetches it from where it stands. The drive to it counts in the tour's time and cost.
  • Carriers. A capacity contract is priced with your own pricing modules. It is limited by its lanes, service areas, operating hours, lead time and order cut-off, and by the goods it accepts.
Rule codesDefault (API / platform)
availability, operational, driving_time, chauffeur_ban, chauffeur_attributeblock / block
adr_chauffeur, certificate, licenceblock / warn
equipment_type, temperature, vehicle_type, vehicle_attributeblock / block
contract_lane, contract_validity, contract_capability, carrier_is_customerblock / block

Where you set it. On the platform, these come from your vehicles, chauffeurs, transport equipment and capacity contracts, and their rule policy from the planning settings (planningSettings.optimizerRules). On the API, send vehicles, chauffeurs, transportEquipments and capacityContracts. See Add drivers, Add trailers and equipment and Add capacity contracts.

Every mode

Forty containers must go from Rotterdam to Milan by Thursday. A train leaves Rotterdam on Tuesday at 18:00 with 28 free slots and a cut-off three hours before departure. Trucks can do the whole distance, or bring the containers to the terminal and collect them in Milan.

What the planner decides. Road, rail, inland waterway, sea and air are planned in one plan. A consignment can also ride a scheduled service door to door: by truck to the terminal, by train, barge, ship or aircraft, and by truck to the door. Cut-offs and capacity per departure count. The road legs at both ends follow the same rules as every other tour.

RuleDefault
Transport mode of the vehicle and the locationalways enforced
Cut-off and capacity per departurealways enforced

Where you set it. On the platform, the optimizer plans over your stored schedule routes (useScheduleRoutes, on by default). On the API, send scheduleRoutes, or set options.chains.useStoredScheduleRoutes. See Add scheduled services.

The load

A reefer leaves the depot with frozen fish in the front and chilled dairy at the rear. A drum of pesticide (ADR class 6.1) is on the same order list for the same customer.

What the planner decides.

  • Load plans. Every proposed trip gets a 3D load plan that the planner can open before saving, in the optimizer and in map planning, whatever engine planned the trip. It shows the stop-by-stop loading order. When the trip is saved, the plan stays with it.
  • Compartments. Multi-temperature reefers, tank compartments and food-grade holds are modelled. A consignment only goes into a compartment that fits its temperature, its dangerous goods and its foodstuff status. Each compartment's capacity is checked against what is on board at the same moment. In the 3D load plan, a bulkhead is a wall.
  • ADR. ADR 1.1.3.6 points add up per tour, over everything on board at the same moment. Incompatible classes are kept apart. Foodstuffs never share a compartment with toxic or infectious classes (6.1 and 6.2 by default; ADR 7.5.4).
Rule codesDefault (API / platform)
compartmentblock / block
adr_vehicle, adr_equipment, adr_mixed_loadingblock / warn
3D packingset by load planning: off, verify or enforce

Where you set it. On the platform, compartments are set on vehicles and transport equipment. Foodstuff and the required temperature are set on the goods. The Load planning setting (Off, Verify, Enforce) needs the stacking module. On the API, send vehicles[].compartments, transportEquipments[].compartments, consignments[].foodstuff, rules.adr and options.loadPlanning. See Add compartments, Add dangerous goods and Calculating a 3D Load Plan.

The places

A distribution centre has two loading docks. Between 07:00 and 08:30 one of them is booked by a supplier's timeslot, and three of your trucks are planned to arrive around 07:30.

What the planner decides. Docks, ramps, berths and rail sidings have a capacity. The planner never plans more vehicles at once than a site can handle. Other trips already at the site and booked dock timeslots count as well. A vehicle that finds every dock taken waits for a free one, and that wait is real waiting time: it counts in the tour time and in the driver's day. When a tour with slack can wait at less cost, it gives way to a tour that cannot. The method is after Bombelli & Fazi (2022), see Research it builds on.

Rule codeDefault (API / platform)
dock_capacityblock / block

Where you set it. On the platform, the capacity of a location is the sum of maxConcurrentOperations over its operational loading docks. Stops of other trips and requested or confirmed timeslot bookings count. The optimizer response shows each wait in dockWaitByStop. On the API, send locations[].docks and read dockWaitSeconds and dockStart per stop. See Add docks and berths.

The equipment between tours

An import container is delivered to a warehouse in Tilburg and is empty once unloaded. Ten kilometres away, an exporter in Waalwijk needs an empty container of the same type that afternoon. The nearest container depot is in Moerdijk.

What the planner decides. Empty containers, swap bodies and pool trailers are shared by all tours. A consignment can need a unit at its pickup, as an export needs an empty container. It can also free one after its delivery, as an import's container is empty once unloaded.

  • Sources. The planner reuses a freed unit on the same tour (a street-turn), or takes one from stock or a depot. A fetch from stock or a depot is priced as a detour on the leg into the pickup.
  • Stock. Stock is tracked over time across all tours, and is never planned below zero.
  • Method. The method is after Fazi, Choudhary & Dong (2023), see Research it builds on.
Rule codeDefault (API / platform)
equipment_stockblock / block

Where you set it. On the platform, a location's equipment stock is set in its site details. A consignment's need or release is its equipmentFlow. The optimizer response shows each source in equipmentByTrip and the stock over time in equipmentStock. On the API, send the top-level equipmentStock and consignments[].equipmentFlow. See Add empty containers and pools.

Your definition of "best"

One planner wants every consignment planned first, then the fewest tours, and only then the lowest cost. Another weighs CO2e and cost together, because a customer pays for the lower emissions.

What the planner decides. You set a custom objective: a weight on each of distance, driving time, tour time, waiting time, money, CO2e, tours, resources, lateness and unplanned consignments. Priority levels can rank them, for example first plan everything, then the fewest tours, then cost. A higher level always outweighs everything below it. The named objectives (distance, time, CO2, cost, fewest assets) are presets of the same weights.

The result explains itself: the objective per component, per tour and in total.

Where you set it. On the platform, choose Custom as the optimisation objective in the optimizer settings and set the default weights. A run can override them in the optimizer. The response holds objective and objectiveByTrip. On the API, send options.objective: "custom" with options.objectiveWeights and options.objectivePriorities, and read routes[].objective and objective. See Choose what "best" means.

Transparency and control

A planner sees that one consignment stayed unplanned and wants to know why. A tenant that has not entered all driver licences yet still wants a plan.

What the planner decides.

  • Every rule can be block, warn or off.
  • A warned rule costs something in the plan, and each tour lists what it breaks in softViolations.
  • Every consignment left out gets a reason, and details counts how many resources each rule refused.

Where you set it. On the platform, set the policy per rule in the planning settings (planningSettings.optimizerRules). On the API, send rules.policy and rules.softWeights. See How strict each rule is.

Rule codes

Every rule below can be set to block (a violation makes the plan infeasible), warn (it costs a penalty and is reported on the tour) or off. The platform defaults to warn for data that most tenants have not filled in yet, so an upgrade never empties a plan.

Rule codeDefault APIDefault platform
operationalblockblock
availabilityblockblock
adr_chauffeurblockwarn
adr_vehicleblockwarn
adr_equipmentblockwarn
adr_mixed_loadingblockwarn
certificateblockwarn
licenceblockwarn
chauffeur_banblockblock
chauffeur_attributeblockblock
vehicle_attributeblockblock
vehicle_typeblockblock
fuel_typeblockblock
emission_standardblockblock
equipment_typeblockblock
location_accessblockwarn
contract_laneblockblock
contract_validityblockblock
contract_capabilityblockblock
carrier_is_customerblockblock
driving_timeblockblock
tour_limitblockblock
temperatureblockblock
compartmentblockblock
equipment_stockblockblock
dock_capacityblockblock

capacity, trip_status and existing_trip always block and cannot be set. The API rejects them as policy keys, and the platform settings ignore them.

Where it runs

WhereWhat it does
Optimizer (POST /trip/optimizer)Plans your consignments with your vehicles, chauffeurs, equipment and contracts from the platform. It proposes trips and saves nothing, unless planningSettings.autoApplyOptimizerPlans is on. See Trips & Planning.
Map planningPlans from the map with the same engine. Each proposed trip has a Load plan button.
POST /vrp/solveTakes a complete problem in the request and stores nothing. Nothing in it has to exist in Transportial. Permission calculate:vrp. See Multi-Modal VRP.
POST /vrp/solve/asyncThe same request as a job, for searches of up to 120 seconds. Poll GET /worker-job/{id}.

Everything on this page is decided by the built-in Transportial engine. When your platform uses another optimizer engine, that engine plans the routes, and its proposals still get load plans.

Research it builds on

Two parts of the planner build on published research. The results below are the papers' own, from their experiments, not measurements of Transportial.

  • Docks. A. Bombelli & S. Fazi (2022), "The ground handler dock capacitated pickup and delivery problem with time windows: A collaborative framework for air cargo operations", Transportation Research Part E 159, 102603. In the paper's experiments, uncoordinated plans queued for docks up to about 3 hours, and some became infeasible. Coordination cut travel time by 2–19%. Our adaptation keeps every plan the search holds dock-feasible. Instead of the paper's penalised overbooking, a tour waits, or the tour that can shift gives way.
  • Empties. S. Fazi, S.K. Choudhary & J.X. Dong (2023), "The multi-trip container drayage problem with synchronization for efficient empty containers re-usage", European Journal of Operational Research 310(1), 343–359. In the paper's real cases near Tilburg and 's-Hertogenbosch, its plans were 25–43% cheaper than the planners' own, with fewer trips. Our adaptation:
    • runs inside our large neighbourhood search instead of branch-and-price;
    • checks stock only when a unit is taken (the paper's "critical times");
    • prices depot fetches as detours ("bypass").

What it does not do yet

  • A consignment is not split over vehicles. It travels on one vehicle, or on one chain of legs.
  • Compartment lengths are fixed. There is no movable bulkhead yet.
  • /vrp/solve checks that every consignment has a matching compartment, but does not report which compartment it got. A load plan reports it per unit in placements[].compartmentId.
  • Separate loading and unloading docks are not modelled. All operational docks of a site count together.
  • Equipment types match exactly. There is no equivalence between ISO size-type groups.
  • Yard capacity is not modelled. A return is never refused because a yard is full.
  • Stock and depot visits do not become explicit stops on a saved trip. They count in the trip's times and distance only.
  • equipmentStock and scheduleRoutes cannot be combined in one request.
  • A trailer from the pool stays with one vehicle for the whole plan. Handing it over to another vehicle is not modelled, and neither is a chassis pool shared between vehicles.
  • Without your own distance matrix, distances are straight-line estimates, and warnings says so.