Skip to content

Commit

Permalink
Update documentation a bit
Browse files Browse the repository at this point in the history
  • Loading branch information
reinterpretcat committed Oct 5, 2023
1 parent 0e5f468 commit 5e8bd78
Show file tree
Hide file tree
Showing 17 changed files with 133 additions and 37 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ All notable changes to this project will be documented in this file.
* apply code style refactoring
* improve selection sampling search
* update dependencies
* improve a bit documentation

### Fixed

Expand Down
3 changes: 2 additions & 1 deletion docs/src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,9 @@
* [Internals](internals/index.md)
* [Overview](internals/overview.md)
* [Development](internals/development/index.md)
* [Project Structure](internals/development/structure.md)
* [Solver extension](internals/development/extension.md)
* [Code style](internals/development/code-style.md)
* [Testing](internals/development/testing.md)
* [Algorithms](internals/algorithms/index.md)
* [Rosomaxa](internals/algorithms/rosomaxa.md)
* [Hyper-heuristic](internals/algorithms/hyper.md)
4 changes: 0 additions & 4 deletions docs/src/internals/algorithms/hyper.md

This file was deleted.

37 changes: 26 additions & 11 deletions docs/src/internals/algorithms/rosomaxa.md
Original file line number Diff line number Diff line change
@@ -1,39 +1,44 @@
# ROSOMAXA

`ROSOMAXA` stands for Routing Optimizations with Self-Organizing Maps And EXtrAs - a custom algorithm which addresses
the problem of population diversity: ability to retain different individuals in the population and use them as an input
for the search procedure. This is important to prevent premature convergence in local optimum.
`ROSOMAXA` stands for Routing Optimizations with Self-Organizing Maps And EXtrAs - a custom evolutionary algorithm which
tries to address the problem of population diversity: ability to retain different individuals in the population and use
them as an input for the search procedure. Additionally, it utilizes reinforcement learning technics to dynamically pick
suitable meta-heuristics for given problem formulation to avoid premature convergence.


## Key ideas

The `rosomaxa` algorithm is based on the following key ideas:

