Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
204 changes: 66 additions & 138 deletions docs/src/concepts/pragmatic/errors/index.md

Large diffs are not rendered by default.

95 changes: 46 additions & 49 deletions docs/src/concepts/pragmatic/problem/objectives.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,12 @@ A classical objective function (or simply objective) for VRP is minimization of
require different objective function or even more than one considered simultaneously. That's why the solver has a concept
of multi objective.


## Understanding multi objective structure

A multi objective is defined by `objectives` property which has array of objectives and defines lexicographical ordered
objective function. Here, priority of objectives decreases from first to the last element of the array. For the same
priority (or in other words, competitive) objectives, a special `multi-objective` type can be used.


## Available objectives

The solver already provides multiple built-in objectives distinguished by their `type`. All these objectives can be
Expand All @@ -21,60 +19,61 @@ split into the following groups.

These objectives specify how "total" cost of job insertion is calculated:

* `minimize-cost`: minimizes total transport cost calculated for all routes. Here, total transport cost is seen as linear
- `minimize-cost`: minimizes total transport cost calculated for all routes. Here, total transport cost is seen as linear
combination of total time and distance
* `minimize-distance`: minimizes total distance of all routes
* `minimize-duration`: minimizes total duration of all routes
- `minimize-distance`: minimizes total distance of all routes
- `minimize-duration`: minimizes total duration of all routes

One of these objectives has to be set and only one.

### Scalar objectives

Besides cost objectives, there are other objectives which are targeting for some scalar characteristic of solution:

* `minimize-unassigned`: minimizes amount of unassigned jobs. Although, solver tries to minimize amount of
unassigned jobs all the time, it is possible that solution, discovered during refinement, has more unassigned jobs than
previously accepted. The reason of that can be conflicting objective (e.g. minimize tours) and restrictive
constraints such as time windows. The objective has the following optional parameter:
* `breaks`: a multiplicative coefficient to make breaks more preferable for assignment. Default value is 1. Setting
this parameter to a value bigger than 1 is useful when it is highly desirable to have break assigned but its
assignment leads to more jobs unassigned.
* `minimize-tours`: minimizes total amount of tours present in solution
* `maximize-tours`: maximizes total amount of tours present in solution
* `minimize-arrival-time`: prefers solutions where work is finished earlier
* `fast-service`: prefers solutions when jobs are served early in tours. Optional parameter:
* `tolerance`: an objective tolerance specifies how different objective values have to be to consider them different.
Relative distance metric is used.
* `hierarchical-areas`: an experimental objective to play with clusters of jobs. Internally uses distance minimization as
- `minimize-unassigned`: minimizes amount of unassigned jobs. Although, solver tries to minimize amount of
unassigned jobs all the time, it is possible that solution, discovered during refinement, has more unassigned jobs than
previously accepted. The reason of that can be conflicting objective (e.g. minimize tours) and restrictive
constraints such as time windows. The objective has the following optional parameter: \* `breaks`: a multiplicative coefficient to make breaks more preferable for assignment. Default value is 1. Setting
this parameter to a value bigger than 1 is useful when it is highly desirable to have break assigned but its
assignment leads to more jobs unassigned.
- `minimize-tours`: minimizes total amount of tours present in solution
- `maximize-tours`: maximizes total amount of tours present in solution
- `minimize-arrival-time`: prefers solutions where work is finished earlier
- `fast-service`: prefers solutions when jobs are served early in tours. Optional parameter:
- `tolerance`: an objective tolerance specifies how different objective values have to be to consider them different.
Relative distance metric is used.
- `hierarchical-areas`: an experimental objective to play with clusters of jobs. Internally uses distance minimization as
a base penalty.
* `levels` - number of hierarchy levels
- `levels` - number of hierarchy levels

### Job distribution objectives

These objectives provide some extra control on job assignment:

* `maximize-value`: maximizes total value of served jobs. It has optional parameters:
* `reductionFactor`: a factor to reduce value cost compared to max routing costs
* `breaks`: a value penalty for skipping a break. Default value is 100.
* `tour-order`: controls desired activity order in tours
* `isConstrained`: violating order is not allowed, even if it leads to less assigned jobs (default is true).
* `compact-tour`: controls how tour is shaped by limiting amount of shared jobs, assigned in different routes,
for a given job' neighbourhood. It has the following mandatory parameters:
* `options`: options to relax objective:
- `jobRadius`: a radius of neighbourhood, minimum is 1
- `threshold`: a minimum shared jobs to count
- `distance`: a minimum relative distance between counts when comparing different solutions.
This objective is supposed to be on the same level within cost ones.

