Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Benders documentation #965

Merged
merged 4 commits into from
Jun 28, 2023
Merged
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
210 changes: 181 additions & 29 deletions docs/src/api/benders.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,93 @@
CurrentModule = Coluna
```

# Benders API
# Benders cut generation

Coluna provides an interface and generic functions to implement a Benders cut generation
algorithm.
Here is an overview of the main concepts and a description of the default implementation.

## Problem information
In this section, we are first going to present the generic functions, the implementation with some theory backgrounds and then give the references of the interface.
The default implementation is based on the paper of

The following methods provide information about the reformulation that the Benders cut
generation algorithm will solve:
You can find the generic functions and the interface in the `Benders` submodule and the
default implementation in the `Algorithm` submodule at `src/Algorithm/benders`.

## Context

The `Benders` submodule provides an interface and generic functions to implement a benders cut generation algorithm. The implementation depends on an object called `context`.

```@docs
Coluna.Benders.AbstractBendersContext
```

Benders provides two types of context:

```@docs
Coluna.Algorithm.BendersContext
Coluna.Algorithm.BendersPrinterContext
```

## Generic functions

Generic functions are the core of the Benders cut generation algorithm.
There are three generic functions:

```@docs
Coluna.Benders.run_benders_loop!
```
See ...

```@docs
Coluna.Benders.run_benders_iteration!
```
See ...

These functions are independant of any other submodule of Coluna.
You can use them to implement your own Benders cut generation algorithm.

## Reformulation

The default implementation works with a reformulated problem contained in
`MathProg.Reformulation` where master and subproblems are `MathProg.Formulation` objects.

The master has the following form:

```math
\begin{aligned}
\min \quad& cx + \sum_{k \in K} \eta_k & &\\
\text{s.t.} \quad& Ax \geq a & & (1) \\
& \text{< benders cuts>} & & (2) \\
& l_1 \leq x \leq u_1 & & (3) \\
& \eta_k \in \mathbb{R} & \forall k \in K \quad& (4)
\end{aligned}
```

where $x$ are first-stage variables,
$\eta_k$ is the second-stage cost variable for the subproblem $k$,
constraints $(1)$ are the first-stage constraints,
constraints $(2)$ are the Benders cuts,
constraints $(3)$ are the bounds on the first-stage variables,
and expression $(4)$ shows that second-stage variables are free.

The subproblems have the following form:

```math
\begin{aligned}
\min \quad& fy + \mathbf{1}z' + \mathbf{1}z'' &&& \\
\text{s.t.} \quad& Dy + z' \geq d - B\bar{x} && (5) \quad& {\color{blue}(\pi)} \\
& Ey + z'' \geq e && (6) \quad& {\color{blue}(\rho)} \\
& l_2 \leq y \leq u_2 && (7) \quad& {\color{blue}(\sigma)}
\end{aligned}
```

where $y$ are second-stage variables, $z'$ and $z''$ are artificial variables,
constraints (5) are the reformulation of linking constraints using the first-stage solution $\bar{x}$,
constraints (6) are the second-stage constraints,
and constraints (7) are the bounds on the second-stage variables.
In blue, we define the dual variables associated to these constraints.


**References**:

```@docs
Coluna.Benders.is_minimization
Expand All @@ -20,46 +97,67 @@ Coluna.Benders.get_master
Coluna.Benders.get_benders_subprobs
```

## Benders cut generation algorithm
## Main loop

This is a description of how the `Coluna.Benders.run_benders_loop!` generic function behaves with the default implementation.

The loop stops if one of the following conditions is met:
- the master is infeasible
- a separation subproblem is infeasible
- the time limit is reached
- the maximum number of iterations is reached
- no new cut generated at the last iteration

The following generic function contains all the logic of the algorithm:
The default implementation returns:

```@docs
Coluna.Benders.run_benders_loop!

