Routific has a new endpoint for re-optimizing an existing solution with new visits. This endpoint does not optimize the entire problem again, but rather attempts to optimally fit new visits into an existing solution.

Following endpoint should be called to optimally add new visits into an existing vrp solution.

https://api.routific.com/v1/fix

To add a new set of pickup & delivery visits into an existing pdp solution, the following endpoint should be invoked.

https://api.routific.com/v1/fix-pdp

The request schema for both /fix and /fix-pdp endpoints are identical to each other as they both contain a visits, fleet, options, solution, and unserved objects at a high level.

Checkout the sidebar for a simple request example for both of these endpoints.

{
    "visits": {
        "order_1": {
            "location": {
                "name": "6800 Cambie",
                "lat": 49.227107,
                "lng": -123.1163085
            },
            "start": "9:00",
            "end": "12:00",
            "duration": 10
        },
        "order_2": {
            "location": {
                "name": "3780 Arbutus",
                "lat": 49.2474624,
                "lng": -123.1532338
            },
            "start": "9:00",
            "end": "12:00",
            "duration": 10
        },
        "order_3": {
            "location": {
                "name": "800 Robson",
                "lat": 49.2819229,
                "lng": -123.1211844
            },
            "start": "8:00",
            "end": "9:00",
            "duration": 10
        },
        "order_4": {
            "location": {
                "name": "UBC",
                "lat": 49.251565,
                "lng": -123.240119
            },
            "start": "9:00",
            "end": "12:00",
            "duration": 10
        },
        "order_5": {
            "location": {
                "name": "300 Cambie St",
                "lat": 49.283255,
                "lng": -123.109079
            },
            "start": "13:00",
            "end": "15:00",
            "duration": 10
        },
        "order_6": {
            "location": {
                "name": "750 King Edward",
                "lat": 49.249010,
                "lng": -123.121391
            },
            "start": "10:00",
            "end": "12:00",
            "duration": 10
        },
        "order_7": {
          "location": {
              "name": "Commercial Driver",
              "lat": 49.269357,
              "lng": -123.069666
          },
          "start": "11:00",
          "end": "12:00",
          "duration": 10
        }
    },
    "fleet": {
        "vehicle_1": {
            "start_location": {
                "id": "depot",
                "name": "800 Kingsway",
                "lat": 49.2553636,
                "lng": -123.0873365
            },
            "end_location": {
                "id": "depot",
                "name": "800 Kingsway",
                "lat": 49.2553636,
                "lng": -123.0873365
            },
            "shift_start": "8:00",
            "shift_end": "12:00"
        }
    },
    "solution": {
      "vehicle_1": [
        "order_1",
        "order_2"
      ]
    },
    "unserved": [
      "order_3",
      "order_4",
      "order_5",
      "order_6",
      "order_7"
    ]
}
{
  "visits": {
      "order_5": {
          "dropoff": {
              "location": {
                  "name": "800 Kingsway, Vancouver, Canada",
                  "lat": 49.25548089999999,
                  "lng": -123.08721350000002
              },
              "duration": 1
          },

          "pickup": {
              "location": {
                  "name": "3780 Arbutus, Vancouver, Canada",
                  "lat": 49.2474623,
                  "lng": -123.15322459999999
              },
              "duration": 1
          }
      },
      "order_4": {
          "dropoff": {
              "location": {
                  "name": "6800 Cambie, Vancouver, Canada",
                  "lat": 49.22462650000001,
                  "lng": -123.11638909999999
              },
              "duration": 1
          },

          "pickup": {
              "location": {
                  "name": "800 Wallace Street, Vancouver",
                  "lat": 49.2480959,
                  "lng": -123.190875
              },
              "duration": 1
          }
      },
      "order_3": {
          "dropoff": {
              "location": {
                  "name": "8500 Granville Street, Vancouver, Canada",
                  "lat": 49.2094459,
                  "lng": -123.14039439999999
              },
              "duration": 1
          },
          "pickup": {
              "location": {
                  "name": "2200 Macdonald Street, Vancouver, Canada",
                  "lat": 49.2666451,
                  "lng": -123.16836490000003
              },
              "duration": 1
          }
      },
      "order_2": {
          "dropoff": {
              "location": {
                  "name": "8600 Knight Street, Vancouver, Canada",
                  "lat": 49.2126414,
                  "lng": -123.07712400000003
              },
              "duration": 1
          },
          "pickup": {
              "location": {
                  "name": "2200 Macdonald Street, Vancouver, BC",
                  "lat": 49.2666451,
                  "lng": -123.16836490000003
              },
              "duration": 1
          }
      },
      "order_1": {
          "dropoff": {
              "location": {
                  "name": "200 Commercial Drive, Vancouver, BC",
                  "lat": 49.28304900000001,
                  "lng": -123.07031840000002
              },
              "duration": 1
          },

          "pickup": {
              "location": {
                  "name": "1800 Robson, Vancouver, Canada",
                  "lat": 49.2915333,
                  "lng": -123.13555350000001
              },
              "duration": 1
          }
      },
      "order_6": {
          "dropoff": {
              "location": {
                  "name": "200 Commercial Drive, Vancouver, BC",
                  "lat": 49.28304900000001,
                  "lng": -123.07031840000002
              },
              "duration": 1
          },

          "pickup": {
              "location": {
                  "name": "1800 Robson, Vancouver, Canada",
                  "lat": 49.2915333,
                  "lng": -123.13555350000001
              },
              "duration": 1
          }
      }
  },
  "fleet": {
      "vehicle_1": {
          "start_location": {
              "id": "depot",
              "name": "778 Beatty, Vancouver, Canada",
              "lat": 49.2779059,
              "lng": -123.1134836
          },
          "end_location": {
              "id": "depot",
              "name": "778 Beatty, Vancouver, Canada",
              "lat": 49.2779059,
              "lng": -123.1134836
          },
          "shift_start": "9:00",
          "shift_end": "20:00",
          "min_visits": 3
      },
      "vehicle_2": {
          "start_location": {
              "id": "depot",
              "name": "778 Beatty, Vancouver, Canada",
              "lat": 49.2779059,
              "lng": -123.1134836
          },
          "end_location": {
              "id": "depot",
              "name": "778 Beatty, Vancouver, Canada",
              "lat": 49.2779059,
              "lng": -123.1134836
          },
          "shift_start": "00:00",
          "shift_end": "16:00",
          "min_visits": 2
      }
  },
  "solution": {
    "vehicle_1": [
      {
        "location_id": "order_3",
        "type": "pickup"
      },
      {
        "location_id": "order_3",
        "type": "dropoff"
      },
      {
        "location_id": "order_5",
        "type": "pickup"
      },
      {
        "location_id": "order_5",
        "type": "dropoff"
      }
    ],
    "vehicle_2": [
      {
        "location_id": "order_1",
        "type": "pickup"
      },
      {
        "location_id": "order_1",
        "type": "dropoff"
      },
      {
        "location_id": "order_2",
        "type": "pickup"
      },
      {
        "location_id": "order_2",
        "type": "dropoff"
      },
      {
        "location_id": "order_4",
        "type": "pickup"
      },
      {
        "location_id": "order_4",
        "type": "dropoff"
      }
    ]
  },
  "unserved": [
    "order_6"
  ]
}

