Templates

Templates

List of available templates

Introduction

The Nextmv SDK templates provide all of the files required to publish an optimization model as a Nextmv app. This guide will walk you through our template structure. For a list of existing templates, check out the full list of available templates below.

Available templates

Focus AreaTemplate NameUse Case
vehicle routingnextrouteSolves a VRP for delivery, distribution, and sourcing problems
vehicle routingroutingSolves a VRP for delivery, distribution, and sourcing problems
vehicle routingrouting-matrix-inputSolves a VRP using a custom matrix
vehicle routingmeasure-matrixInput generator for the routing-matrix-input template
vehicle routingtime-dependent-measureSolves a VRP for measures dependent on time (ie. time windows)
vehicle routingunique-matrix-measureSolves a VRP with a unique matrix that reduces input size
vehicle routingcloud-routingSolves a VRP for existing Nextmv routing app customers
clusteringclusterGroups a set of data points into clusters based on similarities
clusteringcluster-tspCreates a set of clusters equal to the number of vehicles, then solves a TSP for each vehicle
packingknapsackMaximizes the total value without exceeding weight capacity, given a collection of items with a value and weight
packingmip-knapsackSolves the knapsack problem using Mixed Integer Programming
schedulingshift-schedulingAssigns one worker to each shift while maximizing worker happiness
schedulingpager-dutyAssigns users to shifts for incident response on-call duty using input and output data structures compatible with PagerDuty API
customnew-appProvides a skeleton for creating a completely custom model
puzzlesudokuFills a 9x9 grid such that all columns and all 3x3 subgrids contain the numerals 1 through 9
allocationmip-meal-allocationDemonstrates how to solve a Mixed Integer Programming problem using Nextmv

Template Overview

We'll use the nextroute template as our example, but every template will follow the same pattern. To initialize the template, run the following command from your terminal:

nextmv sdk init -t nextroute
Copy

Change directories into the newly created template folder.

cd nextroute
Copy

The following table shows the files that are created under the nextroute folder.

filedescription
LICENSEContains the Apache License 2.0 under which we distribute this template.
README.mdGives a short introduction to the problem and shows you how to run the template.
go.mod and go.sumDefine a Go module and are used to manage dependencies, including the Nextmv SDK.
input.jsonDescribes the input data for a specific problem that is solved by the template.
main.goContains the actual code of the template.
.code-workspaceThis file should be used to open the template in Visual Studio Code. It is pre-configured for you so that you can run and debug the template without any further steps.

Now you can run the template with the Nextmv CLI, reading from the input.json file and writing to an output.json file. The following command shows you how to specify other options as well.

nextmv sdk run . -- -runner.input.path input.json -runner.output.path output.json -solve.duration 10s
Copy

Input File

