API Reference ========================================================== *Tarot Routing - Route Optimisation API* Request ------- RoutingProblem ^^^^^^^^^^^^^^ .. py:data:: RoutingProblem :type: JSON Object A RoutingObject is the body of the request send to the Route Optimisation API endpoint. :param drivers: The :py:data:`Drivers ` to perform the :py:data:`Jobs ` :type drivers: list[:py:data:`Driver`] :param jobs: The :py:data:`Jobs ` to be optimised :type jobs: list[:py:data:`Job`] :param settings: The :py:data:`Settings` under which the optimiser will run :type settings: :py:data:`Settings` Minimal Example .. literalinclude:: _static/ex1.json :language: json Driver ^^^^^^ .. py:data:: Driver :type: JSON Object A :py:data:`Driver` represents a driver, their vehicle, or a theoretical run. :param str uid: A Unique Identifier for this :py:data:`Driver`. No two :py:data:`Drivers ` may have the same UID :param float shift_start: The earliest time this :py:data:`Driver` may begin their shift. Time of day as float (e.g. ``8.5``) in 24h time :param float shift_end: The earliest time this :py:data:`Driver` may begin their shift. Time of day as float (e.g. ``8.5``) in 24h time :param location: Where the :py:data:`Driver` begins their run. :type location: :py:data:`Location` :param end_location: [optional, default=\ ``driver.location``] Where the :py:data:`Driver` ends their run. Ignored if ``end_anywhere=True``. :ref:`Learn More... ` :type end_location: :py:data:`Location` :param bool end_anywhere: [optional, default=\ ``False``] Optimise allowing this Driver to finish at her last Job (instead of returning to the start ``location`` or to the ``end_location``). :ref:`Learn More... ` :param capacity: [optional] Set the capacity of the vehicle. The algorithm compares the total size of all :py:data:`Jobs ` in this :py:data:`Driver`'s run to the capacity of the vehicle. Simple Capacity can be expressed as an integer. For advanced use cases, see :ref:`Capacity `. :type capacity: int or str :param str spec_type: [optional] A :py:data:`Job` can only be served by a :py:data:`Driver` that has at least one ``spec_type`` in common. Learn how to use :ref:`Types ` :param str territories: [optional] A :py:data:`Job` can only be served by a :py:data:`Driver` with at least one of its ``territories`` in common. Learn how to use :ref:`Territories `. :param float speed_multiplier: [optional, default=\ ``1``] Adjust the driving speed of this :py:data:`Driver`. A value of ``0.5`` means that this :py:data:`Driver` will drive half as fast as normal. A value of ``1.2`` means that this :py:data:`Driver` will drive 20% faster than normal. :param float lunch_time: [optional] The earliest time that a :py:data:`Driver` can start their lunch break. Time is represented as decimal 24h time. So a lunch break starting at 1:15pm is expressed as ``13.25`` :param float lunch_duration: [optional] The duration in minutes of the :py:data:`Driver`'s lunch break :param float lunch_latest_start: [optional, default=\ ``lunch_time + lunch_duration/60``] The latest time the :py:data:`Driver`'s lunch break my start. To force an exact lunch time, set ``job.lunch_latest_start = job.lunch_time`` Minimal Example .. code-block:: json { "uid": "unique_driver_id_1", "location": {"lat": -33.867798, "lon": 151.166256}, "shift_start": 9.5, "shift_end": 18.5 } Standard Example .. code-block:: json { "uid": "drvid1", "location": { "lat": -33.84948962, "lon": 151.1274823 }, "shift_start": 9.5, "shift_end": 18.5, "speed_multiplier": 0.8, "lunch_time": 12.5, "lunch_duration": 45, "spec_type": "plumber,electrician", "capacity": 25 } | | | Job ^^^ .. py:data:: Job :type: JSON Object :py:data:`Jobs ` represent tasks, delivery points, customers etc. :param str uid: A Unique Identifier for this :py:data:`Job`. No two :py:data:`Jobs ` may have the same UID :param location: Where the :py:data:`Job` is :type location: :py:data:`Location` :param float duration: The number of minutes the :py:data:`Driver` must spend at this :py:data:`Job`. Include parking, doing the :py:data:`Job`, getting back to the vehicle, etc. Often called the *service time* :param float arrive_after: [optional] The earliest time the :py:data:`Driver` may begin this :py:data:`Job`. Time of day as float (e.g. ``13.75``) in 24h time :param float leave_by: [optional] The latest time the :py:data:`Driver` may finish working on this :py:data:`Job`. Time of day as float (e.g. ``15.5``) in 24h time :param size: [optional] The cumulative ``size`` s of :py:data:`Jobs ` are matched against each :py:data:`Driver's ` ``capacity`` to ensure that a :py:data:`Driver`/vehicle does not exceed her vehicle's capacity. Units can be whatever syou wish, but must be consistent between all :py:data:`Job's ` sizes and :py:data:`Driver's ` capacities. If ANY :py:data:`Job` has a size, ALL :py:data:`Drivers ` must have a capacity. For advanced use cases, see :ref:`Capacity `. :type size: float or str :param str spec_type: [optional] A :py:data:`Job` can only be served by a :py:data:`Driver` that has at least one ``spec_type`` in common. Learn how to use :ref:`Types `. :param str territories: [optional] A :py:data:`Job` can only be served by a :py:data:`Driver` with at least one of its ``territories`` in common. Learn how to use :ref:`Territories `. :param bool priority: [optional, default=\ ``false``] If some :py:data:`Jobs ` are more important than others, mark them as ``priority=true``. In Scenarios where not all :py:data:`Jobs ` can be served by your available :py:data:`Driver`s, these :py:data:`Jobs ` will be served, *even if several others are not*. :param str pickup_from: [optional] This creates a *Pickup and Delivery* constraint by referring to the ``uid`` of another :py:data:`Job`. Learn about :ref:`Pickup Delivery`. :param bool pd_interval_max: [optional] Sets the maximum time in minutes allowed between a :ref:`Pickup Delivery` pair of jobs. It should be set on the **Delivery Job only**. Specifically, it sets a constraint on the Job :ref:`ETAs `, equivalent to ``delivery_job.eta - pickup_job.eta < pd_interval_max`` :param float exclude_period_start: [optional] The start of a *negative* time window. For example, if you don't want to visit a :py:data:`Job` during their lunch break, you could set an ``exclude_period_start`` and ``exclude_period_end`` for it. Time of day as float (e.g. ``13.75``) in 24h time :param float exclude_period_end: [optional] The end of a *negative* time window. For example, if you don't want to visit a :py:data:`Job` during their lunch break, you could set an ``exclude_period_start`` and ``exclude_period_end`` for it. Time of day as float (e.g. ``13.75``) in 24h time :param bool immovable: *beta* [optional, default=\ ``false``] If you are re-optimising a run in real-time (i.e. after the :py:data:`Driver` has already started performing the route), and this :py:data:`Job` has already been served, you can prevent it from being moved during the optimisation by setting ``job.immovable=true``. This parameter may only be used if initial_runs are provided. Minimal Example .. code-block:: json { "uid": "unique_job_id_1", "duration": 10, "location": {"lat": -33.849489, "lon": 151.127482} } Standard Example .. code-block:: json { "uid": "unique_job_id_2", "duration": 10, "arrive_after": 10, "leave_by": 16.5, "location": { "lat": -33.84948962, "lon": 151.1274823 }, } | | | Location ^^^^^^^^ .. py:data:: Location :type: JSON Object A Location defines the geographical position of a :py:data:`Driver` or :py:data:`Job` :param float lat: Latitude :param float lon: Longitude Example .. code-block:: json { "lat": -33.88066125, "lon": 151.1830961 } | | | Settings ^^^^^^^^ .. py:data:: Settings :type: JSON Object Settings convey parameters which affect the way that the optimisation algorithm runs. :param bool allocate_fairly: [optional, default=\ ``false``] | If ``allocate_fairly=true``, the algorithm will attempt to allocate :py:data:`Jobs ` to :py:data:`Drivers ` | in a way that is fair. This means that the algorithm will attempt to allocate roughly the same number of :py:data:`Jobs ` to each :py:data:`Driver `. | Learn more about :ref:`Fairness `. :param bool quick_opt: [optional, default=\ ``true``] | Should the algorithm stop once it reaches a local minimum to get a reasonably optimal result quickly? | If True: The algorithm will stop fairly quickly once it has found a reasonably good solution. | Use ``quick_opt=true`` when it is important to get a solution as fast as possible (e.g. in real time optimisations). | If False: The algorithm will run until it reaches the ``improvement_threshold_per_second`` or the ``max_opt_time``, whichever comes first. | Use ``quick_opt=false`` when it is important to reach a very optimal solution, but be sure to set ``max_opt_time`` and/or ``improvement_threshold_per_second`` | :ref:`Learn More... ` :param int max_opt_time: [optional, default=\ ``450``] | The maximum number of seconds the algorithm is allowed to spend optimising. | :ref:`Learn More... ` :param float improvement_threshold_per_second: [optional, default=\ ``0.00005``] | The algorithm periodically measures the percentage improvement in the result vs time. | If the improvement is less than this threshold, the result is returned instead of continuing the search. | Set it to zero for no improvement threshold | :ref:`Learn More... ` :param bool min_time_aboard: [optional, default=\ ``false``] | Only applies to Pickup Delivery problems. | If ``min_time_aboard=true``, the optimiser will try to minimise the interval between a Pickup and its related Delivery | :ref:`Learn More... ` :param int walkable_threshold: [optional, default=\ ``0``] Seconds | Determines whether to bias neighbouring Jobs to be served consecutively or not. - Setting to 0 disables the bias. - Setting to 1 means that only Jobs at the exact same location are biased to be served together. - Setting to 30 means that any Jobs within 30s drive of each other will be biased to be served consecutively. | :ref:`Learn More... ` .. :param bool first_solution_most_constrained: (optional, default= ``false``) Determines whether the first solution strategy is to create the "most constrained" feasible solution. This is useful if you have a lot of constraints and the algorithm is unable to find a solution otherwise. However, in normal circumstances, you should not use it because it usually creates a worse first solution. Minimal Example .. code-block:: json {} Standard Example .. code-block:: json { "allocate_fairly": true, "quick_opt": false, "max_opt_time": 120, } | | | Response -------- RoutingSolution ^^^^^^^^^^^^^^^ .. py:data:: RoutingSolution :type: JSON Object The API response contains one RoutingSolution. :param runs: A list of :py:data:`Runs ` :type runs: List[:py:data:`Run`] :param unserved_jobs: A list of :py:data:`Jobs ` which the optimiser could not find a way to visit. :type unserved_jobs: List[:py:data:`Job`] Run ^^^ .. py:data:: Run :type: JSON Object :param driver: The Run's :type driver: :py:data:`Driver` :param jobs: A list of (if any) in the sequence they should be driven. :type jobs: List[:py:data:`SolutionJobs `] SolutionJob ^^^^^^^^^^^ .. py:data:: SolutionJob :type: JSON Object Each SolutionJob is **identical to the** :py:data:`Job` which you sent to the optimiser, but it has a few extra fields to help communicate the solution to you. :param int run: A 1-based index indicating which run this Job is planned in. Unserved Jobs have ``run=null``. :param int seq: Indicates this Job's sequence within the :py:data:`Run`. Unserved Jobs have ``seq=null``. :param str eta: Indicates the :ref:`Estimated Time of Arrival ` at that Job as a human-readable string ``HH:MM:SS``. E.g. 2:30pm is represented as ``14:30:00``. Unserved Jobs have ``eta=null``. :param float decimal_eta: Indicates the :ref:`Estimated Time of Arrival ` at that Job as a float. E.g. 2:30pm is represented as ``14.5``. Unserved Jobs have ``decimal_eta=null``. :param str etd: Indicates the :ref:`Estimated Time of Departure ` from that Job as a human-readable string ``HH:MM:SS``. E.g. 2:30pm is represented as ``14:30:00``. Unserved Jobs have ``etd=null``. :param float decimal_etd: Indicates the :ref:`Estimated Time of Departure ` from that Job as a float. E.g. 2:30pm is represented as ``14.5``. Unserved Jobs have ``decimal_eta=null``.