- `maximize-value`: maximizes total value of served jobs. It has optional parameters:
- `reductionFactor`: a factor to reduce value cost compared to max routing costs
- `breaks`: a value penalty for skipping a break. Default value is 100.
- `tour-order`: controls desired activity order in tours
- `isConstrained`: violating order is not allowed, even if it leads to less assigned jobs (default is true).
- `compact-tour`: controls how tour is shaped by limiting amount of shared jobs, assigned in different routes,
for a given job' neighbourhood. It has the following mandatory parameters:
- `options`: options to relax objective: - `jobRadius`: a radius of neighbourhood, minimum is 1 - `threshold`: a minimum shared jobs to count - `distance`: a minimum relative distance between counts when comparing different solutions.
This objective is supposed to be on the same level within cost ones.
- `minimize-tour-size-violation`: penalizes solutions where routes have fewer activities than the `min_tour_size`
limit defined on vehicles. Empty routes (with zero activities) are not penalized. This objective should be used
when vehicles have `min_tour_size` limits defined in their `limits` property.

### Work balance objectives

There are four work balance objectives available:

* `balance-max-load`: balances max load in tour
* `balance-activities`: balances amount of activities performed in tour
* `balance-distance`: balances travelled distance per tour
* `balance-duration`: balances tour durations
- `balance-max-load`: balances max load in tour
- `balance-activities`: balances amount of activities performed in tour
- `balance-distance`: balances travelled distance per tour
- `balance-duration`: balances tour durations
- `balance-shifts`: balances how often different vehicle shifts are used. Optional parameters:
- `saturation` (default `0.05`): controls how strongly small variance deviations are penalized. Lower values enforce nearly equal usage, while higher values allow more imbalance before additional costs are applied.
- `weight` (default `1.0`): multiplies the resulting penalty so you can emphasize or de-emphasize shift balancing relative to other objectives. This is especially important when `balance-shifts` shares a multi-objective block with cost-based objectives whose raw magnitudes are much higher.

Typically, you need to use these objective with one from the cost group combined under single `multi-objective`.

Expand Down Expand Up @@ -104,11 +103,10 @@ If at least one job has non-zero value associated, then the following objective

If order on job task is specified, then it is also added to the list of objectives after `minimize-tours` objective.


## Hints

* pay attention to the order of objectives
* if you're using balancing objective and getting high cost or non-realistic, but balanced routes, try to use multi-objective:
- pay attention to the order of objectives
- if you're using balancing objective and getting high cost or non-realistic, but balanced routes, try to use multi-objective:

```json
"objectives": [
Expand Down Expand Up @@ -137,15 +135,14 @@ If order on job task is specified, then it is also added to the list of objectiv

## Related errors

* [E1600 an empty objective specified](../errors/index.md#e1600)
* [E1601 duplicate objective specified](../errors/index.md#e1601)
* [E1602 missing one of cost objectives](../errors/index.md#e1602)
* [E1603 redundant value objective](../errors/index.md#e1603)
* [E1604 redundant tour order objective](../errors/index.md#e1604)
* [E1605 value or order of a job should be greater than zero](../errors/index.md#e1605)
* [E1606 multiple cost objectives specified](../errors/index.md#e1606)
* [E1607 missing value objective](../errors/index.md#e1607)

- [E1600 an empty objective specified](../errors/index.md#e1600)
- [E1601 duplicate objective specified](../errors/index.md#e1601)
- [E1602 missing one of cost objectives](../errors/index.md#e1602)
- [E1603 redundant value objective](../errors/index.md#e1603)
- [E1604 redundant tour order objective](../errors/index.md#e1604)
- [E1605 value or order of a job should be greater than zero](../errors/index.md#e1605)
- [E1606 multiple cost objectives specified](../errors/index.md#e1606)
- [E1607 missing value objective](../errors/index.md#e1607)

## Examples

Expand Down
105 changes: 62 additions & 43 deletions docs/src/concepts/pragmatic/problem/vehicles.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,52 +3,73 @@
A vehicle types are defined by `fleet.vehicles` property and their schema has the following properties:

- **typeId** (required): a vehicle type id

```json
{{#include ../../../../../examples/data/pragmatic/simple.basic.problem.json:100}}
```

- **vehicleIds** (required): a list of concrete vehicle ids available for usage.

```json
{{#include ../../../../../examples/data/pragmatic/simple.basic.problem.json:101:103}}
```

- **profile** (required): a vehicle profile which is defined by two properties:
- **matrix** (required) : a name of matrix profile
- **scale** (optional): duration scale applied to all travelling times (default is 1.0)
- **matrix** (required) : a name of matrix profile
- **scale** (optional): duration scale applied to all travelling times (default is 1.0)

```json
{{#include ../../../../../examples/data/pragmatic/simple.basic.problem.json:104:106}}
```

- **costs** (required): specifies how expensive is vehicle usage. It has three properties:
- **fixed**: a fixed cost per vehicle tour
- **time**: a cost per time unit
- **distance**: a cost per distance unit

- **fixed**: a fixed cost per vehicle tour
- **time**: a cost per time unit
- **distance**: a cost per distance unit

- **shifts** (required): specify one or more vehicle shift. See detailed description below.

- **capacity** (required): specifies vehicle capacity symmetric to job demand

```json
{{#include ../../../../../examples/data/pragmatic/simple.basic.problem.json:130:132}}
```

- **skills** (optional): vehicle skills needed by some jobs

```json
{{#include ../../../../../examples/data/pragmatic/basics/skills.basic.problem.json:131:133}}
```

- **limits** (optional): vehicle limits. There are two:

- **maxDuration** (optional): max tour duration
- **maxDistance** (optional): max tour distance
- **tourSize** (optional): max amount of activities in the tour (without departure/arrival). Please note, that
clustered activities are counted as one in case of vicinity clustering.

- **maxDuration** (optional): max tour duration
- **maxDistance** (optional): max tour distance
- **tourSize** (optional): max amount of activities in the tour (without departure/arrival). Please note, that
clustered activities are counted as one in case of vicinity clustering.
- **minTourSize** (optional): min amount of activities in the tour (without departure/arrival). When using this
limit, you must include `minimize-tour-size-violation` in your objectives to guide the solver toward valid solutions.
Solutions with tours having fewer activities than this limit will be rejected by the checker.

- **minShifts** (optional): enforces a minimum number of shifts which each `vehicleId` of this type should serve with
actual jobs assigned. It is defined as object with:
- `value`: minimum amount of shifts required for every vehicle id of this type.
- `allowZeroUsage` (optional, default `false`): when `true`, a vehicle id may stay completely unused; otherwise
zero usage counts als Verstoß, auch wenn die Mindestanzahl global erreicht wird.

```json
"minShifts": {
"value": 2,
"allowZeroUsage": false
}
```

An example:

```json
{{#include ../../../../../examples/data/pragmatic/simple.basic.problem.json:99:133}}
```
```

## Shift

Expand All @@ -65,48 +86,46 @@ Each shift can have the following properties:

- **start** (required) specifies vehicle start place defined via location, earliest (required) and latest (optional) departure time
- **end** (optional) specifies vehicle end place defined via location, earliest (reserved) and latest (required) arrival time.
When omitted, then vehicle ends on last job location
When omitted, then vehicle ends on last job location
- **breaks** (optional) a list of vehicle breaks. There are two types of breaks:
* __required__: this break is guaranteed to be assigned at cost of flexibility. It has the following properties:
- `time` (required): a fixed time or time offset interval when the break should happen specified by `earliest` and `latest` properties.
The break will be assigned not earlier, and not later than the range specified.
- `duration` (required): duration of the break
* __optional__: although such break is not guaranteed for assignment, it has some advantages over required break:
- arbitrary break location is supported
- the algorithm has more flexibility for assignment

- **required**: this break is guaranteed to be assigned at cost of flexibility. It has the following properties:
- `time` (required): a fixed time or time offset interval when the break should happen specified by `earliest` and `latest` properties.
The break will be assigned not earlier, and not later than the range specified.
- `duration` (required): duration of the break
- **optional**: although such break is not guaranteed for assignment, it has some advantages over required break:
- arbitrary break location is supported
- the algorithm has more flexibility for assignment
It is specified by:
- `time` (required): time window or time offset interval after which a break should happen (e.g. between 3 or 4 hours after start).
- `places`: list of alternative places defined by `location` (optional), `duration` (required) and `tag` (optional).
If location of a break is omitted then break is stick to location of a job served before break.
- `policy` (optional): a break skip policy. Possible values:
* `skip-if-no-intersection`: allows to skip break if actual tour schedule doesn't intersect with vehicle time window (default)
* `skip-if-arrival-before-end`: allows to skip break if vehicle arrives before break's time window end.
- `time` (required): time window or time offset interval after which a break should happen (e.g. between 3 or 4 hours after start).
- `places`: list of alternative places defined by `location` (optional), `duration` (required) and `tag` (optional).
If location of a break is omitted then break is stick to location of a job served before break.
- `policy` (optional): a break skip policy. Possible values:
- `skip-if-no-intersection`: allows to skip break if actual tour schedule doesn't intersect with vehicle time window (default)
- `skip-if-arrival-before-end`: allows to skip break if vehicle arrives before break's time window end.

Please note that optional break is a soft constraint and can be unassigned in some cases due to other hard constraints, such
as time windows. You can control its unassignment weight using specific property on `minimize-unassigned` objective.
See example [here](../../../examples/pragmatic/basics/break.md)

Additionally, offset time interval requires departure time optimization to be disabled explicitly (see [E1307](../errors/index.md#e1307)).

- **reloads** (optional) a list of vehicle reloads. A reload is a place where vehicle can load new deliveries and unload
pickups. It can be used to model multi trip routes.
pickups. It can be used to model multi trip routes.
Each reload has optional and required fields:
- location (required): an actual place where reload activity happens
- duration (required): duration of reload activity
- times (optional): reload time windows
- tag (optional): a tag which will be propagated back within the corresponding reload activity in solution
- resourceId (optional): a shared reload resource id. It is used to limit amount of deliveries loaded at this reload.
See examples [here](../../../examples/pragmatic/basics/reload.md).
- location (required): an actual place where reload activity happens
- duration (required): duration of reload activity
- times (optional): reload time windows
- tag (optional): a tag which will be propagated back within the corresponding reload activity in solution
- resourceId (optional): a shared reload resource id. It is used to limit amount of deliveries loaded at this reload.
See examples [here](../../../examples/pragmatic/basics/reload.md).
- **recharges** (optional, experimental) specifies recharging stations and max distance limit before recharge should happen.
See examples [here](../../../examples/pragmatic/basics/recharge.md).

## Related errors

* [E1300 duplicated vehicle type ids](../errors/index.md#e1300)
* [E1301 duplicated vehicle ids](../errors/index.md#e1301)
* [E1302 invalid start or end times in vehicle shift](../errors/index.md#e1302)
* [E1303 invalid break time windows in vehicle shift](../errors/index.md#e1303)
* [E1304 invalid reload time windows in vehicle shift](../errors/index.md#e1304)
* [E1306 time and duration costs are zeros](../errors/index.md#e1306)
* [E1307 time offset interval for break is used with departure rescheduling](../errors/index.md#e1307)
* [E1308 invalid vehicle reload resource](../errors/index.md#e1308)
- [E1300 duplicated vehicle type ids](../errors/index.md#e1300)
- [E1301 duplicated vehicle ids](../errors/index.md#e1301)
- [E1302 invalid start or end times in vehicle shift](../errors/index.md#e1302)
- [E1303 invalid break time windows in vehicle shift](../errors/index.md#e1303)
- [E1304 invalid reload time windows in vehicle shift](../errors/index.md#e1304)
- [E1306 time and duration costs are zeros](../errors/index.md#e1306)
- [E1308 invalid vehicle reload resource](../errors/index.md#e1308)
12 changes: 0 additions & 12 deletions examples/python-interop/config_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,6 @@ class Progress:
dumpPopulation: bool


Telemetry.__pydantic_model__.update_forward_refs()


@dataclass
class Config:
termination: Termination
Expand All @@ -47,16 +44,7 @@ class Logging:
enabled: bool


Logging.__pydantic_model__.update_forward_refs()


@dataclass
class Environment:
logging: Logging = Logging(enabled=True)
isExperimental: Optional[bool] = None


Config.__pydantic_model__.update_forward_refs()
Telemetry.__pydantic_model__.update_forward_refs()
Termination.__pydantic_model__.update_forward_refs()
Environment.__pydantic_model__.update_forward_refs()
Loading