The input.json file lists the required fields that will be ingested into the model. These include:

  • actors - available players to utilize in the solution, for routing, this includes Vehicles and Stops, but could also include employees (scheduling), objects (packing), etc
  • constraints - specific requirements that must be met. This includes things like volume and weight limit, time windows, etc
{
  "defaults": {
    "vehicles": {
      "capacity": {
        "bunnies": 20,
        "rabbits": 10
      },
      "start_location": {
        "lat": 35.791729813680874,
        "lon": -78.7401685145487
      },
      "end_location": {
        "lat": 35.791729813680874,
        "lon": -78.7401685145487
      },
      "speed": 10
    },
    "stops": {
      "duration": 300,
      "quantity": {
        "bunnies": -1,
        "rabbits": -1
      },
      "unplanned_penalty": 200000,
      "target_arrival_time": "2023-01-01T10:00:00Z",
      "early_arrival_time_penalty": 1.5,
      "late_arrival_time_penalty": 1.5
    }
  },
  "stops": [
    {
      "id": "s1",
      "location": {
        "lon": -78.90919,
        "lat": 35.72389
      },
      "compatibility_attributes": ["premium"]
    },
    {
      "id": "s2",
      "location": {
        "lon": -78.813862,
        "lat": 35.75712
      },
      "compatibility_attributes": ["premium"]
    },
    {
      "id": "s3",
      "location": {
        "lon": -78.92996,
        "lat": 35.932795
      },
      "compatibility_attributes": ["premium"]
    },
    {
      "id": "s4",
      "location": {
        "lon": -78.505745,
        "lat": 35.77772
      },
      "compatibility_attributes": ["premium"]
    },
    {
      "id": "s5",
      "location": {
        "lon": -78.75084,
        "lat": 35.732995
      },
      "compatibility_attributes": ["premium"]
    },
    {
      "id": "s6",
      "location": {
        "lon": -78.788025,
        "lat": 35.813025
      },
      "compatibility_attributes": ["premium"]
    },
    {
      "id": "s7",
      "location": {
        "lon": -78.749391,
        "lat": 35.74261
      },
      "compatibility_attributes": ["premium"]
    },
    {
      "id": "s8",
      "location": {
        "lon": -78.94658,
        "lat": 36.039135
      },
      "compatibility_attributes": ["basic"]
    },
    {
      "id": "s9",
      "location": {
        "lon": -78.64972,
        "lat": 35.64796
      },
      "compatibility_attributes": ["basic"]
    },
    {
      "id": "s10",
      "location": {
        "lon": -78.747955,
        "lat": 35.672955
      },
      "compatibility_attributes": ["basic"]
    },
    {
      "id": "s11",
      "location": {
        "lon": -78.83403,
        "lat": 35.77013
      },
      "compatibility_attributes": ["basic"]
    },
    {
      "id": "s12",
      "location": {
        "lon": -78.864465,
        "lat": 35.782855
      },
      "compatibility_attributes": ["basic"]
    },
    {
      "id": "s13",
      "location": {
        "lon": -78.952142,
        "lat": 35.88029
      },
      "compatibility_attributes": ["basic"]
    },
    {
      "id": "s14",
      "location": {
        "lon": -78.52748,
        "lat": 35.961465
      },
      "compatibility_attributes": ["basic"]
    },
    {
      "id": "s15",
      "location": {
        "lon": -78.89832,
        "lat": 35.83202
      }
    },
    {
      "id": "s16",
      "location": {
        "lon": -78.63216,
        "lat": 35.83458
      }
    },
    {
      "id": "s17",
      "location": {
        "lon": -78.76063,
        "lat": 35.67337
      }
    },
    {
      "id": "s18",
      "location": {
        "lon": -78.911485,
        "lat": 36.009015
      }
    },
    {
      "id": "s19",
      "location": {
        "lon": -78.522705,
        "lat": 35.93663
      }
    },
    {
      "id": "s20",
      "location": {
        "lon": -78.995162,
        "lat": 35.97414
      }
    },
    {
      "id": "s21",
      "location": {
        "lon": -78.50509,
        "lat": 35.7606
      }
    },
    {
      "id": "s22",
      "location": {
        "lon": -78.828547,
        "lat": 35.962635
      },
      "precedes": ["s16", "s23"]
    },
    {
      "id": "s23",
      "location": {
        "lon": -78.60914,
        "lat": 35.84616
      },
      "start_time_window": [
        "2023-01-01T09:00:00-06:00",
        "2023-01-01T09:30:00-06:00"
      ]
    },
    {
      "id": "s24",
      "location": {
        "lon": -78.65521,
        "lat": 35.740605
      },
      "start_time_window": [
        "2023-01-01T09:00:00-06:00",
        "2023-01-01T09:30:00-06:00"
      ],
      "succeeds": "s25"
    },
    {
      "id": "s25",
      "location": {
        "lon": -78.92051,
        "lat": 35.887575
      },
      "start_time_window": [
        "2023-01-01T09:00:00-06:00",
        "2023-01-01T09:30:00-06:00"
      ],
      "precedes": "s26"
    },
    {
      "id": "s26",
      "location": {
        "lon": -78.84058,
        "lat": 35.823865
      },
      "start_time_window": [
        "2023-01-01T09:00:00-06:00",
        "2023-01-01T09:30:00-06:00"
      ]
    }
  ],
  "vehicles": [
    {
      "id": "vehicle-0",
      "start_time": "2023-01-01T06:00:00-06:00",
      "end_time": "2023-01-01T10:00:00-06:00",
      "activation_penalty": 4000,
      "compatibility_attributes": ["premium"]
    },
    {
      "id": "vehicle-1",
      "start_time": "2023-01-01T10:00:00-06:00",
      "end_time": "2023-01-01T16:00:00-06:00",
      "max_duration": 21000,
      "compatibility_attributes": ["basic"]
    }
  ]
}
Copy

Output File