```

The latter method calls the following methods:
**References**:

```@docs
Coluna.Benders.setup_reformulation!
Coluna.Benders.stop_benders
Coluna.Benders.after_benders_iteration
Coluna.Benders.AbstractBendersOutput
Coluna.Benders.benders_output_type
Coluna.Benders.new_output
```

and the generic function:

```@docs
Coluna.Benders.run_benders_iteration!
```

## Benders cut generation algorithm iteration
## Benders cut generation iteration

The `run_benders_iteration!` generic function calls the following method:

```@docs
Coluna.Benders.benders_iteration_output_type
Coluna.Benders.set_of_cuts
Coluna.Benders.set_of_sep_sols
Coluna.Benders.push_in_set!
Coluna.Benders.master_is_unbounded
Coluna.Benders.insert_cuts!
Coluna.Benders.build_primal_solution
Coluna.Benders.new_iteration_output
```mermaid
flowchart TB;
id1(Optimize master)
id2(Treat unbounded master)
id3(Setup separation subproblems)
id4(Separation subproblem iterator)
id5(Optimize separation subproblem)
id6(Push cut into set)
id7(Insert cut)
id8(Iteration output)
id1 --unbounded--> id2
id2 --certificate--> id3
id1 -- optimal --> id3
id3 --> id4
id4 -- subproblem --> id5
id5 --> id6
id6 --> id4
id4 -- end --> id7
id7 --> id8
click id1 href "#Master-optimization" "Link to doc"
click id2 href "#Unbounded-master-case" "Link to doc"
click id3 href "#Setup-separation-subproblems" "Link to doc"
click id4 href "#Subproblem-iterator" "Link to doc"
click id5 href "#Separation-subproblem-optimization" "Link to doc"
click id6 href "#Set-of-generated-cuts" "Link to doc"
click id7 href "#Cuts-insertion" "Link to doc"
click id8 href "#Iteration-output" "Link to doc"
```

## Optimization of the Master
### Master optimization

The Benders cut generation algorithm is an iterative algorithm that consists in fixing a part of the variable

Expand All @@ -72,26 +170,76 @@ It returns a primal solution.
Coluna.Benders.optimize_master_problem!
```

### Unbounded master case

If the master is unbounded...

**References**:

```@docs
Coluna.Benders.treat_unbounded_master_problem_case!
```

## Separation Problem Optimization
### Setup separation subproblems

Lorem ipsum.

**References**:
```@docs
Coluna.Benders.setup_separation_for_unbounded_master_case!
Coluna.Benders.update_sp_rhs!
```

### Subproblem iterator

Not implemented yet.

### Separation subproblem optimization

Lorem ipsum

**References**:

```@docs
Coluna.Benders.optimize_separation_problem!
Coluna.Benders.treat_infeasible_separation_problem_case!
```

## Optimization Results
### Set of generated cuts

Lorem ipsum:

**References**:

```@docs
Coluna.Benders.set_of_cuts
Coluna.Benders.set_of_sep_sols
Coluna.Benders.push_in_set!
```

### Cuts insertion

Lorem ipsum:

**References**:

```@docs
Coluna.Benders.insert_cuts!
```

### Iteration output

Lorem ipsum:

**References**:

```@docs
Coluna.Benders.AbstractBendersIterationOutput
Coluna.Benders.benders_iteration_output_type
Coluna.Benders.new_iteration_output
```

### Getters for Result data structures

| Method name | Master | Separation |
| ---------------- | ------ | ---------- |
Expand All @@ -110,3 +258,7 @@ Coluna.Benders.get_primal_sol
Coluna.Benders.get_dual_sol
Coluna.Benders.get_obj_val
```

## Stabilization

Not implemented yet.
4 changes: 2 additions & 2 deletions docs/src/api/colgen.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ Coluna.ColGen.is_minimization
This is a description of how the `Coluna.ColGen.run!` generic function behaves in the default
implementation.

The main loop stops when the `Coluna.Colgen.stop_colgen` method returns `true`. This is the case when one of the following conditions holds:
The main loop stops when the `Coluna.ColGen.stop_colgen` method returns `true`. This is the case when one of the following conditions holds:
- the master or a pricing subproblem is infeasible
- the time limit is reached
- the maximum number of iterations is reached
Expand Down Expand Up @@ -578,7 +578,7 @@ Coluna.ColGen.get_master_dual_sol
Coluna.ColGen.get_master_lp_primal_bound
```

### Stabilization
## Stabilization

Coluna provides a default implementation of the smoothing stabilization with a self-adjusted $\alpha$ parameter, $0 \leq \alpha < 1$.

Expand Down
Loading