Runners
Runners are needed to deploy your app. Runners read data into a state structure, run a solver or simulator, and get decisions as data. See the deployment overview page for more information on prebuilt runners available for use with the Nextmv Decision Stack.
Apps
Nextmv apps are industry-specific applications that can be used as is or extended as needed to meet your needs for your specific use case. For example, see the engines overview page for a list of prebuilt filters and constraints available for use with the Dispatch App for routing a fleet of vehicles.
Apps are available on GitHub (contact support@nextmv.io for access).
In each app, the cmd
directory contains the main.go
, cmd.sh
and supporting data files needed to run the app. Apps provide a starting point for solving real-world problems using our solvers and engines. If you are just getting started, check out our n-queens app.
Engines
Engines are Nextmv's implementations of high-performance algorithms that handle common tasks. These can be used directly or as components in your own decision models similar to plugin architectures.
Engines each have a struct defining its expected input. Engines implement Hop's model.State
interface, and can be passed directly to Hop's solver constructors. By convention, engines provide the following exported types and functions for constructing models:
Input
: a struct defining required model input.DefaultModel
: a function that converts anInput
, and any other required data, into a Hop model.DefaultSolver
: a function that converts anInput
, and any other required data, into a Hop solver.DefaultOptions
: a function to configure default solver options for a model.
Additionally, for fleet routing problems, engines provide:
DefaultAssigner
: a function that converts anInput
, and any other required data, into a Hop assigner.
Default solver vs model
There are typically 3 usage patterns for engines:
Problem | Data | Usage Pattern |
---|---|---|
Standard | Adheres to Input structure | Install and run DefaultSolver directly |
Standard | Can be transformed into Input structure | Modify main , build, and run DefaultSolver |
Extension | Adheres to (or can be transformed into) Input structure | Instantiate a DefaultModel , extend standard model, build, and run new solver |
"Standard" here refers to the standard modeling problem represented by an engine. For example, a Traveling Salesperson Problem (TSP) is our standard vehicle engine that can be used standalone (standard) or nested inside of a knapsack problem (extension).
As mentioned above, a user can install and run the DefaultSolver
directly. For example, the package github.com/nextmv-io/code/engines/route
provides a default routing model for the Capacitated Vehicle Routing Problem (CVRP).
If the input data does not conform to the required Input
format, the main
method for the user model can be modified to transform input data into the required format for using the DefaultSolver
directly.
The DefaultSolver configuration can be found in vehicle/default.go
and shows that a cost matrix is the standard measure for this TSP.
Modelers may, however, choose to use engines as components and build extensions around them rather than using the solver directly. Calling DefaultModel
rather than DefaultSolver
gives the modeler access to the exported components of the underlying model which allows a user to build and test models without having to dive into the individual model source.
Constraints
Our engines can be configured with prebuilt, commonly used constraints as well as a constraint interface for building custom constraints unique to your business.
You can find a full list of constraints for each model in the Engines' package docs.
Here is an example of a model with capacity, precedence (pickups happen before dropoffs), window (locations must be visited within cost windows), and max length (route must be less than or equal to the max) constraints for routing vehicles.
Our clustering models can also have constraints. For example you may want to dictate how many points are in a cluster (cardinality) or their combined weight (capacity). Here is an example using both.
Measures
Measures tell the model how to access the cost of an arc or connection between two locations. Engines can be used with a predefined collection of measures (e.g., haversine
and matrix
) which give users flexibility in how routes are compared. Measures also allow you to scale, override, or make cost between locations constant.
In the example below, the measure will tell the Vehicle
model that the cost between any two locations is time (haversine distance scaled by 1/speed) as a default. The override cost will be 0 if the driver is going from any location to the end of their route. This is useful for any routing model that does not specify an end location for the driver or does not return to a depot (think real-time gig economy).
See the Measures page and engine package docs for more information on measures and how to use the different measures available with Nextmv.
Solvers and simulators
While you can use Nextmv solvers and simulators directly, we recommend starting with an app or engine first. See the best practices for more information on using Nextmv solvers and simulators with apps and engines.