The output.json file returns the results of the model based on the inputs. There are three main sections in the output file:

  • options - returns the options defined for the run; like run duration, solver type, etc
  • solutions - prints the results of the run
  • statistics - prints the statistics around the solution(s) found
  • version - returns the version of SDK that was used for the run
{
  "options": {
    "format": {
      "disable": {
        "progression": true
      }
    },
    "model": {
      "constraints": {
        "disable": {
          "attributes": false,
          "capacity": false,
          "distance_limit": false,
          "groups": false,
          "maximum_duration": false,
          "maximum_stops": false,
          "maximum_wait_stop": false,
          "maximum_wait_vehicle": false,
          "precedence": false,
          "start_time_windows": false,
          "vehicle_end_time": false,
          "vehicle_start_time": false
        },
        "enable": {
          "cluster": false
        }
      },
      "objectives": {
        "cluster": 0,
        "early_arrival_penalty": 1,
        "late_arrival_penalty": 1,
        "min_stops": 1,
        "travel_duration": 0,
        "unplanned_penalty": 1,
        "vehicle_activation_penalty": 1,
        "vehicles_duration": 1
      },
      "properties": {
        "disable": {
          "duration_groups": false,
          "durations": false,
          "initial_solution": false,
          "stop_duration_multipliers": false
        }
      },
      "validate": {
        "disable": {
          "resources": false,
          "start_time": false
        },
        "enable": {
          "matrix": false,
          "matrix_asymmetry_tolerance": 20
        }
      }
    },
    "solve": {
      "duration": 10000000000,
      "iterations": 50,
      "parallel_runs": 1,
      "run_deterministically": true,
      "start_solutions": 1
    }
  },
  "solutions": [
    {
      "objective": {
        "name": "1 * vehicle_activation_penalty + 1 * vehicles_duration + 1 * unplanned_penalty + 1 * early_arrival_penalty + 1 * late_arrival_penalty",
        "objectives": [
          {
            "base": 4000,
            "factor": 1,
            "name": "vehicle_activation_penalty",
            "value": 4000
          },
          {
            "base": 34394.3133084774,
            "factor": 1,
            "name": "vehicles_duration",
            "value": 34394.3133084774
          },
          {
            "base": 1400000,
            "factor": 1,
            "name": "unplanned_penalty",
            "value": 1400000
          },
          {
            "factor": 1,
            "name": "early_arrival_penalty",
            "value": 0
          },
          {
            "base": 621271.1251366138,
            "factor": 1,
            "name": "late_arrival_penalty",
            "value": 621271.1251366138
          }
        ],
        "value": 2059665.4384450912
      },
      "unplanned": [
        {
          "id": "s22",
          "location": {
            "lat": 35.962635,
            "lon": -78.828547
          }
        },
        {
          "id": "s16",
          "location": {
            "lat": 35.83458,
            "lon": -78.63216
          }
        },
        {
          "id": "s23",
          "location": {
            "lat": 35.84616,
            "lon": -78.60914
          }
        },
        {
          "id": "s25",
          "location": {
            "lat": 35.887575,
            "lon": -78.92051
          }
        },
        {
          "id": "s24",
          "location": {
            "lat": 35.740605,
            "lon": -78.65521
          }
        },
        {
          "id": "s26",
          "location": {
            "lat": 35.823865,
            "lon": -78.84058
          }
        },
        {
          "id": "s4",
          "location": {
            "lat": 35.77772,
            "lon": -78.505745
          }
        }
      ],
      "vehicles": [
        {
          "id": "vehicle-0",
          "route": [
            {
              "arrival_time": "2023-01-01T06:00:00-06:00",
              "cumulative_travel_duration": 0,
              "end_time": "2023-01-01T06:00:00-06:00",
              "start_time": "2023-01-01T06:00:00-06:00",
              "stop": {
                "id": "vehicle-0-start",
                "location": {
                  "lat": 35.791729813680874,
                  "lon": -78.7401685145487
                }
              },
              "travel_duration": 0
            },
            {
              "arrival_time": "2023-01-01T06:09:12-06:00",
              "cumulative_travel_distance": 5524,
              "cumulative_travel_duration": 552,
              "duration": 300,
              "end_time": "2023-01-01T06:14:12-06:00",
              "late_arrival_duration": 7752,
              "start_time": "2023-01-01T06:09:12-06:00",
              "stop": {
                "id": "s7",
                "location": {
                  "lat": 35.74261,
                  "lon": -78.749391
                }
              },
              "target_arrival_time": "2023-01-01T04:00:00-06:00",
              "travel_distance": 5524,
              "travel_duration": 552
            },
            {
              "arrival_time": "2023-01-01T06:28:29-06:00",
              "cumulative_travel_distance": 14094,
              "cumulative_travel_duration": 1409,
              "duration": 300,
              "end_time": "2023-01-01T06:33:29-06:00",
              "late_arrival_duration": 8909,
              "start_time": "2023-01-01T06:28:29-06:00",
              "stop": {
                "id": "s6",
                "location": {
                  "lat": 35.813025,
                  "lon": -78.788025
                }
              },
              "target_arrival_time": "2023-01-01T04:00:00-06:00",
              "travel_distance": 8570,
              "travel_duration": 857
            },
            {
              "arrival_time": "2023-01-01T06:49:20-06:00",
              "cumulative_travel_distance": 23604,
              "cumulative_travel_duration": 2360,
              "duration": 300,
              "end_time": "2023-01-01T06:54:20-06:00",
              "late_arrival_duration": 10160,
              "start_time": "2023-01-01T06:49:20-06:00",
              "stop": {
                "id": "s5",
                "location": {
                  "lat": 35.732995,
                  "lon": -78.75084
                }
              },
              "target_arrival_time": "2023-01-01T04:00:00-06:00",
              "travel_distance": 9510,
              "travel_duration": 951
            },
            {
              "arrival_time": "2023-01-01T07:05:29-06:00",
              "cumulative_travel_distance": 30292,
              "cumulative_travel_duration": 3029,
              "duration": 300,
              "end_time": "2023-01-01T07:10:29-06:00",
              "late_arrival_duration": 11129,
              "start_time": "2023-01-01T07:05:29-06:00",
              "stop": {
                "id": "s17",
                "location": {
                  "lat": 35.67337,
                  "lon": -78.76063
                }
              },
              "target_arrival_time": "2023-01-01T04:00:00-06:00",
              "travel_distance": 6688,
              "travel_duration": 668
            },
            {
              "arrival_time": "2023-01-01T07:34:43-06:00",
              "cumulative_travel_distance": 44835,
              "cumulative_travel_duration": 4483,
              "duration": 300,
              "end_time": "2023-01-01T07:39:43-06:00",
              "late_arrival_duration": 12883,
              "start_time": "2023-01-01T07:34:43-06:00",
              "stop": {
                "id": "s1",
                "location": {
                  "lat": 35.72389,
                  "lon": -78.90919
                }
              },
              "target_arrival_time": "2023-01-01T04:00:00-06:00",
              "travel_distance": 14543,
              "travel_duration": 1454
            },
            {
              "arrival_time": "2023-01-01T07:55:20-06:00",
              "cumulative_travel_distance": 54198,
              "cumulative_travel_duration": 5420,
              "duration": 300,
              "end_time": "2023-01-01T08:00:20-06:00",
              "late_arrival_duration": 14120,
              "start_time": "2023-01-01T07:55:20-06:00",
              "stop": {
                "id": "s2",
                "location": {
                  "lat": 35.75712,
                  "lon": -78.813862
                }
              },
              "target_arrival_time": "2023-01-01T04:00:00-06:00",
              "travel_distance": 9363,
              "travel_duration": 936
            },
            {
              "arrival_time": "2023-01-01T08:19:08-06:00",
              "cumulative_travel_distance": 65484,
              "cumulative_travel_duration": 6548,
              "duration": 300,
              "end_time": "2023-01-01T08:24:08-06:00",
              "late_arrival_duration": 15548,
              "start_time": "2023-01-01T08:19:08-06:00",
              "stop": {
                "id": "s15",
                "location": {
                  "lat": 35.83202,
                  "lon": -78.89832
                }
              },
              "target_arrival_time": "2023-01-01T04:00:00-06:00",
              "travel_distance": 11286,
              "travel_duration": 1128
            },
            {
              "arrival_time": "2023-01-01T08:43:25-06:00",
              "cumulative_travel_distance": 77046,
              "cumulative_travel_duration": 7705,
              "duration": 300,
              "end_time": "2023-01-01T08:48:25-06:00",
              "late_arrival_duration": 17005,
              "start_time": "2023-01-01T08:43:25-06:00",
              "stop": {
                "id": "s3",
                "location": {
                  "lat": 35.932795,
                  "lon": -78.92996
                }
              },
              "target_arrival_time": "2023-01-01T04:00:00-06:00",
              "travel_distance": 11562,
              "travel_duration": 1156
            },
            {
              "arrival_time": "2023-01-01T09:02:48-06:00",
              "cumulative_travel_distance": 85682,
              "cumulative_travel_duration": 8568,
              "duration": 300,
              "end_time": "2023-01-01T09:07:48-06:00",
              "late_arrival_duration": 18168,
              "start_time": "2023-01-01T09:02:48-06:00",
              "stop": {
                "id": "s18",
                "location": {
                  "lat": 36.009015,
                  "lon": -78.911485
                }
              },
              "target_arrival_time": "2023-01-01T04:00:00-06:00",
              "travel_distance": 8636,
              "travel_duration": 863
            },
            {
              "arrival_time": "2023-01-01T09:55:35-06:00",
              "cumulative_travel_distance": 114350,
              "cumulative_travel_duration": 11435,
              "end_time": "2023-01-01T09:55:35-06:00",
              "start_time": "2023-01-01T09:55:35-06:00",
              "stop": {
                "id": "vehicle-0-end",
                "location": {
                  "lat": 35.791729813680874,
                  "lon": -78.7401685145487
                }
              },
              "travel_distance": 28668,
              "travel_duration": 2866
            }
          ],
          "route_duration": 14135,
          "route_stops_duration": 2700,
          "route_travel_distance": 114350,
          "route_travel_duration": 11435
        },
        {
          "id": "vehicle-1",
          "route": [
            {
              "arrival_time": "2023-01-01T10:00:00-06:00",
              "cumulative_travel_duration": 0,
              "end_time": "2023-01-01T10:00:00-06:00",
              "start_time": "2023-01-01T10:00:00-06:00",
              "stop": {
                "id": "vehicle-1-start",
                "location": {
                  "lat": 35.791729813680874,
                  "lon": -78.7401685145487
                }
              },
              "travel_duration": 0
            },
            {
              "arrival_time": "2023-01-01T10:14:40-06:00",
              "cumulative_travel_distance": 8801,
              "cumulative_travel_duration": 880,
              "duration": 300,
              "end_time": "2023-01-01T10:19:40-06:00",
              "late_arrival_duration": 22480,
              "start_time": "2023-01-01T10:14:40-06:00",
              "stop": {
                "id": "s11",
                "location": {
                  "lat": 35.77013,
                  "lon": -78.83403
                }
              },
              "target_arrival_time": "2023-01-01T04:00:00-06:00",
              "travel_distance": 8801,
              "travel_duration": 880
            },
            {
              "arrival_time": "2023-01-01T10:24:48-06:00",
              "cumulative_travel_distance": 11889,
              "cumulative_travel_duration": 1188,
              "duration": 300,
              "end_time": "2023-01-01T10:29:48-06:00",
              "late_arrival_duration": 23088,
              "start_time": "2023-01-01T10:24:48-06:00",
              "stop": {
                "id": "s12",
                "location": {
                  "lat": 35.782855,
                  "lon": -78.864465
                }
              },
              "target_arrival_time": "2023-01-01T04:00:00-06:00",
              "travel_distance": 3088,
              "travel_duration": 308
            },
            {
              "arrival_time": "2023-01-01T10:56:41-06:00",
              "cumulative_travel_distance": 28011,
              "cumulative_travel_duration": 2801,
              "duration": 300,
              "end_time": "2023-01-01T11:01:41-06:00",
              "late_arrival_duration": 25001,
              "start_time": "2023-01-01T10:56:41-06:00",
              "stop": {
                "id": "s10",
                "location": {
                  "lat": 35.672955,
                  "lon": -78.747955
                }
              },
              "target_arrival_time": "2023-01-01T04:00:00-06:00",
              "travel_distance": 16122,
              "travel_duration": 1612
            },
            {
              "arrival_time": "2023-01-01T11:17:11-06:00",
              "cumulative_travel_distance": 37310,
              "cumulative_travel_duration": 3731,
              "duration": 300,
              "end_time": "2023-01-01T11:22:11-06:00",
              "late_arrival_duration": 26231,
              "start_time": "2023-01-01T11:17:11-06:00",
              "stop": {
                "id": "s9",
                "location": {
                  "lat": 35.64796,
                  "lon": -78.64972
                }
              },
              "target_arrival_time": "2023-01-01T04:00:00-06:00",
              "travel_distance": 9299,
              "travel_duration": 929
            },
            {
              "arrival_time": "2023-01-01T11:52:20-06:00",
              "cumulative_travel_distance": 55404,
              "cumulative_travel_duration": 5540,
              "duration": 300,
              "end_time": "2023-01-01T11:57:20-06:00",
              "late_arrival_duration": 28340,
              "start_time": "2023-01-01T11:52:20-06:00",
              "stop": {
                "id": "s21",
                "location": {
                  "lat": 35.7606,
                  "lon": -78.50509
                }
              },
              "target_arrival_time": "2023-01-01T04:00:00-06:00",
              "travel_distance": 18094,
              "travel_duration": 1809
            },
            {
              "arrival_time": "2023-01-01T12:34:43-06:00",
              "cumulative_travel_distance": 77830,
              "cumulative_travel_duration": 7783,
              "duration": 300,
              "end_time": "2023-01-01T12:39:43-06:00",
              "late_arrival_duration": 30883,
              "start_time": "2023-01-01T12:34:43-06:00",
              "stop": {
                "id": "s14",
                "location": {
                  "lat": 35.961465,
                  "lon": -78.52748
                }
              },
              "target_arrival_time": "2023-01-01T04:00:00-06:00",
              "travel_distance": 22426,
              "travel_duration": 2242
            },
            {
              "arrival_time": "2023-01-01T12:44:22-06:00",
              "cumulative_travel_distance": 80624,
              "cumulative_travel_duration": 8062,
              "duration": 300,
              "end_time": "2023-01-01T12:49:22-06:00",
              "late_arrival_duration": 31462,
              "start_time": "2023-01-01T12:44:22-06:00",
              "stop": {
                "id": "s19",
                "location": {
                  "lat": 35.93663,
                  "lon": -78.522705
                }
              },
              "target_arrival_time": "2023-01-01T04:00:00-06:00",
              "travel_distance": 2794,
              "travel_duration": 279
            },
            {
              "arrival_time": "2023-01-01T13:54:40-06:00",
              "cumulative_travel_distance": 119804,
              "cumulative_travel_duration": 11980,
              "duration": 300,
              "end_time": "2023-01-01T13:59:40-06:00",
              "late_arrival_duration": 35680,
              "start_time": "2023-01-01T13:54:40-06:00",
              "stop": {
                "id": "s13",
                "location": {
                  "lat": 35.88029,
                  "lon": -78.952142
                }
              },
              "target_arrival_time": "2023-01-01T04:00:00-06:00",
              "travel_distance": 39180,
              "travel_duration": 3918
            },
            {
              "arrival_time": "2023-01-01T14:18:14-06:00",
              "cumulative_travel_distance": 130935,
              "cumulative_travel_duration": 13094,
              "duration": 300,
              "end_time": "2023-01-01T14:23:14-06:00",
              "late_arrival_duration": 37094,
              "start_time": "2023-01-01T14:18:14-06:00",
              "stop": {
                "id": "s20",
                "location": {
                  "lat": 35.97414,
                  "lon": -78.995162
                }
              },
              "target_arrival_time": "2023-01-01T04:00:00-06:00",
              "travel_distance": 11131,
              "travel_duration": 1113
            },
            {
              "arrival_time": "2023-01-01T14:37:18-06:00",
              "cumulative_travel_distance": 139380,
              "cumulative_travel_duration": 13938,
              "duration": 300,
              "end_time": "2023-01-01T14:42:18-06:00",
              "late_arrival_duration": 38238,
              "start_time": "2023-01-01T14:37:18-06:00",
              "stop": {
                "id": "s8",
                "location": {
                  "lat": 36.039135,
                  "lon": -78.94658
                }
              },
              "target_arrival_time": "2023-01-01T04:00:00-06:00",
              "travel_distance": 8445,
              "travel_duration": 844
            },
            {
              "arrival_time": "2023-01-01T15:37:38-06:00",
              "cumulative_travel_distance": 172581,
              "cumulative_travel_duration": 17258,
              "end_time": "2023-01-01T15:37:38-06:00",
              "start_time": "2023-01-01T15:37:38-06:00",
              "stop": {
                "id": "vehicle-1-end",
                "location": {
                  "lat": 35.791729813680874,
                  "lon": -78.7401685145487
                }
              },
              "travel_distance": 33201,
              "travel_duration": 3320
            }
          ],
          "route_duration": 20258,
          "route_stops_duration": 3000,
          "route_travel_distance": 172581,
          "route_travel_duration": 17258
        }
      ]
    }
  ],
  "statistics": {
    "result": {
      "custom": {
        "activated_vehicles": 2,
        "max_duration": 20258,
        "max_stops_in_vehicle": 10,
        "max_travel_duration": 17258,
        "min_duration": 14135,
        "min_stops_in_vehicle": 9,
        "min_travel_duration": 11435,
        "unplanned_stops": 3
      },
      "duration": 0.123200958,
      "value": 2059665.4384450912
    },
    "run": {
      "duration": 0.124943291,
      "iterations": 50
    },
    "schema": "v1"
  },
  "version": {
    "sdk": "VERSION"
  }
}
Copy