Visits object
The visits object can contain all the original orders from your initial optimization request, or just the remaining orders that need to be visited from your original solution. Also ensure the new visits that need to be added to the solution are also part of the visits object.
The visit object's schema changes depending whether the request is being made to /fix or /fix-pdp endpoint. For the /fix endpoint the visits object schema should match that of the /vrp or /vrp-long endpoints. When it comes to the /fix-pdp endpoint the visits object schema should reflect that of the /pdp or /pdp-long endpoints.

Fleet & Options object
There are no changes to the schematics for these objects and should be identical to how they are utilized in other endpoints.

Solution object
The solution object should contain routes with remaining visits that are yet to be visited. The format for the solution object should be as below with an array of visit Ids that need to be fulfilled.

"solution": {
        "vehicle_1": [
            "visit3",
            "visit9",
            "visit6",
            "visit13",
            "visit2"
        ],
        "vehicle_2": [
            "visit5",
            "visit8",
            "visit10",
            "visit16",
            "visit4"
        ]
    }

👍

Make sure to exclude the visit Ids that have already been completed from the original solution in the solution object part of the API request.

Unserved array
In the unserved array you can list the orders that you’d like to insert optimally into the current routes described in solution, while keeping the rest of the solution the same. An example of an unserved array with visit Ids looks like below.

"unserved": [
    "visit19",
    "visit20"
]

API Response
If any of the orders in the unserved array cannot fit in the existing route (due to constraints), the API will return those orders still in the unserved array with a message indicating what constraint was preventing the order from fitting into a route.