* use Growing Self-Organizing Map to cluster discovered solutions and retain good, but different ones
* use [Growing Self-Organizing Map](https://en.wikipedia.org/wiki/Growing_self-organizing_map)(GSOM) to cluster discovered solutions and retain good, but different ones
* choice clustering characteristics which are specific to solution geometry rather to objectives
* use 2D visualization to analyze and understand algorithm behavior
* use 2D visualization to analyze and understand algorithm behavior. See an interactive demo [here](https://reinterpretcat.github.io/heuristics/www/)
* utilize reinforcement learning technics in dynamic hyper-heuristic to choose one of pre-defined meta-heuristics on each solution refinement step.


### Clustering

Solution clustering is preformed by custom implementation of [a growing self-organizing map (GSOM)](https://en.wikipedia.org/wiki/Growing_self-organizing_map)
which is a growing variant of a self-organizing map. In `rosomaxa`, it has the following characteristics:
Solution clustering is preformed by custom implementation of a growing self-organizing map which is a growing variant
of a self-organizing map. In `rosomaxa`, it has the following characteristics:

* each node maintains a small population which keeps track of a few solutions selected by elitism approach
* nodes are created and split based on selected solution characteristics, such as:
* nodes are created and split based on selected solution characteristics. For VRP domain, they are such as:
- vehicle max load variance
- standard deviation of the number of customer per tour
- mean of route durations
- mean of route distances
- mean of route waiting times
- average distance between route medoids
- amount of routes
* periodically, the network is compacted and rebalanced to keep search analyzing most prominent local optimums
* periodically, the network is compacted and rebalanced to keep search analyzing most prominent local optimum.
Compaction is done using a "decimation" approach: remove every second-third (configurable) column/row and move
survived cells towards the center (a node with (0, 0) as a coordinate). Overall, this approach seems help to maintain
a good exploration-exploitation ratio.


### Visualization

This animation shows some insights how algorithms performs over time:
This old animation shows some insights how algorithms performs over time:

![Visualization example](../../images/rosomaxa.gif "Visualization")

Expand All @@ -42,9 +47,19 @@ Here:
* `t_matrix` and `l_matrix` shows how often nodes are updated
* `objective_0`, `objective_1`, `objective_2`: objective values such as amount of unassigned jobs, tours, and cost


### Dynamic hyper-heuristic

Essentially, a built-in dynamic hyper-heuristic uses [Multi-Armed Bandit](https://en.wikipedia.org/wiki/Multi-armed_bandit)
with [Thompson sampling](https://en.wikipedia.org/wiki/Thompson_sampling) approach to pick meta-heuristic for the list.
This helps to address [exploration-exploitation dilemma](https://en.wikipedia.org/wiki/Exploration-exploitation_dilemma)
in applying a strategy of picking heuristics.


## Further research

* experiment with different solution characteristics
* rebalance GSOM parameters based on search progression
* analyze "heat" map dynamically to adjust GSOM parameters
* add control of `exploration` vs `exploitation` ratio
* more fine-grained control of `exploration` vs `exploitation` ratio
* try to calculate gradients
44 changes: 44 additions & 0 deletions docs/src/internals/development/extension.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# How to extend solver

This section's intention is to give a very brief explanation of some key concepts which might be needed for adding an extra
feature on top of existing logic. For more detailed information, check the corresponding main crates documentation or
source code

## Constrains & objectives

A Vehicle Routing Problem used to consist of various constraints and objectives functions, such as:
* capacity constraint
* time window constraint
* job's total value maximization
* cost/duration/distance minimization
* etc.

Internally, they can be divided into different groups:
- `hard constraints`: a problem invariants which must be hold. Examples: vehicle capacity, job time window.
- `soft constraints`: a problem variants which should be either maximized or minimized. Examples: job assignment, served job's total value.
- `objectives`: an objective of optimization. Typically, it is hierarchical: first, try to assign all jobs, then reduce the total cost of serving them
- `state`: an auxiliary logic to cache some important state and retrieve it faster during search


Under the hood, a [feature](https://docs.rs/vrp-core/latest/vrp_core/models/struct.Feature.html) concept combines all these groups.
This is based on observation, that many features requires constraint and objective defined at the same time.

## A feature concept

Let's take a brief look at some example: a total job value feature, which purpose to maximize value of assigned jobs.
Here, each job has some associated value (or zero if it is not specified) and the purpose is to maximize it.

The following code below utilizes `FeatureBuilder` to construct the feature:

```rust,no_run,noplayground
{{#include ../../../../vrp-core/src/construction/features/total_value.rs:30:45}}
```

This builder gets:
- a unique feature `name`
- dedicated `objective function` which counts value and prefers solutions where it is maximized
- a dedicated `constraint` which enforces some problem invariants regarding job value (in this case, only for proximity clustering)

Additionally, the builder accepts `FeatureState`. Check existing features for more details.

TODO: expand example
2 changes: 1 addition & 1 deletion docs/src/internals/development/index.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
# Development

This chapter describes development topics, such as code style, testing, etc.
This chapter describes development topics, such as high level architecture, project structure, code style, testing, etc.
36 changes: 36 additions & 0 deletions docs/src/internals/development/structure.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Project structure

The project consists of the main and auxiliary crates. Additionally, there is some logical separation inside each group.

## Main crates

The following crates are "the heart" of VRP solver:

* [`rosomaxa`](https://docs.rs/rosomaxa/latest): contains key algorithms for solving optimization problems __without__
locking to the VRP domain such as hyper heuristics, evolution strategies, etc.
* [`vrp_core`](https://docs.rs/vrp_core/latest): this crate provides all core VRP models with various meta heuristics to
solve rich VRP
* [`vrp_scientific`](https://docs.rs/vrp_scientific/latest): has a building blocks to solve problems from some of scientific
benchmarks. It is useful to evaluate the solver performance in terms of solution quality, search stability and running time.
* [`vrp_pragmatic`](https://docs.rs/vrp_pragmatic/latest): provides models and features to support rich VRP. It includes:
* pragmatic model, serializable in json
* solution checker
* problem validator
* [`vrp_cli`](https://docs.rs/vrp_cli/latest): exposes VRP solve as command line interface or static library. Additionally,
has some extra features, such as:
* various extra commands
* pyO3 bindings to make library usable from Python
* WASM bindings to run solver directly in the browser
* ..

For these crates, you can find extra information normally published on docs.rs.

## Helper crates/functionality

There are few:

* `experiments/heuristic-research`: my way to experiment with heuristic using some hooks and visualizations.
Live version is exposed [here](https://reinterpretcat.github.io/heuristics/www/)
* `examples/json-pragmatic`: provides example how to use the library as a crate + contains tests and benchmarks on test data
* `examples/jvm-interop` / `python-interop`: some examples how to call library from other languages
* `examples/data`: various examples of problem definitions. Mostly used for testing and documentation
8 changes: 4 additions & 4 deletions docs/src/internals/development/testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ The testing module is considered as child module, that's why it has full access
### shared functionality
- fake/stubs
- fake constraints
- add helper logic for repetable setup/validation functionality
- add helper logic for repeatable setup/validation functionality
- simple functions
- builder pattern
- should be easily discoverable
Expand Down Expand Up @@ -74,7 +74,7 @@ The testing module is considered as child module, that's why it has full access
### performance testing
- libraries
- criterion
- can be run using command ..
- can be run using `cargo bench` command
- difficult to have results stable
- no isolation
- non-determinism
Expand All @@ -89,7 +89,7 @@ The testing module is considered as child module, that's why it has full access


### documentation tests
- very few at the moment as the main focus is on standalone usage, not on a crate
- very few at the moment as the main focus is on standalone usage, not on as a crate lib.


## metrics
Expand All @@ -101,4 +101,4 @@ The testing module is considered as child module, that's why it has full access
- 90% is fine

### tests stability
- no random failures
- aim for no random failures
7 changes: 5 additions & 2 deletions vrp-core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
//! Another goal is an intuitive design: it should be relatively easy to start using it without prior
//! knowledge of the domain. That's why the API design does not try to generalize models and
//! implementations in order to develop a general purpose metaheuristic.
//! Check [rosomaxa](https://docs.rs/rosomaxa/latest) crate for more generic models/algorithms.
//!
//!
//! Extra functionality, already developed on top of this crate, is available via following crates:
Expand All @@ -26,19 +27,21 @@
//! The next sections explain some basic concepts such as types used to model VRP definition,
//! constructive heuristics, metaheuristic, etc. Start exploring them, if you are curious about
//! internal implementation or library extension. It you are looking just for user documentation,
//! check! the [`user guide`] documentation.
//! check the [`user guide`] documentation.
//!
//! [`user guide`]: https://reinterpretcat.github.io/vrp/
//!
//!
//! # Modeling VRP
//!
//! Model definitions can be split into three groups:
//! Model definitions can be split into the following groups:
//!
//! - [`common`] group contains common models: time-specific, location, distance, etc.
//! - [`problem`] group contains VRP definition models: job, vehicle, cost-specific, etc.
//! - [`solution`] group contains models which used to represent a VRP solution: route, tour, activity, etc.
//!
//! Additionally, there are a key concepts such as `Feature` and `GoalContext`.
//!
//! Check corresponding modules for details.
//!
//! [`common`]: ./models/common/index.html
Expand Down
11 changes: 4 additions & 7 deletions vrp-core/src/models/problem/fleet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,8 @@ pub struct Costs {
#[derive(Clone, Hash, Eq, PartialEq)]
pub struct DriverDetail {}

/// Represents a driver, person who drives Vehicle.
/// Introduced to allow the following scenarios:
/// * reuse vehicle multiple times with different drivers
/// * solve best driver-vehicle match problem.
/// NOTE: At the moment, it is not used.
/// Represents a driver, person who drives Vehicle. Reserved for future usage, e.g. to allow
/// reuse same vehicle more than once at different times.
pub struct Driver {
/// Specifies operating costs for driver.
pub costs: Costs,
Expand Down Expand Up @@ -80,7 +77,7 @@ pub struct Vehicle {
pub details: Vec<VehicleDetail>,
}

/// Represents an actor detail.
/// Represents an actor detail: exact start/end location and operating time.
#[derive(Clone, Hash, Eq, PartialEq)]
pub struct ActorDetail {
/// A place where actor's vehicle starts.
Expand All @@ -93,7 +90,7 @@ pub struct ActorDetail {
pub time: TimeWindow,
}

/// Represents an actor.
/// Represents an actor: abstraction over vehicle and driver.
pub struct Actor {
/// A vehicle associated within actor.
pub vehicle: Arc<Vehicle>,
Expand Down
5 changes: 3 additions & 2 deletions vrp-core/src/models/problem/jobs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,8 @@ impl Debug for Multi {
}
}

/// Defines a trait to work with multi job's permutations.
/// Defines a trait to work with multi job's permutations. Essentially, it specifies valid combinations
/// of sub-jobs inside multi-job.
pub trait JobPermutation {
// TODO fix all implementations to support returning reference
/// Returns a valid permutation.
Expand All @@ -132,7 +133,7 @@ pub trait JobPermutation {
fn validate(&self, permutation: &[usize]) -> bool;
}

/// Specifies permutation generator which allows only fixed set of permutations.
/// Specifies job permutation generator which allows only fixed set of permutations.
pub struct FixedJobPermutation {
permutations: Vec<Vec<usize>>,
}
Expand Down
2 changes: 1 addition & 1 deletion vrp-pragmatic/src/construction/enablers/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//! Provides extension logic.
//! Provides extension logic for building various VRP features.
use std::sync::Arc;
use vrp_core::models::common::Dimensions;
Expand Down
2 changes: 1 addition & 1 deletion vrp-pragmatic/src/construction/features/reachable.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//! Creates a feature to detect filter jobs based on their reachability.
//! A feature to detect filter jobs based on their reachability.
use super::*;
use vrp_core::models::problem::{TransportCost, TravelTime};
Expand Down
3 changes: 2 additions & 1 deletion vrp-pragmatic/src/construction/features/recharge.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
//! Provides way to insert recharge stations in the tour to recharge (refuel) vehicle.
//! An experimental feature which provides way to insert recharge stations in the tour to recharge
//! (refuel) vehicle.
#[cfg(test)]
#[path = "../../../tests/unit/construction/features/recharge_test.rs"]
Expand Down
2 changes: 1 addition & 1 deletion vrp-pragmatic/src/format/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ impl std::fmt::Display for Location {
/// A custom location type which has no reference to matrix.
#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
pub enum CustomLocationType {
/// Unknown type which has a zero distance/duration to any other location.
/// Unknown location type which has a zero distance/duration to any other location.
#[serde(rename(deserialize = "unknown", serialize = "unknown"))]
Unknown,
}
Expand Down
2 changes: 1 addition & 1 deletion vrp-pragmatic/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ use time::format_description::well_known::Rfc3339;
use time::OffsetDateTime;
use vrp_core::prelude::GenericError;

/// Get lists of problem.
/// Get lists of unique locations in the problem. Use it to request routing matrix from outside.
pub fn get_unique_locations(problem: &Problem) -> Vec<Location> {
CoordIndex::new(problem).unique()
}
Expand Down
1 change: 1 addition & 0 deletions vrp-scientific/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
//!
//! - **solomon**: see [Solomon benchmark](https://www.sintef.no/projectweb/top/vrptw/solomon-benchmark)
//! - **lilim**: see [Li&Lim benchmark](https://www.sintef.no/projectweb/top/pdptw/li-lim-benchmark)
//! - **tsplib** subset of TSPLIB95 format
#![warn(missing_docs)]
#![forbid(unsafe_code)]
Expand Down

0 comments on commit 5e8bd78

Please sign in to comment.