Continue reading to learn more about each available template within the sdk command suite of Nextmv CLI.

nextroute template

The nextroute template is the recommended starting point when solving a vehicle routing problem (VRP) requiring custom constraints or objective functions. This includes use cases for delivery, distribution, and sourcing, such as: food delivery, waste management, ridesharing, and more. Note if custom constraints or objective functions are not required, then we recommend starting with the Nextmv routing app (the app is based on the nextroute template).

standard input:

  • vehicles - list of vehicle id
  • stops - array of stop id, and position

Check out our vehicle routing features for a full list of options that can easily be configured to solve most routing problems and our routing tutorial for more information on using the nextroute template

routing template

The routing template is a legacy template for use solving a vehicle routing problem (VRP). This includes use cases for delivery, distribution, and sourcing, such as: food delivery, waste management, ridesharing, and more. The routing template uses the Nextmv Router Engine to assign and sequence vehicle visits to stops in the form of routes.

standard input:

  • vehicles - list of vehicle id
  • stops - array of stop id, and position

See the router engine options how-to guide for a full list of options that can easily be configured to solve most routing problems and our legacy routing tutorial for more information on using the routing template

cloud-routing template

Similar to the routing template, cloud-routing is a legacy template that solves a VRP but uses a different input structure which handles flexible and optional constraints based on the input file.

