This feature is configurable through options, without the need for code customization and is available in both the Marketplace app and Platform. You can find a list of all available features here.
Nextcheck is a feature that can be used with apps based on our vehicle routing engine in the following scenarios:
- Input check: In this scenario the submitted input file is checked. As a result Nextcheck will report which plan units can be planned and which cannot. This check can be run locally to test input files ad hoc, or it could be used as a pre-check for your input files.
- Solution check: In this use case you have a solution and want to know why you have unplanned stops.
Usage
A move is a definition of a plan action for a plan unit. For each stop in the plan unit the move defines where the stop is added to an existing vehicle solution. A move is used to determine if it can be executed (aka it does not violate any constraints) and if so what the impact is on the objective.
The Nextcheck report is enabled by defining the verbosity level for Nextcheck through options. There are four levels of verbosity that you can request for your report: off
, low
, medium
, and high
.
off
— Nextcheck is disabled, no report is generated. This is the default setting for Nextcheck.low
— For each plan unit we determine if there is a feasible move that improves the solution.medium
— For each plan unit we determine the best feasible move that improves the solution and report its impact on the objective. At this level we also report what vehicles have a feasible move for the plan unit.- For each plan unit, Nextcheck determines the best feasible move that improves the solution and reports its impact on the objective. At this level, it also reports how many moves on each vehicle can be executed.
- If there is no executable move, the report will provide a list of constraints that have prevented a feasible move and the number of times that constraint was responsible for not accepting a move. Note that other constraints may have been violated as well, but as soon as Nextcheck encounters a constraint violation for a move, it stops checking for other constraint violations for that move because it is no longer necessary to do so.
high
— For each plan unit, we report the same level of detail defined inmedium
above with the addition of a property that defines which vehicles have moves for the plan unit that will improve the solution.
To check an input file you need to make sure that none of the vehicles have any initial stops with the property fixed
set to false
. Once the input file complies with this requirement the check can be performed.
If you want to check a solution, you need to create an input file where your previously generated solution is added to the vehicles as initial stops.
You can see an example output here where the verbosity
was set to high
:
Interpretation
The following table contains an overview of what the individual parts of the nextcheck summary are:
Field name | Description |
---|---|
check.remark | Status of the check by nextcheck. Possible values: completed (The check was completed), timeout (The check was not completed due to a timeout during the check. Try a higher duration maximum setting for nextcheck.). |
check.verbosity | Reports the level of verbosity of nextcheck. Possible values: off , low , medium , high . |
check.duration_maxium | The maximum duration of the check (default 30s). |
check.duration_used | The time nextcheck used to finish the analyis (in seconds). |
check.solution | Contains an overview of the solution. |
check.summary | Contains a summary of nextcheck's analysis. |
check.plan_units | Contains a list of the unplanned plan units together with a list of reasons why they were not planned. |
check.vehicles | Contains a list of vehicles, where each vehicle is represented by its ID and the number of plan units that have a move on this vehicle (plan_units_have_moves ). |
check.solution
Field name | Description |
---|---|
check.solution.stops_planned | The number of planned stops in the solution. |
check.solution.plan_units_planned | The number of planned plan units in the solution. |
check.solution.plan_units_unplanned | The number of unplanned plan units in the solution. |
check.solution.vehicles_used | The number of used vehicles in the solution. |
check.solution.vehicles_not_used | The number of not utilized vehicles in the solution. |
check.solution.objective | An overview of the value function, showing the individual terms with their values as well as the total value. |
check.summary
Field name | Description |
---|---|
check.summary.plan_units_to_be_checked | The number of plan units that needed to be checked by nextcheck. |
check.summary.plan_units_checked | The number of plan units that were checked by nextcheck. If this is less than plan_units_to_be_checked a time-out occured. |
check.summary.plan_units_best_move_found | The number of plan units for which at least one executable move has been found. The moves do not necessarily improve the objective. |
check.summary.plan_units_have_no_move | The number of plan units for which no executable move has been found or no move exists at all. |
check.summary.number_of_plan_units_making_objective_worse | The number of plan units where the best executable move increases the objective value. As the solver is minimizing the objective value, it won't select such a move and therefore such a plan unit would not be assigned to a vehicle. |
check.summary.plan_units_best_move_failed | The number of plan units for which the best move can't be planned. |
check.summary.moves_failed | The number of checked moves that violated constraints. |
check.plan_units
Field name | Description |
---|---|
stops | The stop IDs belonging to the plan unit. |
has_plannable_best_move | Whether a plannable move was found for the plan unit and it was executed successfully. If no move was found, it's possible that the plan unit has too many restrictions from constraints or that it is too expensive. |
planning_makes_objective_worse | Whether the best executable move of the plan unit increases the objective value. As the solver is minimizing the objective value, it won't select such a move and therefore such a plan unit would not be assigned to a vehicle. |
best_move_failed | Whether the best move of the plan unit failed to execute. |
vehicles_have_moves | The number of vehicles for which a move with this plan unit exists. Only displayed if verbosity is set to medium or high . |
vehicles_with_moves | A list of vehicles, for which a move for this plan unit exists. |
best_move_objective | The estimate of the objective of the best move if the plan unit has one. |
constraints | Contains a list of constraints that have been violated by this plan unit. For each constraint, the number of vehicles for which the constraint fails is also given. |
check.plan_units.vehicles_with_moves
Field name | Description |
---|---|
vehicle_id | The ID of the vehicle. |
delta_objective_estimate | The estimate of the delta that would be incurred by the move on this vehicle. |
delta_objective | The actual delta that would be incurred by the move on this vehicle. This value should be equal to delta_objective_estimate . If it is not, this is reason to investigate the implementation of the objective function. |
failed_constraints | The constraints that are violated by the move on this vehicle. |
was_plannable | Whether the move was plannable or not. |
positions | Defines where the stop should be inserted with a move on this vehicle. |
check.plan_units.vehicles_with_moves.positions
Field name | Description |
---|---|
previous | The ID of the stop after which the stop should be inserted. |
stop | The ID of the stop that should be inserted. |
next | The ID of the stop before the stop should be inserted. |
check.plan_units.constraints
The following table gives an overview of possible constraints for which a plan unit might fail. In order to better understand some of these constraints, it is worth noting the definition of certain semantics:
- arrival time at the location of a stop = end time of the previous stop + travel duration to the current stop
- start time of a stop = max(arrival time at the location of the stop, earliest allowed start time of the stop)
- end time of a stop = start time of the stop + duration of the stop
- wait time at the location of a stop = start time of the stop - arrival time at the location of stop
Field name | Description |
---|---|
late_start_penalty | It is only possible to start a stop after the end of the allowed window for this stop. |
late_end_penalty | The plan unit can only be planned such that it ends after its latest end. |
attributes | There is a mismatch between the attributes of this plan unit and the attributes of the indicated vehicles. |
maximum_duration | The plan unit can't be assigned unless the total violates breaks the maximum duration constraint. The total duration is defined as last_stop.end - first_stop.start of a vehicle. |
maximum_stops | The plan unit can't be assigned without breaking the maximum stops constraint. |
maximum_travel_duration | The plan unit can't be assigned without breaking the maximum travel duration constraint. |
maximum_stop_wait | The plan unit can't be assigned without having a longer wait time than what is allowed by the maximum wait time constraint for the stop. |
maximum_vehicle_wait | The plan unit can't be assigned without having a longer wait time than what is allowed by the maximum wait time constraint for the vehicle. |
no_mix | The plan unit can't be assigned without mixing it with another plan unit, for which a no mix constraint exists. |
successor | The plan unit can only be assigned such that it is planned after stops that disallow this plan unit as a successor. |
check.vehicles
Field name | Description |
---|---|
id | The ID of the vehicle. |
plan_units_have_moves | The number of plan units that have a move for this vehicle. Is only displayed if verbosity is set to medium or high . |