Represents a vehicle type in a VRP.
Vehicle types define the characteristics of vehicles in the fleet, including capacity, costs, time windows, and depot assignments.
Summary
Types
@type t() :: %ExVrp.VehicleType{ capacity: [non_neg_integer()], end_depot: non_neg_integer(), fixed_cost: non_neg_integer(), forbidden_windows: [{non_neg_integer(), non_neg_integer()}], initial_load: [non_neg_integer()], max_distance: non_neg_integer() | :infinity, max_duration: non_neg_integer() | :infinity, max_reloads: non_neg_integer() | :infinity, name: String.t(), num_available: pos_integer(), overtime_start: non_neg_integer() | :infinity, profile: non_neg_integer(), reload_depots: [non_neg_integer()], shift_duration: non_neg_integer() | :infinity, start_depot: non_neg_integer(), start_late: non_neg_integer(), tw_early: non_neg_integer(), tw_late: non_neg_integer() | :infinity, unit_distance_cost: non_neg_integer(), unit_duration_cost: non_neg_integer(), unit_overtime_cost: non_neg_integer() }
Functions
Creates a new vehicle type.
Required Options
:num_available- Number of vehicles of this type available:capacity- List of capacity values per dimension
Optional Options
:time_windows- List of{start, end}tuples representing operating windows (default:[{0, :infinity}]). Overlapping/adjacent windows are merged automatically. Example:[{0, 500}, {600, 1000}]becomestw_early: 0, tw_late: 1000, forbidden_windows: [{500, 600}].:start_depot- Index of starting depot (default:0):end_depot- Index of ending depot (default:0):fixed_cost- Fixed cost for using this vehicle (default:0):shift_duration- Maximum shift duration (default::infinity):max_distance- Maximum distance allowed (default::infinity):unit_distance_cost- Cost per unit distance (default:1):unit_duration_cost- Cost per unit time (default:0):profile- Index of distance/duration matrix to use (default:0):start_late- Latest allowed start time (default:0):max_duration- Hard maximum route duration, independent of:shift_durationbut defaulting to it, i.e. a route may not run longer than its nominal shift unless you say otherwise. Measures elapsed time from route start to route end, so idle time between stops counts against it; it is not a cap on time worked.new/1resolves the default, so the struct always carries a concrete value:unit_overtime_cost- Cost per unit of overtime (default:0):overtime_start- Clock time after which work counts as overtime, on the same axis as:time_windows(default::infinity). When set, overtime ismax(0, route_end - overtime_start)— time worked past the contracted end, regardless of how long the route itself took. When left at:infinity, overtime ismax(0, duration - shift_duration)instead — which only ever exceeds zero if:max_durationwas raised above:shift_duration.:reload_depots- List of depot indices where vehicle can reload (default:[]):max_reloads- Maximum number of reloads per route (default::infinity):initial_load- Initial load per dimension (default:[]):name- Vehicle type name (default:"")
Raises
ArgumentErrorif:time_windowscontains invalid tuples (start >= end or negative start)ArgumentErrorif:time_windowsis an empty listArgumentErrorif legacy options:tw_early,:tw_late, or:forbidden_windowsare passed
Examples
iex> vt = ExVrp.VehicleType.new(num_available: 3, capacity: [100, 50], time_windows: [{0, 28_800}])
iex> {vt.num_available, vt.capacity, vt.tw_early, vt.tw_late}
{3, [100, 50], 0, 28_800}Gaps between windows become forbidden windows:
iex> vt = ExVrp.VehicleType.new(num_available: 2, capacity: [100], time_windows: [{0, 500}, {600, 1000}])
iex> {vt.tw_early, vt.tw_late, vt.forbidden_windows}
{0, 1000, [{500, 600}]}Passing the derived fields directly is an error:
iex> ExVrp.VehicleType.new(num_available: 1, capacity: [10], tw_early: 5)
** (ArgumentError) [:tw_early] cannot be set directly, use :time_windows instead