standard input:

  • vehicles - array of vehicle id, capacity and start location
  • stops - array of stop id, position and quantity

Optional constraints such as penalties, precedence, and shifts are outlined in our router engine options how-to guide.

cluster template

A cluster is a collection of points that are similar to one another in some way. The goal of clustering is to find natural groupings of the data, such that the points within a cluster are more similar to each other than to points in other clusters.

Clustering has a wide range of applications in various fields, such as:

  • vehicle routing: group customers or delivery locations based on proximity/similarities. Clustering can be used to identify patterns in customer demand, such as time of day or day of the week, and then use this information to optimize the routing plan accordingly.

  • marketing: segment customers into different groups based on their demographics, purchasing habits, interests, etc. This can help companies target their marketing efforts more effectively.

  • data analysis: identify patterns and relationships in large datasets, which can help organizations make more informed decisions.

  • social network analysis: identify groups of individuals with similar characteristics or behavior in social networks, which can help researchers understand how information spreads and how communities form.

The main entities involved in the cluster template are the data points to be clustered and the clusters themselves. Each data point is a representation of an object or phenomenon in the real world, and a cluster is a group of similar data points.

standard input:

  • points - each data point to be clustered
  • clusters - number of total clusters to create
  • maximum_weight - max weight value allowed per cluster
  • weight - weight given to each point
  • maximum_points - max number of points assigned to a given cluster

