ExVrp.VehicleType (ExVrp v0.8.0)

Copy Markdown View Source

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

Functions

Creates a new vehicle type.

Types

t()

@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

new(opts)

@spec new(keyword()) :: t()

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}] becomes tw_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_duration but 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/1 resolves 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 is max(0, route_end - overtime_start) — time worked past the contracted end, regardless of how long the route itself took. When left at :infinity, overtime is max(0, duration - shift_duration) instead — which only ever exceeds zero if :max_duration was 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

  • ArgumentError if :time_windows contains invalid tuples (start >= end or negative start)
  • ArgumentError if :time_windows is an empty list
  • ArgumentError if legacy options :tw_early, :tw_late, or :forbidden_windows are 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