Community apps are decision models which you can use either directly via subscription apps or as a starting point to develop your own custom app. They are pre-built decision models which provide all of the files required to publish the app to the Nextmv Platform.
This guide will walk you through our app structure. For a list of existing apps, run the following command:
Name | Type | Description |
---|---|---|
python-ortools-costflow | Python | Demonstrates how to solve a cost-flow problem using Google OR-Tools. |
go-highs-knapsack | Go | Demonstrates how to solve a Mixed Integer Programming problem using Nextmv Go SDK. |
java-ortools-knapsack | Java | Demonstrates how to solve a Mixed Integer Programming problem using the open source software suite OR–Tools. |
python-ortools-knapsack | Python | Demonstrates how to solve a Mixed Integer Programming problem using the open source software suite OR–Tools. |
python-pyomo-knapsack | Python | Demonstrates how to solve a Mixed Integer Programming problem using the open source software suite Pyomo. |
knapsack-xpress | Python | Demonstrates how to solve a Mixed Integer Programming problem using the commercial solver FICO Xpress. |
go-nextroute | Go | Solves a vehicle routing problem for delivery, distribution, and sourcing problems using nextroute . |
go-highs-orderfulfillment | Python | Solves a MIP-based order fulfillment model using the Nextmv SDK. |
python-ortools-routing | Python | Solves an unconstrained vehicle routing problem. |
python-ortools-shiftassignment | Python | Solves a MIP-based shift assignment model using OR-Tools. |
python-pyomo-shiftassignment | Python | Solves a MIP-based shift assignment model using Pyomo. |
python-ortools-shiftplanning | Python | Solves a MIP-based shift planning model using OR-Tools. |
python-pyomo-shiftplanning | Python | Solves a MIP-based shift planning model using Pyomo. |
go-highs-shiftscheduling | Go | Solves a MIP-based shift scheduling model using the Nextmv SDK. |
To clone the app locally, run the following command from your terminal (the example showcases the nextroute
app):
This command uses the "latest"
version of the app. You can also specify a version for the app.
The available versions of each app can be listed using the following command:
Once the app is cloned locally, change directories into the newly created app folder.
The following table shows the main files that are created under the app folder.
File | Description |
---|---|
LICENSE | Contains the license under which we distribute this app. |
README.md | Gives a short introduction to the problem and shows you how to run the app. |
app.yaml | Contains the configuration (app manifest) for the app. |
input.json | Describes the input data for a specific problem that is solved by the app. |
main.go /Main.java /main.py | Contains the main code of the app. |
.code-workspace | This file should be used to open the app in Visual Studio Code. It is pre-configured for you so that you can run and debug the app without any further steps. |
Now you can run the app locally 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.
Look for the app's README.md
file, where precise instructions on how to run the app are provided.
Input File
The input.json
file lists the required fields that will be ingested into the model. These include:
- entities - available entities to utilize in the solution, for routing, this includes
Vehicles
andStops
, 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"] } ] }
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 runduration
, 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": { "check": { "duration": 30000000000, "verbosity": "off" }, "format": { "disable": { "progression": true } }, "model": { "constraints": { "disable": { "attributes": false, "capacities": null, "capacity": false, "distance_limit": false, "groups": false, "maximum_duration": false, "maximum_stops": false, "maximum_wait_stop": false, "maximum_wait_vehicle": false, "mixing_items": false, "precedence": false, "start_time_windows": false, "vehicle_end_time": false, "vehicle_start_time": false }, "enable": { "cluster": false } }, "objectives": { "capacities": "", "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": 3000000000, "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": "s16", "location": { "lat": 35.83458, "lon": -78.63216 } }, { "id": "s22", "location": { "lat": 35.962635, "lon": -78.828547 } }, { "id": "s23", "location": { "lat": 35.84616, "lon": -78.60914 } }, { "id": "s24", "location": { "lat": 35.740605, "lon": -78.65521 } }, { "id": "s25", "location": { "lat": 35.887575, "lon": -78.92051 } }, { "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": 7 }, "duration": 0.123, "value": 2059665.4384450912 }, "run": { "duration": 0.123, "iterations": 50 }, "schema": "v1" }, "version": { "nextroute": "VERSION", "sdk": "VERSION" } }