For more information on clusters, check out the sdk cluster package reference guide.

cluster-tsp template

The cluster-tsp template reads a routing input data format but instead of solving a VRP directly, it creates a set of clusters in a pre-processing step, similar to the cluster template. The number of clusters created match the number of vehicles available in the input file, the cluster size is calculated such that points are distributed evenly among them. Then, for each vehicle, a traveling salesman problem (TSP) is solved. This is achieved by using the Attributes option in the routing engine.

Standard input:

  • vehicles - list of vehicle id
  • stops - array of stop id and position
  • stop_weight - weight given to each stop
  • cluster_capacities - max weight allowed for each cluster

For more information, check out the clustered routes tutorial.

knapsack template

The knapsack template solves the knapsack problem using a decision diagram-based solver. The knapsack problem is a common combinatorial optimization problem: Given a set of items, each with a weight and a value, determine which items to include in the collection so that the total weight is less than or equal to a given limit while maximizing the total value.

This template has a wide range of applications, such as:

  • Bin packing: stacking objects into bins and not caring about how it’s stacked.

  • Simple marketing spend: optimizing spend for a single marketing campaign.

  • Material cutting problems: Finding the best way to cut steel coils or irregular shapes out of some textiles with least waste/clippings.

  • Pallet packing: stacking objects in a particular way (e.g., so nothing gets crushed due to weight, etc.).

standard input:

  • items - array of potential item id, value, and weight
  • capacity - an integer representing the max weight of the knapsack

For more information about the knapsack template, check out the knapsack how-to guide

mip-knapsack template

The mip-knapsack template solves the knapsack problem described above using Mixed Integer Programming and the open-source solver HiGHS.

Assigns a set number of items to a knapsack (or container). Not all items must be assigned. Optimize for the most valuable set of items possible while not exceeding the container's carrying capacity.

standard input:

  • items - array of item_id, value, weight, and volume
  • weight_capacity - max weight the knapsack can hold
  • volume_capacity - max volume the knapsack can accept

shift-scheduling template

The shift-scheduling template assigns assigns one worker to each shift while maximizing worker happiness score (the number of times a preference of a worker has been met) and covering all shifts with as few workers as possible.

standard input:

  • days - number of days in the schedule
  • workers - number of available workers
  • preference - array of shift_type including workers who prefer a type of day
  • unavailable - array of worker and unavailable days

This template is applicable to a wide range of applications that vary in terms of complexity. This can include:

  • nurse scheduling
  • sports scheduling
  • teacher coverage
  • driver assignments
  • cloud resource allocation

For additional information, check out our shift scheduling how-to guide

pager-duty template

The pager-duty template is a specific flavor of shift scheduling that assigns users to shifts (days) for incident response on-call duty using input and output data structures compatible with PagerDuty API.

input:

  • schedule_start - the start date of the schedule
  • schedule_end - the end date of the schedule
  • users - list of users to assign to shifts, containing name, id, type, and optional unavailable days and preferences

Click here to learn how to set up and run the pager duty app, and for more background on applying the pager-duty app, check out our blog.

new-app template

The new-app template is a template shell that provides a skeleton with guidance on how to utilize store to create a completely custom model. If you want to build a completely new model from scratch, start with this template, which gives sensible defaults for how to structure, validate, and generate a new store. Note, the new-app template requires additional code and input data to run.

sudoku template

Creating an algorithmic solver for Sudoku puzzles is a common optimization programming challenge. The sudoku template demonstrates how this can be done with Nextmv. This template completes a 9x9 grid such that all columns, rows, and 3x3 subgrids contain the numerals 1 through 9.

standard inputs:

  • 9x9 matrix listing initial values (1 through 9) and empty spaces (represented by 0)

mip-meal-allocation template

The mip-meal-allocation template solves a bunny-inspired twist on the Stigler diet problem that involves determining the best allocation of meals (array of meal name) including a list of ingredients to bunnies in order to maximize the number of binkies produced. We demonstrate this by solving a demo-problem we named mip-meal-allocation.

This template allocates meals (diets) consisting of carrot and endive ingredients to bunnies with the goal of maximizing their happiness through good diets and nutrition. This template uses the open-source solver HiGHS to maximize the number of binkies our bunnies will execute by selecting their meal.

A binky is when a bunny jumps straight up and quickly twists its hind end, head, or both. A bunny may binky because it is feeling happy or safe in its environment.

The input defines a number of meals we can use to maximize binkies, which indicates their level of happiness. Each meal consists out of one or more items and in total we can only use the number of items we have in stock.

standard input:

  • items - array of food name and amount in stock

routing-matrix-input template

When using the routing-matrix-input template, the measure-matrix app must be run first to generate the necessary input required for this template.

A modeling kit for VRPs, this legacy template shows how to use a custom matrix that is passed via an input file. Together with measure-matrix, these templates create a matrix of points from a measure that is accepted by the routing app. For more information on using the routing-matrix-input template, check out the custom matrices tutorial.

standard input:

  • stops - array of stop id and position
  • vehicles - list of vehicle id
  • starts - list of vehicle start location
  • ends - list of vehicle end location
  • shifts - array of vehicle shift start and end times
  • duration_matrix - matrix of point to point costs in travel time
  • distance_matrix - matrix of point to point costs in distance

measure-matrix template

Serves as an input generator for the routing-matrix-input app. The generated input data includes matrices for distance and travel time using one of our supported measures.

For more information on using the legacy measure-matrix template, check out the custom matrices tutorial.

time-dependent-measure template

In real world VRPs, it is often needed to take the time of the day into account when calculating routes, e.g. to calculate correct ETAs during rush hours. time dependent measure is a legacy template that shows you how to make use of time dependent measures and apply different costs according to time. This template is based on the routing template and can easily be combined with more options that are shown there like time windows or capacities (among many more).

standard input:

  • vehicles - list of vehicle id
  • stops - array of stop id and position
  • shifts - array of start and end times for each vehicle

For additional information, check out the time dependent measures tutorial.

unique-matrix-measure template

The purpose of this legacy template is to reduce input file size.

If the input has many duplicate stops, instead of passing a full matrix for each point, you can find all unique points in the matrix and use a unique matrix and a list of all unique points. Every stop then references a unique point. This data can then be used to recreate a full matrix as it is expected by the solver.

If the input has many duplicate stops input file size can be reduced drastically.

standard input:

  • stops - array of stop id and position
  • vehicles - list of vehicle id
  • starts - list of vehicle start location
  • ends - list of vehicle end location
  • unique_points - a unique set of locations that need to be visited
  • unique_matrix - represents a matrix of costs for going from each of the unique points to another

Check out the unique-matrix-measure tutorial to learn more about using this template.

Page last updated

Go to on-page nav menu