Update 0.2 docs

docs
Alinson S. Xavier 4 years ago
parent 623ce5c216
commit 465005b493

@ -1,4 +1,4 @@
# Sphinx build info version 1 # Sphinx build info version 1
# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. # This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done.
config: 46f2ab906726eb386ff6943cee2732ea config: 3772558d35a82a60dc512dba5e805386
tags: d77d1c0d9ca2f4c8421862c7c5a0d620 tags: d77d1c0d9ca2f4c8421862c7c5a0d620

@ -1,58 +0,0 @@
```{sectnum}
---
start: 4
depth: 2
suffix: .
---
```
# About
## Authors
* **Alinson S. Xavier,** Argonne National Laboratory <<axavier@anl.gov>>
* **Feng Qiu,** Argonne National Laboratory <<fqiu@anl.gov>>
## Acknowledgments
* Based upon work supported by **Laboratory Directed Research and Development** (LDRD) funding from Argonne National Laboratory, provided by the Director, Office of Science, of the U.S. Department of Energy under Contract No. DE-AC02-06CH11357, and the **U.S. Department of Energy Advanced Grid Modeling Program** under Grant DE-OE0000875.
## References
If you use MIPLearn in your research, or the included problem generators, we kindly request that you cite the package as follows:
* **Alinson S. Xavier, Feng Qiu.** *MIPLearn: An Extensible Framework for Learning-Enhanced Optimization*. Zenodo (2020). DOI: [10.5281/zenodo.4287567](https://doi.org/10.5281/zenodo.4287567)
If you use MIPLearn in the field of power systems optimization, we kindly request that you cite the reference below, in which the main techniques implemented in MIPLearn were first developed:
* **Alinson S. Xavier, Feng Qiu, Shabbir Ahmed.** *Learning to Solve Large-Scale Unit Commitment Problems.* INFORMS Journal on Computing (2020). DOI: [10.1287/ijoc.2020.0976](https://doi.org/10.1287/ijoc.2020.0976)
## License
```text
MIPLearn, an extensible framework for Learning-Enhanced Mixed-Integer Optimization
Copyright © 2020, UChicago Argonne, LLC. All Rights Reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted
provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of
conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of
conditions and the following disclaimer in the documentation and/or other materials provided
with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors may be used to
endorse or promote products derived from this software without specific prior written
permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
```

@ -1,177 +0,0 @@
```{sectnum}
---
start: 2
depth: 2
suffix: .
---
```
# Benchmarks
MIPLearn provides a selection of benchmark problems and random instance generators, covering applications from different fields, that can be used to evaluate new learning-enhanced MIP techniques in a measurable and reproducible way. In this page, we describe these problems, the included instance generators, and we present some benchmark results for `LearningSolver` with default parameters.
## Preliminaries
### Benchmark challenges
When evaluating the performance of a conventional MIP solver, *benchmark sets*, such as MIPLIB and TSPLIB, are typically used. The performance of newly proposed solvers or solution techniques are typically measured as the average (or total) running time the solver takes to solve the entire benchmark set. For Learning-Enhanced MIP solvers, it is also necessary to specify what instances should the solver be trained on (the *training instances*) before solving the actual set of instances we are interested in (the *test instances*). If the training instances are very similar to the test instances, we would expect a Learning-Enhanced Solver to present stronger perfomance benefits.
In MIPLearn, each optimization problem comes with a set of **benchmark challenges**, which specify how should the training and test instances be generated. The first challenges are typically easier, in the sense that training and test instances are very similar. Later challenges gradually make the sets more distinct, and therefore harder to learn from.
### Baseline results
To illustrate the performance of `LearningSolver`, and to set a baseline for newly proposed techniques, we present in this page, for each benchmark challenge, a small set of computational results measuring the solution speed of the solver and the solution quality with default parameters. For more detailed computational studies, see [references](about.md#references). We compare three solvers:
* **baseline:** Gurobi 9.0 with default settings (a conventional state-of-the-art MIP solver)
* **ml-exact:** `LearningSolver` with default settings, using Gurobi 9.0 as internal MIP solver
* **ml-heuristic:** Same as above, but with `mode="heuristic"`
All experiments presented here were performed on a Linux server (Ubuntu Linux 18.04 LTS) with Intel Xeon Gold 6230s (2 processors, 40 cores, 80 threads) and 256 GB RAM (DDR4, 2933 MHz). All solvers were restricted to use 4 threads, with no time limits, and 10 instances were solved simultaneously at a time.
## Maximum Weight Stable Set Problem
### Problem definition
Given a simple undirected graph $G=(V,E)$ and weights $w \in \mathbb{R}^V$, the problem is to find a stable set $S \subseteq V$ that maximizes $ \sum_{v \in V} w_v$. We recall that a subset $S \subseteq V$ is a *stable set* if no two vertices of $S$ are adjacent. This is one of Karp's 21 NP-complete problems.
### Random instance generator
The class `MaxWeightStableSetGenerator` can be used to generate random instances of this problem, with user-specified probability distributions. When the constructor parameter `fix_graph=True` is provided, one random Erdős-Rényi graph $G_{n,p}$ is generated during the constructor, where $n$ and $p$ are sampled from user-provided probability distributions `n` and `p`. To generate each instance, the generator independently samples each $w_v$ from the user-provided probability distribution `w`. When `fix_graph=False`, a new random graph is generated for each instance, while the remaining parameters are sampled in the same way.
### Challenge A
* Fixed random Erdős-Rényi graph $G_{n,p}$ with $n=200$ and $p=5\%$
* Random vertex weights $w_v \sim U(100, 150)$
* 500 training instances, 50 test instances
```python
MaxWeightStableSetGenerator(w=uniform(loc=100., scale=50.),
n=randint(low=200, high=201),
p=uniform(loc=0.05, scale=0.0),
fix_graph=True)
```
![alt](figures/benchmark_stab_a.png)
## Traveling Salesman Problem
### Problem definition
Given a list of cities and the distance between each pair of cities, the problem asks for the
shortest route starting at the first city, visiting each other city exactly once, then returning
to the first city. This problem is a generalization of the Hamiltonian path problem, one of Karp's
21 NP-complete problems.
### Random problem generator
The class `TravelingSalesmanGenerator` can be used to generate random instances of this
problem. Initially, the generator creates $n$ cities $(x_1,y_1),\ldots,(x_n,y_n) \in \mathbb{R}^2$,
where $n, x_i$ and $y_i$ are sampled independently from the provided probability distributions `n`,
`x` and `y`. For each pair of cities $(i,j)$, the distance $d_{i,j}$ between them is set to:
$$
d_{i,j} = \gamma_{i,j} \sqrt{(x_i-x_j)^2 + (y_i - y_j)^2}
$$
where $\gamma_{i,j}$ is sampled from the distribution `gamma`.
If `fix_cities=True` is provided, the list of cities is kept the same for all generated instances.
The $gamma$ values, and therefore also the distances, are still different.
By default, all distances $d_{i,j}$ are rounded to the nearest integer. If `round=False`
is provided, this rounding will be disabled.
### Challenge A
* Fixed list of 350 cities in the $[0, 1000]^2$ square
* $\gamma_{i,j} \sim U(0.95, 1.05)$
* 500 training instances, 50 test instances
```python
TravelingSalesmanGenerator(x=uniform(loc=0.0, scale=1000.0),
y=uniform(loc=0.0, scale=1000.0),
n=randint(low=350, high=351),
gamma=uniform(loc=0.95, scale=0.1),
fix_cities=True,
round=True,
)
```
![alt](figures/benchmark_tsp_a.png)
## Multidimensional 0-1 Knapsack Problem
### Problem definition
Given a set of $n$ items and $m$ types of resources (also called *knapsacks*), the problem is to find a subset of items that maximizes profit without consuming more resources than it is available. More precisely, the problem is:
$$
\begin{align*}
\text{maximize}
& \sum_{j=1}^n p_j x_j
\\
\text{subject to}
& \sum_{j=1}^n w_{ij} x_j \leq b_i
& \forall i=1,\ldots,m \\
& x_j \in \{0,1\}
& \forall j=1,\ldots,n
\end{align*}
$$
### Random instance generator
The class `MultiKnapsackGenerator` can be used to generate random instances of this problem. The number of items $n$ and knapsacks $m$ are sampled from the user-provided probability distributions `n` and `m`. The weights $w_{ij}$ are sampled independently from the provided distribution `w`. The capacity of knapsack $i$ is set to
$$
b_i = \alpha_i \sum_{j=1}^n w_{ij}
$$
where $\alpha_i$, the tightness ratio, is sampled from the provided probability
distribution `alpha`. To make the instances more challenging, the costs of the items
are linearly correlated to their average weights. More specifically, the price of each
item $j$ is set to:
$$
p_j = \sum_{i=1}^m \frac{w_{ij}}{m} + K u_j,
$$
where $K$, the correlation coefficient, and $u_j$, the correlation multiplier, are sampled
from the provided probability distributions `K` and `u`.
If `fix_w=True` is provided, then $w_{ij}$ are kept the same in all generated instances. This also implies that $n$ and $m$ are kept fixed. Although the prices and capacities are derived from $w_{ij}$, as long as `u` and `K` are not constants, the generated instances will still not be completely identical.
If a probability distribution `w_jitter` is provided, then item weights will be set to $w_{ij} \gamma_{ij}$ where $\gamma_{ij}$ is sampled from `w_jitter`. When combined with `fix_w=True`, this argument may be used to generate instances where the weight of each item is roughly the same, but not exactly identical, across all instances. The prices of the items and the capacities of the knapsacks will be calculated as above, but using these perturbed weights instead.
By default, all generated prices, weights and capacities are rounded to the nearest integer number. If `round=False` is provided, this rounding will be disabled.
!!! note "References"
* Freville, Arnaud, and Gérard Plateau. *An efficient preprocessing procedure for the multidimensional 01 knapsack problem.* Discrete applied mathematics 49.1-3 (1994): 189-212.
* Fréville, Arnaud. *The multidimensional 01 knapsack problem: An overview.* European Journal of Operational Research 155.1 (2004): 1-21.
### Challenge A
* 250 variables, 10 constraints, fixed weights
* $w \sim U(0, 1000), \gamma \sim U(0.95, 1.05)$
* $K = 500, u \sim U(0, 1), \alpha = 0.25$
* 500 training instances, 50 test instances
```python
MultiKnapsackGenerator(n=randint(low=250, high=251),
m=randint(low=10, high=11),
w=uniform(loc=0.0, scale=1000.0),
K=uniform(loc=500.0, scale=0.0),
u=uniform(loc=0.0, scale=1.0),
alpha=uniform(loc=0.25, scale=0.0),
fix_w=True,
w_jitter=uniform(loc=0.95, scale=0.1),
)
```
![alt](figures/benchmark_knapsack_a.png)

@ -0,0 +1,29 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "792bbfa2",
"metadata": {},
"source": [
"# Facility Location\n",
"\n",
"TODO"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Julia 1.6.0",
"language": "julia",
"name": "julia-1.6"
},
"language_info": {
"file_extension": ".jl",
"mimetype": "application/julia",
"name": "julia",
"version": "1.6.0"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

@ -0,0 +1,111 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "d236e2a0",
"metadata": {},
"source": [
"# Multidimensional Knapsack\n",
"\n",
"### Problem definition\n",
"\n",
"Given a set of $n$ items and $m$ types of resources (also called *knapsacks*), the problem is to find a subset of items that maximizes profit without consuming more resources than it is available. More precisely, the problem is:\n",
"\n",
"$$\n",
"\\begin{align*}\n",
" \\text{maximize}\n",
" & \\sum_{j=1}^n p_j x_j\n",
" \\\\\n",
" \\text{subject to}\n",
" & \\sum_{j=1}^n w_{ij} x_j \\leq b_i\n",
" & \\forall i=1,\\ldots,m \\\\\n",
" & x_j \\in \\{0,1\\}\n",
" & \\forall j=1,\\ldots,n\n",
"\\end{align*}\n",
"$$\n",
"\n",
"### Random instance generator\n",
"\n",
"The class `MultiKnapsackGenerator` can be used to generate random instances of this problem. The number of items $n$ and knapsacks $m$ are sampled from the user-provided probability distributions `n` and `m`. The weights $w_{ij}$ are sampled independently from the provided distribution `w`. The capacity of knapsack $i$ is set to\n",
"\n",
"$$\n",
" b_i = \\alpha_i \\sum_{j=1}^n w_{ij}\n",
"$$\n",
"\n",
"where $\\alpha_i$, the tightness ratio, is sampled from the provided probability\n",
"distribution `alpha`. To make the instances more challenging, the costs of the items\n",
"are linearly correlated to their average weights. More specifically, the price of each\n",
"item $j$ is set to:\n",
"\n",
"$$\n",
" p_j = \\sum_{i=1}^m \\frac{w_{ij}}{m} + K u_j,\n",
"$$\n",
"\n",
"where $K$, the correlation coefficient, and $u_j$, the correlation multiplier, are sampled\n",
"from the provided probability distributions `K` and `u`.\n",
"\n",
"If `fix_w=True` is provided, then $w_{ij}$ are kept the same in all generated instances. This also implies that $n$ and $m$ are kept fixed. Although the prices and capacities are derived from $w_{ij}$, as long as `u` and `K` are not constants, the generated instances will still not be completely identical.\n",
"\n",
"\n",
"If a probability distribution `w_jitter` is provided, then item weights will be set to $w_{ij} \\gamma_{ij}$ where $\\gamma_{ij}$ is sampled from `w_jitter`. When combined with `fix_w=True`, this argument may be used to generate instances where the weight of each item is roughly the same, but not exactly identical, across all instances. The prices of the items and the capacities of the knapsacks will be calculated as above, but using these perturbed weights instead.\n",
"\n",
"By default, all generated prices, weights and capacities are rounded to the nearest integer number. If `round=False` is provided, this rounding will be disabled.\n",
"\n",
"\n",
"<div class=\"alert alert-info\">\n",
"References\n",
"\n",
"* **Freville, Arnaud, and Gérard Plateau.** *An efficient preprocessing procedure for the multidimensional 01 knapsack problem.* Discrete applied mathematics 49.1-3 (1994): 189-212.\n",
"* **Fréville, Arnaud.** *The multidimensional 01 knapsack problem: An overview.* European Journal of Operational Research 155.1 (2004): 1-21.\n",
"</div>\n",
" \n",
"### Challenge A\n",
"\n",
"* 250 variables, 10 constraints, fixed weights\n",
"* $w \\sim U(0, 1000), \\gamma \\sim U(0.95, 1.05)$\n",
"* $K = 500, u \\sim U(0, 1), \\alpha = 0.25$\n",
"* 500 training instances, 50 test instances\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "39be5cda",
"metadata": {},
"outputs": [],
"source": [
"MultiKnapsackGenerator(\n",
" n=randint(low=250, high=251),\n",
" m=randint(low=10, high=11),\n",
" w=uniform(loc=0.0, scale=1000.0),\n",
" K=uniform(loc=500.0, scale=0.0),\n",
" u=uniform(loc=0.0, scale=1.0),\n",
" alpha=uniform(loc=0.25, scale=0.0),\n",
" fix_w=True,\n",
" w_jitter=uniform(loc=0.95, scale=0.1),\n",
")"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "miplearn",
"language": "python",
"name": "miplearn"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.8.10"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

@ -0,0 +1,43 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "423ee254",
"metadata": {},
"source": [
"# Preliminaries\n",
"\n",
"## Benchmark challenges\n",
"\n",
"When evaluating the performance of a conventional MIP solver, *benchmark sets*, such as MIPLIB and TSPLIB, are typically used. The performance of newly proposed solvers or solution techniques are typically measured as the average (or total) running time the solver takes to solve the entire benchmark set. For Learning-Enhanced MIP solvers, it is also necessary to specify what instances should the solver be trained on (the *training instances*) before solving the actual set of instances we are interested in (the *test instances*). If the training instances are very similar to the test instances, we would expect a Learning-Enhanced Solver to present stronger perfomance benefits.\n",
"\n",
"In MIPLearn, each optimization problem comes with a set of **benchmark challenges**, which specify how should the training and test instances be generated. The first challenges are typically easier, in the sense that training and test instances are very similar. Later challenges gradually make the sets more distinct, and therefore harder to learn from.\n",
"\n",
"## Baseline results\n",
"\n",
"To illustrate the performance of `LearningSolver`, and to set a baseline for newly proposed techniques, we present in this page, for each benchmark challenge, a small set of computational results measuring the solution speed of the solver and the solution quality with default parameters. For more detailed computational studies, see [references](index.md#references). We compare three solvers:\n",
"\n",
"* **baseline:** Gurobi 9.1 with default settings (a conventional state-of-the-art MIP solver)\n",
"* **ml-exact:** `LearningSolver` with default settings, using Gurobi 9.0 as internal MIP solver\n",
"* **ml-heuristic:** Same as above, but with `mode=\"heuristic\"`\n",
"\n",
"All experiments presented here were performed on a Linux server (Ubuntu Linux 18.04 LTS) with Intel Xeon Gold 6230s (2 processors, 40 cores, 80 threads) and 256 GB RAM (DDR4, 2933 MHz). All solvers were restricted to use 4 threads, with no time limits, and 10 instances were solved simultaneously at a time."
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Julia 1.6.0",
"language": "julia",
"name": "julia-1.6"
},
"language_info": {
"file_extension": ".jl",
"mimetype": "application/julia",
"name": "julia",
"version": "1.6.0"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

@ -0,0 +1,62 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "23083bd9",
"metadata": {},
"source": [
"# Maximum Weight Stable Set\n",
"\n",
"## Problem definition\n",
"\n",
"Given a simple undirected graph $G=(V,E)$ and weights $w \\in \\mathbb{R}^V$, the problem is to find a stable set $S \\subseteq V$ that maximizes $ \\sum_{v \\in V} w_v$. We recall that a subset $S \\subseteq V$ is a *stable set* if no two vertices of $S$ are adjacent. This is one of Karp's 21 NP-complete problems.\n",
"\n",
"## Random instance generator\n",
"\n",
"The class `MaxWeightStableSetGenerator` can be used to generate random instances of this problem, with user-specified probability distributions. When the constructor parameter `fix_graph=True` is provided, one random Erdős-Rényi graph $G_{n,p}$ is generated during the constructor, where $n$ and $p$ are sampled from user-provided probability distributions `n` and `p`. To generate each instance, the generator independently samples each $w_v$ from the user-provided probability distribution `w`. When `fix_graph=False`, a new random graph is generated for each instance, while the remaining parameters are sampled in the same way.\n",
"\n",
"## Challenge A\n",
"\n",
"* Fixed random Erdős-Rényi graph $G_{n,p}$ with $n=200$ and $p=5\\%$\n",
"* Random vertex weights $w_v \\sim U(100, 150)$\n",
"* 500 training instances, 50 test instances"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "207c7846",
"metadata": {},
"outputs": [],
"source": [
"MaxWeightStableSetGenerator(\n",
" w=uniform(loc=100., scale=50.),\n",
" n=randint(low=200, high=201),\n",
" p=uniform(loc=0.05, scale=0.0),\n",
" fix_graph=True,\n",
")"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "miplearn",
"language": "python",
"name": "miplearn"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.8.10"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

@ -0,0 +1,88 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "2f39414b",
"metadata": {},
"source": [
"# Traveling Salesman\n",
"\n",
"### Problem definition\n",
"\n",
"Given a list of cities and the distance between each pair of cities, the problem asks for the\n",
"shortest route starting at the first city, visiting each other city exactly once, then returning\n",
"to the first city. This problem is a generalization of the Hamiltonian path problem, one of Karp's\n",
"21 NP-complete problems.\n",
"\n",
"### Random problem generator\n",
"\n",
"The class `TravelingSalesmanGenerator` can be used to generate random instances of this\n",
"problem. Initially, the generator creates $n$ cities $(x_1,y_1),\\ldots,(x_n,y_n) \\in \\mathbb{R}^2$,\n",
"where $n, x_i$ and $y_i$ are sampled independently from the provided probability distributions `n`,\n",
"`x` and `y`. For each pair of cities $(i,j)$, the distance $d_{i,j}$ between them is set to:\n",
"$$\n",
" d_{i,j} = \\gamma_{i,j} \\sqrt{(x_i-x_j)^2 + (y_i - y_j)^2}\n",
"$$\n",
"where $\\gamma_{i,j}$ is sampled from the distribution `gamma`.\n",
"\n",
"If `fix_cities=True` is provided, the list of cities is kept the same for all generated instances.\n",
"The $gamma$ values, and therefore also the distances, are still different.\n",
"\n",
"By default, all distances $d_{i,j}$ are rounded to the nearest integer. If `round=False`\n",
"is provided, this rounding will be disabled.\n",
"\n",
"### Challenge A\n",
"\n",
"* Fixed list of 350 cities in the $[0, 1000]^2$ square\n",
"* $\\gamma_{i,j} \\sim U(0.95, 1.05)$\n",
"* 500 training instances, 50 test instances"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "6b2c4ff9",
"metadata": {},
"outputs": [],
"source": [
"TravelingSalesmanGenerator(\n",
" x=uniform(loc=0.0, scale=1000.0),\n",
" y=uniform(loc=0.0, scale=1000.0),\n",
" n=randint(low=350, high=351),\n",
" gamma=uniform(loc=0.95, scale=0.1),\n",
" fix_cities=True,\n",
" round=True,\n",
")"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "cc125860",
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "miplearn",
"language": "python",
"name": "miplearn"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.8.10"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

@ -0,0 +1,29 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "ed7d4bdc",
"metadata": {},
"source": [
"# Unit Commitment\n",
"\n",
"TODO"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Julia 1.6.0",
"language": "julia",
"name": "julia-1.6"
},
"language_info": {
"file_extension": ".jl",
"mimetype": "application/julia",
"name": "julia",
"version": "1.6.0"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

@ -1,182 +0,0 @@
```{sectnum}
---
start: 3
depth: 2
suffix: .
---
```
# Customization
## Customizing solver parameters
### Selecting the internal MIP solver
By default, `LearningSolver` uses [Gurobi](https://www.gurobi.com/) as its internal MIP solver, and expects models to be provided using the Pyomo modeling language. Supported solvers and modeling languages include:
* `GurobiPyomoSolver`: Gurobi with Pyomo (default).
* `CplexPyomoSolver`: [IBM ILOG CPLEX](https://www.ibm.com/products/ilog-cplex-optimization-studio) with Pyomo.
* `XpressPyomoSolver`: [FICO XPRESS Solver](https://www.fico.com/en/products/fico-xpress-solver) with Pyomo.
* `GurobiSolver`: Gurobi without any modeling language.
To switch between solvers, provide the desired class using the `solver` argument:
```python
from miplearn import LearningSolver, CplexPyomoSolver
solver = LearningSolver(solver=CplexPyomoSolver)
```
To configure a particular solver, use the `params` constructor argument, as shown below.
```python
from miplearn import LearningSolver, GurobiPyomoSolver
solver = LearningSolver(
solver=lambda: GurobiPyomoSolver(
params={
"TimeLimit": 900,
"MIPGap": 1e-3,
"NodeLimit": 1000,
}
),
)
```
## Customizing solver components
`LearningSolver` is composed by a number of individual machine-learning components, each targeting a different part of the solution process. Each component can be individually enabled, disabled or customized. The following components are enabled by default:
* `LazyConstraintComponent`: Predicts which lazy constraint to initially enforce.
* `ObjectiveValueComponent`: Predicts the optimal value of the optimization problem, given the optimal solution to the LP relaxation.
* `PrimalSolutionComponent`: Predicts optimal values for binary decision variables. In heuristic mode, this component fixes the variables to their predicted values. In exact mode, the predicted values are provided to the solver as a (partial) MIP start.
The following components are also available, but not enabled by default:
* `BranchPriorityComponent`: Predicts good branch priorities for decision variables.
### Selecting components
To create a `LearningSolver` with a specific set of components, the `components` constructor argument may be used, as the next example shows:
```python
# Create a solver without any components
solver1 = LearningSolver(components=[])
# Create a solver with only two components
solver2 = LearningSolver(components=[
LazyConstraintComponent(...),
PrimalSolutionComponent(...),
])
```
### Adjusting component aggressiveness
The aggressiveness of classification components, such as `PrimalSolutionComponent` and `LazyConstraintComponent`, can be adjusted through the `threshold` constructor argument. Internally, these components ask the machine learning models how confident are they on each prediction they make, then automatically discard all predictions that have low confidence. The `threshold` argument specifies how confident should the ML models be for a prediction to be considered trustworthy. Lowering a component's threshold increases its aggressiveness, while raising a component's threshold makes it more conservative.
For example, if the ML model predicts that a certain binary variable will assume value `1.0` in the optimal solution with 75% confidence, and if the `PrimalSolutionComponent` is configured to discard all predictions with less than 90% confidence, then this variable will not be included in the predicted MIP start.
MIPLearn currently provides two types of thresholds:
* `MinProbabilityThreshold(p: List[float])` A threshold which indicates that a prediction is trustworthy if its probability of being correct, as computed by the machine learning model, is above a fixed value.
* `MinPrecisionThreshold(p: List[float])` A dynamic threshold which automatically adjusts itself during training to ensure that the component achieves at least a given precision on the training data set. Note that increasing a component's precision may reduce its recall.
The example below shows how to build a `PrimalSolutionComponent` which fixes variables to zero with at least 80% precision, and to one with at least 95% precision. Other components are configured similarly.
```python
from miplearn import PrimalSolutionComponent, MinPrecisionThreshold
PrimalSolutionComponent(
mode="heuristic",
threshold=MinPrecisionThreshold([0.80, 0.95]),
)
```
### Evaluating component performance
MIPLearn allows solver components to be modified, trained and evaluated in isolation. In the following example, we build and
fit `PrimalSolutionComponent` outside the solver, then evaluate its performance.
```python
from miplearn import PrimalSolutionComponent
# User-provided set of previously-solved instances
train_instances = [...]
# Construct and fit component on a subset of training instances
comp = PrimalSolutionComponent()
comp.fit(train_instances[:100])
# Evaluate performance on an additional set of training instances
ev = comp.evaluate(train_instances[100:150])
```
The method `evaluate` returns a dictionary with performance evaluation statistics for each training instance provided,
and for each type of prediction the component makes. To obtain a summary across all instances, pandas may be used, as below:
```python
import pandas as pd
pd.DataFrame(ev["Fix one"]).mean(axis=1)
```
```text
Predicted positive 3.120000
Predicted negative 196.880000
Condition positive 62.500000
Condition negative 137.500000
True positive 3.060000
True negative 137.440000
False positive 0.060000
False negative 59.440000
Accuracy 0.702500
F1 score 0.093050
Recall 0.048921
Precision 0.981667
Predicted positive (%) 1.560000
Predicted negative (%) 98.440000
Condition positive (%) 31.250000
Condition negative (%) 68.750000
True positive (%) 1.530000
True negative (%) 68.720000
False positive (%) 0.030000
False negative (%) 29.720000
dtype: float64
```
Regression components (such as `ObjectiveValueComponent`) can also be trained and evaluated similarly,
as the next example shows:
```python
from miplearn import ObjectiveValueComponent
comp = ObjectiveValueComponent()
comp.fit(train_instances[:100])
ev = comp.evaluate(train_instances[100:150])
import pandas as pd
pd.DataFrame(ev).mean(axis=1)
```
```text
Mean squared error 7001.977827
Explained variance 0.519790
Max error 242.375804
Mean absolute error 65.843924
R2 0.517612
Median absolute error 65.843924
dtype: float64
```
### Using customized ML classifiers and regressors
By default, given a training set of instantes, MIPLearn trains a fixed set of ML classifiers and regressors, then selects the best one based on cross-validation performance. Alternatively, the user may specify which ML model a component should use through the `classifier` or `regressor` contructor parameters. Scikit-learn classifiers and regressors are currently supported. A future version of the package will add compatibility with Keras models.
The example below shows how to construct a `PrimalSolutionComponent` which internally uses scikit-learn's `KNeighborsClassifiers`. Any other scikit-learn classifier or pipeline can be used. It needs to be wrapped in `ScikitLearnClassifier` to ensure that all the proper data transformations are applied.
```python
from miplearn import PrimalSolutionComponent, ScikitLearnClassifier
from sklearn.neighbors import KNeighborsClassifier
comp = PrimalSolutionComponent(
classifier=ScikitLearnClassifier(
KNeighborsClassifier(n_neighbors=5),
),
)
comp.fit(train_instances)
```

@ -5,31 +5,96 @@
Unlike pure ML methods, MIPLearn is not only able to find high-quality solutions to discrete optimization problems, but it can also prove the optimality and feasibility of these solutions. Unlike pure ML methods, MIPLearn is not only able to find high-quality solutions to discrete optimization problems, but it can also prove the optimality and feasibility of these solutions.
Unlike conventional MIP solvers, MIPLearn can take full advantage of very specific observations that happen to be true in a particular family of instances (such as the observation that a particular constraint is typically redundant, or that a particular variable typically assumes a certain value). Unlike conventional MIP solvers, MIPLearn can take full advantage of very specific observations that happen to be true in a particular family of instances (such as the observation that a particular constraint is typically redundant, or that a particular variable typically assumes a certain value).
For certain classes of problems, this approach has been shown to provide significant performance benefits (see [benchmarks](benchmark.md) and [references](about.md)). ## Table of Contents
## Features ```{toctree}
---
* **MIPLearn proposes a flexible problem specification format,** which allows users to describe their particular optimization problems to a Learning-Enhanced MIP solver, both from the MIP perspective and from the ML perspective, without making any assumptions on the problem being modeled, the mathematical formulation of the problem, or ML encoding. While the format is very flexible, some constraints are enforced to ensure that it is usable by an actual solver. maxdepth: 1
caption: Julia Tutorials
* **MIPLearn provides a reference implementation of a *Learning-Enhanced Solver*,** which can use the above problem specification format to automatically predict, based on previously solved instances, a number of hints to accelerate MIP performance. Currently, the reference solver is able to predict: (i) partial solutions which are likely to work well as MIP starts; (ii) an initial set of lazy constraints to enforce; (iii) variable branching priorities to accelerate the exploration of the branch-and-bound tree; (iv) the optimal objective value based on the solution to the LP relaxation. The usage of the solver is very straightforward. The most suitable ML models are automatically selected, trained, cross-validated and applied to the problem with no user intervention. numbered: true
---
* **MIPLearn provides a set of benchmark problems and random instance generators,** covering applications from different domains, which can be used to quickly evaluate new learning-enhanced MIP techniques in a measurable and reproducible way. jump-tutorials/getting-started.ipynb
#jump-tutorials/lazy-constraints.ipynb
#jump-tutorials/user-cuts.ipynb
#jump-tutorials/customizing-ml.ipynb
```
* **MIPLearn is customizable and extensible**. For MIP and ML researchers exploring new techniques to accelerate MIP performance based on historical data, each component of the reference solver can be individually replaced, extended or customized. ```{toctree}
---
maxdepth: 1
caption: Benchmarks
numbered: true
---
benchmarks/preliminaries.ipynb
benchmarks/stab.ipynb
#benchmarks/uc.ipynb
#benchmarks/facility.ipynb
benchmarks/knapsack.ipynb
benchmarks/tsp.ipynb
```
## Site contents
```{toctree} ```{toctree}
--- ---
maxdepth: 2 maxdepth: 1
caption: MIPLearn Internals
numbered: true
--- ---
usage.md #internals/solver-interfaces.ipynb
benchmark.md #internals/data-collection.ipynb
customization.md #internals/abstract-component.ipynb
about.md #internals/primal.ipynb
#internals/static-lazy.ipynb
#internals/dynamic-lazy.ipynb
``` ```
## Source Code ## Source Code
* [https://github.com/ANL-CEEESA/MIPLearn](https://github.com/ANL-CEEESA/MIPLearn) * [https://github.com/ANL-CEEESA/MIPLearn](https://github.com/ANL-CEEESA/MIPLearn)
## Authors
* **Alinson S. Xavier,** Argonne National Laboratory <<axavier@anl.gov>>
* **Feng Qiu,** Argonne National Laboratory <<fqiu@anl.gov>>
## Acknowledgments
* Based upon work supported by **Laboratory Directed Research and Development** (LDRD) funding from Argonne National Laboratory, provided by the Director, Office of Science, of the U.S. Department of Energy under Contract No. DE-AC02-06CH11357, and the **U.S. Department of Energy Advanced Grid Modeling Program** under Grant DE-OE0000875.
## References
If you use MIPLearn in your research, or the included problem generators, we kindly request that you cite the package as follows:
- **Alinson S. Xavier, Feng Qiu.** *MIPLearn: An Extensible Framework for Learning-Enhanced Optimization*. Zenodo (2020). DOI: [10.5281/zenodo.4287567](https://doi.org/10.5281/zenodo.4287567)
If you use MIPLearn in the field of power systems optimization, we kindly request that you cite the reference below, in which the main techniques implemented in MIPLearn were first developed:
- **Alinson S. Xavier, Feng Qiu, Shabbir Ahmed.** *Learning to Solve Large-Scale Unit Commitment Problems.* INFORMS Journal on Computing (2021). DOI: [10.1287/ijoc.2020.0976](https://doi.org/10.1287/ijoc.2020.0976)
## License
```text
MIPLearn, an extensible framework for Learning-Enhanced Mixed-Integer Optimization
Copyright © 2020, UChicago Argonne, LLC. All Rights Reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted
provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of
conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of
conditions and the following disclaimer in the documentation and/or other materials provided
with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors may be used to
endorse or promote products derived from this software without specific prior written
permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
```

@ -0,0 +1,29 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "ad9274ff",
"metadata": {},
"source": [
"# Abstract component\n",
"\n",
"TODO"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Julia 1.6.0",
"language": "julia",
"name": "julia-1.6"
},
"language_info": {
"file_extension": ".jl",
"mimetype": "application/julia",
"name": "julia",
"version": "1.6.0"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

@ -0,0 +1,29 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "780b4172",
"metadata": {},
"source": [
"# Training data collection\n",
"\n",
"TODO"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Julia 1.6.0",
"language": "julia",
"name": "julia-1.6"
},
"language_info": {
"file_extension": ".jl",
"mimetype": "application/julia",
"name": "julia",
"version": "1.6.0"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

@ -0,0 +1,29 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "5e3dd4c0",
"metadata": {},
"source": [
"# Dynamic lazy constraints & user cuts\n",
"\n",
"TODO"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Julia 1.6.0",
"language": "julia",
"name": "julia-1.6"
},
"language_info": {
"file_extension": ".jl",
"mimetype": "application/julia",
"name": "julia",
"version": "1.6.0"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

@ -0,0 +1,29 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "c6d0d8dc",
"metadata": {},
"source": [
"# Primal solutions\n",
"\n",
"TODO"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Julia 1.6.0",
"language": "julia",
"name": "julia-1.6"
},
"language_info": {
"file_extension": ".jl",
"mimetype": "application/julia",
"name": "julia",
"version": "1.6.0"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

@ -0,0 +1,29 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "ac509ea5",
"metadata": {},
"source": [
"# Solver interfaces\n",
"\n",
"TODO"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Julia 1.6.0",
"language": "julia",
"name": "julia-1.6"
},
"language_info": {
"file_extension": ".jl",
"mimetype": "application/julia",
"name": "julia",
"version": "1.6.0"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

@ -0,0 +1,29 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "ae350662",
"metadata": {},
"source": [
"# Static lazy constraints\n",
"\n",
"TODO"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Julia 1.6.0",
"language": "julia",
"name": "julia-1.6"
},
"language_info": {
"file_extension": ".jl",
"mimetype": "application/julia",
"name": "julia",
"version": "1.6.0"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

@ -0,0 +1,29 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "ea2dc06a",
"metadata": {},
"source": [
"# Customizing the ML models\n",
"\n",
"TODO"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Julia 1.6.0",
"language": "julia",
"name": "julia-1.6"
},
"language_info": {
"file_extension": ".jl",
"mimetype": "application/julia",
"name": "julia",
"version": "1.6.0"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

@ -0,0 +1,758 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "c5a596fb",
"metadata": {},
"source": [
"# Getting started with MIPLearn\n",
"\n",
"## Introduction\n",
"\n",
"**MIPLearn** is an open source framework that uses machine learning (ML) to accelerate the performance of both commercial and open source mixed-integer programming solvers (e.g. Gurobi, CPLEX, XPRESS, Cbc or SCIP). In this tutorial, we will:\n",
"\n",
"1. Install the Julia/JuMP version of MIPLearn\n",
"2. Model a simple optimization problem using JuMP\n",
"3. Generate training data and train the ML models\n",
"4. Use the ML models together with SCIP to solve new instances\n",
"\n",
"<div class=\"alert alert-info\">\n",
"Note\n",
" \n",
"We use SCIP in this tutorial because it is a fast and widely available noncommercial MIP solver. All the steps shown here also work for Gurobi, CPLEX and XPRESS, although the performance impact might be different.\n",
" \n",
"</div>\n",
"\n",
"<div class=\"alert alert-warning\">\n",
"Warning\n",
" \n",
"MIPLearn is still in early development stage. If run into any bugs or issues, please submit a bug report in our GitHub repository. Comments, suggestions and pull requests are also very welcome!\n",
" \n",
"</div>\n"
]
},
{
"cell_type": "markdown",
"id": "1f59417f",
"metadata": {},
"source": [
"## Installing MIPLearn\n",
"\n",
"MIPLearn is available in two versions:\n",
"\n",
"- Python version, compatible with the Pyomo modeling language,\n",
"- Julia version, compatible with the JuMP modeling language.\n",
"\n",
"In this tutorial, we will demonstrate how to use and install the Julia/JuMP version of the package. The first step is to install the Julia programming language in your computer. [See the official instructions for more details](https://julialang.org/downloads/). Note that MIPLearn was developed and tested with Julia 1.6, and may not be compatible with newer versions of the language. After Julia is installed, launch its console and run the following commands to download and install the package:"
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "1ddeeb8e",
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"Path `/home/axavier/Packages/MIPLearn.jl/dev` exists and looks like the correct package. Using existing path.\n",
"\u001b[32m\u001b[1m Resolving\u001b[22m\u001b[39m package versions...\n",
"\u001b[32m\u001b[1m No Changes\u001b[22m\u001b[39m to `~/Packages/MIPLearn/dev/docs/jump-tutorials/Project.toml`\n",
"\u001b[32m\u001b[1m No Changes\u001b[22m\u001b[39m to `~/Packages/MIPLearn/dev/docs/jump-tutorials/Manifest.toml`\n"
]
}
],
"source": [
"using Pkg\n",
"Pkg.develop(PackageSpec(path=\"/home/axavier/Packages/MIPLearn.jl/dev\"))"
]
},
{
"cell_type": "markdown",
"id": "de7ab489",
"metadata": {},
"source": [
"In addition to MIPLearn itself, we will also install a few other packages that are required for this tutorial:\n",
"\n",
"- `SCIP`, a non-commercial mixed-integer programming solver\n",
"- `JuMP`, an open-source modeling language for Julia\n",
"- `Distributions`, a statistics package that we will use to generate random inputs\n",
"- `Glob`, a package that retrieves all files in a directory matching a certain pattern"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "29d29925",
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"\u001b[32m\u001b[1m Updating\u001b[22m\u001b[39m registry at `~/.julia/registries/General`\n",
"\u001b[32m\u001b[1m Updating\u001b[22m\u001b[39m git-repo `https://github.com/JuliaRegistries/General.git`\n",
"\u001b[32m\u001b[1m Resolving\u001b[22m\u001b[39m package versions...\n",
"\u001b[32m\u001b[1m No Changes\u001b[22m\u001b[39m to `~/Packages/MIPLearn/dev/docs/jump-tutorials/Project.toml`\n",
"\u001b[32m\u001b[1m No Changes\u001b[22m\u001b[39m to `~/Packages/MIPLearn/dev/docs/jump-tutorials/Manifest.toml`\n",
"\u001b[32m\u001b[1mPrecompiling\u001b[22m\u001b[39m project...\n",
"\u001b[32m ✓ \u001b[39mMIPLearn\n",
"1 dependency successfully precompiled in 10 seconds (96 already precompiled)\n"
]
}
],
"source": [
"using Pkg\n",
"Pkg.add([\n",
" PackageSpec(url=\"https://github.com/scipopt/SCIP.jl.git\", rev=\"7aa79aaa\"),\n",
" PackageSpec(name=\"JuMP\", version=\"0.21\"),\n",
" PackageSpec(name=\"Distributions\", version=\"0.25\"),\n",
" PackageSpec(name=\"Glob\", version=\"1\"),\n",
"])\n",
"using Revise"
]
},
{
"cell_type": "markdown",
"id": "88074d87",
"metadata": {},
"source": [
"<div class=\"alert alert-info\">\n",
" \n",
"Note\n",
" \n",
"In the code above, we install specific version of all packages to ensure that this tutorial keeps running in the future, even when newer (and possibly incompatible) versions of the packages are released. This is usually a recommended practice for all Julia projects.\n",
" \n",
"</div>"
]
},
{
"cell_type": "markdown",
"id": "78482747",
"metadata": {},
"source": [
"## Modeling a simple optimization problem\n",
"\n",
"To illustrate how can MIPLearn be used, we will model and solve a small optimization problem related to power systems optimization. The problem we discuss below is a simplification of the **unit commitment problem,** a practical optimization problem solved daily by electric grid operators around the world. \n",
"\n",
"Suppose that you work at a utility company, and that it is your job to decide which electrical generators should be online at a certain hour of the day, and how much power should each generator produce. More specifically, assume that your company owns $n$ generators, denoted by $g_1, \\ldots, g_n$. Each generator can either be online or offline. An online generator $g_i$ can produce between $p^\\text{min}_i$ to $p^\\text{max}_i$ megawatts of power, and it costs your company $c^\\text{fixed}_i + c^\\text{var}_i y_i$, where $y_i$ is the amount of power produced. An offline generator produces nothing, and costs nothing. You also know that the total amount of power to be produced needs to be exactly equal to the total demand $d$ (in megawatts). To minimize the costs to your company, which generators should be online, and how much power should they produce?\n",
"\n",
"This simple problem be modeled as a *mixed-integer linear optimization* problem as follows. For each generator $g_i$, let $x_i \\in \\{0,1\\}$ be a decision variable indicating whether $g_i$ is online, and let $y_i \\geq 0$ be a decision variable indicating how much power does $g_i$ produce. The problem we need to solve is given by:\n",
"\n",
"$$\n",
"\\begin{align}\n",
"\\text{minimize } \\quad & \\sum_{i=1}^n \\left( c^\\text{fix}_i x_i + c^\\text{var}_i y_i \\right) \\\\\n",
"\\text{subject to } \\quad & y_i \\leq p^\\text{max}_i x_i & i=1,\\ldots,n \\\\\n",
"& y_i \\geq p^\\text{min}_i x_i & i=1,\\ldots,n \\\\\n",
"& \\sum_{i=1}^n y_i = d \\\\\n",
"& x_i \\in \\{0,1\\} & i=1,\\ldots,n \\\\\n",
"& y_i \\geq 0 & i=1,\\ldots,n\n",
"\\end{align}\n",
"$$\n",
"\n",
"<div class=\"alert alert-info\">\n",
" \n",
"Note\n",
" \n",
"We use a simplified version of the unit commitment problem in this tutorial just to make it easier to follow. MIPLearn can also handle realistic, large-scale versions of this problem. See the benchmark sections for more details.\n",
" \n",
"</div>\n",
"\n",
"Next, let us convert this abstract mathematical formulation into a concrete optimization model, using the Julia and the JuMP modeling language. We start by defining a data structure that holds all input data:"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "ec7dbab4",
"metadata": {},
"outputs": [],
"source": [
"Base.@kwdef struct UnitCommitmentData\n",
" demand::Float64\n",
" pmin::Vector{Float64}\n",
" pmax::Vector{Float64}\n",
" cfix::Vector{Float64}\n",
" cvar::Vector{Float64}\n",
"end;"
]
},
{
"cell_type": "markdown",
"id": "c8f6a5b8",
"metadata": {},
"source": [
"Next, we create a function that converts this data into a concrete JuMP model:"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "14e84c92",
"metadata": {},
"outputs": [],
"source": [
"using JuMP\n",
"\n",
"function build_uc_model(data::UnitCommitmentData)::Model\n",
" model = Model()\n",
" n = length(data.pmin)\n",
" @variable(model, x[1:n], Bin)\n",
" @variable(model, y[1:n] >= 0)\n",
" @objective(\n",
" model,\n",
" Min,\n",
" sum(\n",
" data.cfix[i] * x[i] +\n",
" data.cvar[i] * y[i]\n",
" for i in 1:n\n",
" )\n",
" )\n",
" @constraint(model, eq_max_power[i in 1:n], y[i] <= data.pmax[i] * x[i])\n",
" @constraint(model, eq_min_power[i in 1:n], y[i] >= data.pmin[i] * x[i])\n",
" @constraint(model, eq_demand, sum(y[i] for i in 1:n) == data.demand)\n",
" return model\n",
"end;"
]
},
{
"cell_type": "markdown",
"id": "f647734f",
"metadata": {},
"source": [
"At this point, we can already use JuMP and any mixed-integer linear programming solver to find optimal solutions to any instance of this problem. To illustrate this, let us solve a small instance with three generators, using SCIP:"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "b2abe5e2",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"obj = 1320.0\n",
" x = [0.0, 1.0, 1.0]\n",
" y = [0.0, 60.0, 40.0]\n"
]
}
],
"source": [
"using SCIP\n",
"using Printf\n",
"\n",
"model = build_uc_model(\n",
" UnitCommitmentData(\n",
" demand = 100.0,\n",
" pmin = [10, 20, 30],\n",
" pmax = [50, 60, 70],\n",
" cfix = [700, 600, 500],\n",
" cvar = [1.5, 2.0, 2.5],\n",
" )\n",
")\n",
"\n",
"scip = optimizer_with_attributes(SCIP.Optimizer, \"limits/gap\" => 1e-4)\n",
"set_optimizer(model, scip)\n",
"set_silent(model)\n",
"optimize!(model)\n",
"\n",
"println(\"obj = \", objective_value(model))\n",
"println(\" x = \", round.(value.(model[:x])))\n",
"println(\" y = \", round.(value.(model[:y]), digits=2));"
]
},
{
"cell_type": "markdown",
"id": "5be976f5",
"metadata": {},
"source": [
"Running the code above, we found that the optimal solution for our small problem instance costs \\$1320. It is achieve by keeping generators 2 and 3 online and producing, respectively, 60 MW and 40 MW of power."
]
},
{
"cell_type": "markdown",
"id": "96a1f952",
"metadata": {},
"source": [
"## Generating training data\n",
"\n",
"Although SCIP could solve the small example above in a fraction of a second, it gets slower for larger and more complex versions of the problem. If this is a problem that needs to be solved frequently, as it is often the case in practice, it could make sense to spend some time upfront generating a **trained** version of SCIP, which can solve new instances (similar to the ones it was trained on) faster.\n",
"\n",
"In the following, we will use MIPLearn to train machine learning models that can be used to accelerate SCIP's performance on a particular set of instances. More specifically, MIPLearn will train a model that is able to predict the optimal solution for instances that follow a given probability distribution, then it will provide this predicted solution to SCIP as a warm start.\n",
"\n",
"Before we can train the model, we need to collect training data by solving a large number of instances. In real-world situations, we may construct these training instances based on historical data. In this tutorial, we will construct them using a random instance generator:"
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "353e6199",
"metadata": {},
"outputs": [],
"source": [
"using Distributions\n",
"using Random\n",
"\n",
"function random_uc_data(; samples::Int, n::Int, seed=42)\n",
" Random.seed!(seed)\n",
" pmin = rand(Uniform(100, 500.0), n)\n",
" pmax = pmin .* rand(Uniform(2.0, 2.5), n)\n",
" cfix = pmin .* rand(Uniform(100.0, 125.0), n)\n",
" cvar = rand(Uniform(1.25, 1.5), n)\n",
" return [\n",
" UnitCommitmentData(;\n",
" pmin,\n",
" pmax,\n",
" cfix,\n",
" cvar,\n",
" demand = sum(pmax) * rand(Uniform(0.5, 0.75)),\n",
" )\n",
" for i in 1:samples\n",
" ]\n",
"end;"
]
},
{
"cell_type": "markdown",
"id": "2140968d",
"metadata": {},
"source": [
"In this example, for simplicity, only the demands change from one instance to the next. We could also have made the prices and the production limits random. The more randomization we have in the training data, however, the more challenging it is for the machine learning models to learn solution patterns.\n",
"\n",
"Now we generate 100 instances of this problem, each one with 1,000 generators. We will use the first 90 instances for training, and the remaining 10 instances to evaluate SCIP's performance."
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "1bb24909",
"metadata": {},
"outputs": [],
"source": [
"data = random_uc_data(samples=100, n=1000);\n",
"train_data = data[1:90]\n",
"test_data = data[91:100];"
]
},
{
"cell_type": "markdown",
"id": "96bc0e42",
"metadata": {},
"source": [
"Next, we will write these data structures to individual files. MIPLearn uses files during the training process because, for large-scale optimization problems, it is often impractical to hold the entire training data, as well as the concrete JuMP models, in memory. Files also make it much easier to solve multiple instances simultaneously, potentially even on multiple machines. We will cover parallel and distributed computing in a future tutorial.\n",
"\n",
"The code below generates the files `uc/train/000001.jld2`, `uc/train/000002.jld2`, etc."
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "8ec476b1",
"metadata": {},
"outputs": [],
"source": [
"using MIPLearn\n",
"using Glob\n",
"\n",
"MIPLearn.save(data[1:90], \"uc/train/\")\n",
"MIPLearn.save(data[91:100], \"uc/test/\")\n",
"\n",
"train_files = glob(\"uc/train/*.jld2\")\n",
"test_files = glob(\"uc/test/*.jld2\");"
]
},
{
"cell_type": "markdown",
"id": "5d53a783",
"metadata": {},
"source": [
"Finally, we use `MIPLearn.LearningSolver` and `MIPLearn.solve!` to solve all the training instances. `LearningSolver` is the main component provided by MIPLearn, which integrates MIP solvers and ML. The `solve!` function can be used to solve either one or multiple instances, and requires: (i) the list of files containing the training data; and (ii) the function that converts the data structure into a concrete JuMP model:"
]
},
{
"cell_type": "code",
"execution_count": 9,
"id": "514a3b3a",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"101.279699 seconds (93.52 M allocations: 3.599 GiB, 1.23% gc time, 0.52% compilation time)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"WARNING: Dual bound 1.98665e+07 is larger than the objective of the primal solution 1.98665e+07. The solution might not be optimal.\n"
]
}
],
"source": [
"using Glob\n",
"solver = LearningSolver(scip)\n",
"@time solve!(solver, train_files, build_uc_model);"
]
},
{
"cell_type": "markdown",
"id": "72eb09f4",
"metadata": {},
"source": [
"The macro `@time` shows us how long did the code take to run. We can see that SCIP was able to solve all training instances in about 2 minutes. The solutions, and other useful training data, is stored by MIPLearn in `.h5` files, stored side-by-side with the original `.jld2` files."
]
},
{
"cell_type": "markdown",
"id": "90406b90",
"metadata": {},
"source": [
"## Solving new instances\n",
"\n",
"Now that we have training data, we can fit the ML models using `MIPLearn.fit!`, then solve the test instances with `MIPLearn.solve!`, as shown below:"
]
},
{
"cell_type": "code",
"execution_count": 10,
"id": "e4de94db",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
" 5.693951 seconds (9.33 M allocations: 334.689 MiB, 1.62% gc time)\n"
]
}
],
"source": [
"solver_ml = LearningSolver(scip)\n",
"fit!(solver_ml, train_files, build_uc_model)\n",
"@time solve!(solver_ml, test_files, build_uc_model);"
]
},
{
"cell_type": "markdown",
"id": "247c1087",
"metadata": {},
"source": [
"The trained MIP solver was able to solve all test instances in about 5 seconds. To see that ML is being helpful here, let us repeat the code above, but remove the `fit!` line:"
]
},
{
"cell_type": "code",
"execution_count": 11,
"id": "62061b12",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
" 9.829350 seconds (8.17 M allocations: 278.008 MiB, 0.47% gc time)\n"
]
}
],
"source": [
"solver_baseline = LearningSolver(scip)\n",
"@time solve!(solver_baseline, test_files, build_uc_model);"
]
},
{
"cell_type": "markdown",
"id": "8ea5c423",
"metadata": {},
"source": [
"Without the help of the ML models, SCIP took around 10 seconds to solve the same test instances, or about twice as long.\n",
"\n",
"<div class=\"alert alert-info\">\n",
"Note\n",
" \n",
"Note that is is not necessary to specify what ML models to use. MIPLearn, by default, will try a number of classical ML models and will choose the one that performs the best, based on k-fold cross validation. MIPLearn is also able to automatically collect features based on the MIP formulation of the problem and the solution to the LP relaxation, among other things, so it does not require handcrafted features. If you do want to customize the models and features, however, that is also possible, as we will see in a later tutorial.\n",
"</div>"
]
},
{
"cell_type": "markdown",
"id": "569f7c7a",
"metadata": {},
"source": [
"## Understanding the acceleration\n",
"\n",
"Let us know go a bit deeper and try to understand how exactly did MIPLearn accelerate SCIP's performance. First, we are going to solve one of the training instances again, using the trained solver, but this time using the `tee=true` parameter, so that we can see SCIP's log:"
]
},
{
"cell_type": "code",
"execution_count": 12,
"id": "46739739",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"presolving:\n",
"(round 1, fast) 861 del vars, 861 del conss, 0 add conss, 2000 chg bounds, 0 chg sides, 0 chg coeffs, 0 upgd conss, 0 impls, 0 clqs\n",
"(round 2, fast) 861 del vars, 1722 del conss, 0 add conss, 2000 chg bounds, 0 chg sides, 0 chg coeffs, 0 upgd conss, 0 impls, 0 clqs\n",
"(round 3, fast) 862 del vars, 1722 del conss, 0 add conss, 2000 chg bounds, 0 chg sides, 0 chg coeffs, 0 upgd conss, 0 impls, 0 clqs\n",
"presolving (4 rounds: 4 fast, 1 medium, 1 exhaustive):\n",
" 862 deleted vars, 1722 deleted constraints, 0 added constraints, 2000 tightened bounds, 0 added holes, 0 changed sides, 0 changed coefficients\n",
" 0 implications, 0 cliques\n",
"presolved problem has 1138 variables (0 bin, 0 int, 0 impl, 1138 cont) and 279 constraints\n",
" 279 constraints of type <linear>\n",
"Presolving Time: 0.03\n",
"\n",
" time | node | left |LP iter|LP it/n|mem/heur|mdpt |vars |cons |rows |cuts |sepa|confs|strbr| dualbound | primalbound | gap | compl. \n",
"* 0.0s| 1 | 0 | 203 | - | LP | 0 |1138 | 279 | 279 | 0 | 0 | 0 | 0 | 1.705035e+07 | 1.705035e+07 | 0.00%| unknown\n",
" 0.0s| 1 | 0 | 203 | - | 8950k | 0 |1138 | 279 | 279 | 0 | 0 | 0 | 0 | 1.705035e+07 | 1.705035e+07 | 0.00%| unknown\n",
"\n",
"SCIP Status : problem is solved [optimal solution found]\n",
"Solving Time (sec) : 0.04\n",
"Solving Nodes : 1\n",
"Primal Bound : +1.70503465600131e+07 (1 solutions)\n",
"Dual Bound : +1.70503465600131e+07\n",
"Gap : 0.00 %\n",
"\n",
"violation: integrality condition of variable <> = 0.338047247943162\n",
"all 1 solutions given by solution candidate storage are infeasible\n",
"\n",
"feasible solution found by completesol heuristic after 0.1 seconds, objective value 1.705169e+07\n",
"presolving:\n",
"(round 1, fast) 0 del vars, 0 del conss, 0 add conss, 3000 chg bounds, 0 chg sides, 0 chg coeffs, 0 upgd conss, 0 impls, 0 clqs\n",
"(round 2, exhaustive) 0 del vars, 0 del conss, 0 add conss, 3000 chg bounds, 0 chg sides, 0 chg coeffs, 1000 upgd conss, 0 impls, 0 clqs\n",
"(round 3, exhaustive) 0 del vars, 0 del conss, 0 add conss, 3000 chg bounds, 0 chg sides, 0 chg coeffs, 2000 upgd conss, 1000 impls, 0 clqs\n",
" (0.1s) probing: 51/1000 (5.1%) - 0 fixings, 0 aggregations, 0 implications, 0 bound changes\n",
" (0.1s) probing aborted: 50/50 successive totally useless probings\n",
" (0.1s) symmetry computation started: requiring (bin +, int -, cont +), (fixed: bin -, int +, cont -)\n",
" (0.1s) no symmetry present\n",
"presolving (4 rounds: 4 fast, 3 medium, 3 exhaustive):\n",
" 0 deleted vars, 0 deleted constraints, 0 added constraints, 3000 tightened bounds, 0 added holes, 0 changed sides, 0 changed coefficients\n",
" 2000 implications, 0 cliques\n",
"presolved problem has 2000 variables (1000 bin, 0 int, 0 impl, 1000 cont) and 2001 constraints\n",
" 2000 constraints of type <varbound>\n",
" 1 constraints of type <linear>\n",
"Presolving Time: 0.10\n",
"transformed 1/1 original solutions to the transformed problem space\n",
"\n",
" time | node | left |LP iter|LP it/n|mem/heur|mdpt |vars |cons |rows |cuts |sepa|confs|strbr| dualbound | primalbound | gap | compl. \n",
" 0.2s| 1 | 0 | 1201 | - | 20M | 0 |2000 |2001 |2001 | 0 | 0 | 0 | 0 | 1.705035e+07 | 1.705169e+07 | 0.01%| unknown\n",
"\n",
"SCIP Status : solving was interrupted [gap limit reached]\n",
"Solving Time (sec) : 0.21\n",
"Solving Nodes : 1\n",
"Primal Bound : +1.70516871251443e+07 (1 solutions)\n",
"Dual Bound : +1.70503465600130e+07\n",
"Gap : 0.01 %\n",
"\n"
]
}
],
"source": [
"solve!(solver_ml, test_files[1], build_uc_model, tee=true);"
]
},
{
"cell_type": "markdown",
"id": "9cdc02d0",
"metadata": {},
"source": [
"The log above is quite complicated if you have never seen it before, but the important line in the one starting with `feasible solution found [...] objective value 1.705169e+07`. This line indicates that MIPLearn was able to construct a warm start with value `1.705169e+07`. Using this warm start, SCIP then proceeded with the branch-and-cut process to either prove its optimality or find an even better solution. Very quickly, however, SCIP proved that the solution produced by MIPLearn was indeed optimal and terminated. It was able to do this without generating a single cutting plane or running any other heuristics; it could tell the optimality by the root LP relaxation alone, which was very fast. \n",
"\n",
"Let us now do the same thing again, but using the untrained solver this time:"
]
},
{
"cell_type": "code",
"execution_count": 13,
"id": "555af477",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"presolving:\n",
"(round 1, fast) 861 del vars, 861 del conss, 0 add conss, 2000 chg bounds, 0 chg sides, 0 chg coeffs, 0 upgd conss, 0 impls, 0 clqs\n",
"(round 2, fast) 861 del vars, 1722 del conss, 0 add conss, 2000 chg bounds, 0 chg sides, 0 chg coeffs, 0 upgd conss, 0 impls, 0 clqs\n",
"(round 3, fast) 862 del vars, 1722 del conss, 0 add conss, 2000 chg bounds, 0 chg sides, 0 chg coeffs, 0 upgd conss, 0 impls, 0 clqs\n",
"presolving (4 rounds: 4 fast, 1 medium, 1 exhaustive):\n",
" 862 deleted vars, 1722 deleted constraints, 0 added constraints, 2000 tightened bounds, 0 added holes, 0 changed sides, 0 changed coefficients\n",
" 0 implications, 0 cliques\n",
"presolved problem has 1138 variables (0 bin, 0 int, 0 impl, 1138 cont) and 279 constraints\n",
" 279 constraints of type <linear>\n",
"Presolving Time: 0.03\n",
"\n",
" time | node | left |LP iter|LP it/n|mem/heur|mdpt |vars |cons |rows |cuts |sepa|confs|strbr| dualbound | primalbound | gap | compl. \n",
"* 0.0s| 1 | 0 | 203 | - | LP | 0 |1138 | 279 | 279 | 0 | 0 | 0 | 0 | 1.705035e+07 | 1.705035e+07 | 0.00%| unknown\n",
" 0.0s| 1 | 0 | 203 | - | 8950k | 0 |1138 | 279 | 279 | 0 | 0 | 0 | 0 | 1.705035e+07 | 1.705035e+07 | 0.00%| unknown\n",
"\n",
"SCIP Status : problem is solved [optimal solution found]\n",
"Solving Time (sec) : 0.04\n",
"Solving Nodes : 1\n",
"Primal Bound : +1.70503465600131e+07 (1 solutions)\n",
"Dual Bound : +1.70503465600131e+07\n",
"Gap : 0.00 %\n",
"\n",
"violation: integrality condition of variable <> = 0.338047247943162\n",
"all 1 solutions given by solution candidate storage are infeasible\n",
"\n",
"presolving:\n",
"(round 1, fast) 0 del vars, 0 del conss, 0 add conss, 2000 chg bounds, 0 chg sides, 0 chg coeffs, 0 upgd conss, 0 impls, 0 clqs\n",
"(round 2, exhaustive) 0 del vars, 0 del conss, 0 add conss, 2000 chg bounds, 0 chg sides, 0 chg coeffs, 1000 upgd conss, 0 impls, 0 clqs\n",
"(round 3, exhaustive) 0 del vars, 0 del conss, 0 add conss, 2000 chg bounds, 0 chg sides, 0 chg coeffs, 2000 upgd conss, 1000 impls, 0 clqs\n",
" (0.0s) probing: 51/1000 (5.1%) - 0 fixings, 0 aggregations, 0 implications, 0 bound changes\n",
" (0.0s) probing aborted: 50/50 successive totally useless probings\n",
" (0.0s) symmetry computation started: requiring (bin +, int -, cont +), (fixed: bin -, int +, cont -)\n",
" (0.0s) no symmetry present\n",
"presolving (4 rounds: 4 fast, 3 medium, 3 exhaustive):\n",
" 0 deleted vars, 0 deleted constraints, 0 added constraints, 2000 tightened bounds, 0 added holes, 0 changed sides, 0 changed coefficients\n",
" 2000 implications, 0 cliques\n",
"presolved problem has 2000 variables (1000 bin, 0 int, 0 impl, 1000 cont) and 2001 constraints\n",
" 2000 constraints of type <varbound>\n",
" 1 constraints of type <linear>\n",
"Presolving Time: 0.03\n",
"\n",
" time | node | left |LP iter|LP it/n|mem/heur|mdpt |vars |cons |rows |cuts |sepa|confs|strbr| dualbound | primalbound | gap | compl. \n",
"p 0.0s| 1 | 0 | 1 | - | locks| 0 |2000 |2001 |2001 | 0 | 0 | 0 | 0 | 0.000000e+00 | 2.335200e+07 | Inf | unknown\n",
"p 0.0s| 1 | 0 | 2 | - | vbounds| 0 |2000 |2001 |2001 | 0 | 0 | 0 | 0 | 0.000000e+00 | 1.839873e+07 | Inf | unknown\n",
" 0.1s| 1 | 0 | 1204 | - | 20M | 0 |2000 |2001 |2001 | 0 | 0 | 0 | 0 | 1.705035e+07 | 1.839873e+07 | 7.91%| unknown\n",
" 0.1s| 1 | 0 | 1207 | - | 22M | 0 |2000 |2001 |2002 | 1 | 1 | 0 | 0 | 1.705036e+07 | 1.839873e+07 | 7.91%| unknown\n",
"r 0.1s| 1 | 0 | 1207 | - |shifting| 0 |2000 |2001 |2002 | 1 | 1 | 0 | 0 | 1.705036e+07 | 1.711399e+07 | 0.37%| unknown\n",
" 0.1s| 1 | 0 | 1209 | - | 22M | 0 |2000 |2001 |2003 | 2 | 2 | 0 | 0 | 1.705037e+07 | 1.711399e+07 | 0.37%| unknown\n",
"r 0.1s| 1 | 0 | 1209 | - |shifting| 0 |2000 |2001 |2003 | 2 | 2 | 0 | 0 | 1.705037e+07 | 1.706492e+07 | 0.09%| unknown\n",
" 0.1s| 1 | 0 | 1210 | - | 22M | 0 |2000 |2001 |2004 | 3 | 3 | 0 | 0 | 1.705037e+07 | 1.706492e+07 | 0.09%| unknown\n",
" 0.1s| 1 | 0 | 1211 | - | 23M | 0 |2000 |2001 |2005 | 4 | 4 | 0 | 0 | 1.705037e+07 | 1.706492e+07 | 0.09%| unknown\n",
" 0.1s| 1 | 0 | 1212 | - | 23M | 0 |2000 |2001 |2006 | 5 | 5 | 0 | 0 | 1.705037e+07 | 1.706492e+07 | 0.09%| unknown\n",
"r 0.1s| 1 | 0 | 1212 | - |shifting| 0 |2000 |2001 |2006 | 5 | 5 | 0 | 0 | 1.705037e+07 | 1.706228e+07 | 0.07%| unknown\n",
" 0.1s| 1 | 0 | 1214 | - | 24M | 0 |2000 |2001 |2007 | 6 | 7 | 0 | 0 | 1.705037e+07 | 1.706228e+07 | 0.07%| unknown\n",
" 0.2s| 1 | 0 | 1216 | - | 24M | 0 |2000 |2001 |2009 | 8 | 8 | 0 | 0 | 1.705037e+07 | 1.706228e+07 | 0.07%| unknown\n",
" 0.2s| 1 | 0 | 1220 | - | 25M | 0 |2000 |2001 |2011 | 10 | 9 | 0 | 0 | 1.705037e+07 | 1.706228e+07 | 0.07%| unknown\n",
" 0.2s| 1 | 0 | 1223 | - | 25M | 0 |2000 |2001 |2014 | 13 | 10 | 0 | 0 | 1.705037e+07 | 1.706228e+07 | 0.07%| unknown\n",
" time | node | left |LP iter|LP it/n|mem/heur|mdpt |vars |cons |rows |cuts |sepa|confs|strbr| dualbound | primalbound | gap | compl. \n",
" 0.2s| 1 | 0 | 1229 | - | 26M | 0 |2000 |2001 |2015 | 14 | 11 | 0 | 0 | 1.705038e+07 | 1.706228e+07 | 0.07%| unknown\n",
"r 0.2s| 1 | 0 | 1403 | - |intshift| 0 |2000 |2001 |2015 | 14 | 11 | 0 | 0 | 1.705038e+07 | 1.705687e+07 | 0.04%| unknown\n",
"L 0.6s| 1 | 0 | 1707 | - | rens| 0 |2000 |2001 |2015 | 14 | 11 | 0 | 0 | 1.705038e+07 | 1.705332e+07 | 0.02%| unknown\n",
"L 0.7s| 1 | 0 | 1707 | - | alns| 0 |2000 |2001 |2015 | 14 | 11 | 0 | 0 | 1.705038e+07 | 1.705178e+07 | 0.01%| unknown\n",
"\n",
"SCIP Status : solving was interrupted [gap limit reached]\n",
"Solving Time (sec) : 0.67\n",
"Solving Nodes : 1\n",
"Primal Bound : +1.70517823853380e+07 (13 solutions)\n",
"Dual Bound : +1.70503798271962e+07\n",
"Gap : 0.01 %\n",
"\n"
]
}
],
"source": [
"solve!(solver_baseline, test_files[1], build_uc_model, tee=true);"
]
},
{
"cell_type": "markdown",
"id": "72a52d26",
"metadata": {},
"source": [
"In this log file, notice how the line we saw before is now missing; SCIP needs to find an initial solution using its own internal heuristics. The solution SCIP initially found has value `2.335200e+07`, which is significantly worse than the one MIPLearn constructed before. SCIP then proceeds to improve this solution by generating a number of cutting planes and repeatedly running primal heuristics. In the end, it is able to find the optimal solution, as expected, but it takes longer."
]
},
{
"cell_type": "markdown",
"id": "36fb5f02",
"metadata": {},
"source": [
"## Accessing the solution\n",
"\n",
"In the example above, we used `MIPLearn.solve!` together with data files to solve both the training and the test instances. The solutions were saved to a `.h5` files in the train/test folders, and could be retrieved by reading theses files, but that is not very convenient. In this section we will use an easier method.\n",
"\n",
"We can use the function `MIPLearn.load!` to obtain a regular JuMP model:"
]
},
{
"cell_type": "code",
"execution_count": 14,
"id": "f62f28b4",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"A JuMP Model\n",
"Minimization problem with:\n",
"Variables: 2000\n",
"Objective function type: AffExpr\n",
"`AffExpr`-in-`MathOptInterface.EqualTo{Float64}`: 1 constraint\n",
"`AffExpr`-in-`MathOptInterface.GreaterThan{Float64}`: 1000 constraints\n",
"`AffExpr`-in-`MathOptInterface.LessThan{Float64}`: 1000 constraints\n",
"`VariableRef`-in-`MathOptInterface.GreaterThan{Float64}`: 1000 constraints\n",
"`VariableRef`-in-`MathOptInterface.ZeroOne`: 1000 constraints\n",
"Model mode: AUTOMATIC\n",
"CachingOptimizer state: NO_OPTIMIZER\n",
"Solver name: No optimizer attached.\n",
"Names registered in the model: eq_demand, eq_max_power, eq_min_power, x, y"
]
},
"execution_count": 14,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"model = MIPLearn.load(\"uc/test/000001.jld2\", build_uc_model)"
]
},
{
"cell_type": "markdown",
"id": "d5722dcf",
"metadata": {},
"source": [
"We can then solve this model as before, with `MIPLearn.solve!`:"
]
},
{
"cell_type": "code",
"execution_count": 15,
"id": "e49f9e60",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"obj = 1.7051217395548128e7\n",
" x = [1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0]\n",
" y = [767.11, 646.61, 230.28, 365.46, 1150.99, 1103.36, 0.0, 0.0, 0.0, 0.0]\n"
]
}
],
"source": [
"solve!(solver_ml, model)\n",
"println(\"obj = \", objective_value(model))\n",
"println(\" x = \", round.(value.(model[:x][1:10])))\n",
"println(\" y = \", round.(value.(model[:y][1:10]), digits=2))"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Julia 1.6.0",
"language": "julia",
"name": "julia-1.6"
},
"language_info": {
"file_extension": ".jl",
"mimetype": "application/julia",
"name": "julia",
"version": "1.6.0"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

@ -0,0 +1,29 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "18dd2957",
"metadata": {},
"source": [
"# Modeling lazy constraints\n",
"\n",
"TODO"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Julia 1.6.0",
"language": "julia",
"name": "julia-1.6"
},
"language_info": {
"file_extension": ".jl",
"mimetype": "application/julia",
"name": "julia",
"version": "1.6.0"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

@ -0,0 +1,29 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "8e6b5f28",
"metadata": {},
"source": [
"# Modeling user cuts\n",
"\n",
"TODO"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Julia 1.6.0",
"language": "julia",
"name": "julia-1.6"
},
"language_info": {
"file_extension": ".jl",
"mimetype": "application/julia",
"name": "julia",
"version": "1.6.0"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

@ -1,246 +0,0 @@
```{sectnum}
---
start: 1
depth: 2
suffix: .
---
```
# Using MIPLearn
## Installation
In these docs, we describe the Python/Pyomo version of the package, although a [Julia/JuMP version](https://github.com/ANL-CEEESA/MIPLearn.jl) is also available. A mixed-integer solver is also required and its Python bindings must be properly installed. Supported solvers are currently CPLEX, Gurobi and XPRESS.
To install MIPLearn, run:
```bash
pip3 install --upgrade miplearn==0.2.*
```
After installation, the package `miplearn` should become available to Python. It can be imported
as follows:
```python
import miplearn
```
## Using `LearningSolver`
The main class provided by this package is `LearningSolver`, a learning-enhanced MIP solver which uses information from previously solved instances to accelerate the solution of new instances. The following example shows its basic usage:
```python
from miplearn import LearningSolver
# List of user-provided instances
training_instances = [...]
test_instances = [...]
# Create solver
solver = LearningSolver()
# Solve all training instances
for instance in training_instances:
solver.solve(instance)
# Learn from training instances
solver.fit(training_instances)
# Solve all test instances
for instance in test_instances:
solver.solve(instance)
```
In this example, we have two lists of user-provided instances: `training_instances` and `test_instances`. We start by solving all training instances. Since there is no historical information available at this point, the instances will be processed from scratch, with no ML acceleration. After solving each instance, the solver stores within each `instance` object the optimal solution, the optimal objective value, and other information that can be used to accelerate future solves. After all training instances are solved, we call `solver.fit(training_instances)`. This instructs the solver to train all its internal machine-learning models based on the solutions of the (solved) trained instances. Subsequent calls to `solver.solve(instance)` will automatically use the trained Machine Learning models to accelerate the solution process.
## Describing problem instances
Instances to be solved by `LearningSolver` must derive from the abstract class `miplearn.Instance`. The following three abstract methods must be implemented:
* `instance.to_model()`, which returns a concrete Pyomo model corresponding to the instance;
* `instance.get_instance_features()`, which returns a 1-dimensional Numpy array of (numerical) features describing the entire instance;
* `instance.get_variable_features(var_name, index)`, which returns a 1-dimensional array of (numerical) features describing a particular decision variable.
The first method is used by `LearningSolver` to construct a concrete Pyomo model, which will be provided to the internal MIP solver. The second and third methods provide an encoding of the instance, which can be used by the ML models to make predictions. In the knapsack problem, for example, an implementation may decide to provide as instance features the average weights, average prices, number of items and the size of the knapsack. The weight and the price of each individual item could be provided as variable features. See `src/python/miplearn/problems/knapsack.py` for a concrete example.
An optional method which can be implemented is `instance.get_variable_category(var_name, index)`, which returns a category (a string, an integer or any hashable type) for each decision variable. If two variables have the same category, `LearningSolver` will use the same internal ML model to predict the values of both variables. By default, all variables belong to the `"default"` category, and therefore only one ML model is used for all variables. If the returned category is `None`, ML predictors will ignore the variable.
It is not necessary to have a one-to-one correspondence between features and problem instances. One important (and deliberate) limitation of MIPLearn, however, is that `get_instance_features()` must always return arrays of same length for all relevant instances of the problem. Similarly, `get_variable_features(var_name, index)` must also always return arrays of same length for all variables in each category. It is up to the user to decide how to encode variable-length characteristics of the problem into fixed-length vectors. In graph problems, for example, graph embeddings can be used to reduce the (variable-length) lists of nodes and edges into a fixed-length structure that still preserves some properties of the graph. Different instance encodings may have significant impact on performance.
## Describing lazy constraints
For many MIP formulations, it is not desirable to add all constraints up-front, either because the total number of constraints is very large, or because some of the constraints, even in relatively small numbers, can still cause significant performance impact when added to the formulation. In these situations, it may be desirable to generate and add constraints incrementaly, during the solution process itself. Conventional MIP solvers typically start by solving the problem without any lazy constraints. Whenever a candidate solution is found, the solver finds all violated lazy constraints and adds them to the formulation. MIPLearn significantly accelerates this process by using ML to predict which lazy constraints should be enforced from the very beginning of the optimization process, even before a candidate solution is available.
MIPLearn supports two types of lazy constraints: through constraint annotations and through callbacks.
### Adding lazy constraints through annotations
The easiest way to create lazy constraints in MIPLearn is to add them to the model (just like any regular constraints), then annotate them as lazy, as described below. Just before the optimization starts, MIPLearn removes all lazy constraints from the model and places them in a lazy constraint pool. If any trained ML models are available, MIPLearn queries these models to decide which of these constraints should be moved back into the formulation. After this step, the optimization starts, and lazy constraints from the pool are added to the model in the conventional fashion.
To tag a constraint as lazy, the following methods must be implemented:
* `instance.has_static_lazy_constraints()`, which returns `True` if the model has any annotated lazy constraints. By default, this method returns `False`.
* `instance.is_constraint_lazy(cid)`, which returns `True` if the constraint with name `cid` should be treated as a lazy constraint, and `False` otherwise.
* `instance.get_constraint_features(cid)`, which returns a 1-dimensional Numpy array of (numerical) features describing the constraint.
For instances such that `has_lazy_constraints` returns `True`, MIPLearn calls `is_constraint_lazy` for each constraint in the formulation, providing the name of the constraint. For constraints such that `is_constraint_lazy` returns `True`, MIPLearn additionally calls `get_constraint_features` to gather a ML representation of each constraint. These features are used to predict which lazy constraints should be initially enforced.
An additional method that can be implemented is `get_lazy_constraint_category(cid)`, which returns a category (a string or any other hashable type) for each lazy constraint. Similarly to decision variable categories, if two lazy constraints have the same category, then MIPLearn will use the same internal ML model to decide whether to initially enforce them. By default, all lazy constraints belong to the `"default"` category, and therefore a single ML model is used.
!!! warning
If two lazy constraints belong to the same category, their feature vectors should have the same length.
### Adding lazy constraints through callbacks
Although convenient, the method described in the previous subsection still requires the generation of all lazy constraints ahead of time, which can be prohibitively expensive. An alternative method is through a lazy constraint callbacks, described below. During the solution process, MIPLearn will repeatedly call a user-provided function to identify any violated lazy constraints. If violated constraints are identified, MIPLearn will additionally call another user-provided function to generate the constraint and add it to the formulation.
To describe lazy constraints through user callbacks, the following methods need to be implemented:
* `instance.has_dynamic_lazy_constraints()`, which returns `True` if the model has any lazy constraints generated by user callbacks. By default, this method returns `False`.
* `instance.find_violated_lazy_constraints(model)`, which returns a list of identifiers corresponding to the lazy constraints found to be violated by the current solution. These identifiers should be strings, tuples or any other hashable type.
* `instance.build_violated_lazy_constraints(model, cid)`, which returns either a list of Pyomo constraints, or a single Pyomo constraint, corresponding to the given lazy constraint identifier.
* `instance.get_constraint_features(cid)`, which returns a 1-dimensional Numpy array of (numerical) features describing the constraint. If this constraint is not valid, returns `None`.
* `instance.get_lazy_constraint_category(cid)`, which returns a category (a string or any other hashable type) for each lazy constraint, indicating which ML model to use. By default, returns `"default"`.
Assuming that trained ML models are available, immediately after calling `solver.solve`, MIPLearn will call `get_constraint_features` for each lazy constraint identifier found in the training set. For constraints such that `get_constraint_features` returns a vector (instead of `None`), MIPLearn will call `get_constraint_category` to decide which trained ML model to use. It will then query the ML model to decide whether the constraint should be initially enforced. Assuming that the ML predicts this constraint will be necessary, MIPLearn calls `build_violated_constraints` then adds the returned list of Pyomo constraints to the model. The optimization then starts. When no trained ML models are available, this entire initial process is skipped, and MIPLearn behaves like a conventional solver.
After the optimization process starts, MIPLearn will periodically call `find_violated_lazy_constraints` to verify if the current solution violates any lazy constraints. If any violated lazy constraints are found, MIPLearn will call the method `build_violated_lazy_constraints` and add the returned constraints to the formulation.
```{tip}
When implementing `find_violated_lazy_constraints(self, model)`, the current solution may be accessed through `self.solution[var_name][index]`.
```
## Obtaining heuristic solutions
By default, `LearningSolver` uses Machine Learning to accelerate the MIP solution process, while maintaining all optimality guarantees provided by the MIP solver. In the default mode of operation, for example, predicted optimal solutions are used only as MIP starts.
For more significant performance benefits, `LearningSolver` can also be configured to place additional trust in the Machine Learning predictors, by using the `mode="heuristic"` constructor argument. When operating in this mode, if a ML model is statistically shown (through *stratified k-fold cross validation*) to have exceptionally high accuracy, the solver may decide to restrict the search space based on its predictions. The parts of the solution which the ML models cannot predict accurately will still be explored using traditional (branch-and-bound) methods. For particular applications, this mode has been shown to quickly produce optimal or near-optimal solutions (see [references](about.md#references) and [benchmark results](benchmark.md)).
```{danger}
The `heuristic` mode provides no optimality guarantees, and therefore should only be used if the solver is first trained on a large and representative set of training instances. Training on a small or non-representative set of instances may produce low-quality solutions, or make the solver incorrectly classify new instances as infeasible.
```
## Scaling Up
### Saving and loading solver state
After solving a large number of training instances, it may be desirable to save the current state of `LearningSolver` to disk, so that the solver can still use the acquired knowledge after the application restarts. This can be accomplished by using the the utility functions `write_pickle_gz` and `read_pickle_gz`, as the following example illustrates:
```python
from miplearn import LearningSolver, write_pickle_gz, read_pickle_gz
# Solve training instances
training_instances = [...]
solver = LearningSolver()
for instance in training_instances:
solver.solve(instance)
# Train machine-learning models
solver.fit(training_instances)
# Save trained solver to disk
write_pickle_gz(solver, "solver.pkl.gz")
# Application restarts...
# Load trained solver from disk
solver = read_pickle_gz("solver.pkl.gz")
# Solve additional instances
test_instances = [...]
for instance in test_instances:
solver.solve(instance)
```
### Solving instances in parallel
In many situations, instances can be solved in parallel to accelerate the training process. `LearningSolver` provides the method `parallel_solve(instances)` to easily achieve this:
```python
from miplearn import LearningSolver
training_instances = [...]
solver = LearningSolver()
solver.parallel_solve(training_instances, n_jobs=4)
solver.fit(training_instances)
# Test phase...
test_instances = [...]
solver.parallel_solve(test_instances)
```
### Solving instances from the disk
In all examples above, we have assumed that instances are available as Python objects, stored in memory. When problem instances are very large, or when there is a large number of problem instances, this approach may require an excessive amount of memory. To reduce memory requirements, MIPLearn can also operate on instances that are stored on disk, through the `PickleGzInstance` class, as the next example illustrates.
```python
import pickle
from miplearn import (
LearningSolver,
PickleGzInstance,
write_pickle_gz,
)
# Construct and pickle 600 problem instances
for i in range(600):
instance = MyProblemInstance([...])
write_pickle_gz(instance, "instance_%03d.pkl" % i)
# Split instances into training and test
test_instances = [PickleGzInstance("instance_%03d.pkl" % i) for i in range(500)]
train_instances = [PickleGzInstance("instance_%03d.pkl" % i) for i in range(500, 600)]
# Create solver
solver = LearningSolver([...])
# Solve training instances
solver.parallel_solve(train_instances, n_jobs=4)
# Train ML models
solver.fit(train_instances)
# Solve test instances
solver.parallel_solve(test_instances, n_jobs=4)
```
By default, `solve` and `parallel_solve` modify files in place. That is, after the instances are loaded from disk and solved, MIPLearn writes them back to the disk, overwriting the original files. To discard the modifications instead, use `LearningSolver(..., discard_outputs=True)`. This can be useful, for example, during benchmarks.
## Running benchmarks
MIPLearn provides the utility class `BenchmarkRunner`, which simplifies the task of comparing the performance of different solvers. The snippet below shows its basic usage:
```python
from miplearn import BenchmarkRunner, LearningSolver
# Create train and test instances
train_instances = [...]
test_instances = [...]
# Training phase...
training_solver = LearningSolver(...)
training_solver.parallel_solve(train_instances, n_jobs=10)
# Test phase...
benchmark = BenchmarkRunner({
"Baseline": LearningSolver(...),
"Strategy A": LearningSolver(...),
"Strategy B": LearningSolver(...),
"Strategy C": LearningSolver(...),
})
benchmark.fit(train_instances)
benchmark.parallel_solve(test_instances, n_jobs=5)
benchmark.write_csv("results.csv")
```
The method `fit` trains the ML models for each individual solver. The method `parallel_solve` solves the test instances in parallel, and collects solver statistics such as running time and optimal value. Finally, `write_csv` produces a table of results. The columns in the CSV file depend on the components added to the solver.
## Current Limitations
* Only binary and continuous decision variables are currently supported. General integer variables are not currently supported by some solver components.

@ -5,3 +5,59 @@ h1.site-logo {
h1.site-logo small { h1.site-logo small {
font-size: 20px !important; font-size: 20px !important;
} }
code {
display: inline-block;
color: #222 !important;
background-color: rgba(0 0 0 / 8%);
border-radius: 4px;
padding: 0 4px;
}
.right-next, .left-prev {
border-radius: 8px;
border-width: 0px !important;
box-shadow: 2px 2px 6px rgba(0, 0, 0, 0.2);
}
.right-next:hover, .left-prev:hover {
text-decoration: none;
}
.admonition {
border-radius: 8px;
border-width: 0;
box-shadow: 0 0 0 !important;
}
.note { background-color: rgba(0, 123, 255, 0.1); }
.note * { color: rgb(69 94 121); }
.warning { background-color: rgb(220 150 40 / 10%); }
.warning * { color: rgb(105 72 28); }
.input_area, .output_area {
border-radius: 8px !important;
border-width: 0 !important;
margin: 8px 0 8px 0;
}
.output_area {
padding: 12px;
background-color: hsl(227 60% 11% / 0.7) !important;
}
.output_area pre {
//overflow: hidden;
color: #fff;
}
.input_area pre {
background-color: rgba(0 0 0 / 3%) !important;
padding: 12px !important;
}
.ansi-green-intense-fg {
color: #64d88b !important;
}

@ -1,310 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>4. About &#8212; MIPLearn&lt;br/&gt;&lt;small&gt;0.2.0&lt;/small&gt;</title>
<link href="../_static/css/theme.css" rel="stylesheet" />
<link href="../_static/css/index.c5995385ac14fb8791e8eb36b4908be2.css" rel="stylesheet" />
<link rel="stylesheet"
href="../_static/vendor/fontawesome/5.13.0/css/all.min.css">
<link rel="preload" as="font" type="font/woff2" crossorigin
href="../_static/vendor/fontawesome/5.13.0/webfonts/fa-solid-900.woff2">
<link rel="preload" as="font" type="font/woff2" crossorigin
href="../_static/vendor/fontawesome/5.13.0/webfonts/fa-brands-400.woff2">
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
<link rel="stylesheet" href="../_static/sphinx-book-theme.acff12b8f9c144ce68a297486a2fa670.css" type="text/css" />
<link rel="stylesheet" type="text/css" href="../_static/custom.css" />
<link rel="preload" as="script" href="../_static/js/index.1c5a1a01449ed65a7b51.js">
<script id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
<script src="../_static/jquery.js"></script>
<script src="../_static/underscore.js"></script>
<script src="../_static/doctools.js"></script>
<script src="../_static/sphinx-book-theme.12a9622fbb08dcb3a2a40b2c02b83a57.js"></script>
<link rel="author" title="About these documents" href="#" />
<link rel="index" title="Index" href="../genindex/" />
<link rel="search" title="Search" href="../search/" />
<link rel="prev" title="3. Customization" href="../customization/" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="docsearch:language" content="en" />
</head>
<body data-spy="scroll" data-target="#bd-toc-nav" data-offset="80">
<div class="container-fluid" id="banner"></div>
<div class="container-xl">
<div class="row">
<div class="col-12 col-md-3 bd-sidebar site-navigation show" id="site-navigation">
<div class="navbar-brand-box">
<a class="navbar-brand text-wrap" href="../">
<h1 class="site-logo" id="site-title">MIPLearn<br/><small>0.2.0</small></h1>
</a>
</div><form class="bd-search d-flex align-items-center" action="../search/" method="get">
<i class="icon fas fa-search"></i>
<input type="search" class="form-control" name="q" id="search-input" placeholder="Search the docs ..." aria-label="Search the docs ..." autocomplete="off" >
</form><nav class="bd-links" id="bd-docs-nav" aria-label="Main navigation">
<div class="bd-toc-item active">
<ul class="current nav bd-sidenav">
<li class="toctree-l1">
<a class="reference internal" href="../usage/">
<span class="sectnum">
1.
</span>
Using MIPLearn
</a>
</li>
<li class="toctree-l1">
<a class="reference internal" href="../benchmark/">
<span class="sectnum">
2.
</span>
Benchmarks
</a>
</li>
<li class="toctree-l1">
<a class="reference internal" href="../customization/">
<span class="sectnum">
3.
</span>
Customization
</a>
</li>
<li class="toctree-l1 current active">
<a class="current reference internal" href="#">
<span class="sectnum">
4.
</span>
About
</a>
</li>
</ul>
</div>
</nav> <!-- To handle the deprecated key -->
</div>
<main class="col py-md-3 pl-md-4 bd-content overflow-auto" role="main">
<div class="topbar container-xl fixed-top">
<div class="topbar-contents row">
<div class="col-12 col-md-3 bd-topbar-whitespace site-navigation show"></div>
<div class="col pl-md-4 topbar-main">
<button id="navbar-toggler" class="navbar-toggler ml-0" type="button" data-toggle="collapse"
data-toggle="tooltip" data-placement="bottom" data-target=".site-navigation" aria-controls="navbar-menu"
aria-expanded="true" aria-label="Toggle navigation" aria-controls="site-navigation"
title="Toggle navigation" data-toggle="tooltip" data-placement="left">
<i class="fas fa-bars"></i>
<i class="fas fa-arrow-left"></i>
<i class="fas fa-arrow-up"></i>
</button>
<div class="dropdown-buttons-trigger">
<button id="dropdown-buttons-trigger" class="btn btn-secondary topbarbtn" aria-label="Download this page"><i
class="fas fa-download"></i></button>
<div class="dropdown-buttons">
<!-- ipynb file if we had a myst markdown file -->
<!-- Download raw file -->
<a class="dropdown-buttons" href="../_sources/about.md.txt"><button type="button"
class="btn btn-secondary topbarbtn" title="Download source file" data-toggle="tooltip"
data-placement="left">.md</button></a>
<!-- Download PDF via print -->
<button type="button" id="download-print" class="btn btn-secondary topbarbtn" title="Print to PDF"
onClick="window.print()" data-toggle="tooltip" data-placement="left">.pdf</button>
</div>
</div>
<!-- Source interaction buttons -->
<div class="dropdown-buttons-trigger">
<button id="dropdown-buttons-trigger" class="btn btn-secondary topbarbtn"
aria-label="Connect with source repository"><i class="fab fa-github"></i></button>
<div class="dropdown-buttons sourcebuttons">
<a class="repository-button"
href="https://github.com/ANL-CEEESA/MIPLearn/"><button type="button" class="btn btn-secondary topbarbtn"
data-toggle="tooltip" data-placement="left" title="Source repository"><i
class="fab fa-github"></i>repository</button></a>
</div>
</div>
<!-- Full screen (wrap in <a> to have style consistency -->
<a class="full-screen-button"><button type="button" class="btn btn-secondary topbarbtn" data-toggle="tooltip"
data-placement="bottom" onclick="toggleFullScreen()" aria-label="Fullscreen mode"
title="Fullscreen mode"><i
class="fas fa-expand"></i></button></a>
<!-- Launch buttons -->
</div>
<!-- Table of contents -->
<div class="d-none d-md-block col-md-2 bd-toc show">
<div class="tocsection onthispage pt-5 pb-3">
<i class="fas fa-list"></i> Contents
</div>
<nav id="bd-toc-nav">
<ul class="visible nav section-nav flex-column">
<li class="toc-h2 nav-item toc-entry">
<a class="reference internal nav-link" href="#authors">
<span class="sectnum">
4.1.
</span>
Authors
</a>
</li>
<li class="toc-h2 nav-item toc-entry">
<a class="reference internal nav-link" href="#acknowledgments">
<span class="sectnum">
4.2.
</span>
Acknowledgments
</a>
</li>
<li class="toc-h2 nav-item toc-entry">
<a class="reference internal nav-link" href="#references">
<span class="sectnum">
4.3.
</span>
References
</a>
</li>
<li class="toc-h2 nav-item toc-entry">
<a class="reference internal nav-link" href="#license">
<span class="sectnum">
4.4.
</span>
License
</a>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div id="main-content" class="row">
<div class="col-12 col-md-9 pl-md-3 pr-md-0">
<div>
<div class="section" id="about">
<h1><span class="sectnum">4.</span> About<a class="headerlink" href="#about" title="Permalink to this headline"></a></h1>
<div class="section" id="authors">
<h2><span class="sectnum">4.1.</span> Authors<a class="headerlink" href="#authors" title="Permalink to this headline"></a></h2>
<ul class="simple">
<li><p><strong>Alinson S. Xavier,</strong> Argonne National Laboratory &lt;<a class="reference external" href="mailto:axavier&#37;&#52;&#48;anl&#46;gov">mailto:axavier<span>&#64;</span>anl<span>&#46;</span>gov</a>&gt;</p></li>
<li><p><strong>Feng Qiu,</strong> Argonne National Laboratory &lt;<a class="reference external" href="mailto:fqiu&#37;&#52;&#48;anl&#46;gov">mailto:fqiu<span>&#64;</span>anl<span>&#46;</span>gov</a>&gt;</p></li>
</ul>
</div>
<div class="section" id="acknowledgments">
<h2><span class="sectnum">4.2.</span> Acknowledgments<a class="headerlink" href="#acknowledgments" title="Permalink to this headline"></a></h2>
<ul class="simple">
<li><p>Based upon work supported by <strong>Laboratory Directed Research and Development</strong> (LDRD) funding from Argonne National Laboratory, provided by the Director, Office of Science, of the U.S. Department of Energy under Contract No. DE-AC02-06CH11357, and the <strong>U.S. Department of Energy Advanced Grid Modeling Program</strong> under Grant DE-OE0000875.</p></li>
</ul>
</div>
<div class="section" id="references">
<h2><span class="sectnum">4.3.</span> References<a class="headerlink" href="#references" title="Permalink to this headline"></a></h2>
<p>If you use MIPLearn in your research, or the included problem generators, we kindly request that you cite the package as follows:</p>
<ul class="simple">
<li><p><strong>Alinson S. Xavier, Feng Qiu.</strong> <em>MIPLearn: An Extensible Framework for Learning-Enhanced Optimization</em>. Zenodo (2020). DOI: <a class="reference external" href="https://doi.org/10.5281/zenodo.4287567">10.5281/zenodo.4287567</a></p></li>
</ul>
<p>If you use MIPLearn in the field of power systems optimization, we kindly request that you cite the reference below, in which the main techniques implemented in MIPLearn were first developed:</p>
<ul class="simple">
<li><p><strong>Alinson S. Xavier, Feng Qiu, Shabbir Ahmed.</strong> <em>Learning to Solve Large-Scale Unit Commitment Problems.</em> INFORMS Journal on Computing (2020). DOI: <a class="reference external" href="https://doi.org/10.1287/ijoc.2020.0976">10.1287/ijoc.2020.0976</a></p></li>
</ul>
</div>
<div class="section" id="license">
<h2><span class="sectnum">4.4.</span> License<a class="headerlink" href="#license" title="Permalink to this headline"></a></h2>
<div class="highlight-text notranslate"><div class="highlight"><pre><span></span>MIPLearn, an extensible framework for Learning-Enhanced Mixed-Integer Optimization
Copyright © 2020, UChicago Argonne, LLC. All Rights Reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted
provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of
conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of
conditions and the following disclaimer in the documentation and/or other materials provided
with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors may be used to
endorse or promote products derived from this software without specific prior written
permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS &quot;AS IS&quot; AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
</pre></div>
</div>
</div>
</div>
</div>
<div class='prev-next-bottom'>
<a class='left-prev' id="prev-link" href="../customization/" title="previous page"><span class="sectnum">3.</span> Customization</a>
</div>
</div>
</div>
<footer class="footer mt-5 mt-md-0">
<div class="container">
<p>
&copy; Copyright 2020-2021, UChicago Argonne, LLC.<br/>
</p>
</div>
</footer>
</main>
</div>
</div>
<script src="../_static/js/index.1c5a1a01449ed65a7b51.js"></script>
</body>
</html>

@ -1,477 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>2. Benchmarks &#8212; MIPLearn&lt;br/&gt;&lt;small&gt;0.2.0&lt;/small&gt;</title>
<link href="../_static/css/theme.css" rel="stylesheet" />
<link href="../_static/css/index.c5995385ac14fb8791e8eb36b4908be2.css" rel="stylesheet" />
<link rel="stylesheet"
href="../_static/vendor/fontawesome/5.13.0/css/all.min.css">
<link rel="preload" as="font" type="font/woff2" crossorigin
href="../_static/vendor/fontawesome/5.13.0/webfonts/fa-solid-900.woff2">
<link rel="preload" as="font" type="font/woff2" crossorigin
href="../_static/vendor/fontawesome/5.13.0/webfonts/fa-brands-400.woff2">
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
<link rel="stylesheet" href="../_static/sphinx-book-theme.acff12b8f9c144ce68a297486a2fa670.css" type="text/css" />
<link rel="stylesheet" type="text/css" href="../_static/custom.css" />
<link rel="preload" as="script" href="../_static/js/index.1c5a1a01449ed65a7b51.js">
<script id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
<script src="../_static/jquery.js"></script>
<script src="../_static/underscore.js"></script>
<script src="../_static/doctools.js"></script>
<script src="../_static/sphinx-book-theme.12a9622fbb08dcb3a2a40b2c02b83a57.js"></script>
<script async="async" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.7/latest.js?config=TeX-AMS-MML_HTMLorMML"></script>
<script type="text/x-mathjax-config">MathJax.Hub.Config({"tex2jax": {"inlineMath": [["\\(", "\\)"]], "displayMath": [["\\[", "\\]"]], "processRefs": false, "processEnvironments": false}})</script>
<link rel="author" title="About these documents" href="../about/" />
<link rel="index" title="Index" href="../genindex/" />
<link rel="search" title="Search" href="../search/" />
<link rel="next" title="3. Customization" href="../customization/" />
<link rel="prev" title="1. Using MIPLearn" href="../usage/" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="docsearch:language" content="en" />
</head>
<body data-spy="scroll" data-target="#bd-toc-nav" data-offset="80">
<div class="container-fluid" id="banner"></div>
<div class="container-xl">
<div class="row">
<div class="col-12 col-md-3 bd-sidebar site-navigation show" id="site-navigation">
<div class="navbar-brand-box">
<a class="navbar-brand text-wrap" href="../">
<h1 class="site-logo" id="site-title">MIPLearn<br/><small>0.2.0</small></h1>
</a>
</div><form class="bd-search d-flex align-items-center" action="../search/" method="get">
<i class="icon fas fa-search"></i>
<input type="search" class="form-control" name="q" id="search-input" placeholder="Search the docs ..." aria-label="Search the docs ..." autocomplete="off" >
</form><nav class="bd-links" id="bd-docs-nav" aria-label="Main navigation">
<div class="bd-toc-item active">
<ul class="current nav bd-sidenav">
<li class="toctree-l1">
<a class="reference internal" href="../usage/">
<span class="sectnum">
1.
</span>
Using MIPLearn
</a>
</li>
<li class="toctree-l1 current active">
<a class="current reference internal" href="#">
<span class="sectnum">
2.
</span>
Benchmarks
</a>
</li>
<li class="toctree-l1">
<a class="reference internal" href="../customization/">
<span class="sectnum">
3.
</span>
Customization
</a>
</li>
<li class="toctree-l1">
<a class="reference internal" href="../about/">
<span class="sectnum">
4.
</span>
About
</a>
</li>
</ul>
</div>
</nav> <!-- To handle the deprecated key -->
</div>
<main class="col py-md-3 pl-md-4 bd-content overflow-auto" role="main">
<div class="topbar container-xl fixed-top">
<div class="topbar-contents row">
<div class="col-12 col-md-3 bd-topbar-whitespace site-navigation show"></div>
<div class="col pl-md-4 topbar-main">
<button id="navbar-toggler" class="navbar-toggler ml-0" type="button" data-toggle="collapse"
data-toggle="tooltip" data-placement="bottom" data-target=".site-navigation" aria-controls="navbar-menu"
aria-expanded="true" aria-label="Toggle navigation" aria-controls="site-navigation"
title="Toggle navigation" data-toggle="tooltip" data-placement="left">
<i class="fas fa-bars"></i>
<i class="fas fa-arrow-left"></i>
<i class="fas fa-arrow-up"></i>
</button>
<div class="dropdown-buttons-trigger">
<button id="dropdown-buttons-trigger" class="btn btn-secondary topbarbtn" aria-label="Download this page"><i
class="fas fa-download"></i></button>
<div class="dropdown-buttons">
<!-- ipynb file if we had a myst markdown file -->
<!-- Download raw file -->
<a class="dropdown-buttons" href="../_sources/benchmark.md.txt"><button type="button"
class="btn btn-secondary topbarbtn" title="Download source file" data-toggle="tooltip"
data-placement="left">.md</button></a>
<!-- Download PDF via print -->
<button type="button" id="download-print" class="btn btn-secondary topbarbtn" title="Print to PDF"
onClick="window.print()" data-toggle="tooltip" data-placement="left">.pdf</button>
</div>
</div>
<!-- Source interaction buttons -->
<div class="dropdown-buttons-trigger">
<button id="dropdown-buttons-trigger" class="btn btn-secondary topbarbtn"
aria-label="Connect with source repository"><i class="fab fa-github"></i></button>
<div class="dropdown-buttons sourcebuttons">
<a class="repository-button"
href="https://github.com/ANL-CEEESA/MIPLearn/"><button type="button" class="btn btn-secondary topbarbtn"
data-toggle="tooltip" data-placement="left" title="Source repository"><i
class="fab fa-github"></i>repository</button></a>
</div>
</div>
<!-- Full screen (wrap in <a> to have style consistency -->
<a class="full-screen-button"><button type="button" class="btn btn-secondary topbarbtn" data-toggle="tooltip"
data-placement="bottom" onclick="toggleFullScreen()" aria-label="Fullscreen mode"
title="Fullscreen mode"><i
class="fas fa-expand"></i></button></a>
<!-- Launch buttons -->
</div>
<!-- Table of contents -->
<div class="d-none d-md-block col-md-2 bd-toc show">
<div class="tocsection onthispage pt-5 pb-3">
<i class="fas fa-list"></i> Contents
</div>
<nav id="bd-toc-nav">
<ul class="visible nav section-nav flex-column">
<li class="toc-h2 nav-item toc-entry">
<a class="reference internal nav-link" href="#preliminaries">
<span class="sectnum">
2.1.
</span>
Preliminaries
</a>
<ul class="nav section-nav flex-column">
<li class="toc-h3 nav-item toc-entry">
<a class="reference internal nav-link" href="#benchmark-challenges">
Benchmark challenges
</a>
</li>
<li class="toc-h3 nav-item toc-entry">
<a class="reference internal nav-link" href="#baseline-results">
Baseline results
</a>
</li>
</ul>
</li>
<li class="toc-h2 nav-item toc-entry">
<a class="reference internal nav-link" href="#maximum-weight-stable-set-problem">
<span class="sectnum">
2.2.
</span>
Maximum Weight Stable Set Problem
</a>
<ul class="nav section-nav flex-column">
<li class="toc-h3 nav-item toc-entry">
<a class="reference internal nav-link" href="#problem-definition">
Problem definition
</a>
</li>
<li class="toc-h3 nav-item toc-entry">
<a class="reference internal nav-link" href="#random-instance-generator">
Random instance generator
</a>
</li>
<li class="toc-h3 nav-item toc-entry">
<a class="reference internal nav-link" href="#challenge-a">
Challenge A
</a>
</li>
</ul>
</li>
<li class="toc-h2 nav-item toc-entry">
<a class="reference internal nav-link" href="#traveling-salesman-problem">
<span class="sectnum">
2.3.
</span>
Traveling Salesman Problem
</a>
<ul class="nav section-nav flex-column">
<li class="toc-h3 nav-item toc-entry">
<a class="reference internal nav-link" href="#id1">
Problem definition
</a>
</li>
<li class="toc-h3 nav-item toc-entry">
<a class="reference internal nav-link" href="#random-problem-generator">
Random problem generator
</a>
</li>
<li class="toc-h3 nav-item toc-entry">
<a class="reference internal nav-link" href="#id2">
Challenge A
</a>
</li>
</ul>
</li>
<li class="toc-h2 nav-item toc-entry">
<a class="reference internal nav-link" href="#multidimensional-0-1-knapsack-problem">
<span class="sectnum">
2.4.
</span>
Multidimensional 0-1 Knapsack Problem
</a>
<ul class="nav section-nav flex-column">
<li class="toc-h3 nav-item toc-entry">
<a class="reference internal nav-link" href="#id3">
Problem definition
</a>
</li>
<li class="toc-h3 nav-item toc-entry">
<a class="reference internal nav-link" href="#id4">
Random instance generator
</a>
</li>
<li class="toc-h3 nav-item toc-entry">
<a class="reference internal nav-link" href="#id5">
Challenge A
</a>
</li>
</ul>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div id="main-content" class="row">
<div class="col-12 col-md-9 pl-md-3 pr-md-0">
<div>
<div class="section" id="benchmarks">
<h1><span class="sectnum">2.</span> Benchmarks<a class="headerlink" href="#benchmarks" title="Permalink to this headline"></a></h1>
<p>MIPLearn provides a selection of benchmark problems and random instance generators, covering applications from different fields, that can be used to evaluate new learning-enhanced MIP techniques in a measurable and reproducible way. In this page, we describe these problems, the included instance generators, and we present some benchmark results for <code class="docutils literal notranslate"><span class="pre">LearningSolver</span></code> with default parameters.</p>
<div class="section" id="preliminaries">
<h2><span class="sectnum">2.1.</span> Preliminaries<a class="headerlink" href="#preliminaries" title="Permalink to this headline"></a></h2>
<div class="section" id="benchmark-challenges">
<h3>Benchmark challenges<a class="headerlink" href="#benchmark-challenges" title="Permalink to this headline"></a></h3>
<p>When evaluating the performance of a conventional MIP solver, <em>benchmark sets</em>, such as MIPLIB and TSPLIB, are typically used. The performance of newly proposed solvers or solution techniques are typically measured as the average (or total) running time the solver takes to solve the entire benchmark set. For Learning-Enhanced MIP solvers, it is also necessary to specify what instances should the solver be trained on (the <em>training instances</em>) before solving the actual set of instances we are interested in (the <em>test instances</em>). If the training instances are very similar to the test instances, we would expect a Learning-Enhanced Solver to present stronger perfomance benefits.</p>
<p>In MIPLearn, each optimization problem comes with a set of <strong>benchmark challenges</strong>, which specify how should the training and test instances be generated. The first challenges are typically easier, in the sense that training and test instances are very similar. Later challenges gradually make the sets more distinct, and therefore harder to learn from.</p>
</div>
<div class="section" id="baseline-results">
<h3>Baseline results<a class="headerlink" href="#baseline-results" title="Permalink to this headline"></a></h3>
<p>To illustrate the performance of <code class="docutils literal notranslate"><span class="pre">LearningSolver</span></code>, and to set a baseline for newly proposed techniques, we present in this page, for each benchmark challenge, a small set of computational results measuring the solution speed of the solver and the solution quality with default parameters. For more detailed computational studies, see <a class="reference external" href="about.md#references">references</a>. We compare three solvers:</p>
<ul class="simple">
<li><p><strong>baseline:</strong> Gurobi 9.0 with default settings (a conventional state-of-the-art MIP solver)</p></li>
<li><p><strong>ml-exact:</strong> <code class="docutils literal notranslate"><span class="pre">LearningSolver</span></code> with default settings, using Gurobi 9.0 as internal MIP solver</p></li>
<li><p><strong>ml-heuristic:</strong> Same as above, but with <code class="docutils literal notranslate"><span class="pre">mode=&quot;heuristic&quot;</span></code></p></li>
</ul>
<p>All experiments presented here were performed on a Linux server (Ubuntu Linux 18.04 LTS) with Intel Xeon Gold 6230s (2 processors, 40 cores, 80 threads) and 256 GB RAM (DDR4, 2933 MHz). All solvers were restricted to use 4 threads, with no time limits, and 10 instances were solved simultaneously at a time.</p>
</div>
</div>
<div class="section" id="maximum-weight-stable-set-problem">
<h2><span class="sectnum">2.2.</span> Maximum Weight Stable Set Problem<a class="headerlink" href="#maximum-weight-stable-set-problem" title="Permalink to this headline"></a></h2>
<div class="section" id="problem-definition">
<h3>Problem definition<a class="headerlink" href="#problem-definition" title="Permalink to this headline"></a></h3>
<p>Given a simple undirected graph <span class="math notranslate nohighlight">\(G=(V,E)\)</span> and weights <span class="math notranslate nohighlight">\(w \in \mathbb{R}^V\)</span>, the problem is to find a stable set <span class="math notranslate nohighlight">\(S \subseteq V\)</span> that maximizes <span class="math notranslate nohighlight">\( \sum_{v \in V} w_v\)</span>. We recall that a subset <span class="math notranslate nohighlight">\(S \subseteq V\)</span> is a <em>stable set</em> if no two vertices of <span class="math notranslate nohighlight">\(S\)</span> are adjacent. This is one of Karps 21 NP-complete problems.</p>
</div>
<div class="section" id="random-instance-generator">
<h3>Random instance generator<a class="headerlink" href="#random-instance-generator" title="Permalink to this headline"></a></h3>
<p>The class <code class="docutils literal notranslate"><span class="pre">MaxWeightStableSetGenerator</span></code> can be used to generate random instances of this problem, with user-specified probability distributions. When the constructor parameter <code class="docutils literal notranslate"><span class="pre">fix_graph=True</span></code> is provided, one random Erdős-Rényi graph <span class="math notranslate nohighlight">\(G_{n,p}\)</span> is generated during the constructor, where <span class="math notranslate nohighlight">\(n\)</span> and <span class="math notranslate nohighlight">\(p\)</span> are sampled from user-provided probability distributions <code class="docutils literal notranslate"><span class="pre">n</span></code> and <code class="docutils literal notranslate"><span class="pre">p</span></code>. To generate each instance, the generator independently samples each <span class="math notranslate nohighlight">\(w_v\)</span> from the user-provided probability distribution <code class="docutils literal notranslate"><span class="pre">w</span></code>. When <code class="docutils literal notranslate"><span class="pre">fix_graph=False</span></code>, a new random graph is generated for each instance, while the remaining parameters are sampled in the same way.</p>
</div>
<div class="section" id="challenge-a">
<h3>Challenge A<a class="headerlink" href="#challenge-a" title="Permalink to this headline"></a></h3>
<ul class="simple">
<li><p>Fixed random Erdős-Rényi graph <span class="math notranslate nohighlight">\(G_{n,p}\)</span> with <span class="math notranslate nohighlight">\(n=200\)</span> and <span class="math notranslate nohighlight">\(p=5\%\)</span></p></li>
<li><p>Random vertex weights <span class="math notranslate nohighlight">\(w_v \sim U(100, 150)\)</span></p></li>
<li><p>500 training instances, 50 test instances</p></li>
</ul>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">MaxWeightStableSetGenerator</span><span class="p">(</span><span class="n">w</span><span class="o">=</span><span class="n">uniform</span><span class="p">(</span><span class="n">loc</span><span class="o">=</span><span class="mf">100.</span><span class="p">,</span> <span class="n">scale</span><span class="o">=</span><span class="mf">50.</span><span class="p">),</span>
<span class="n">n</span><span class="o">=</span><span class="n">randint</span><span class="p">(</span><span class="n">low</span><span class="o">=</span><span class="mi">200</span><span class="p">,</span> <span class="n">high</span><span class="o">=</span><span class="mi">201</span><span class="p">),</span>
<span class="n">p</span><span class="o">=</span><span class="n">uniform</span><span class="p">(</span><span class="n">loc</span><span class="o">=</span><span class="mf">0.05</span><span class="p">,</span> <span class="n">scale</span><span class="o">=</span><span class="mf">0.0</span><span class="p">),</span>
<span class="n">fix_graph</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
</pre></div>
</div>
<p><img alt="alt" src="figures/benchmark_stab_a.png" /></p>
</div>
</div>
<div class="section" id="traveling-salesman-problem">
<h2><span class="sectnum">2.3.</span> Traveling Salesman Problem<a class="headerlink" href="#traveling-salesman-problem" title="Permalink to this headline"></a></h2>
<div class="section" id="id1">
<h3>Problem definition<a class="headerlink" href="#id1" title="Permalink to this headline"></a></h3>
<p>Given a list of cities and the distance between each pair of cities, the problem asks for the
shortest route starting at the first city, visiting each other city exactly once, then returning
to the first city. This problem is a generalization of the Hamiltonian path problem, one of Karps
21 NP-complete problems.</p>
</div>
<div class="section" id="random-problem-generator">
<h3>Random problem generator<a class="headerlink" href="#random-problem-generator" title="Permalink to this headline"></a></h3>
<p>The class <code class="docutils literal notranslate"><span class="pre">TravelingSalesmanGenerator</span></code> can be used to generate random instances of this
problem. Initially, the generator creates <span class="math notranslate nohighlight">\(n\)</span> cities <span class="math notranslate nohighlight">\((x_1,y_1),\ldots,(x_n,y_n) \in \mathbb{R}^2\)</span>,
where <span class="math notranslate nohighlight">\(n, x_i\)</span> and <span class="math notranslate nohighlight">\(y_i\)</span> are sampled independently from the provided probability distributions <code class="docutils literal notranslate"><span class="pre">n</span></code>,
<code class="docutils literal notranslate"><span class="pre">x</span></code> and <code class="docutils literal notranslate"><span class="pre">y</span></code>. For each pair of cities <span class="math notranslate nohighlight">\((i,j)\)</span>, the distance <span class="math notranslate nohighlight">\(d_{i,j}\)</span> between them is set to:
$<span class="math notranslate nohighlight">\(
d_{i,j} = \gamma_{i,j} \sqrt{(x_i-x_j)^2 + (y_i - y_j)^2}
\)</span><span class="math notranslate nohighlight">\(
where \)</span>\gamma_{i,j}$ is sampled from the distribution <code class="docutils literal notranslate"><span class="pre">gamma</span></code>.</p>
<p>If <code class="docutils literal notranslate"><span class="pre">fix_cities=True</span></code> is provided, the list of cities is kept the same for all generated instances.
The <span class="math notranslate nohighlight">\(gamma\)</span> values, and therefore also the distances, are still different.</p>
<p>By default, all distances <span class="math notranslate nohighlight">\(d_{i,j}\)</span> are rounded to the nearest integer. If <code class="docutils literal notranslate"><span class="pre">round=False</span></code>
is provided, this rounding will be disabled.</p>
</div>
<div class="section" id="id2">
<h3>Challenge A<a class="headerlink" href="#id2" title="Permalink to this headline"></a></h3>
<ul class="simple">
<li><p>Fixed list of 350 cities in the <span class="math notranslate nohighlight">\([0, 1000]^2\)</span> square</p></li>
<li><p><span class="math notranslate nohighlight">\(\gamma_{i,j} \sim U(0.95, 1.05)\)</span></p></li>
<li><p>500 training instances, 50 test instances</p></li>
</ul>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">TravelingSalesmanGenerator</span><span class="p">(</span><span class="n">x</span><span class="o">=</span><span class="n">uniform</span><span class="p">(</span><span class="n">loc</span><span class="o">=</span><span class="mf">0.0</span><span class="p">,</span> <span class="n">scale</span><span class="o">=</span><span class="mf">1000.0</span><span class="p">),</span>
<span class="n">y</span><span class="o">=</span><span class="n">uniform</span><span class="p">(</span><span class="n">loc</span><span class="o">=</span><span class="mf">0.0</span><span class="p">,</span> <span class="n">scale</span><span class="o">=</span><span class="mf">1000.0</span><span class="p">),</span>
<span class="n">n</span><span class="o">=</span><span class="n">randint</span><span class="p">(</span><span class="n">low</span><span class="o">=</span><span class="mi">350</span><span class="p">,</span> <span class="n">high</span><span class="o">=</span><span class="mi">351</span><span class="p">),</span>
<span class="n">gamma</span><span class="o">=</span><span class="n">uniform</span><span class="p">(</span><span class="n">loc</span><span class="o">=</span><span class="mf">0.95</span><span class="p">,</span> <span class="n">scale</span><span class="o">=</span><span class="mf">0.1</span><span class="p">),</span>
<span class="n">fix_cities</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span>
<span class="nb">round</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span>
<span class="p">)</span>
</pre></div>
</div>
<p><img alt="alt" src="figures/benchmark_tsp_a.png" /></p>
</div>
</div>
<div class="section" id="multidimensional-0-1-knapsack-problem">
<h2><span class="sectnum">2.4.</span> Multidimensional 0-1 Knapsack Problem<a class="headerlink" href="#multidimensional-0-1-knapsack-problem" title="Permalink to this headline"></a></h2>
<div class="section" id="id3">
<h3>Problem definition<a class="headerlink" href="#id3" title="Permalink to this headline"></a></h3>
<p>Given a set of <span class="math notranslate nohighlight">\(n\)</span> items and <span class="math notranslate nohighlight">\(m\)</span> types of resources (also called <em>knapsacks</em>), the problem is to find a subset of items that maximizes profit without consuming more resources than it is available. More precisely, the problem is:</p>
<div class="math notranslate nohighlight">
\[\begin{split}
\begin{align*}
\text{maximize}
&amp; \sum_{j=1}^n p_j x_j
\\
\text{subject to}
&amp; \sum_{j=1}^n w_{ij} x_j \leq b_i
&amp; \forall i=1,\ldots,m \\
&amp; x_j \in \{0,1\}
&amp; \forall j=1,\ldots,n
\end{align*}
\end{split}\]</div>
</div>
<div class="section" id="id4">
<h3>Random instance generator<a class="headerlink" href="#id4" title="Permalink to this headline"></a></h3>
<p>The class <code class="docutils literal notranslate"><span class="pre">MultiKnapsackGenerator</span></code> can be used to generate random instances of this problem. The number of items <span class="math notranslate nohighlight">\(n\)</span> and knapsacks <span class="math notranslate nohighlight">\(m\)</span> are sampled from the user-provided probability distributions <code class="docutils literal notranslate"><span class="pre">n</span></code> and <code class="docutils literal notranslate"><span class="pre">m</span></code>. The weights <span class="math notranslate nohighlight">\(w_{ij}\)</span> are sampled independently from the provided distribution <code class="docutils literal notranslate"><span class="pre">w</span></code>. The capacity of knapsack <span class="math notranslate nohighlight">\(i\)</span> is set to</p>
<div class="math notranslate nohighlight">
\[
b_i = \alpha_i \sum_{j=1}^n w_{ij}
\]</div>
<p>where <span class="math notranslate nohighlight">\(\alpha_i\)</span>, the tightness ratio, is sampled from the provided probability
distribution <code class="docutils literal notranslate"><span class="pre">alpha</span></code>. To make the instances more challenging, the costs of the items
are linearly correlated to their average weights. More specifically, the price of each
item <span class="math notranslate nohighlight">\(j\)</span> is set to:</p>
<div class="math notranslate nohighlight">
\[
p_j = \sum_{i=1}^m \frac{w_{ij}}{m} + K u_j,
\]</div>
<p>where <span class="math notranslate nohighlight">\(K\)</span>, the correlation coefficient, and <span class="math notranslate nohighlight">\(u_j\)</span>, the correlation multiplier, are sampled
from the provided probability distributions <code class="docutils literal notranslate"><span class="pre">K</span></code> and <code class="docutils literal notranslate"><span class="pre">u</span></code>.</p>
<p>If <code class="docutils literal notranslate"><span class="pre">fix_w=True</span></code> is provided, then <span class="math notranslate nohighlight">\(w_{ij}\)</span> are kept the same in all generated instances. This also implies that <span class="math notranslate nohighlight">\(n\)</span> and <span class="math notranslate nohighlight">\(m\)</span> are kept fixed. Although the prices and capacities are derived from <span class="math notranslate nohighlight">\(w_{ij}\)</span>, as long as <code class="docutils literal notranslate"><span class="pre">u</span></code> and <code class="docutils literal notranslate"><span class="pre">K</span></code> are not constants, the generated instances will still not be completely identical.</p>
<p>If a probability distribution <code class="docutils literal notranslate"><span class="pre">w_jitter</span></code> is provided, then item weights will be set to <span class="math notranslate nohighlight">\(w_{ij} \gamma_{ij}\)</span> where <span class="math notranslate nohighlight">\(\gamma_{ij}\)</span> is sampled from <code class="docutils literal notranslate"><span class="pre">w_jitter</span></code>. When combined with <code class="docutils literal notranslate"><span class="pre">fix_w=True</span></code>, this argument may be used to generate instances where the weight of each item is roughly the same, but not exactly identical, across all instances. The prices of the items and the capacities of the knapsacks will be calculated as above, but using these perturbed weights instead.</p>
<p>By default, all generated prices, weights and capacities are rounded to the nearest integer number. If <code class="docutils literal notranslate"><span class="pre">round=False</span></code> is provided, this rounding will be disabled.</p>
<p>!!! note “References”
* Freville, Arnaud, and Gérard Plateau. <em>An efficient preprocessing procedure for the multidimensional 01 knapsack problem.</em> Discrete applied mathematics 49.1-3 (1994): 189-212.
* Fréville, Arnaud. <em>The multidimensional 01 knapsack problem: An overview.</em> European Journal of Operational Research 155.1 (2004): 1-21.</p>
</div>
<div class="section" id="id5">
<h3>Challenge A<a class="headerlink" href="#id5" title="Permalink to this headline"></a></h3>
<ul class="simple">
<li><p>250 variables, 10 constraints, fixed weights</p></li>
<li><p><span class="math notranslate nohighlight">\(w \sim U(0, 1000), \gamma \sim U(0.95, 1.05)\)</span></p></li>
<li><p><span class="math notranslate nohighlight">\(K = 500, u \sim U(0, 1), \alpha = 0.25\)</span></p></li>
<li><p>500 training instances, 50 test instances</p></li>
</ul>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">MultiKnapsackGenerator</span><span class="p">(</span><span class="n">n</span><span class="o">=</span><span class="n">randint</span><span class="p">(</span><span class="n">low</span><span class="o">=</span><span class="mi">250</span><span class="p">,</span> <span class="n">high</span><span class="o">=</span><span class="mi">251</span><span class="p">),</span>
<span class="n">m</span><span class="o">=</span><span class="n">randint</span><span class="p">(</span><span class="n">low</span><span class="o">=</span><span class="mi">10</span><span class="p">,</span> <span class="n">high</span><span class="o">=</span><span class="mi">11</span><span class="p">),</span>
<span class="n">w</span><span class="o">=</span><span class="n">uniform</span><span class="p">(</span><span class="n">loc</span><span class="o">=</span><span class="mf">0.0</span><span class="p">,</span> <span class="n">scale</span><span class="o">=</span><span class="mf">1000.0</span><span class="p">),</span>
<span class="n">K</span><span class="o">=</span><span class="n">uniform</span><span class="p">(</span><span class="n">loc</span><span class="o">=</span><span class="mf">500.0</span><span class="p">,</span> <span class="n">scale</span><span class="o">=</span><span class="mf">0.0</span><span class="p">),</span>
<span class="n">u</span><span class="o">=</span><span class="n">uniform</span><span class="p">(</span><span class="n">loc</span><span class="o">=</span><span class="mf">0.0</span><span class="p">,</span> <span class="n">scale</span><span class="o">=</span><span class="mf">1.0</span><span class="p">),</span>
<span class="n">alpha</span><span class="o">=</span><span class="n">uniform</span><span class="p">(</span><span class="n">loc</span><span class="o">=</span><span class="mf">0.25</span><span class="p">,</span> <span class="n">scale</span><span class="o">=</span><span class="mf">0.0</span><span class="p">),</span>
<span class="n">fix_w</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span>
<span class="n">w_jitter</span><span class="o">=</span><span class="n">uniform</span><span class="p">(</span><span class="n">loc</span><span class="o">=</span><span class="mf">0.95</span><span class="p">,</span> <span class="n">scale</span><span class="o">=</span><span class="mf">0.1</span><span class="p">),</span>
<span class="p">)</span>
</pre></div>
</div>
<p><img alt="alt" src="figures/benchmark_knapsack_a.png" /></p>
</div>
</div>
</div>
</div>
<div class='prev-next-bottom'>
<a class='left-prev' id="prev-link" href="../usage/" title="previous page"><span class="sectnum">1.</span> Using MIPLearn</a>
<a class='right-next' id="next-link" href="../customization/" title="next page"><span class="sectnum">3.</span> Customization</a>
</div>
</div>
</div>
<footer class="footer mt-5 mt-md-0">
<div class="container">
<p>
&copy; Copyright 2020-2021, UChicago Argonne, LLC.<br/>
</p>
</div>
</footer>
</main>
</div>
</div>
<script src="../_static/js/index.1c5a1a01449ed65a7b51.js"></script>
</body>
</html>

@ -0,0 +1,29 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "792bbfa2",
"metadata": {},
"source": [
"# Facility Location\n",
"\n",
"TODO"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Julia 1.6.0",
"language": "julia",
"name": "julia-1.6"
},
"language_info": {
"file_extension": ".jl",
"mimetype": "application/julia",
"name": "julia",
"version": "1.6.0"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

@ -0,0 +1,210 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Facility Location &#8212; MIPLearn&lt;br/&gt;&lt;small&gt;0.2.0&lt;/small&gt;</title>
<link href="../../_static/css/theme.css" rel="stylesheet" />
<link href="../../_static/css/index.c5995385ac14fb8791e8eb36b4908be2.css" rel="stylesheet" />
<link rel="stylesheet"
href="../../_static/vendor/fontawesome/5.13.0/css/all.min.css">
<link rel="preload" as="font" type="font/woff2" crossorigin
href="../../_static/vendor/fontawesome/5.13.0/webfonts/fa-solid-900.woff2">
<link rel="preload" as="font" type="font/woff2" crossorigin
href="../../_static/vendor/fontawesome/5.13.0/webfonts/fa-brands-400.woff2">
<link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
<link rel="stylesheet" href="../../_static/sphinx-book-theme.acff12b8f9c144ce68a297486a2fa670.css" type="text/css" />
<link rel="stylesheet" type="text/css" href="../../_static/custom.css" />
<link rel="preload" as="script" href="../../_static/js/index.1c5a1a01449ed65a7b51.js">
<script id="documentation_options" data-url_root="../../" src="../../_static/documentation_options.js"></script>
<script src="../../_static/jquery.js"></script>
<script src="../../_static/underscore.js"></script>
<script src="../../_static/doctools.js"></script>
<script crossorigin="anonymous" integrity="sha256-Ae2Vz/4ePdIu6ZyI/5ZGsYnb+m0JlOmKPjt6XZ9JJkA=" src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.3.4/require.min.js"></script>
<script src="../../_static/sphinx-book-theme.12a9622fbb08dcb3a2a40b2c02b83a57.js"></script>
<script async="async" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.7/latest.js?config=TeX-AMS-MML_HTMLorMML"></script>
<script type="text/x-mathjax-config">MathJax.Hub.Config({"tex2jax": {"inlineMath": [["\\(", "\\)"]], "displayMath": [["\\[", "\\]"]], "processRefs": false, "processEnvironments": false}})</script>
<link rel="index" title="Index" href="../../genindex/" />
<link rel="search" title="Search" href="../../search/" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="docsearch:language" content="en" />
</head>
<body data-spy="scroll" data-target="#bd-toc-nav" data-offset="80">
<div class="container-fluid" id="banner"></div>
<div class="container-xl">
<div class="row">
<div class="col-12 col-md-3 bd-sidebar site-navigation show" id="site-navigation">
<div class="navbar-brand-box">
<a class="navbar-brand text-wrap" href="../../">
<h1 class="site-logo" id="site-title">MIPLearn<br/><small>0.2.0</small></h1>
</a>
</div><form class="bd-search d-flex align-items-center" action="../../search/" method="get">
<i class="icon fas fa-search"></i>
<input type="search" class="form-control" name="q" id="search-input" placeholder="Search the docs ..." aria-label="Search the docs ..." autocomplete="off" >
</form><nav class="bd-links" id="bd-docs-nav" aria-label="Main navigation">
<div class="bd-toc-item active">
<p class="caption">
<span class="caption-text">
Julia Tutorials
</span>
</p>
<ul class="nav bd-sidenav">
<li class="toctree-l1">
<a class="reference internal" href="../../jump-tutorials/getting-started/">
1. Getting started with MIPLearn
</a>
</li>
</ul>
<p class="caption">
<span class="caption-text">
Benchmarks
</span>
</p>
<ul class="nav bd-sidenav">
<li class="toctree-l1">
<a class="reference internal" href="../preliminaries/">
1. Preliminaries
</a>
</li>
<li class="toctree-l1">
<a class="reference internal" href="../stab/">
2. Maximum Weight Stable Set
</a>
</li>
<li class="toctree-l1">
<a class="reference internal" href="../knapsack/">
3. Multidimensional Knapsack
</a>
</li>
<li class="toctree-l1">
<a class="reference internal" href="../tsp/">
4. Traveling Salesman
</a>
</li>
</ul>
</div>
</nav> <!-- To handle the deprecated key -->
</div>
<main class="col py-md-3 pl-md-4 bd-content overflow-auto" role="main">
<div class="topbar container-xl fixed-top">
<div class="topbar-contents row">
<div class="col-12 col-md-3 bd-topbar-whitespace site-navigation show"></div>
<div class="col pl-md-4 topbar-main">
<button id="navbar-toggler" class="navbar-toggler ml-0" type="button" data-toggle="collapse"
data-toggle="tooltip" data-placement="bottom" data-target=".site-navigation" aria-controls="navbar-menu"
aria-expanded="true" aria-label="Toggle navigation" aria-controls="site-navigation"
title="Toggle navigation" data-toggle="tooltip" data-placement="left">
<i class="fas fa-bars"></i>
<i class="fas fa-arrow-left"></i>
<i class="fas fa-arrow-up"></i>
</button>
<div class="dropdown-buttons-trigger">
<button id="dropdown-buttons-trigger" class="btn btn-secondary topbarbtn" aria-label="Download this page"><i
class="fas fa-download"></i></button>
<div class="dropdown-buttons">
<!-- ipynb file if we had a myst markdown file -->
<!-- Download raw file -->
<a class="dropdown-buttons" href="../../_sources/benchmarks/facility.ipynb.txt"><button type="button"
class="btn btn-secondary topbarbtn" title="Download source file" data-toggle="tooltip"
data-placement="left">.ipynb</button></a>
<!-- Download PDF via print -->
<button type="button" id="download-print" class="btn btn-secondary topbarbtn" title="Print to PDF"
onClick="window.print()" data-toggle="tooltip" data-placement="left">.pdf</button>
</div>
</div>
<!-- Source interaction buttons -->
<!-- Full screen (wrap in <a> to have style consistency -->
<a class="full-screen-button"><button type="button" class="btn btn-secondary topbarbtn" data-toggle="tooltip"
data-placement="bottom" onclick="toggleFullScreen()" aria-label="Fullscreen mode"
title="Fullscreen mode"><i
class="fas fa-expand"></i></button></a>
<!-- Launch buttons -->
</div>
<!-- Table of contents -->
<div class="d-none d-md-block col-md-2 bd-toc show">
</div>
</div>
</div>
<div id="main-content" class="row">
<div class="col-12 col-md-9 pl-md-3 pr-md-0">
<div>
<div class="section" id="Facility-Location">
<h1>Facility Location<a class="headerlink" href="#Facility-Location" title="Permalink to this headline"></a></h1>
<p>TODO</p>
</div>
</div>
<div class='prev-next-bottom'>
</div>
</div>
</div>
<footer class="footer mt-5 mt-md-0">
<div class="container">
<p>
&copy; Copyright 2020-2021, UChicago Argonne, LLC.<br/>
</p>
</div>
</footer>
</main>
</div>
</div>
<script src="../../_static/js/index.1c5a1a01449ed65a7b51.js"></script>
</body>
</html>

@ -0,0 +1,111 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "d236e2a0",
"metadata": {},
"source": [
"# Multidimensional Knapsack\n",
"\n",
"### Problem definition\n",
"\n",
"Given a set of $n$ items and $m$ types of resources (also called *knapsacks*), the problem is to find a subset of items that maximizes profit without consuming more resources than it is available. More precisely, the problem is:\n",
"\n",
"$$\n",
"\\begin{align*}\n",
" \\text{maximize}\n",
" & \\sum_{j=1}^n p_j x_j\n",
" \\\\\n",
" \\text{subject to}\n",
" & \\sum_{j=1}^n w_{ij} x_j \\leq b_i\n",
" & \\forall i=1,\\ldots,m \\\\\n",
" & x_j \\in \\{0,1\\}\n",
" & \\forall j=1,\\ldots,n\n",
"\\end{align*}\n",
"$$\n",
"\n",
"### Random instance generator\n",
"\n",
"The class `MultiKnapsackGenerator` can be used to generate random instances of this problem. The number of items $n$ and knapsacks $m$ are sampled from the user-provided probability distributions `n` and `m`. The weights $w_{ij}$ are sampled independently from the provided distribution `w`. The capacity of knapsack $i$ is set to\n",
"\n",
"$$\n",
" b_i = \\alpha_i \\sum_{j=1}^n w_{ij}\n",
"$$\n",
"\n",
"where $\\alpha_i$, the tightness ratio, is sampled from the provided probability\n",
"distribution `alpha`. To make the instances more challenging, the costs of the items\n",
"are linearly correlated to their average weights. More specifically, the price of each\n",
"item $j$ is set to:\n",
"\n",
"$$\n",
" p_j = \\sum_{i=1}^m \\frac{w_{ij}}{m} + K u_j,\n",
"$$\n",
"\n",
"where $K$, the correlation coefficient, and $u_j$, the correlation multiplier, are sampled\n",
"from the provided probability distributions `K` and `u`.\n",
"\n",
"If `fix_w=True` is provided, then $w_{ij}$ are kept the same in all generated instances. This also implies that $n$ and $m$ are kept fixed. Although the prices and capacities are derived from $w_{ij}$, as long as `u` and `K` are not constants, the generated instances will still not be completely identical.\n",
"\n",
"\n",
"If a probability distribution `w_jitter` is provided, then item weights will be set to $w_{ij} \\gamma_{ij}$ where $\\gamma_{ij}$ is sampled from `w_jitter`. When combined with `fix_w=True`, this argument may be used to generate instances where the weight of each item is roughly the same, but not exactly identical, across all instances. The prices of the items and the capacities of the knapsacks will be calculated as above, but using these perturbed weights instead.\n",
"\n",
"By default, all generated prices, weights and capacities are rounded to the nearest integer number. If `round=False` is provided, this rounding will be disabled.\n",
"\n",
"\n",
"<div class=\"alert alert-info\">\n",
"References\n",
"\n",
"* **Freville, Arnaud, and Gérard Plateau.** *An efficient preprocessing procedure for the multidimensional 01 knapsack problem.* Discrete applied mathematics 49.1-3 (1994): 189-212.\n",
"* **Fréville, Arnaud.** *The multidimensional 01 knapsack problem: An overview.* European Journal of Operational Research 155.1 (2004): 1-21.\n",
"</div>\n",
" \n",
"### Challenge A\n",
"\n",
"* 250 variables, 10 constraints, fixed weights\n",
"* $w \\sim U(0, 1000), \\gamma \\sim U(0.95, 1.05)$\n",
"* $K = 500, u \\sim U(0, 1), \\alpha = 0.25$\n",
"* 500 training instances, 50 test instances\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "39be5cda",
"metadata": {},
"outputs": [],
"source": [
"MultiKnapsackGenerator(\n",
" n=randint(low=250, high=251),\n",
" m=randint(low=10, high=11),\n",
" w=uniform(loc=0.0, scale=1000.0),\n",
" K=uniform(loc=500.0, scale=0.0),\n",
" u=uniform(loc=0.0, scale=1.0),\n",
" alpha=uniform(loc=0.25, scale=0.0),\n",
" fix_w=True,\n",
" w_jitter=uniform(loc=0.95, scale=0.1),\n",
")"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "miplearn",
"language": "python",
"name": "miplearn"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.8.10"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

@ -0,0 +1,546 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>3. Multidimensional Knapsack &#8212; MIPLearn&lt;br/&gt;&lt;small&gt;0.2.0&lt;/small&gt;</title>
<link href="../../_static/css/theme.css" rel="stylesheet" />
<link href="../../_static/css/index.c5995385ac14fb8791e8eb36b4908be2.css" rel="stylesheet" />
<link rel="stylesheet"
href="../../_static/vendor/fontawesome/5.13.0/css/all.min.css">
<link rel="preload" as="font" type="font/woff2" crossorigin
href="../../_static/vendor/fontawesome/5.13.0/webfonts/fa-solid-900.woff2">
<link rel="preload" as="font" type="font/woff2" crossorigin
href="../../_static/vendor/fontawesome/5.13.0/webfonts/fa-brands-400.woff2">
<link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
<link rel="stylesheet" href="../../_static/sphinx-book-theme.acff12b8f9c144ce68a297486a2fa670.css" type="text/css" />
<link rel="stylesheet" type="text/css" href="../../_static/custom.css" />
<link rel="preload" as="script" href="../../_static/js/index.1c5a1a01449ed65a7b51.js">
<script id="documentation_options" data-url_root="../../" src="../../_static/documentation_options.js"></script>
<script src="../../_static/jquery.js"></script>
<script src="../../_static/underscore.js"></script>
<script src="../../_static/doctools.js"></script>
<script crossorigin="anonymous" integrity="sha256-Ae2Vz/4ePdIu6ZyI/5ZGsYnb+m0JlOmKPjt6XZ9JJkA=" src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.3.4/require.min.js"></script>
<script src="../../_static/sphinx-book-theme.12a9622fbb08dcb3a2a40b2c02b83a57.js"></script>
<script async="async" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.7/latest.js?config=TeX-AMS-MML_HTMLorMML"></script>
<script type="text/x-mathjax-config">MathJax.Hub.Config({"tex2jax": {"inlineMath": [["\\(", "\\)"]], "displayMath": [["\\[", "\\]"]], "processRefs": false, "processEnvironments": false}})</script>
<link rel="index" title="Index" href="../../genindex/" />
<link rel="search" title="Search" href="../../search/" />
<link rel="next" title="4. Traveling Salesman" href="../tsp/" />
<link rel="prev" title="2. Maximum Weight Stable Set" href="../stab/" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="docsearch:language" content="en" />
</head>
<body data-spy="scroll" data-target="#bd-toc-nav" data-offset="80">
<div class="container-fluid" id="banner"></div>
<div class="container-xl">
<div class="row">
<div class="col-12 col-md-3 bd-sidebar site-navigation show" id="site-navigation">
<div class="navbar-brand-box">
<a class="navbar-brand text-wrap" href="../../">
<h1 class="site-logo" id="site-title">MIPLearn<br/><small>0.2.0</small></h1>
</a>
</div><form class="bd-search d-flex align-items-center" action="../../search/" method="get">
<i class="icon fas fa-search"></i>
<input type="search" class="form-control" name="q" id="search-input" placeholder="Search the docs ..." aria-label="Search the docs ..." autocomplete="off" >
</form><nav class="bd-links" id="bd-docs-nav" aria-label="Main navigation">
<div class="bd-toc-item active">
<p class="caption">
<span class="caption-text">
Julia Tutorials
</span>
</p>
<ul class="nav bd-sidenav">
<li class="toctree-l1">
<a class="reference internal" href="../../jump-tutorials/getting-started/">
1. Getting started with MIPLearn
</a>
</li>
</ul>
<p class="caption">
<span class="caption-text">
Benchmarks
</span>
</p>
<ul class="current nav bd-sidenav">
<li class="toctree-l1">
<a class="reference internal" href="../preliminaries/">
1. Preliminaries
</a>
</li>
<li class="toctree-l1">
<a class="reference internal" href="../stab/">
2. Maximum Weight Stable Set
</a>
</li>
<li class="toctree-l1 current active">
<a class="current reference internal" href="#">
3. Multidimensional Knapsack
</a>
</li>
<li class="toctree-l1">
<a class="reference internal" href="../tsp/">
4. Traveling Salesman
</a>
</li>
</ul>
</div>
</nav> <!-- To handle the deprecated key -->
</div>
<main class="col py-md-3 pl-md-4 bd-content overflow-auto" role="main">
<div class="topbar container-xl fixed-top">
<div class="topbar-contents row">
<div class="col-12 col-md-3 bd-topbar-whitespace site-navigation show"></div>
<div class="col pl-md-4 topbar-main">
<button id="navbar-toggler" class="navbar-toggler ml-0" type="button" data-toggle="collapse"
data-toggle="tooltip" data-placement="bottom" data-target=".site-navigation" aria-controls="navbar-menu"
aria-expanded="true" aria-label="Toggle navigation" aria-controls="site-navigation"
title="Toggle navigation" data-toggle="tooltip" data-placement="left">
<i class="fas fa-bars"></i>
<i class="fas fa-arrow-left"></i>
<i class="fas fa-arrow-up"></i>
</button>
<div class="dropdown-buttons-trigger">
<button id="dropdown-buttons-trigger" class="btn btn-secondary topbarbtn" aria-label="Download this page"><i
class="fas fa-download"></i></button>
<div class="dropdown-buttons">
<!-- ipynb file if we had a myst markdown file -->
<!-- Download raw file -->
<a class="dropdown-buttons" href="../../_sources/benchmarks/knapsack.ipynb.txt"><button type="button"
class="btn btn-secondary topbarbtn" title="Download source file" data-toggle="tooltip"
data-placement="left">.ipynb</button></a>
<!-- Download PDF via print -->
<button type="button" id="download-print" class="btn btn-secondary topbarbtn" title="Print to PDF"
onClick="window.print()" data-toggle="tooltip" data-placement="left">.pdf</button>
</div>
</div>
<!-- Source interaction buttons -->
<!-- Full screen (wrap in <a> to have style consistency -->
<a class="full-screen-button"><button type="button" class="btn btn-secondary topbarbtn" data-toggle="tooltip"
data-placement="bottom" onclick="toggleFullScreen()" aria-label="Fullscreen mode"
title="Fullscreen mode"><i
class="fas fa-expand"></i></button></a>
<!-- Launch buttons -->
</div>
<!-- Table of contents -->
<div class="d-none d-md-block col-md-2 bd-toc show">
<div class="tocsection onthispage pt-5 pb-3">
<i class="fas fa-list"></i> Contents
</div>
<nav id="bd-toc-nav">
<ul class="visible nav section-nav flex-column">
<li class="toc-h2 nav-item toc-entry">
<a class="reference internal nav-link" href="#Problem-definition">
3.1. Problem definition
</a>
</li>
<li class="toc-h2 nav-item toc-entry">
<a class="reference internal nav-link" href="#Random-instance-generator">
3.2. Random instance generator
</a>
</li>
<li class="toc-h2 nav-item toc-entry">
<a class="reference internal nav-link" href="#Challenge-A">
3.3. Challenge A
</a>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div id="main-content" class="row">
<div class="col-12 col-md-9 pl-md-3 pr-md-0">
<div>
<style>
/* CSS for nbsphinx extension */
/* remove conflicting styling from Sphinx themes */
div.nbinput.container div.prompt *,
div.nboutput.container div.prompt *,
div.nbinput.container div.input_area pre,
div.nboutput.container div.output_area pre,
div.nbinput.container div.input_area .highlight,
div.nboutput.container div.output_area .highlight {
border: none;
padding: 0;
margin: 0;
box-shadow: none;
}
div.nbinput.container > div[class*=highlight],
div.nboutput.container > div[class*=highlight] {
margin: 0;
}
div.nbinput.container div.prompt *,
div.nboutput.container div.prompt * {
background: none;
}
div.nboutput.container div.output_area .highlight,
div.nboutput.container div.output_area pre {
background: unset;
}
div.nboutput.container div.output_area div.highlight {
color: unset; /* override Pygments text color */
}
/* avoid gaps between output lines */
div.nboutput.container div[class*=highlight] pre {
line-height: normal;
}
/* input/output containers */
div.nbinput.container,
div.nboutput.container {
display: -webkit-flex;
display: flex;
align-items: flex-start;
margin: 0;
width: 100%;
}
@media (max-width: 540px) {
div.nbinput.container,
div.nboutput.container {
flex-direction: column;
}
}
/* input container */
div.nbinput.container {
padding-top: 5px;
}
/* last container */
div.nblast.container {
padding-bottom: 5px;
}
/* input prompt */
div.nbinput.container div.prompt pre {
color: #307FC1;
}
/* output prompt */
div.nboutput.container div.prompt pre {
color: #BF5B3D;
}
/* all prompts */
div.nbinput.container div.prompt,
div.nboutput.container div.prompt {
width: 4.5ex;
padding-top: 5px;
position: relative;
user-select: none;
}
div.nbinput.container div.prompt > div,
div.nboutput.container div.prompt > div {
position: absolute;
right: 0;
margin-right: 0.3ex;
}
@media (max-width: 540px) {
div.nbinput.container div.prompt,
div.nboutput.container div.prompt {
width: unset;
text-align: left;
padding: 0.4em;
}
div.nboutput.container div.prompt.empty {
padding: 0;
}
div.nbinput.container div.prompt > div,
div.nboutput.container div.prompt > div {
position: unset;
}
}
/* disable scrollbars on prompts */
div.nbinput.container div.prompt pre,
div.nboutput.container div.prompt pre {
overflow: hidden;
}
/* input/output area */
div.nbinput.container div.input_area,
div.nboutput.container div.output_area {
-webkit-flex: 1;
flex: 1;
overflow: auto;
}
@media (max-width: 540px) {
div.nbinput.container div.input_area,
div.nboutput.container div.output_area {
width: 100%;
}
}
/* input area */
div.nbinput.container div.input_area {
border: 1px solid #e0e0e0;
border-radius: 2px;
/*background: #f5f5f5;*/
}
/* override MathJax center alignment in output cells */
div.nboutput.container div[class*=MathJax] {
text-align: left !important;
}
/* override sphinx.ext.imgmath center alignment in output cells */
div.nboutput.container div.math p {
text-align: left;
}
/* standard error */
div.nboutput.container div.output_area.stderr {
background: #fdd;
}
/* ANSI colors */
.ansi-black-fg { color: #3E424D; }
.ansi-black-bg { background-color: #3E424D; }
.ansi-black-intense-fg { color: #282C36; }
.ansi-black-intense-bg { background-color: #282C36; }
.ansi-red-fg { color: #E75C58; }
.ansi-red-bg { background-color: #E75C58; }
.ansi-red-intense-fg { color: #B22B31; }
.ansi-red-intense-bg { background-color: #B22B31; }
.ansi-green-fg { color: #00A250; }
.ansi-green-bg { background-color: #00A250; }
.ansi-green-intense-fg { color: #007427; }
.ansi-green-intense-bg { background-color: #007427; }
.ansi-yellow-fg { color: #DDB62B; }
.ansi-yellow-bg { background-color: #DDB62B; }
.ansi-yellow-intense-fg { color: #B27D12; }
.ansi-yellow-intense-bg { background-color: #B27D12; }
.ansi-blue-fg { color: #208FFB; }
.ansi-blue-bg { background-color: #208FFB; }
.ansi-blue-intense-fg { color: #0065CA; }
.ansi-blue-intense-bg { background-color: #0065CA; }
.ansi-magenta-fg { color: #D160C4; }
.ansi-magenta-bg { background-color: #D160C4; }
.ansi-magenta-intense-fg { color: #A03196; }
.ansi-magenta-intense-bg { background-color: #A03196; }
.ansi-cyan-fg { color: #60C6C8; }
.ansi-cyan-bg { background-color: #60C6C8; }
.ansi-cyan-intense-fg { color: #258F8F; }
.ansi-cyan-intense-bg { background-color: #258F8F; }
.ansi-white-fg { color: #C5C1B4; }
.ansi-white-bg { background-color: #C5C1B4; }
.ansi-white-intense-fg { color: #A1A6B2; }
.ansi-white-intense-bg { background-color: #A1A6B2; }
.ansi-default-inverse-fg { color: #FFFFFF; }
.ansi-default-inverse-bg { background-color: #000000; }
.ansi-bold { font-weight: bold; }
.ansi-underline { text-decoration: underline; }
div.nbinput.container div.input_area div[class*=highlight] > pre,
div.nboutput.container div.output_area div[class*=highlight] > pre,
div.nboutput.container div.output_area div[class*=highlight].math,
div.nboutput.container div.output_area.rendered_html,
div.nboutput.container div.output_area > div.output_javascript,
div.nboutput.container div.output_area:not(.rendered_html) > img{
padding: 5px;
margin: 0;
}
/* fix copybtn overflow problem in chromium (needed for 'sphinx_copybutton') */
div.nbinput.container div.input_area > div[class^='highlight'],
div.nboutput.container div.output_area > div[class^='highlight']{
overflow-y: hidden;
}
/* hide copybtn icon on prompts (needed for 'sphinx_copybutton') */
.prompt a.copybtn {
display: none;
}
/* Some additional styling taken form the Jupyter notebook CSS */
div.rendered_html table {
border: none;
border-collapse: collapse;
border-spacing: 0;
color: black;
font-size: 12px;
table-layout: fixed;
}
div.rendered_html thead {
border-bottom: 1px solid black;
vertical-align: bottom;
}
div.rendered_html tr,
div.rendered_html th,
div.rendered_html td {
text-align: right;
vertical-align: middle;
padding: 0.5em 0.5em;
line-height: normal;
white-space: normal;
max-width: none;
border: none;
}
div.rendered_html th {
font-weight: bold;
}
div.rendered_html tbody tr:nth-child(odd) {
background: #f5f5f5;
}
div.rendered_html tbody tr:hover {
background: rgba(66, 165, 245, 0.2);
}
</style>
<div class="section" id="Multidimensional-Knapsack">
<h1><span class="section-number">3. </span>Multidimensional Knapsack<a class="headerlink" href="#Multidimensional-Knapsack" title="Permalink to this headline"></a></h1>
<div class="section" id="Problem-definition">
<h2><span class="section-number">3.1. </span>Problem definition<a class="headerlink" href="#Problem-definition" title="Permalink to this headline"></a></h2>
<p>Given a set of <span class="math notranslate nohighlight">\(n\)</span> items and <span class="math notranslate nohighlight">\(m\)</span> types of resources (also called <em>knapsacks</em>), the problem is to find a subset of items that maximizes profit without consuming more resources than it is available. More precisely, the problem is:</p>
<div class="math notranslate nohighlight">
\[\begin{split}\begin{align*}
\text{maximize}
&amp; \sum_{j=1}^n p_j x_j
\\
\text{subject to}
&amp; \sum_{j=1}^n w_{ij} x_j \leq b_i
&amp; \forall i=1,\ldots,m \\
&amp; x_j \in \{0,1\}
&amp; \forall j=1,\ldots,n
\end{align*}\end{split}\]</div>
</div>
<div class="section" id="Random-instance-generator">
<h2><span class="section-number">3.2. </span>Random instance generator<a class="headerlink" href="#Random-instance-generator" title="Permalink to this headline"></a></h2>
<p>The class <code class="docutils literal notranslate"><span class="pre">MultiKnapsackGenerator</span></code> can be used to generate random instances of this problem. The number of items <span class="math notranslate nohighlight">\(n\)</span> and knapsacks <span class="math notranslate nohighlight">\(m\)</span> are sampled from the user-provided probability distributions <code class="docutils literal notranslate"><span class="pre">n</span></code> and <code class="docutils literal notranslate"><span class="pre">m</span></code>. The weights <span class="math notranslate nohighlight">\(w_{ij}\)</span> are sampled independently from the provided distribution <code class="docutils literal notranslate"><span class="pre">w</span></code>. The capacity of knapsack <span class="math notranslate nohighlight">\(i\)</span> is set to</p>
<div class="math notranslate nohighlight">
\[b_i = \alpha_i \sum_{j=1}^n w_{ij}\]</div>
<p>where <span class="math notranslate nohighlight">\(\alpha_i\)</span>, the tightness ratio, is sampled from the provided probability distribution <code class="docutils literal notranslate"><span class="pre">alpha</span></code>. To make the instances more challenging, the costs of the items are linearly correlated to their average weights. More specifically, the price of each item <span class="math notranslate nohighlight">\(j\)</span> is set to:</p>
<div class="math notranslate nohighlight">
\[p_j = \sum_{i=1}^m \frac{w_{ij}}{m} + K u_j,\]</div>
<p>where <span class="math notranslate nohighlight">\(K\)</span>, the correlation coefficient, and <span class="math notranslate nohighlight">\(u_j\)</span>, the correlation multiplier, are sampled from the provided probability distributions <code class="docutils literal notranslate"><span class="pre">K</span></code> and <code class="docutils literal notranslate"><span class="pre">u</span></code>.</p>
<p>If <code class="docutils literal notranslate"><span class="pre">fix_w=True</span></code> is provided, then <span class="math notranslate nohighlight">\(w_{ij}\)</span> are kept the same in all generated instances. This also implies that <span class="math notranslate nohighlight">\(n\)</span> and <span class="math notranslate nohighlight">\(m\)</span> are kept fixed. Although the prices and capacities are derived from <span class="math notranslate nohighlight">\(w_{ij}\)</span>, as long as <code class="docutils literal notranslate"><span class="pre">u</span></code> and <code class="docutils literal notranslate"><span class="pre">K</span></code> are not constants, the generated instances will still not be completely identical.</p>
<p>If a probability distribution <code class="docutils literal notranslate"><span class="pre">w_jitter</span></code> is provided, then item weights will be set to <span class="math notranslate nohighlight">\(w_{ij} \gamma_{ij}\)</span> where <span class="math notranslate nohighlight">\(\gamma_{ij}\)</span> is sampled from <code class="docutils literal notranslate"><span class="pre">w_jitter</span></code>. When combined with <code class="docutils literal notranslate"><span class="pre">fix_w=True</span></code>, this argument may be used to generate instances where the weight of each item is roughly the same, but not exactly identical, across all instances. The prices of the items and the capacities of the knapsacks will be calculated as above, but using these perturbed weights instead.</p>
<p>By default, all generated prices, weights and capacities are rounded to the nearest integer number. If <code class="docutils literal notranslate"><span class="pre">round=False</span></code> is provided, this rounding will be disabled.</p>
<div class="admonition note">
<p class="admonition-title">References</p>
<ul class="simple">
<li><p><strong>Freville, Arnaud, and Gérard Plateau.</strong> <em>An efficient preprocessing procedure for the multidimensional 01 knapsack problem.</em> Discrete applied mathematics 49.1-3 (1994): 189-212.</p></li>
<li><p><strong>Fréville, Arnaud.</strong> <em>The multidimensional 01 knapsack problem: An overview.</em> European Journal of Operational Research 155.1 (2004): 1-21.</p></li>
</ul>
</div>
</div>
<div class="section" id="Challenge-A">
<h2><span class="section-number">3.3. </span>Challenge A<a class="headerlink" href="#Challenge-A" title="Permalink to this headline"></a></h2>
<ul class="simple">
<li><p>250 variables, 10 constraints, fixed weights</p></li>
<li><p><span class="math notranslate nohighlight">\(w \sim U(0, 1000), \gamma \sim U(0.95, 1.05)\)</span></p></li>
<li><p><span class="math notranslate nohighlight">\(K = 500, u \sim U(0, 1), \alpha = 0.25\)</span></p></li>
<li><p>500 training instances, 50 test instances</p></li>
</ul>
<div class="nbinput nblast docutils container">
<div class="prompt highlight-none notranslate"><div class="highlight"><pre><span></span>[ ]:
</pre></div>
</div>
<div class="input_area highlight-ipython3 notranslate"><div class="highlight"><pre>
<span></span><span class="n">MultiKnapsackGenerator</span><span class="p">(</span>
<span class="n">n</span><span class="o">=</span><span class="n">randint</span><span class="p">(</span><span class="n">low</span><span class="o">=</span><span class="mi">250</span><span class="p">,</span> <span class="n">high</span><span class="o">=</span><span class="mi">251</span><span class="p">),</span>
<span class="n">m</span><span class="o">=</span><span class="n">randint</span><span class="p">(</span><span class="n">low</span><span class="o">=</span><span class="mi">10</span><span class="p">,</span> <span class="n">high</span><span class="o">=</span><span class="mi">11</span><span class="p">),</span>
<span class="n">w</span><span class="o">=</span><span class="n">uniform</span><span class="p">(</span><span class="n">loc</span><span class="o">=</span><span class="mf">0.0</span><span class="p">,</span> <span class="n">scale</span><span class="o">=</span><span class="mf">1000.0</span><span class="p">),</span>
<span class="n">K</span><span class="o">=</span><span class="n">uniform</span><span class="p">(</span><span class="n">loc</span><span class="o">=</span><span class="mf">500.0</span><span class="p">,</span> <span class="n">scale</span><span class="o">=</span><span class="mf">0.0</span><span class="p">),</span>
<span class="n">u</span><span class="o">=</span><span class="n">uniform</span><span class="p">(</span><span class="n">loc</span><span class="o">=</span><span class="mf">0.0</span><span class="p">,</span> <span class="n">scale</span><span class="o">=</span><span class="mf">1.0</span><span class="p">),</span>
<span class="n">alpha</span><span class="o">=</span><span class="n">uniform</span><span class="p">(</span><span class="n">loc</span><span class="o">=</span><span class="mf">0.25</span><span class="p">,</span> <span class="n">scale</span><span class="o">=</span><span class="mf">0.0</span><span class="p">),</span>
<span class="n">fix_w</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span>
<span class="n">w_jitter</span><span class="o">=</span><span class="n">uniform</span><span class="p">(</span><span class="n">loc</span><span class="o">=</span><span class="mf">0.95</span><span class="p">,</span> <span class="n">scale</span><span class="o">=</span><span class="mf">0.1</span><span class="p">),</span>
<span class="p">)</span>
</pre></div>
</div>
</div>
</div>
</div>
</div>
<div class='prev-next-bottom'>
<a class='left-prev' id="prev-link" href="../stab/" title="previous page"><span class="section-number">2. </span>Maximum Weight Stable Set</a>
<a class='right-next' id="next-link" href="../tsp/" title="next page"><span class="section-number">4. </span>Traveling Salesman</a>
</div>
</div>
</div>
<footer class="footer mt-5 mt-md-0">
<div class="container">
<p>
&copy; Copyright 2020-2021, UChicago Argonne, LLC.<br/>
</p>
</div>
</footer>
</main>
</div>
</div>
<script src="../../_static/js/index.1c5a1a01449ed65a7b51.js"></script>
</body>
</html>

@ -0,0 +1,43 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "423ee254",
"metadata": {},
"source": [
"# Preliminaries\n",
"\n",
"## Benchmark challenges\n",
"\n",
"When evaluating the performance of a conventional MIP solver, *benchmark sets*, such as MIPLIB and TSPLIB, are typically used. The performance of newly proposed solvers or solution techniques are typically measured as the average (or total) running time the solver takes to solve the entire benchmark set. For Learning-Enhanced MIP solvers, it is also necessary to specify what instances should the solver be trained on (the *training instances*) before solving the actual set of instances we are interested in (the *test instances*). If the training instances are very similar to the test instances, we would expect a Learning-Enhanced Solver to present stronger perfomance benefits.\n",
"\n",
"In MIPLearn, each optimization problem comes with a set of **benchmark challenges**, which specify how should the training and test instances be generated. The first challenges are typically easier, in the sense that training and test instances are very similar. Later challenges gradually make the sets more distinct, and therefore harder to learn from.\n",
"\n",
"## Baseline results\n",
"\n",
"To illustrate the performance of `LearningSolver`, and to set a baseline for newly proposed techniques, we present in this page, for each benchmark challenge, a small set of computational results measuring the solution speed of the solver and the solution quality with default parameters. For more detailed computational studies, see [references](index.md#references). We compare three solvers:\n",
"\n",
"* **baseline:** Gurobi 9.1 with default settings (a conventional state-of-the-art MIP solver)\n",
"* **ml-exact:** `LearningSolver` with default settings, using Gurobi 9.0 as internal MIP solver\n",
"* **ml-heuristic:** Same as above, but with `mode=\"heuristic\"`\n",
"\n",
"All experiments presented here were performed on a Linux server (Ubuntu Linux 18.04 LTS) with Intel Xeon Gold 6230s (2 processors, 40 cores, 80 threads) and 256 GB RAM (DDR4, 2933 MHz). All solvers were restricted to use 4 threads, with no time limits, and 10 instances were solved simultaneously at a time."
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Julia 1.6.0",
"language": "julia",
"name": "julia-1.6"
},
"language_info": {
"file_extension": ".jl",
"mimetype": "application/julia",
"name": "julia",
"version": "1.6.0"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

@ -0,0 +1,247 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>1. Preliminaries &#8212; MIPLearn&lt;br/&gt;&lt;small&gt;0.2.0&lt;/small&gt;</title>
<link href="../../_static/css/theme.css" rel="stylesheet" />
<link href="../../_static/css/index.c5995385ac14fb8791e8eb36b4908be2.css" rel="stylesheet" />
<link rel="stylesheet"
href="../../_static/vendor/fontawesome/5.13.0/css/all.min.css">
<link rel="preload" as="font" type="font/woff2" crossorigin
href="../../_static/vendor/fontawesome/5.13.0/webfonts/fa-solid-900.woff2">
<link rel="preload" as="font" type="font/woff2" crossorigin
href="../../_static/vendor/fontawesome/5.13.0/webfonts/fa-brands-400.woff2">
<link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
<link rel="stylesheet" href="../../_static/sphinx-book-theme.acff12b8f9c144ce68a297486a2fa670.css" type="text/css" />
<link rel="stylesheet" type="text/css" href="../../_static/custom.css" />
<link rel="preload" as="script" href="../../_static/js/index.1c5a1a01449ed65a7b51.js">
<script id="documentation_options" data-url_root="../../" src="../../_static/documentation_options.js"></script>
<script src="../../_static/jquery.js"></script>
<script src="../../_static/underscore.js"></script>
<script src="../../_static/doctools.js"></script>
<script crossorigin="anonymous" integrity="sha256-Ae2Vz/4ePdIu6ZyI/5ZGsYnb+m0JlOmKPjt6XZ9JJkA=" src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.3.4/require.min.js"></script>
<script src="../../_static/sphinx-book-theme.12a9622fbb08dcb3a2a40b2c02b83a57.js"></script>
<script async="async" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.7/latest.js?config=TeX-AMS-MML_HTMLorMML"></script>
<script type="text/x-mathjax-config">MathJax.Hub.Config({"tex2jax": {"inlineMath": [["\\(", "\\)"]], "displayMath": [["\\[", "\\]"]], "processRefs": false, "processEnvironments": false}})</script>
<link rel="index" title="Index" href="../../genindex/" />
<link rel="search" title="Search" href="../../search/" />
<link rel="next" title="2. Maximum Weight Stable Set" href="../stab/" />
<link rel="prev" title="1. Getting started with MIPLearn" href="../../jump-tutorials/getting-started/" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="docsearch:language" content="en" />
</head>
<body data-spy="scroll" data-target="#bd-toc-nav" data-offset="80">
<div class="container-fluid" id="banner"></div>
<div class="container-xl">
<div class="row">
<div class="col-12 col-md-3 bd-sidebar site-navigation show" id="site-navigation">
<div class="navbar-brand-box">
<a class="navbar-brand text-wrap" href="../../">
<h1 class="site-logo" id="site-title">MIPLearn<br/><small>0.2.0</small></h1>
</a>
</div><form class="bd-search d-flex align-items-center" action="../../search/" method="get">
<i class="icon fas fa-search"></i>
<input type="search" class="form-control" name="q" id="search-input" placeholder="Search the docs ..." aria-label="Search the docs ..." autocomplete="off" >
</form><nav class="bd-links" id="bd-docs-nav" aria-label="Main navigation">
<div class="bd-toc-item active">
<p class="caption">
<span class="caption-text">
Julia Tutorials
</span>
</p>
<ul class="nav bd-sidenav">
<li class="toctree-l1">
<a class="reference internal" href="../../jump-tutorials/getting-started/">
1. Getting started with MIPLearn
</a>
</li>
</ul>
<p class="caption">
<span class="caption-text">
Benchmarks
</span>
</p>
<ul class="current nav bd-sidenav">
<li class="toctree-l1 current active">
<a class="current reference internal" href="#">
1. Preliminaries
</a>
</li>
<li class="toctree-l1">
<a class="reference internal" href="../stab/">
2. Maximum Weight Stable Set
</a>
</li>
<li class="toctree-l1">
<a class="reference internal" href="../knapsack/">
3. Multidimensional Knapsack
</a>
</li>
<li class="toctree-l1">
<a class="reference internal" href="../tsp/">
4. Traveling Salesman
</a>
</li>
</ul>
</div>
</nav> <!-- To handle the deprecated key -->
</div>
<main class="col py-md-3 pl-md-4 bd-content overflow-auto" role="main">
<div class="topbar container-xl fixed-top">
<div class="topbar-contents row">
<div class="col-12 col-md-3 bd-topbar-whitespace site-navigation show"></div>
<div class="col pl-md-4 topbar-main">
<button id="navbar-toggler" class="navbar-toggler ml-0" type="button" data-toggle="collapse"
data-toggle="tooltip" data-placement="bottom" data-target=".site-navigation" aria-controls="navbar-menu"
aria-expanded="true" aria-label="Toggle navigation" aria-controls="site-navigation"
title="Toggle navigation" data-toggle="tooltip" data-placement="left">
<i class="fas fa-bars"></i>
<i class="fas fa-arrow-left"></i>
<i class="fas fa-arrow-up"></i>
</button>
<div class="dropdown-buttons-trigger">
<button id="dropdown-buttons-trigger" class="btn btn-secondary topbarbtn" aria-label="Download this page"><i
class="fas fa-download"></i></button>
<div class="dropdown-buttons">
<!-- ipynb file if we had a myst markdown file -->
<!-- Download raw file -->
<a class="dropdown-buttons" href="../../_sources/benchmarks/preliminaries.ipynb.txt"><button type="button"
class="btn btn-secondary topbarbtn" title="Download source file" data-toggle="tooltip"
data-placement="left">.ipynb</button></a>
<!-- Download PDF via print -->
<button type="button" id="download-print" class="btn btn-secondary topbarbtn" title="Print to PDF"
onClick="window.print()" data-toggle="tooltip" data-placement="left">.pdf</button>
</div>
</div>
<!-- Source interaction buttons -->
<!-- Full screen (wrap in <a> to have style consistency -->
<a class="full-screen-button"><button type="button" class="btn btn-secondary topbarbtn" data-toggle="tooltip"
data-placement="bottom" onclick="toggleFullScreen()" aria-label="Fullscreen mode"
title="Fullscreen mode"><i
class="fas fa-expand"></i></button></a>
<!-- Launch buttons -->
</div>
<!-- Table of contents -->
<div class="d-none d-md-block col-md-2 bd-toc show">
<div class="tocsection onthispage pt-5 pb-3">
<i class="fas fa-list"></i> Contents
</div>
<nav id="bd-toc-nav">
<ul class="visible nav section-nav flex-column">
<li class="toc-h2 nav-item toc-entry">
<a class="reference internal nav-link" href="#Benchmark-challenges">
1.1. Benchmark challenges
</a>
</li>
<li class="toc-h2 nav-item toc-entry">
<a class="reference internal nav-link" href="#Baseline-results">
1.2. Baseline results
</a>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div id="main-content" class="row">
<div class="col-12 col-md-9 pl-md-3 pr-md-0">
<div>
<div class="section" id="Preliminaries">
<h1><span class="section-number">1. </span>Preliminaries<a class="headerlink" href="#Preliminaries" title="Permalink to this headline"></a></h1>
<div class="section" id="Benchmark-challenges">
<h2><span class="section-number">1.1. </span>Benchmark challenges<a class="headerlink" href="#Benchmark-challenges" title="Permalink to this headline"></a></h2>
<p>When evaluating the performance of a conventional MIP solver, <em>benchmark sets</em>, such as MIPLIB and TSPLIB, are typically used. The performance of newly proposed solvers or solution techniques are typically measured as the average (or total) running time the solver takes to solve the entire benchmark set. For Learning-Enhanced MIP solvers, it is also necessary to specify what instances should the solver be trained on (the <em>training instances</em>) before solving the actual set of instances we are
interested in (the <em>test instances</em>). If the training instances are very similar to the test instances, we would expect a Learning-Enhanced Solver to present stronger perfomance benefits.</p>
<p>In MIPLearn, each optimization problem comes with a set of <strong>benchmark challenges</strong>, which specify how should the training and test instances be generated. The first challenges are typically easier, in the sense that training and test instances are very similar. Later challenges gradually make the sets more distinct, and therefore harder to learn from.</p>
</div>
<div class="section" id="Baseline-results">
<h2><span class="section-number">1.2. </span>Baseline results<a class="headerlink" href="#Baseline-results" title="Permalink to this headline"></a></h2>
<p>To illustrate the performance of <code class="docutils literal notranslate"><span class="pre">LearningSolver</span></code>, and to set a baseline for newly proposed techniques, we present in this page, for each benchmark challenge, a small set of computational results measuring the solution speed of the solver and the solution quality with default parameters. For more detailed computational studies, see <a class="reference external" href="index.md#references">references</a>. We compare three solvers:</p>
<ul class="simple">
<li><p><strong>baseline:</strong> Gurobi 9.1 with default settings (a conventional state-of-the-art MIP solver)</p></li>
<li><p><strong>ml-exact:</strong> <code class="docutils literal notranslate"><span class="pre">LearningSolver</span></code> with default settings, using Gurobi 9.0 as internal MIP solver</p></li>
<li><p><strong>ml-heuristic:</strong> Same as above, but with <code class="docutils literal notranslate"><span class="pre">mode=&quot;heuristic&quot;</span></code></p></li>
</ul>
<p>All experiments presented here were performed on a Linux server (Ubuntu Linux 18.04 LTS) with Intel Xeon Gold 6230s (2 processors, 40 cores, 80 threads) and 256 GB RAM (DDR4, 2933 MHz). All solvers were restricted to use 4 threads, with no time limits, and 10 instances were solved simultaneously at a time.</p>
</div>
</div>
</div>
<div class='prev-next-bottom'>
<a class='left-prev' id="prev-link" href="../../jump-tutorials/getting-started/" title="previous page"><span class="section-number">1. </span>Getting started with MIPLearn</a>
<a class='right-next' id="next-link" href="../stab/" title="next page"><span class="section-number">2. </span>Maximum Weight Stable Set</a>
</div>
</div>
</div>
<footer class="footer mt-5 mt-md-0">
<div class="container">
<p>
&copy; Copyright 2020-2021, UChicago Argonne, LLC.<br/>
</p>
</div>
</footer>
</main>
</div>
</div>
<script src="../../_static/js/index.1c5a1a01449ed65a7b51.js"></script>
</body>
</html>

@ -0,0 +1,62 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "23083bd9",
"metadata": {},
"source": [
"# Maximum Weight Stable Set\n",
"\n",
"## Problem definition\n",
"\n",
"Given a simple undirected graph $G=(V,E)$ and weights $w \\in \\mathbb{R}^V$, the problem is to find a stable set $S \\subseteq V$ that maximizes $ \\sum_{v \\in V} w_v$. We recall that a subset $S \\subseteq V$ is a *stable set* if no two vertices of $S$ are adjacent. This is one of Karp's 21 NP-complete problems.\n",
"\n",
"## Random instance generator\n",
"\n",
"The class `MaxWeightStableSetGenerator` can be used to generate random instances of this problem, with user-specified probability distributions. When the constructor parameter `fix_graph=True` is provided, one random Erdős-Rényi graph $G_{n,p}$ is generated during the constructor, where $n$ and $p$ are sampled from user-provided probability distributions `n` and `p`. To generate each instance, the generator independently samples each $w_v$ from the user-provided probability distribution `w`. When `fix_graph=False`, a new random graph is generated for each instance, while the remaining parameters are sampled in the same way.\n",
"\n",
"## Challenge A\n",
"\n",
"* Fixed random Erdős-Rényi graph $G_{n,p}$ with $n=200$ and $p=5\\%$\n",
"* Random vertex weights $w_v \\sim U(100, 150)$\n",
"* 500 training instances, 50 test instances"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "207c7846",
"metadata": {},
"outputs": [],
"source": [
"MaxWeightStableSetGenerator(\n",
" w=uniform(loc=100., scale=50.),\n",
" n=randint(low=200, high=201),\n",
" p=uniform(loc=0.05, scale=0.0),\n",
" fix_graph=True,\n",
")"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "miplearn",
"language": "python",
"name": "miplearn"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.8.10"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

@ -0,0 +1,515 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>2. Maximum Weight Stable Set &#8212; MIPLearn&lt;br/&gt;&lt;small&gt;0.2.0&lt;/small&gt;</title>
<link href="../../_static/css/theme.css" rel="stylesheet" />
<link href="../../_static/css/index.c5995385ac14fb8791e8eb36b4908be2.css" rel="stylesheet" />
<link rel="stylesheet"
href="../../_static/vendor/fontawesome/5.13.0/css/all.min.css">
<link rel="preload" as="font" type="font/woff2" crossorigin
href="../../_static/vendor/fontawesome/5.13.0/webfonts/fa-solid-900.woff2">
<link rel="preload" as="font" type="font/woff2" crossorigin
href="../../_static/vendor/fontawesome/5.13.0/webfonts/fa-brands-400.woff2">
<link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
<link rel="stylesheet" href="../../_static/sphinx-book-theme.acff12b8f9c144ce68a297486a2fa670.css" type="text/css" />
<link rel="stylesheet" type="text/css" href="../../_static/custom.css" />
<link rel="preload" as="script" href="../../_static/js/index.1c5a1a01449ed65a7b51.js">
<script id="documentation_options" data-url_root="../../" src="../../_static/documentation_options.js"></script>
<script src="../../_static/jquery.js"></script>
<script src="../../_static/underscore.js"></script>
<script src="../../_static/doctools.js"></script>
<script crossorigin="anonymous" integrity="sha256-Ae2Vz/4ePdIu6ZyI/5ZGsYnb+m0JlOmKPjt6XZ9JJkA=" src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.3.4/require.min.js"></script>
<script src="../../_static/sphinx-book-theme.12a9622fbb08dcb3a2a40b2c02b83a57.js"></script>
<script async="async" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.7/latest.js?config=TeX-AMS-MML_HTMLorMML"></script>
<script type="text/x-mathjax-config">MathJax.Hub.Config({"tex2jax": {"inlineMath": [["\\(", "\\)"]], "displayMath": [["\\[", "\\]"]], "processRefs": false, "processEnvironments": false}})</script>
<link rel="index" title="Index" href="../../genindex/" />
<link rel="search" title="Search" href="../../search/" />
<link rel="next" title="3. Multidimensional Knapsack" href="../knapsack/" />
<link rel="prev" title="1. Preliminaries" href="../preliminaries/" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="docsearch:language" content="en" />
</head>
<body data-spy="scroll" data-target="#bd-toc-nav" data-offset="80">
<div class="container-fluid" id="banner"></div>
<div class="container-xl">
<div class="row">
<div class="col-12 col-md-3 bd-sidebar site-navigation show" id="site-navigation">
<div class="navbar-brand-box">
<a class="navbar-brand text-wrap" href="../../">
<h1 class="site-logo" id="site-title">MIPLearn<br/><small>0.2.0</small></h1>
</a>
</div><form class="bd-search d-flex align-items-center" action="../../search/" method="get">
<i class="icon fas fa-search"></i>
<input type="search" class="form-control" name="q" id="search-input" placeholder="Search the docs ..." aria-label="Search the docs ..." autocomplete="off" >
</form><nav class="bd-links" id="bd-docs-nav" aria-label="Main navigation">
<div class="bd-toc-item active">
<p class="caption">
<span class="caption-text">
Julia Tutorials
</span>
</p>
<ul class="nav bd-sidenav">
<li class="toctree-l1">
<a class="reference internal" href="../../jump-tutorials/getting-started/">
1. Getting started with MIPLearn
</a>
</li>
</ul>
<p class="caption">
<span class="caption-text">
Benchmarks
</span>
</p>
<ul class="current nav bd-sidenav">
<li class="toctree-l1">
<a class="reference internal" href="../preliminaries/">
1. Preliminaries
</a>
</li>
<li class="toctree-l1 current active">
<a class="current reference internal" href="#">
2. Maximum Weight Stable Set
</a>
</li>
<li class="toctree-l1">
<a class="reference internal" href="../knapsack/">
3. Multidimensional Knapsack
</a>
</li>
<li class="toctree-l1">
<a class="reference internal" href="../tsp/">
4. Traveling Salesman
</a>
</li>
</ul>
</div>
</nav> <!-- To handle the deprecated key -->
</div>
<main class="col py-md-3 pl-md-4 bd-content overflow-auto" role="main">
<div class="topbar container-xl fixed-top">
<div class="topbar-contents row">
<div class="col-12 col-md-3 bd-topbar-whitespace site-navigation show"></div>
<div class="col pl-md-4 topbar-main">
<button id="navbar-toggler" class="navbar-toggler ml-0" type="button" data-toggle="collapse"
data-toggle="tooltip" data-placement="bottom" data-target=".site-navigation" aria-controls="navbar-menu"
aria-expanded="true" aria-label="Toggle navigation" aria-controls="site-navigation"
title="Toggle navigation" data-toggle="tooltip" data-placement="left">
<i class="fas fa-bars"></i>
<i class="fas fa-arrow-left"></i>
<i class="fas fa-arrow-up"></i>
</button>
<div class="dropdown-buttons-trigger">
<button id="dropdown-buttons-trigger" class="btn btn-secondary topbarbtn" aria-label="Download this page"><i
class="fas fa-download"></i></button>
<div class="dropdown-buttons">
<!-- ipynb file if we had a myst markdown file -->
<!-- Download raw file -->
<a class="dropdown-buttons" href="../../_sources/benchmarks/stab.ipynb.txt"><button type="button"
class="btn btn-secondary topbarbtn" title="Download source file" data-toggle="tooltip"
data-placement="left">.ipynb</button></a>
<!-- Download PDF via print -->
<button type="button" id="download-print" class="btn btn-secondary topbarbtn" title="Print to PDF"
onClick="window.print()" data-toggle="tooltip" data-placement="left">.pdf</button>
</div>
</div>
<!-- Source interaction buttons -->
<!-- Full screen (wrap in <a> to have style consistency -->
<a class="full-screen-button"><button type="button" class="btn btn-secondary topbarbtn" data-toggle="tooltip"
data-placement="bottom" onclick="toggleFullScreen()" aria-label="Fullscreen mode"
title="Fullscreen mode"><i
class="fas fa-expand"></i></button></a>
<!-- Launch buttons -->
</div>
<!-- Table of contents -->
<div class="d-none d-md-block col-md-2 bd-toc show">
<div class="tocsection onthispage pt-5 pb-3">
<i class="fas fa-list"></i> Contents
</div>
<nav id="bd-toc-nav">
<ul class="visible nav section-nav flex-column">
<li class="toc-h2 nav-item toc-entry">
<a class="reference internal nav-link" href="#Problem-definition">
2.1. Problem definition
</a>
</li>
<li class="toc-h2 nav-item toc-entry">
<a class="reference internal nav-link" href="#Random-instance-generator">
2.2. Random instance generator
</a>
</li>
<li class="toc-h2 nav-item toc-entry">
<a class="reference internal nav-link" href="#Challenge-A">
2.3. Challenge A
</a>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div id="main-content" class="row">
<div class="col-12 col-md-9 pl-md-3 pr-md-0">
<div>
<style>
/* CSS for nbsphinx extension */
/* remove conflicting styling from Sphinx themes */
div.nbinput.container div.prompt *,
div.nboutput.container div.prompt *,
div.nbinput.container div.input_area pre,
div.nboutput.container div.output_area pre,
div.nbinput.container div.input_area .highlight,
div.nboutput.container div.output_area .highlight {
border: none;
padding: 0;
margin: 0;
box-shadow: none;
}
div.nbinput.container > div[class*=highlight],
div.nboutput.container > div[class*=highlight] {
margin: 0;
}
div.nbinput.container div.prompt *,
div.nboutput.container div.prompt * {
background: none;
}
div.nboutput.container div.output_area .highlight,
div.nboutput.container div.output_area pre {
background: unset;
}
div.nboutput.container div.output_area div.highlight {
color: unset; /* override Pygments text color */
}
/* avoid gaps between output lines */
div.nboutput.container div[class*=highlight] pre {
line-height: normal;
}
/* input/output containers */
div.nbinput.container,
div.nboutput.container {
display: -webkit-flex;
display: flex;
align-items: flex-start;
margin: 0;
width: 100%;
}
@media (max-width: 540px) {
div.nbinput.container,
div.nboutput.container {
flex-direction: column;
}
}
/* input container */
div.nbinput.container {
padding-top: 5px;
}
/* last container */
div.nblast.container {
padding-bottom: 5px;
}
/* input prompt */
div.nbinput.container div.prompt pre {
color: #307FC1;
}
/* output prompt */
div.nboutput.container div.prompt pre {
color: #BF5B3D;
}
/* all prompts */
div.nbinput.container div.prompt,
div.nboutput.container div.prompt {
width: 4.5ex;
padding-top: 5px;
position: relative;
user-select: none;
}
div.nbinput.container div.prompt > div,
div.nboutput.container div.prompt > div {
position: absolute;
right: 0;
margin-right: 0.3ex;
}
@media (max-width: 540px) {
div.nbinput.container div.prompt,
div.nboutput.container div.prompt {
width: unset;
text-align: left;
padding: 0.4em;
}
div.nboutput.container div.prompt.empty {
padding: 0;
}
div.nbinput.container div.prompt > div,
div.nboutput.container div.prompt > div {
position: unset;
}
}
/* disable scrollbars on prompts */
div.nbinput.container div.prompt pre,
div.nboutput.container div.prompt pre {
overflow: hidden;
}
/* input/output area */
div.nbinput.container div.input_area,
div.nboutput.container div.output_area {
-webkit-flex: 1;
flex: 1;
overflow: auto;
}
@media (max-width: 540px) {
div.nbinput.container div.input_area,
div.nboutput.container div.output_area {
width: 100%;
}
}
/* input area */
div.nbinput.container div.input_area {
border: 1px solid #e0e0e0;
border-radius: 2px;
/*background: #f5f5f5;*/
}
/* override MathJax center alignment in output cells */
div.nboutput.container div[class*=MathJax] {
text-align: left !important;
}
/* override sphinx.ext.imgmath center alignment in output cells */
div.nboutput.container div.math p {
text-align: left;
}
/* standard error */
div.nboutput.container div.output_area.stderr {
background: #fdd;
}
/* ANSI colors */
.ansi-black-fg { color: #3E424D; }
.ansi-black-bg { background-color: #3E424D; }
.ansi-black-intense-fg { color: #282C36; }
.ansi-black-intense-bg { background-color: #282C36; }
.ansi-red-fg { color: #E75C58; }
.ansi-red-bg { background-color: #E75C58; }
.ansi-red-intense-fg { color: #B22B31; }
.ansi-red-intense-bg { background-color: #B22B31; }
.ansi-green-fg { color: #00A250; }
.ansi-green-bg { background-color: #00A250; }
.ansi-green-intense-fg { color: #007427; }
.ansi-green-intense-bg { background-color: #007427; }
.ansi-yellow-fg { color: #DDB62B; }
.ansi-yellow-bg { background-color: #DDB62B; }
.ansi-yellow-intense-fg { color: #B27D12; }
.ansi-yellow-intense-bg { background-color: #B27D12; }
.ansi-blue-fg { color: #208FFB; }
.ansi-blue-bg { background-color: #208FFB; }
.ansi-blue-intense-fg { color: #0065CA; }
.ansi-blue-intense-bg { background-color: #0065CA; }
.ansi-magenta-fg { color: #D160C4; }
.ansi-magenta-bg { background-color: #D160C4; }
.ansi-magenta-intense-fg { color: #A03196; }
.ansi-magenta-intense-bg { background-color: #A03196; }
.ansi-cyan-fg { color: #60C6C8; }
.ansi-cyan-bg { background-color: #60C6C8; }
.ansi-cyan-intense-fg { color: #258F8F; }
.ansi-cyan-intense-bg { background-color: #258F8F; }
.ansi-white-fg { color: #C5C1B4; }
.ansi-white-bg { background-color: #C5C1B4; }
.ansi-white-intense-fg { color: #A1A6B2; }
.ansi-white-intense-bg { background-color: #A1A6B2; }
.ansi-default-inverse-fg { color: #FFFFFF; }
.ansi-default-inverse-bg { background-color: #000000; }
.ansi-bold { font-weight: bold; }
.ansi-underline { text-decoration: underline; }
div.nbinput.container div.input_area div[class*=highlight] > pre,
div.nboutput.container div.output_area div[class*=highlight] > pre,
div.nboutput.container div.output_area div[class*=highlight].math,
div.nboutput.container div.output_area.rendered_html,
div.nboutput.container div.output_area > div.output_javascript,
div.nboutput.container div.output_area:not(.rendered_html) > img{
padding: 5px;
margin: 0;
}
/* fix copybtn overflow problem in chromium (needed for 'sphinx_copybutton') */
div.nbinput.container div.input_area > div[class^='highlight'],
div.nboutput.container div.output_area > div[class^='highlight']{
overflow-y: hidden;
}
/* hide copybtn icon on prompts (needed for 'sphinx_copybutton') */
.prompt a.copybtn {
display: none;
}
/* Some additional styling taken form the Jupyter notebook CSS */
div.rendered_html table {
border: none;
border-collapse: collapse;
border-spacing: 0;
color: black;
font-size: 12px;
table-layout: fixed;
}
div.rendered_html thead {
border-bottom: 1px solid black;
vertical-align: bottom;
}
div.rendered_html tr,
div.rendered_html th,
div.rendered_html td {
text-align: right;
vertical-align: middle;
padding: 0.5em 0.5em;
line-height: normal;
white-space: normal;
max-width: none;
border: none;
}
div.rendered_html th {
font-weight: bold;
}
div.rendered_html tbody tr:nth-child(odd) {
background: #f5f5f5;
}
div.rendered_html tbody tr:hover {
background: rgba(66, 165, 245, 0.2);
}
</style>
<div class="section" id="Maximum-Weight-Stable-Set">
<h1><span class="section-number">2. </span>Maximum Weight Stable Set<a class="headerlink" href="#Maximum-Weight-Stable-Set" title="Permalink to this headline"></a></h1>
<div class="section" id="Problem-definition">
<h2><span class="section-number">2.1. </span>Problem definition<a class="headerlink" href="#Problem-definition" title="Permalink to this headline"></a></h2>
<p>Given a simple undirected graph <span class="math notranslate nohighlight">\(G=(V,E)\)</span> and weights <span class="math notranslate nohighlight">\(w \in \mathbb{R}^V\)</span>, the problem is to find a stable set <span class="math notranslate nohighlight">\(S \subseteq V\)</span> that maximizes $ <span class="math">\sum</span>_{v <span class="math">\in `V} w_v$. We recall that a subset :math:`S \subseteq V</span> is a <em>stable set</em> if no two vertices of <span class="math notranslate nohighlight">\(S\)</span> are adjacent. This is one of Karps 21 NP-complete problems.</p>
</div>
<div class="section" id="Random-instance-generator">
<h2><span class="section-number">2.2. </span>Random instance generator<a class="headerlink" href="#Random-instance-generator" title="Permalink to this headline"></a></h2>
<p>The class <code class="docutils literal notranslate"><span class="pre">MaxWeightStableSetGenerator</span></code> can be used to generate random instances of this problem, with user-specified probability distributions. When the constructor parameter <code class="docutils literal notranslate"><span class="pre">fix_graph=True</span></code> is provided, one random Erdős-Rényi graph <span class="math notranslate nohighlight">\(G_{n,p}\)</span> is generated during the constructor, where <span class="math notranslate nohighlight">\(n\)</span> and <span class="math notranslate nohighlight">\(p\)</span> are sampled from user-provided probability distributions <code class="docutils literal notranslate"><span class="pre">n</span></code> and <code class="docutils literal notranslate"><span class="pre">p</span></code>. To generate each instance, the generator independently samples each <span class="math notranslate nohighlight">\(w_v\)</span> from the user-provided
probability distribution <code class="docutils literal notranslate"><span class="pre">w</span></code>. When <code class="docutils literal notranslate"><span class="pre">fix_graph=False</span></code>, a new random graph is generated for each instance, while the remaining parameters are sampled in the same way.</p>
</div>
<div class="section" id="Challenge-A">
<h2><span class="section-number">2.3. </span>Challenge A<a class="headerlink" href="#Challenge-A" title="Permalink to this headline"></a></h2>
<ul class="simple">
<li><p>Fixed random Erdős-Rényi graph <span class="math notranslate nohighlight">\(G_{n,p}\)</span> with <span class="math notranslate nohighlight">\(n=200\)</span> and <span class="math notranslate nohighlight">\(p=5\%\)</span></p></li>
<li><p>Random vertex weights <span class="math notranslate nohighlight">\(w_v \sim U(100, 150)\)</span></p></li>
<li><p>500 training instances, 50 test instances</p></li>
</ul>
<div class="nbinput nblast docutils container">
<div class="prompt highlight-none notranslate"><div class="highlight"><pre><span></span>[ ]:
</pre></div>
</div>
<div class="input_area highlight-ipython3 notranslate"><div class="highlight"><pre>
<span></span><span class="n">MaxWeightStableSetGenerator</span><span class="p">(</span>
<span class="n">w</span><span class="o">=</span><span class="n">uniform</span><span class="p">(</span><span class="n">loc</span><span class="o">=</span><span class="mf">100.</span><span class="p">,</span> <span class="n">scale</span><span class="o">=</span><span class="mf">50.</span><span class="p">),</span>
<span class="n">n</span><span class="o">=</span><span class="n">randint</span><span class="p">(</span><span class="n">low</span><span class="o">=</span><span class="mi">200</span><span class="p">,</span> <span class="n">high</span><span class="o">=</span><span class="mi">201</span><span class="p">),</span>
<span class="n">p</span><span class="o">=</span><span class="n">uniform</span><span class="p">(</span><span class="n">loc</span><span class="o">=</span><span class="mf">0.05</span><span class="p">,</span> <span class="n">scale</span><span class="o">=</span><span class="mf">0.0</span><span class="p">),</span>
<span class="n">fix_graph</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span>
<span class="p">)</span>
</pre></div>
</div>
</div>
</div>
</div>
</div>
<div class='prev-next-bottom'>
<a class='left-prev' id="prev-link" href="../preliminaries/" title="previous page"><span class="section-number">1. </span>Preliminaries</a>
<a class='right-next' id="next-link" href="../knapsack/" title="next page"><span class="section-number">3. </span>Multidimensional Knapsack</a>
</div>
</div>
</div>
<footer class="footer mt-5 mt-md-0">
<div class="container">
<p>
&copy; Copyright 2020-2021, UChicago Argonne, LLC.<br/>
</p>
</div>
</footer>
</main>
</div>
</div>
<script src="../../_static/js/index.1c5a1a01449ed65a7b51.js"></script>
</body>
</html>

@ -0,0 +1,88 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "2f39414b",
"metadata": {},
"source": [
"# Traveling Salesman\n",
"\n",
"### Problem definition\n",
"\n",
"Given a list of cities and the distance between each pair of cities, the problem asks for the\n",
"shortest route starting at the first city, visiting each other city exactly once, then returning\n",
"to the first city. This problem is a generalization of the Hamiltonian path problem, one of Karp's\n",
"21 NP-complete problems.\n",
"\n",
"### Random problem generator\n",
"\n",
"The class `TravelingSalesmanGenerator` can be used to generate random instances of this\n",
"problem. Initially, the generator creates $n$ cities $(x_1,y_1),\\ldots,(x_n,y_n) \\in \\mathbb{R}^2$,\n",
"where $n, x_i$ and $y_i$ are sampled independently from the provided probability distributions `n`,\n",
"`x` and `y`. For each pair of cities $(i,j)$, the distance $d_{i,j}$ between them is set to:\n",
"$$\n",
" d_{i,j} = \\gamma_{i,j} \\sqrt{(x_i-x_j)^2 + (y_i - y_j)^2}\n",
"$$\n",
"where $\\gamma_{i,j}$ is sampled from the distribution `gamma`.\n",
"\n",
"If `fix_cities=True` is provided, the list of cities is kept the same for all generated instances.\n",
"The $gamma$ values, and therefore also the distances, are still different.\n",
"\n",
"By default, all distances $d_{i,j}$ are rounded to the nearest integer. If `round=False`\n",
"is provided, this rounding will be disabled.\n",
"\n",
"### Challenge A\n",
"\n",
"* Fixed list of 350 cities in the $[0, 1000]^2$ square\n",
"* $\\gamma_{i,j} \\sim U(0.95, 1.05)$\n",
"* 500 training instances, 50 test instances"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "6b2c4ff9",
"metadata": {},
"outputs": [],
"source": [
"TravelingSalesmanGenerator(\n",
" x=uniform(loc=0.0, scale=1000.0),\n",
" y=uniform(loc=0.0, scale=1000.0),\n",
" n=randint(low=350, high=351),\n",
" gamma=uniform(loc=0.95, scale=0.1),\n",
" fix_cities=True,\n",
" round=True,\n",
")"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "cc125860",
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "miplearn",
"language": "python",
"name": "miplearn"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.8.10"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

@ -0,0 +1,528 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>4. Traveling Salesman &#8212; MIPLearn&lt;br/&gt;&lt;small&gt;0.2.0&lt;/small&gt;</title>
<link href="../../_static/css/theme.css" rel="stylesheet" />
<link href="../../_static/css/index.c5995385ac14fb8791e8eb36b4908be2.css" rel="stylesheet" />
<link rel="stylesheet"
href="../../_static/vendor/fontawesome/5.13.0/css/all.min.css">
<link rel="preload" as="font" type="font/woff2" crossorigin
href="../../_static/vendor/fontawesome/5.13.0/webfonts/fa-solid-900.woff2">
<link rel="preload" as="font" type="font/woff2" crossorigin
href="../../_static/vendor/fontawesome/5.13.0/webfonts/fa-brands-400.woff2">
<link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
<link rel="stylesheet" href="../../_static/sphinx-book-theme.acff12b8f9c144ce68a297486a2fa670.css" type="text/css" />
<link rel="stylesheet" type="text/css" href="../../_static/custom.css" />
<link rel="preload" as="script" href="../../_static/js/index.1c5a1a01449ed65a7b51.js">
<script id="documentation_options" data-url_root="../../" src="../../_static/documentation_options.js"></script>
<script src="../../_static/jquery.js"></script>
<script src="../../_static/underscore.js"></script>
<script src="../../_static/doctools.js"></script>
<script crossorigin="anonymous" integrity="sha256-Ae2Vz/4ePdIu6ZyI/5ZGsYnb+m0JlOmKPjt6XZ9JJkA=" src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.3.4/require.min.js"></script>
<script src="../../_static/sphinx-book-theme.12a9622fbb08dcb3a2a40b2c02b83a57.js"></script>
<script async="async" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.7/latest.js?config=TeX-AMS-MML_HTMLorMML"></script>
<script type="text/x-mathjax-config">MathJax.Hub.Config({"tex2jax": {"inlineMath": [["\\(", "\\)"]], "displayMath": [["\\[", "\\]"]], "processRefs": false, "processEnvironments": false}})</script>
<link rel="index" title="Index" href="../../genindex/" />
<link rel="search" title="Search" href="../../search/" />
<link rel="prev" title="3. Multidimensional Knapsack" href="../knapsack/" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="docsearch:language" content="en" />
</head>
<body data-spy="scroll" data-target="#bd-toc-nav" data-offset="80">
<div class="container-fluid" id="banner"></div>
<div class="container-xl">
<div class="row">
<div class="col-12 col-md-3 bd-sidebar site-navigation show" id="site-navigation">
<div class="navbar-brand-box">
<a class="navbar-brand text-wrap" href="../../">
<h1 class="site-logo" id="site-title">MIPLearn<br/><small>0.2.0</small></h1>
</a>
</div><form class="bd-search d-flex align-items-center" action="../../search/" method="get">
<i class="icon fas fa-search"></i>
<input type="search" class="form-control" name="q" id="search-input" placeholder="Search the docs ..." aria-label="Search the docs ..." autocomplete="off" >
</form><nav class="bd-links" id="bd-docs-nav" aria-label="Main navigation">
<div class="bd-toc-item active">
<p class="caption">
<span class="caption-text">
Julia Tutorials
</span>
</p>
<ul class="nav bd-sidenav">
<li class="toctree-l1">
<a class="reference internal" href="../../jump-tutorials/getting-started/">
1. Getting started with MIPLearn
</a>
</li>
</ul>
<p class="caption">
<span class="caption-text">
Benchmarks
</span>
</p>
<ul class="current nav bd-sidenav">
<li class="toctree-l1">
<a class="reference internal" href="../preliminaries/">
1. Preliminaries
</a>
</li>
<li class="toctree-l1">
<a class="reference internal" href="../stab/">
2. Maximum Weight Stable Set
</a>
</li>
<li class="toctree-l1">
<a class="reference internal" href="../knapsack/">
3. Multidimensional Knapsack
</a>
</li>
<li class="toctree-l1 current active">
<a class="current reference internal" href="#">
4. Traveling Salesman
</a>
</li>
</ul>
</div>
</nav> <!-- To handle the deprecated key -->
</div>
<main class="col py-md-3 pl-md-4 bd-content overflow-auto" role="main">
<div class="topbar container-xl fixed-top">
<div class="topbar-contents row">
<div class="col-12 col-md-3 bd-topbar-whitespace site-navigation show"></div>
<div class="col pl-md-4 topbar-main">
<button id="navbar-toggler" class="navbar-toggler ml-0" type="button" data-toggle="collapse"
data-toggle="tooltip" data-placement="bottom" data-target=".site-navigation" aria-controls="navbar-menu"
aria-expanded="true" aria-label="Toggle navigation" aria-controls="site-navigation"
title="Toggle navigation" data-toggle="tooltip" data-placement="left">
<i class="fas fa-bars"></i>
<i class="fas fa-arrow-left"></i>
<i class="fas fa-arrow-up"></i>
</button>
<div class="dropdown-buttons-trigger">
<button id="dropdown-buttons-trigger" class="btn btn-secondary topbarbtn" aria-label="Download this page"><i
class="fas fa-download"></i></button>
<div class="dropdown-buttons">
<!-- ipynb file if we had a myst markdown file -->
<!-- Download raw file -->
<a class="dropdown-buttons" href="../../_sources/benchmarks/tsp.ipynb.txt"><button type="button"
class="btn btn-secondary topbarbtn" title="Download source file" data-toggle="tooltip"
data-placement="left">.ipynb</button></a>
<!-- Download PDF via print -->
<button type="button" id="download-print" class="btn btn-secondary topbarbtn" title="Print to PDF"
onClick="window.print()" data-toggle="tooltip" data-placement="left">.pdf</button>
</div>
</div>
<!-- Source interaction buttons -->
<!-- Full screen (wrap in <a> to have style consistency -->
<a class="full-screen-button"><button type="button" class="btn btn-secondary topbarbtn" data-toggle="tooltip"
data-placement="bottom" onclick="toggleFullScreen()" aria-label="Fullscreen mode"
title="Fullscreen mode"><i
class="fas fa-expand"></i></button></a>
<!-- Launch buttons -->
</div>
<!-- Table of contents -->
<div class="d-none d-md-block col-md-2 bd-toc show">
<div class="tocsection onthispage pt-5 pb-3">
<i class="fas fa-list"></i> Contents
</div>
<nav id="bd-toc-nav">
<ul class="visible nav section-nav flex-column">
<li class="toc-h2 nav-item toc-entry">
<a class="reference internal nav-link" href="#Problem-definition">
4.1. Problem definition
</a>
</li>
<li class="toc-h2 nav-item toc-entry">
<a class="reference internal nav-link" href="#Random-problem-generator">
4.2. Random problem generator
</a>
</li>
<li class="toc-h2 nav-item toc-entry">
<a class="reference internal nav-link" href="#Challenge-A">
4.3. Challenge A
</a>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div id="main-content" class="row">
<div class="col-12 col-md-9 pl-md-3 pr-md-0">
<div>
<style>
/* CSS for nbsphinx extension */
/* remove conflicting styling from Sphinx themes */
div.nbinput.container div.prompt *,
div.nboutput.container div.prompt *,
div.nbinput.container div.input_area pre,
div.nboutput.container div.output_area pre,
div.nbinput.container div.input_area .highlight,
div.nboutput.container div.output_area .highlight {
border: none;
padding: 0;
margin: 0;
box-shadow: none;
}
div.nbinput.container > div[class*=highlight],
div.nboutput.container > div[class*=highlight] {
margin: 0;
}
div.nbinput.container div.prompt *,
div.nboutput.container div.prompt * {
background: none;
}
div.nboutput.container div.output_area .highlight,
div.nboutput.container div.output_area pre {
background: unset;
}
div.nboutput.container div.output_area div.highlight {
color: unset; /* override Pygments text color */
}
/* avoid gaps between output lines */
div.nboutput.container div[class*=highlight] pre {
line-height: normal;
}
/* input/output containers */
div.nbinput.container,
div.nboutput.container {
display: -webkit-flex;
display: flex;
align-items: flex-start;
margin: 0;
width: 100%;
}
@media (max-width: 540px) {
div.nbinput.container,
div.nboutput.container {
flex-direction: column;
}
}
/* input container */
div.nbinput.container {
padding-top: 5px;
}
/* last container */
div.nblast.container {
padding-bottom: 5px;
}
/* input prompt */
div.nbinput.container div.prompt pre {
color: #307FC1;
}
/* output prompt */
div.nboutput.container div.prompt pre {
color: #BF5B3D;
}
/* all prompts */
div.nbinput.container div.prompt,
div.nboutput.container div.prompt {
width: 4.5ex;
padding-top: 5px;
position: relative;
user-select: none;
}
div.nbinput.container div.prompt > div,
div.nboutput.container div.prompt > div {
position: absolute;
right: 0;
margin-right: 0.3ex;
}
@media (max-width: 540px) {
div.nbinput.container div.prompt,
div.nboutput.container div.prompt {
width: unset;
text-align: left;
padding: 0.4em;
}
div.nboutput.container div.prompt.empty {
padding: 0;
}
div.nbinput.container div.prompt > div,
div.nboutput.container div.prompt > div {
position: unset;
}
}
/* disable scrollbars on prompts */
div.nbinput.container div.prompt pre,
div.nboutput.container div.prompt pre {
overflow: hidden;
}
/* input/output area */
div.nbinput.container div.input_area,
div.nboutput.container div.output_area {
-webkit-flex: 1;
flex: 1;
overflow: auto;
}
@media (max-width: 540px) {
div.nbinput.container div.input_area,
div.nboutput.container div.output_area {
width: 100%;
}
}
/* input area */
div.nbinput.container div.input_area {
border: 1px solid #e0e0e0;
border-radius: 2px;
/*background: #f5f5f5;*/
}
/* override MathJax center alignment in output cells */
div.nboutput.container div[class*=MathJax] {
text-align: left !important;
}
/* override sphinx.ext.imgmath center alignment in output cells */
div.nboutput.container div.math p {
text-align: left;
}
/* standard error */
div.nboutput.container div.output_area.stderr {
background: #fdd;
}
/* ANSI colors */
.ansi-black-fg { color: #3E424D; }
.ansi-black-bg { background-color: #3E424D; }
.ansi-black-intense-fg { color: #282C36; }
.ansi-black-intense-bg { background-color: #282C36; }
.ansi-red-fg { color: #E75C58; }
.ansi-red-bg { background-color: #E75C58; }
.ansi-red-intense-fg { color: #B22B31; }
.ansi-red-intense-bg { background-color: #B22B31; }
.ansi-green-fg { color: #00A250; }
.ansi-green-bg { background-color: #00A250; }
.ansi-green-intense-fg { color: #007427; }
.ansi-green-intense-bg { background-color: #007427; }
.ansi-yellow-fg { color: #DDB62B; }
.ansi-yellow-bg { background-color: #DDB62B; }
.ansi-yellow-intense-fg { color: #B27D12; }
.ansi-yellow-intense-bg { background-color: #B27D12; }
.ansi-blue-fg { color: #208FFB; }
.ansi-blue-bg { background-color: #208FFB; }
.ansi-blue-intense-fg { color: #0065CA; }
.ansi-blue-intense-bg { background-color: #0065CA; }
.ansi-magenta-fg { color: #D160C4; }
.ansi-magenta-bg { background-color: #D160C4; }
.ansi-magenta-intense-fg { color: #A03196; }
.ansi-magenta-intense-bg { background-color: #A03196; }
.ansi-cyan-fg { color: #60C6C8; }
.ansi-cyan-bg { background-color: #60C6C8; }
.ansi-cyan-intense-fg { color: #258F8F; }
.ansi-cyan-intense-bg { background-color: #258F8F; }
.ansi-white-fg { color: #C5C1B4; }
.ansi-white-bg { background-color: #C5C1B4; }
.ansi-white-intense-fg { color: #A1A6B2; }
.ansi-white-intense-bg { background-color: #A1A6B2; }
.ansi-default-inverse-fg { color: #FFFFFF; }
.ansi-default-inverse-bg { background-color: #000000; }
.ansi-bold { font-weight: bold; }
.ansi-underline { text-decoration: underline; }
div.nbinput.container div.input_area div[class*=highlight] > pre,
div.nboutput.container div.output_area div[class*=highlight] > pre,
div.nboutput.container div.output_area div[class*=highlight].math,
div.nboutput.container div.output_area.rendered_html,
div.nboutput.container div.output_area > div.output_javascript,
div.nboutput.container div.output_area:not(.rendered_html) > img{
padding: 5px;
margin: 0;
}
/* fix copybtn overflow problem in chromium (needed for 'sphinx_copybutton') */
div.nbinput.container div.input_area > div[class^='highlight'],
div.nboutput.container div.output_area > div[class^='highlight']{
overflow-y: hidden;
}
/* hide copybtn icon on prompts (needed for 'sphinx_copybutton') */
.prompt a.copybtn {
display: none;
}
/* Some additional styling taken form the Jupyter notebook CSS */
div.rendered_html table {
border: none;
border-collapse: collapse;
border-spacing: 0;
color: black;
font-size: 12px;
table-layout: fixed;
}
div.rendered_html thead {
border-bottom: 1px solid black;
vertical-align: bottom;
}
div.rendered_html tr,
div.rendered_html th,
div.rendered_html td {
text-align: right;
vertical-align: middle;
padding: 0.5em 0.5em;
line-height: normal;
white-space: normal;
max-width: none;
border: none;
}
div.rendered_html th {
font-weight: bold;
}
div.rendered_html tbody tr:nth-child(odd) {
background: #f5f5f5;
}
div.rendered_html tbody tr:hover {
background: rgba(66, 165, 245, 0.2);
}
</style>
<div class="section" id="Traveling-Salesman">
<h1><span class="section-number">4. </span>Traveling Salesman<a class="headerlink" href="#Traveling-Salesman" title="Permalink to this headline"></a></h1>
<div class="section" id="Problem-definition">
<h2><span class="section-number">4.1. </span>Problem definition<a class="headerlink" href="#Problem-definition" title="Permalink to this headline"></a></h2>
<p>Given a list of cities and the distance between each pair of cities, the problem asks for the shortest route starting at the first city, visiting each other city exactly once, then returning to the first city. This problem is a generalization of the Hamiltonian path problem, one of Karps 21 NP-complete problems.</p>
</div>
<div class="section" id="Random-problem-generator">
<h2><span class="section-number">4.2. </span>Random problem generator<a class="headerlink" href="#Random-problem-generator" title="Permalink to this headline"></a></h2>
<p>The class <code class="docutils literal notranslate"><span class="pre">TravelingSalesmanGenerator</span></code> can be used to generate random instances of this problem. Initially, the generator creates <span class="math notranslate nohighlight">\(n\)</span> cities <span class="math notranslate nohighlight">\((x_1,y_1),\ldots,(x_n,y_n) \in \mathbb{R}^2\)</span>, where <span class="math notranslate nohighlight">\(n, x_i\)</span> and <span class="math notranslate nohighlight">\(y_i\)</span> are sampled independently from the provided probability distributions <code class="docutils literal notranslate"><span class="pre">n</span></code>, <code class="docutils literal notranslate"><span class="pre">x</span></code> and <code class="docutils literal notranslate"><span class="pre">y</span></code>. For each pair of cities <span class="math notranslate nohighlight">\((i,j)\)</span>, the distance <span class="math notranslate nohighlight">\(d_{i,j}\)</span> between them is set to:</p>
<div class="math notranslate nohighlight">
\[d_{i,j} = \gamma_{i,j} \sqrt{(x_i-x_j)^2 + (y_i - y_j)^2}\]</div>
<p>where <span class="math notranslate nohighlight">\(\gamma_{i,j}\)</span> is sampled from the distribution <code class="docutils literal notranslate"><span class="pre">gamma</span></code>.</p>
<p>If <code class="docutils literal notranslate"><span class="pre">fix_cities=True</span></code> is provided, the list of cities is kept the same for all generated instances. The <span class="math notranslate nohighlight">\(gamma\)</span> values, and therefore also the distances, are still different.</p>
<p>By default, all distances <span class="math notranslate nohighlight">\(d_{i,j}\)</span> are rounded to the nearest integer. If <code class="docutils literal notranslate"><span class="pre">round=False</span></code> is provided, this rounding will be disabled.</p>
</div>
<div class="section" id="Challenge-A">
<h2><span class="section-number">4.3. </span>Challenge A<a class="headerlink" href="#Challenge-A" title="Permalink to this headline"></a></h2>
<ul class="simple">
<li><p>Fixed list of 350 cities in the <span class="math notranslate nohighlight">\([0, 1000]^2\)</span> square</p></li>
<li><p><span class="math notranslate nohighlight">\(\gamma_{i,j} \sim U(0.95, 1.05)\)</span></p></li>
<li><p>500 training instances, 50 test instances</p></li>
</ul>
<div class="nbinput nblast docutils container">
<div class="prompt highlight-none notranslate"><div class="highlight"><pre><span></span>[ ]:
</pre></div>
</div>
<div class="input_area highlight-ipython3 notranslate"><div class="highlight"><pre>
<span></span><span class="n">TravelingSalesmanGenerator</span><span class="p">(</span>
<span class="n">x</span><span class="o">=</span><span class="n">uniform</span><span class="p">(</span><span class="n">loc</span><span class="o">=</span><span class="mf">0.0</span><span class="p">,</span> <span class="n">scale</span><span class="o">=</span><span class="mf">1000.0</span><span class="p">),</span>
<span class="n">y</span><span class="o">=</span><span class="n">uniform</span><span class="p">(</span><span class="n">loc</span><span class="o">=</span><span class="mf">0.0</span><span class="p">,</span> <span class="n">scale</span><span class="o">=</span><span class="mf">1000.0</span><span class="p">),</span>
<span class="n">n</span><span class="o">=</span><span class="n">randint</span><span class="p">(</span><span class="n">low</span><span class="o">=</span><span class="mi">350</span><span class="p">,</span> <span class="n">high</span><span class="o">=</span><span class="mi">351</span><span class="p">),</span>
<span class="n">gamma</span><span class="o">=</span><span class="n">uniform</span><span class="p">(</span><span class="n">loc</span><span class="o">=</span><span class="mf">0.95</span><span class="p">,</span> <span class="n">scale</span><span class="o">=</span><span class="mf">0.1</span><span class="p">),</span>
<span class="n">fix_cities</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span>
<span class="nb">round</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span>
<span class="p">)</span>
</pre></div>
</div>
</div>
<div class="nbinput nblast docutils container">
<div class="prompt highlight-none notranslate"><div class="highlight"><pre><span></span>[ ]:
</pre></div>
</div>
<div class="input_area highlight-ipython3 notranslate"><div class="highlight"><pre>
<span></span>
</pre></div>
</div>
</div>
</div>
</div>
</div>
<div class='prev-next-bottom'>
<a class='left-prev' id="prev-link" href="../knapsack/" title="previous page"><span class="section-number">3. </span>Multidimensional Knapsack</a>
</div>
</div>
</div>
<footer class="footer mt-5 mt-md-0">
<div class="container">
<p>
&copy; Copyright 2020-2021, UChicago Argonne, LLC.<br/>
</p>
</div>
</footer>
</main>
</div>
</div>
<script src="../../_static/js/index.1c5a1a01449ed65a7b51.js"></script>
</body>
</html>

@ -0,0 +1,29 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "ed7d4bdc",
"metadata": {},
"source": [
"# Unit Commitment\n",
"\n",
"TODO"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Julia 1.6.0",
"language": "julia",
"name": "julia-1.6"
},
"language_info": {
"file_extension": ".jl",
"mimetype": "application/julia",
"name": "julia",
"version": "1.6.0"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

@ -0,0 +1,210 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Unit Commitment &#8212; MIPLearn&lt;br/&gt;&lt;small&gt;0.2.0&lt;/small&gt;</title>
<link href="../../_static/css/theme.css" rel="stylesheet" />
<link href="../../_static/css/index.c5995385ac14fb8791e8eb36b4908be2.css" rel="stylesheet" />
<link rel="stylesheet"
href="../../_static/vendor/fontawesome/5.13.0/css/all.min.css">
<link rel="preload" as="font" type="font/woff2" crossorigin
href="../../_static/vendor/fontawesome/5.13.0/webfonts/fa-solid-900.woff2">
<link rel="preload" as="font" type="font/woff2" crossorigin
href="../../_static/vendor/fontawesome/5.13.0/webfonts/fa-brands-400.woff2">
<link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
<link rel="stylesheet" href="../../_static/sphinx-book-theme.acff12b8f9c144ce68a297486a2fa670.css" type="text/css" />
<link rel="stylesheet" type="text/css" href="../../_static/custom.css" />
<link rel="preload" as="script" href="../../_static/js/index.1c5a1a01449ed65a7b51.js">
<script id="documentation_options" data-url_root="../../" src="../../_static/documentation_options.js"></script>
<script src="../../_static/jquery.js"></script>
<script src="../../_static/underscore.js"></script>
<script src="../../_static/doctools.js"></script>
<script crossorigin="anonymous" integrity="sha256-Ae2Vz/4ePdIu6ZyI/5ZGsYnb+m0JlOmKPjt6XZ9JJkA=" src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.3.4/require.min.js"></script>
<script src="../../_static/sphinx-book-theme.12a9622fbb08dcb3a2a40b2c02b83a57.js"></script>
<script async="async" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.7/latest.js?config=TeX-AMS-MML_HTMLorMML"></script>
<script type="text/x-mathjax-config">MathJax.Hub.Config({"tex2jax": {"inlineMath": [["\\(", "\\)"]], "displayMath": [["\\[", "\\]"]], "processRefs": false, "processEnvironments": false}})</script>
<link rel="index" title="Index" href="../../genindex/" />
<link rel="search" title="Search" href="../../search/" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="docsearch:language" content="en" />
</head>
<body data-spy="scroll" data-target="#bd-toc-nav" data-offset="80">
<div class="container-fluid" id="banner"></div>
<div class="container-xl">
<div class="row">
<div class="col-12 col-md-3 bd-sidebar site-navigation show" id="site-navigation">
<div class="navbar-brand-box">
<a class="navbar-brand text-wrap" href="../../">
<h1 class="site-logo" id="site-title">MIPLearn<br/><small>0.2.0</small></h1>
</a>
</div><form class="bd-search d-flex align-items-center" action="../../search/" method="get">
<i class="icon fas fa-search"></i>
<input type="search" class="form-control" name="q" id="search-input" placeholder="Search the docs ..." aria-label="Search the docs ..." autocomplete="off" >
</form><nav class="bd-links" id="bd-docs-nav" aria-label="Main navigation">
<div class="bd-toc-item active">
<p class="caption">
<span class="caption-text">
Julia Tutorials
</span>
</p>
<ul class="nav bd-sidenav">
<li class="toctree-l1">
<a class="reference internal" href="../../jump-tutorials/getting-started/">
1. Getting started with MIPLearn
</a>
</li>
</ul>
<p class="caption">
<span class="caption-text">
Benchmarks
</span>
</p>
<ul class="nav bd-sidenav">
<li class="toctree-l1">
<a class="reference internal" href="../preliminaries/">
1. Preliminaries
</a>
</li>
<li class="toctree-l1">
<a class="reference internal" href="../stab/">
2. Maximum Weight Stable Set
</a>
</li>
<li class="toctree-l1">
<a class="reference internal" href="../knapsack/">
3. Multidimensional Knapsack
</a>
</li>
<li class="toctree-l1">
<a class="reference internal" href="../tsp/">
4. Traveling Salesman
</a>
</li>
</ul>
</div>
</nav> <!-- To handle the deprecated key -->
</div>
<main class="col py-md-3 pl-md-4 bd-content overflow-auto" role="main">
<div class="topbar container-xl fixed-top">
<div class="topbar-contents row">
<div class="col-12 col-md-3 bd-topbar-whitespace site-navigation show"></div>
<div class="col pl-md-4 topbar-main">
<button id="navbar-toggler" class="navbar-toggler ml-0" type="button" data-toggle="collapse"
data-toggle="tooltip" data-placement="bottom" data-target=".site-navigation" aria-controls="navbar-menu"
aria-expanded="true" aria-label="Toggle navigation" aria-controls="site-navigation"
title="Toggle navigation" data-toggle="tooltip" data-placement="left">
<i class="fas fa-bars"></i>
<i class="fas fa-arrow-left"></i>
<i class="fas fa-arrow-up"></i>
</button>
<div class="dropdown-buttons-trigger">
<button id="dropdown-buttons-trigger" class="btn btn-secondary topbarbtn" aria-label="Download this page"><i
class="fas fa-download"></i></button>
<div class="dropdown-buttons">
<!-- ipynb file if we had a myst markdown file -->
<!-- Download raw file -->
<a class="dropdown-buttons" href="../../_sources/benchmarks/uc.ipynb.txt"><button type="button"
class="btn btn-secondary topbarbtn" title="Download source file" data-toggle="tooltip"
data-placement="left">.ipynb</button></a>
<!-- Download PDF via print -->
<button type="button" id="download-print" class="btn btn-secondary topbarbtn" title="Print to PDF"
onClick="window.print()" data-toggle="tooltip" data-placement="left">.pdf</button>
</div>
</div>
<!-- Source interaction buttons -->
<!-- Full screen (wrap in <a> to have style consistency -->
<a class="full-screen-button"><button type="button" class="btn btn-secondary topbarbtn" data-toggle="tooltip"
data-placement="bottom" onclick="toggleFullScreen()" aria-label="Fullscreen mode"
title="Fullscreen mode"><i
class="fas fa-expand"></i></button></a>
<!-- Launch buttons -->
</div>
<!-- Table of contents -->
<div class="d-none d-md-block col-md-2 bd-toc show">
</div>
</div>
</div>
<div id="main-content" class="row">
<div class="col-12 col-md-9 pl-md-3 pr-md-0">
<div>
<div class="section" id="Unit-Commitment">
<h1>Unit Commitment<a class="headerlink" href="#Unit-Commitment" title="Permalink to this headline"></a></h1>
<p>TODO</p>
</div>
</div>
<div class='prev-next-bottom'>
</div>
</div>
</div>
<footer class="footer mt-5 mt-md-0">
<div class="container">
<p>
&copy; Copyright 2020-2021, UChicago Argonne, LLC.<br/>
</p>
</div>
</footer>
</main>
</div>
</div>
<script src="../../_static/js/index.1c5a1a01449ed65a7b51.js"></script>
</body>
</html>

@ -1,432 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>3. Customization &#8212; MIPLearn&lt;br/&gt;&lt;small&gt;0.2.0&lt;/small&gt;</title>
<link href="../_static/css/theme.css" rel="stylesheet" />
<link href="../_static/css/index.c5995385ac14fb8791e8eb36b4908be2.css" rel="stylesheet" />
<link rel="stylesheet"
href="../_static/vendor/fontawesome/5.13.0/css/all.min.css">
<link rel="preload" as="font" type="font/woff2" crossorigin
href="../_static/vendor/fontawesome/5.13.0/webfonts/fa-solid-900.woff2">
<link rel="preload" as="font" type="font/woff2" crossorigin
href="../_static/vendor/fontawesome/5.13.0/webfonts/fa-brands-400.woff2">
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
<link rel="stylesheet" href="../_static/sphinx-book-theme.acff12b8f9c144ce68a297486a2fa670.css" type="text/css" />
<link rel="stylesheet" type="text/css" href="../_static/custom.css" />
<link rel="preload" as="script" href="../_static/js/index.1c5a1a01449ed65a7b51.js">
<script id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
<script src="../_static/jquery.js"></script>
<script src="../_static/underscore.js"></script>
<script src="../_static/doctools.js"></script>
<script src="../_static/sphinx-book-theme.12a9622fbb08dcb3a2a40b2c02b83a57.js"></script>
<link rel="author" title="About these documents" href="../about/" />
<link rel="index" title="Index" href="../genindex/" />
<link rel="search" title="Search" href="../search/" />
<link rel="next" title="4. About" href="../about/" />
<link rel="prev" title="2. Benchmarks" href="../benchmark/" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="docsearch:language" content="en" />
</head>
<body data-spy="scroll" data-target="#bd-toc-nav" data-offset="80">
<div class="container-fluid" id="banner"></div>
<div class="container-xl">
<div class="row">
<div class="col-12 col-md-3 bd-sidebar site-navigation show" id="site-navigation">
<div class="navbar-brand-box">
<a class="navbar-brand text-wrap" href="../">
<h1 class="site-logo" id="site-title">MIPLearn<br/><small>0.2.0</small></h1>
</a>
</div><form class="bd-search d-flex align-items-center" action="../search/" method="get">
<i class="icon fas fa-search"></i>
<input type="search" class="form-control" name="q" id="search-input" placeholder="Search the docs ..." aria-label="Search the docs ..." autocomplete="off" >
</form><nav class="bd-links" id="bd-docs-nav" aria-label="Main navigation">
<div class="bd-toc-item active">
<ul class="current nav bd-sidenav">
<li class="toctree-l1">
<a class="reference internal" href="../usage/">
<span class="sectnum">
1.
</span>
Using MIPLearn
</a>
</li>
<li class="toctree-l1">
<a class="reference internal" href="../benchmark/">
<span class="sectnum">
2.
</span>
Benchmarks
</a>
</li>
<li class="toctree-l1 current active">
<a class="current reference internal" href="#">
<span class="sectnum">
3.
</span>
Customization
</a>
</li>
<li class="toctree-l1">
<a class="reference internal" href="../about/">
<span class="sectnum">
4.
</span>
About
</a>
</li>
</ul>
</div>
</nav> <!-- To handle the deprecated key -->
</div>
<main class="col py-md-3 pl-md-4 bd-content overflow-auto" role="main">
<div class="topbar container-xl fixed-top">
<div class="topbar-contents row">
<div class="col-12 col-md-3 bd-topbar-whitespace site-navigation show"></div>
<div class="col pl-md-4 topbar-main">
<button id="navbar-toggler" class="navbar-toggler ml-0" type="button" data-toggle="collapse"
data-toggle="tooltip" data-placement="bottom" data-target=".site-navigation" aria-controls="navbar-menu"
aria-expanded="true" aria-label="Toggle navigation" aria-controls="site-navigation"
title="Toggle navigation" data-toggle="tooltip" data-placement="left">
<i class="fas fa-bars"></i>
<i class="fas fa-arrow-left"></i>
<i class="fas fa-arrow-up"></i>
</button>
<div class="dropdown-buttons-trigger">
<button id="dropdown-buttons-trigger" class="btn btn-secondary topbarbtn" aria-label="Download this page"><i
class="fas fa-download"></i></button>
<div class="dropdown-buttons">
<!-- ipynb file if we had a myst markdown file -->
<!-- Download raw file -->
<a class="dropdown-buttons" href="../_sources/customization.md.txt"><button type="button"
class="btn btn-secondary topbarbtn" title="Download source file" data-toggle="tooltip"
data-placement="left">.md</button></a>
<!-- Download PDF via print -->
<button type="button" id="download-print" class="btn btn-secondary topbarbtn" title="Print to PDF"
onClick="window.print()" data-toggle="tooltip" data-placement="left">.pdf</button>
</div>
</div>
<!-- Source interaction buttons -->
<div class="dropdown-buttons-trigger">
<button id="dropdown-buttons-trigger" class="btn btn-secondary topbarbtn"
aria-label="Connect with source repository"><i class="fab fa-github"></i></button>
<div class="dropdown-buttons sourcebuttons">
<a class="repository-button"
href="https://github.com/ANL-CEEESA/MIPLearn/"><button type="button" class="btn btn-secondary topbarbtn"
data-toggle="tooltip" data-placement="left" title="Source repository"><i
class="fab fa-github"></i>repository</button></a>
</div>
</div>
<!-- Full screen (wrap in <a> to have style consistency -->
<a class="full-screen-button"><button type="button" class="btn btn-secondary topbarbtn" data-toggle="tooltip"
data-placement="bottom" onclick="toggleFullScreen()" aria-label="Fullscreen mode"
title="Fullscreen mode"><i
class="fas fa-expand"></i></button></a>
<!-- Launch buttons -->
</div>
<!-- Table of contents -->
<div class="d-none d-md-block col-md-2 bd-toc show">
<div class="tocsection onthispage pt-5 pb-3">
<i class="fas fa-list"></i> Contents
</div>
<nav id="bd-toc-nav">
<ul class="visible nav section-nav flex-column">
<li class="toc-h2 nav-item toc-entry">
<a class="reference internal nav-link" href="#customizing-solver-parameters">
<span class="sectnum">
3.1.
</span>
Customizing solver parameters
</a>
<ul class="nav section-nav flex-column">
<li class="toc-h3 nav-item toc-entry">
<a class="reference internal nav-link" href="#selecting-the-internal-mip-solver">
Selecting the internal MIP solver
</a>
</li>
</ul>
</li>
<li class="toc-h2 nav-item toc-entry">
<a class="reference internal nav-link" href="#customizing-solver-components">
<span class="sectnum">
3.2.
</span>
Customizing solver components
</a>
<ul class="nav section-nav flex-column">
<li class="toc-h3 nav-item toc-entry">
<a class="reference internal nav-link" href="#selecting-components">
Selecting components
</a>
</li>
<li class="toc-h3 nav-item toc-entry">
<a class="reference internal nav-link" href="#adjusting-component-aggressiveness">
Adjusting component aggressiveness
</a>
</li>
<li class="toc-h3 nav-item toc-entry">
<a class="reference internal nav-link" href="#evaluating-component-performance">
Evaluating component performance
</a>
</li>
<li class="toc-h3 nav-item toc-entry">
<a class="reference internal nav-link" href="#using-customized-ml-classifiers-and-regressors">
Using customized ML classifiers and regressors
</a>
</li>
</ul>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div id="main-content" class="row">
<div class="col-12 col-md-9 pl-md-3 pr-md-0">
<div>
<div class="section" id="customization">
<h1><span class="sectnum">3.</span> Customization<a class="headerlink" href="#customization" title="Permalink to this headline"></a></h1>
<div class="section" id="customizing-solver-parameters">
<h2><span class="sectnum">3.1.</span> Customizing solver parameters<a class="headerlink" href="#customizing-solver-parameters" title="Permalink to this headline"></a></h2>
<div class="section" id="selecting-the-internal-mip-solver">
<h3>Selecting the internal MIP solver<a class="headerlink" href="#selecting-the-internal-mip-solver" title="Permalink to this headline"></a></h3>
<p>By default, <code class="docutils literal notranslate"><span class="pre">LearningSolver</span></code> uses <a class="reference external" href="https://www.gurobi.com/">Gurobi</a> as its internal MIP solver, and expects models to be provided using the Pyomo modeling language. Supported solvers and modeling languages include:</p>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">GurobiPyomoSolver</span></code>: Gurobi with Pyomo (default).</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">CplexPyomoSolver</span></code>: <a class="reference external" href="https://www.ibm.com/products/ilog-cplex-optimization-studio">IBM ILOG CPLEX</a> with Pyomo.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">XpressPyomoSolver</span></code>: <a class="reference external" href="https://www.fico.com/en/products/fico-xpress-solver">FICO XPRESS Solver</a> with Pyomo.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">GurobiSolver</span></code>: Gurobi without any modeling language.</p></li>
</ul>
<p>To switch between solvers, provide the desired class using the <code class="docutils literal notranslate"><span class="pre">solver</span></code> argument:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">miplearn</span> <span class="kn">import</span> <span class="n">LearningSolver</span><span class="p">,</span> <span class="n">CplexPyomoSolver</span>
<span class="n">solver</span> <span class="o">=</span> <span class="n">LearningSolver</span><span class="p">(</span><span class="n">solver</span><span class="o">=</span><span class="n">CplexPyomoSolver</span><span class="p">)</span>
</pre></div>
</div>
<p>To configure a particular solver, use the <code class="docutils literal notranslate"><span class="pre">params</span></code> constructor argument, as shown below.</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">miplearn</span> <span class="kn">import</span> <span class="n">LearningSolver</span><span class="p">,</span> <span class="n">GurobiPyomoSolver</span>
<span class="n">solver</span> <span class="o">=</span> <span class="n">LearningSolver</span><span class="p">(</span>
<span class="n">solver</span><span class="o">=</span><span class="k">lambda</span><span class="p">:</span> <span class="n">GurobiPyomoSolver</span><span class="p">(</span>
<span class="n">params</span><span class="o">=</span><span class="p">{</span>
<span class="s2">&quot;TimeLimit&quot;</span><span class="p">:</span> <span class="mi">900</span><span class="p">,</span>
<span class="s2">&quot;MIPGap&quot;</span><span class="p">:</span> <span class="mf">1e-3</span><span class="p">,</span>
<span class="s2">&quot;NodeLimit&quot;</span><span class="p">:</span> <span class="mi">1000</span><span class="p">,</span>
<span class="p">}</span>
<span class="p">),</span>
<span class="p">)</span>
</pre></div>
</div>
</div>
</div>
<div class="section" id="customizing-solver-components">
<h2><span class="sectnum">3.2.</span> Customizing solver components<a class="headerlink" href="#customizing-solver-components" title="Permalink to this headline"></a></h2>
<p><code class="docutils literal notranslate"><span class="pre">LearningSolver</span></code> is composed by a number of individual machine-learning components, each targeting a different part of the solution process. Each component can be individually enabled, disabled or customized. The following components are enabled by default:</p>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">LazyConstraintComponent</span></code>: Predicts which lazy constraint to initially enforce.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">ObjectiveValueComponent</span></code>: Predicts the optimal value of the optimization problem, given the optimal solution to the LP relaxation.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">PrimalSolutionComponent</span></code>: Predicts optimal values for binary decision variables. In heuristic mode, this component fixes the variables to their predicted values. In exact mode, the predicted values are provided to the solver as a (partial) MIP start.</p></li>
</ul>
<p>The following components are also available, but not enabled by default:</p>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">BranchPriorityComponent</span></code>: Predicts good branch priorities for decision variables.</p></li>
</ul>
<div class="section" id="selecting-components">
<h3>Selecting components<a class="headerlink" href="#selecting-components" title="Permalink to this headline"></a></h3>
<p>To create a <code class="docutils literal notranslate"><span class="pre">LearningSolver</span></code> with a specific set of components, the <code class="docutils literal notranslate"><span class="pre">components</span></code> constructor argument may be used, as the next example shows:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># Create a solver without any components</span>
<span class="n">solver1</span> <span class="o">=</span> <span class="n">LearningSolver</span><span class="p">(</span><span class="n">components</span><span class="o">=</span><span class="p">[])</span>
<span class="c1"># Create a solver with only two components</span>
<span class="n">solver2</span> <span class="o">=</span> <span class="n">LearningSolver</span><span class="p">(</span><span class="n">components</span><span class="o">=</span><span class="p">[</span>
<span class="n">LazyConstraintComponent</span><span class="p">(</span><span class="o">...</span><span class="p">),</span>
<span class="n">PrimalSolutionComponent</span><span class="p">(</span><span class="o">...</span><span class="p">),</span>
<span class="p">])</span>
</pre></div>
</div>
</div>
<div class="section" id="adjusting-component-aggressiveness">
<h3>Adjusting component aggressiveness<a class="headerlink" href="#adjusting-component-aggressiveness" title="Permalink to this headline"></a></h3>
<p>The aggressiveness of classification components, such as <code class="docutils literal notranslate"><span class="pre">PrimalSolutionComponent</span></code> and <code class="docutils literal notranslate"><span class="pre">LazyConstraintComponent</span></code>, can be adjusted through the <code class="docutils literal notranslate"><span class="pre">threshold</span></code> constructor argument. Internally, these components ask the machine learning models how confident are they on each prediction they make, then automatically discard all predictions that have low confidence. The <code class="docutils literal notranslate"><span class="pre">threshold</span></code> argument specifies how confident should the ML models be for a prediction to be considered trustworthy. Lowering a components threshold increases its aggressiveness, while raising a components threshold makes it more conservative.</p>
<p>For example, if the ML model predicts that a certain binary variable will assume value <code class="docutils literal notranslate"><span class="pre">1.0</span></code> in the optimal solution with 75% confidence, and if the <code class="docutils literal notranslate"><span class="pre">PrimalSolutionComponent</span></code> is configured to discard all predictions with less than 90% confidence, then this variable will not be included in the predicted MIP start.</p>
<p>MIPLearn currently provides two types of thresholds:</p>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">MinProbabilityThreshold(p:</span> <span class="pre">List[float])</span></code> A threshold which indicates that a prediction is trustworthy if its probability of being correct, as computed by the machine learning model, is above a fixed value.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">MinPrecisionThreshold(p:</span> <span class="pre">List[float])</span></code> A dynamic threshold which automatically adjusts itself during training to ensure that the component achieves at least a given precision on the training data set. Note that increasing a components precision may reduce its recall.</p></li>
</ul>
<p>The example below shows how to build a <code class="docutils literal notranslate"><span class="pre">PrimalSolutionComponent</span></code> which fixes variables to zero with at least 80% precision, and to one with at least 95% precision. Other components are configured similarly.</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">miplearn</span> <span class="kn">import</span> <span class="n">PrimalSolutionComponent</span><span class="p">,</span> <span class="n">MinPrecisionThreshold</span>
<span class="n">PrimalSolutionComponent</span><span class="p">(</span>
<span class="n">mode</span><span class="o">=</span><span class="s2">&quot;heuristic&quot;</span><span class="p">,</span>
<span class="n">threshold</span><span class="o">=</span><span class="n">MinPrecisionThreshold</span><span class="p">([</span><span class="mf">0.80</span><span class="p">,</span> <span class="mf">0.95</span><span class="p">]),</span>
<span class="p">)</span>
</pre></div>
</div>
</div>
<div class="section" id="evaluating-component-performance">
<h3>Evaluating component performance<a class="headerlink" href="#evaluating-component-performance" title="Permalink to this headline"></a></h3>
<p>MIPLearn allows solver components to be modified, trained and evaluated in isolation. In the following example, we build and
fit <code class="docutils literal notranslate"><span class="pre">PrimalSolutionComponent</span></code> outside the solver, then evaluate its performance.</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">miplearn</span> <span class="kn">import</span> <span class="n">PrimalSolutionComponent</span>
<span class="c1"># User-provided set of previously-solved instances</span>
<span class="n">train_instances</span> <span class="o">=</span> <span class="p">[</span><span class="o">...</span><span class="p">]</span>
<span class="c1"># Construct and fit component on a subset of training instances</span>
<span class="n">comp</span> <span class="o">=</span> <span class="n">PrimalSolutionComponent</span><span class="p">()</span>
<span class="n">comp</span><span class="o">.</span><span class="n">fit</span><span class="p">(</span><span class="n">train_instances</span><span class="p">[:</span><span class="mi">100</span><span class="p">])</span>
<span class="c1"># Evaluate performance on an additional set of training instances</span>
<span class="n">ev</span> <span class="o">=</span> <span class="n">comp</span><span class="o">.</span><span class="n">evaluate</span><span class="p">(</span><span class="n">train_instances</span><span class="p">[</span><span class="mi">100</span><span class="p">:</span><span class="mi">150</span><span class="p">])</span>
</pre></div>
</div>
<p>The method <code class="docutils literal notranslate"><span class="pre">evaluate</span></code> returns a dictionary with performance evaluation statistics for each training instance provided,
and for each type of prediction the component makes. To obtain a summary across all instances, pandas may be used, as below:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">pandas</span> <span class="k">as</span> <span class="nn">pd</span>
<span class="n">pd</span><span class="o">.</span><span class="n">DataFrame</span><span class="p">(</span><span class="n">ev</span><span class="p">[</span><span class="s2">&quot;Fix one&quot;</span><span class="p">])</span><span class="o">.</span><span class="n">mean</span><span class="p">(</span><span class="n">axis</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-text notranslate"><div class="highlight"><pre><span></span>Predicted positive 3.120000
Predicted negative 196.880000
Condition positive 62.500000
Condition negative 137.500000
True positive 3.060000
True negative 137.440000
False positive 0.060000
False negative 59.440000
Accuracy 0.702500
F1 score 0.093050
Recall 0.048921
Precision 0.981667
Predicted positive (%) 1.560000
Predicted negative (%) 98.440000
Condition positive (%) 31.250000
Condition negative (%) 68.750000
True positive (%) 1.530000
True negative (%) 68.720000
False positive (%) 0.030000
False negative (%) 29.720000
dtype: float64
</pre></div>
</div>
<p>Regression components (such as <code class="docutils literal notranslate"><span class="pre">ObjectiveValueComponent</span></code>) can also be trained and evaluated similarly,
as the next example shows:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">miplearn</span> <span class="kn">import</span> <span class="n">ObjectiveValueComponent</span>
<span class="n">comp</span> <span class="o">=</span> <span class="n">ObjectiveValueComponent</span><span class="p">()</span>
<span class="n">comp</span><span class="o">.</span><span class="n">fit</span><span class="p">(</span><span class="n">train_instances</span><span class="p">[:</span><span class="mi">100</span><span class="p">])</span>
<span class="n">ev</span> <span class="o">=</span> <span class="n">comp</span><span class="o">.</span><span class="n">evaluate</span><span class="p">(</span><span class="n">train_instances</span><span class="p">[</span><span class="mi">100</span><span class="p">:</span><span class="mi">150</span><span class="p">])</span>
<span class="kn">import</span> <span class="nn">pandas</span> <span class="k">as</span> <span class="nn">pd</span>
<span class="n">pd</span><span class="o">.</span><span class="n">DataFrame</span><span class="p">(</span><span class="n">ev</span><span class="p">)</span><span class="o">.</span><span class="n">mean</span><span class="p">(</span><span class="n">axis</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-text notranslate"><div class="highlight"><pre><span></span>Mean squared error 7001.977827
Explained variance 0.519790
Max error 242.375804
Mean absolute error 65.843924
R2 0.517612
Median absolute error 65.843924
dtype: float64
</pre></div>
</div>
</div>
<div class="section" id="using-customized-ml-classifiers-and-regressors">
<h3>Using customized ML classifiers and regressors<a class="headerlink" href="#using-customized-ml-classifiers-and-regressors" title="Permalink to this headline"></a></h3>
<p>By default, given a training set of instantes, MIPLearn trains a fixed set of ML classifiers and regressors, then selects the best one based on cross-validation performance. Alternatively, the user may specify which ML model a component should use through the <code class="docutils literal notranslate"><span class="pre">classifier</span></code> or <code class="docutils literal notranslate"><span class="pre">regressor</span></code> contructor parameters. Scikit-learn classifiers and regressors are currently supported. A future version of the package will add compatibility with Keras models.</p>
<p>The example below shows how to construct a <code class="docutils literal notranslate"><span class="pre">PrimalSolutionComponent</span></code> which internally uses scikit-learns <code class="docutils literal notranslate"><span class="pre">KNeighborsClassifiers</span></code>. Any other scikit-learn classifier or pipeline can be used. It needs to be wrapped in <code class="docutils literal notranslate"><span class="pre">ScikitLearnClassifier</span></code> to ensure that all the proper data transformations are applied.</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">miplearn</span> <span class="kn">import</span> <span class="n">PrimalSolutionComponent</span><span class="p">,</span> <span class="n">ScikitLearnClassifier</span>
<span class="kn">from</span> <span class="nn">sklearn.neighbors</span> <span class="kn">import</span> <span class="n">KNeighborsClassifier</span>
<span class="n">comp</span> <span class="o">=</span> <span class="n">PrimalSolutionComponent</span><span class="p">(</span>
<span class="n">classifier</span><span class="o">=</span><span class="n">ScikitLearnClassifier</span><span class="p">(</span>
<span class="n">KNeighborsClassifier</span><span class="p">(</span><span class="n">n_neighbors</span><span class="o">=</span><span class="mi">5</span><span class="p">),</span>
<span class="p">),</span>
<span class="p">)</span>
<span class="n">comp</span><span class="o">.</span><span class="n">fit</span><span class="p">(</span><span class="n">train_instances</span><span class="p">)</span>
</pre></div>
</div>
</div>
</div>
</div>
</div>
<div class='prev-next-bottom'>
<a class='left-prev' id="prev-link" href="../benchmark/" title="previous page"><span class="sectnum">2.</span> Benchmarks</a>
<a class='right-next' id="next-link" href="../about/" title="next page"><span class="sectnum">4.</span> About</a>
</div>
</div>
</div>
<footer class="footer mt-5 mt-md-0">
<div class="container">
<p>
&copy; Copyright 2020-2021, UChicago Argonne, LLC.<br/>
</p>
</div>
</footer>
</main>
</div>
</div>
<script src="../_static/js/index.1c5a1a01449ed65a7b51.js"></script>
</body>
</html>

@ -32,8 +32,8 @@
<script src="../_static/jquery.js"></script> <script src="../_static/jquery.js"></script>
<script src="../_static/underscore.js"></script> <script src="../_static/underscore.js"></script>
<script src="../_static/doctools.js"></script> <script src="../_static/doctools.js"></script>
<script crossorigin="anonymous" integrity="sha256-Ae2Vz/4ePdIu6ZyI/5ZGsYnb+m0JlOmKPjt6XZ9JJkA=" src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.3.4/require.min.js"></script>
<script src="../_static/sphinx-book-theme.12a9622fbb08dcb3a2a40b2c02b83a57.js"></script> <script src="../_static/sphinx-book-theme.12a9622fbb08dcb3a2a40b2c02b83a57.js"></script>
<link rel="author" title="About these documents" href="../about/" />
<link rel="index" title="Index" href="#" /> <link rel="index" title="Index" href="#" />
<link rel="search" title="Search" href="../search/" /> <link rel="search" title="Search" href="../search/" />
<meta name="viewport" content="width=device-width, initial-scale=1" /> <meta name="viewport" content="width=device-width, initial-scale=1" />
@ -63,37 +63,42 @@
<input type="search" class="form-control" name="q" id="search-input" placeholder="Search the docs ..." aria-label="Search the docs ..." autocomplete="off" > <input type="search" class="form-control" name="q" id="search-input" placeholder="Search the docs ..." aria-label="Search the docs ..." autocomplete="off" >
</form><nav class="bd-links" id="bd-docs-nav" aria-label="Main navigation"> </form><nav class="bd-links" id="bd-docs-nav" aria-label="Main navigation">
<div class="bd-toc-item active"> <div class="bd-toc-item active">
<ul class="nav bd-sidenav"> <p class="caption">
<span class="caption-text">
Julia Tutorials
</span>
</p>
<ul class="nav bd-sidenav">
<li class="toctree-l1"> <li class="toctree-l1">
<a class="reference internal" href="../usage/"> <a class="reference internal" href="../jump-tutorials/getting-started/">
<span class="sectnum"> 1. Getting started with MIPLearn
1.
</span>
Using MIPLearn
</a> </a>
</li> </li>
</ul>
<p class="caption">
<span class="caption-text">
Benchmarks
</span>
</p>
<ul class="nav bd-sidenav">
<li class="toctree-l1"> <li class="toctree-l1">
<a class="reference internal" href="../benchmark/"> <a class="reference internal" href="../benchmarks/preliminaries/">
<span class="sectnum"> 1. Preliminaries
2.
</span>
Benchmarks
</a> </a>
</li> </li>
<li class="toctree-l1"> <li class="toctree-l1">
<a class="reference internal" href="../customization/"> <a class="reference internal" href="../benchmarks/stab/">
<span class="sectnum"> 2. Maximum Weight Stable Set
3.
</span>
Customization
</a> </a>
</li> </li>
<li class="toctree-l1"> <li class="toctree-l1">
<a class="reference internal" href="../about/"> <a class="reference internal" href="../benchmarks/knapsack/">
<span class="sectnum"> 3. Multidimensional Knapsack
4. </a>
</span> </li>
About <li class="toctree-l1">
<a class="reference internal" href="../benchmarks/tsp/">
4. Traveling Salesman
</a> </a>
</li> </li>
</ul> </ul>
@ -127,19 +132,6 @@
<!-- Source interaction buttons --> <!-- Source interaction buttons -->
<div class="dropdown-buttons-trigger">
<button id="dropdown-buttons-trigger" class="btn btn-secondary topbarbtn"
aria-label="Connect with source repository"><i class="fab fa-github"></i></button>
<div class="dropdown-buttons sourcebuttons">
<a class="repository-button"
href="https://github.com/ANL-CEEESA/MIPLearn/"><button type="button" class="btn btn-secondary topbarbtn"
data-toggle="tooltip" data-placement="left" title="Source repository"><i
class="fab fa-github"></i>repository</button></a>
</div>
</div>
<!-- Full screen (wrap in <a> to have style consistency --> <!-- Full screen (wrap in <a> to have style consistency -->
<a class="full-screen-button"><button type="button" class="btn btn-secondary topbarbtn" data-toggle="tooltip" <a class="full-screen-button"><button type="button" class="btn btn-secondary topbarbtn" data-toggle="tooltip"

@ -32,11 +32,11 @@
<script src="_static/jquery.js"></script> <script src="_static/jquery.js"></script>
<script src="_static/underscore.js"></script> <script src="_static/underscore.js"></script>
<script src="_static/doctools.js"></script> <script src="_static/doctools.js"></script>
<script crossorigin="anonymous" integrity="sha256-Ae2Vz/4ePdIu6ZyI/5ZGsYnb+m0JlOmKPjt6XZ9JJkA=" src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.3.4/require.min.js"></script>
<script src="_static/sphinx-book-theme.12a9622fbb08dcb3a2a40b2c02b83a57.js"></script> <script src="_static/sphinx-book-theme.12a9622fbb08dcb3a2a40b2c02b83a57.js"></script>
<link rel="author" title="About these documents" href="about/" />
<link rel="index" title="Index" href="genindex/" /> <link rel="index" title="Index" href="genindex/" />
<link rel="search" title="Search" href="search/" /> <link rel="search" title="Search" href="search/" />
<link rel="next" title="1. Using MIPLearn" href="usage/" /> <link rel="next" title="1. Getting started with MIPLearn" href="jump-tutorials/getting-started/" />
<meta name="viewport" content="width=device-width, initial-scale=1" /> <meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="docsearch:language" content="en" /> <meta name="docsearch:language" content="en" />
@ -64,37 +64,42 @@
<input type="search" class="form-control" name="q" id="search-input" placeholder="Search the docs ..." aria-label="Search the docs ..." autocomplete="off" > <input type="search" class="form-control" name="q" id="search-input" placeholder="Search the docs ..." aria-label="Search the docs ..." autocomplete="off" >
</form><nav class="bd-links" id="bd-docs-nav" aria-label="Main navigation"> </form><nav class="bd-links" id="bd-docs-nav" aria-label="Main navigation">
<div class="bd-toc-item active"> <div class="bd-toc-item active">
<ul class="nav bd-sidenav"> <p class="caption">
<span class="caption-text">
Julia Tutorials
</span>
</p>
<ul class="nav bd-sidenav">
<li class="toctree-l1"> <li class="toctree-l1">
<a class="reference internal" href="usage/"> <a class="reference internal" href="jump-tutorials/getting-started/">
<span class="sectnum"> 1. Getting started with MIPLearn
1. </a>
</span> </li>
Using MIPLearn </ul>
<p class="caption">
<span class="caption-text">
Benchmarks
</span>
</p>
<ul class="nav bd-sidenav">
<li class="toctree-l1">
<a class="reference internal" href="benchmarks/preliminaries/">
1. Preliminaries
</a> </a>
</li> </li>
<li class="toctree-l1"> <li class="toctree-l1">
<a class="reference internal" href="benchmark/"> <a class="reference internal" href="benchmarks/stab/">
<span class="sectnum"> 2. Maximum Weight Stable Set
2.
</span>
Benchmarks
</a> </a>
</li> </li>
<li class="toctree-l1"> <li class="toctree-l1">
<a class="reference internal" href="customization/"> <a class="reference internal" href="benchmarks/knapsack/">
<span class="sectnum"> 3. Multidimensional Knapsack
3.
</span>
Customization
</a> </a>
</li> </li>
<li class="toctree-l1"> <li class="toctree-l1">
<a class="reference internal" href="about/"> <a class="reference internal" href="benchmarks/tsp/">
<span class="sectnum"> 4. Traveling Salesman
4.
</span>
About
</a> </a>
</li> </li>
</ul> </ul>
@ -145,19 +150,6 @@
<!-- Source interaction buttons --> <!-- Source interaction buttons -->
<div class="dropdown-buttons-trigger">
<button id="dropdown-buttons-trigger" class="btn btn-secondary topbarbtn"
aria-label="Connect with source repository"><i class="fab fa-github"></i></button>
<div class="dropdown-buttons sourcebuttons">
<a class="repository-button"
href="https://github.com/ANL-CEEESA/MIPLearn/"><button type="button" class="btn btn-secondary topbarbtn"
data-toggle="tooltip" data-placement="left" title="Source repository"><i
class="fab fa-github"></i>repository</button></a>
</div>
</div>
<!-- Full screen (wrap in <a> to have style consistency --> <!-- Full screen (wrap in <a> to have style consistency -->
<a class="full-screen-button"><button type="button" class="btn btn-secondary topbarbtn" data-toggle="tooltip" <a class="full-screen-button"><button type="button" class="btn btn-secondary topbarbtn" data-toggle="tooltip"
@ -178,18 +170,35 @@
<nav id="bd-toc-nav"> <nav id="bd-toc-nav">
<ul class="visible nav section-nav flex-column"> <ul class="visible nav section-nav flex-column">
<li class="toc-h2 nav-item toc-entry"> <li class="toc-h2 nav-item toc-entry">
<a class="reference internal nav-link" href="#features"> <a class="reference internal nav-link" href="#table-of-contents">
Features Table of Contents
</a> </a>
<ul class="nav section-nav flex-column">
</ul>
</li> </li>
<li class="toc-h2 nav-item toc-entry"> <li class="toc-h2 nav-item toc-entry">
<a class="reference internal nav-link" href="#site-contents"> <a class="reference internal nav-link" href="#source-code">
Site contents Source Code
</a> </a>
</li> </li>
<li class="toc-h2 nav-item toc-entry"> <li class="toc-h2 nav-item toc-entry">
<a class="reference internal nav-link" href="#source-code"> <a class="reference internal nav-link" href="#authors">
Source Code Authors
</a>
</li>
<li class="toc-h2 nav-item toc-entry">
<a class="reference internal nav-link" href="#acknowledgments">
Acknowledgments
</a>
</li>
<li class="toc-h2 nav-item toc-entry">
<a class="reference internal nav-link" href="#references">
References
</a>
</li>
<li class="toc-h2 nav-item toc-entry">
<a class="reference internal nav-link" href="#license">
License
</a> </a>
</li> </li>
</ul> </ul>
@ -208,52 +217,25 @@
<p><strong>MIPLearn</strong> is an extensible framework for solving discrete optimization problems using a combination of Mixed-Integer Linear Programming (MIP) and Machine Learning (ML). The framework uses ML methods to automatically identify patterns in previously solved instances of the problem, then uses these patterns to accelerate the performance of conventional state-of-the-art MIP solvers (such as CPLEX, Gurobi or XPRESS).</p> <p><strong>MIPLearn</strong> is an extensible framework for solving discrete optimization problems using a combination of Mixed-Integer Linear Programming (MIP) and Machine Learning (ML). The framework uses ML methods to automatically identify patterns in previously solved instances of the problem, then uses these patterns to accelerate the performance of conventional state-of-the-art MIP solvers (such as CPLEX, Gurobi or XPRESS).</p>
<p>Unlike pure ML methods, MIPLearn is not only able to find high-quality solutions to discrete optimization problems, but it can also prove the optimality and feasibility of these solutions. <p>Unlike pure ML methods, MIPLearn is not only able to find high-quality solutions to discrete optimization problems, but it can also prove the optimality and feasibility of these solutions.
Unlike conventional MIP solvers, MIPLearn can take full advantage of very specific observations that happen to be true in a particular family of instances (such as the observation that a particular constraint is typically redundant, or that a particular variable typically assumes a certain value).</p> Unlike conventional MIP solvers, MIPLearn can take full advantage of very specific observations that happen to be true in a particular family of instances (such as the observation that a particular constraint is typically redundant, or that a particular variable typically assumes a certain value).</p>
<p>For certain classes of problems, this approach has been shown to provide significant performance benefits (see <a class="reference internal" href="benchmark/"><span class="doc std std-doc">benchmarks</span></a> and <a class="reference internal" href="about/"><span class="doc std std-doc">references</span></a>).</p> <div class="section" id="table-of-contents">
<div class="section" id="features"> <h2>Table of Contents<a class="headerlink" href="#table-of-contents" title="Permalink to this headline"></a></h2>
<h2>Features<a class="headerlink" href="#features" title="Permalink to this headline"></a></h2> <div class="toctree-wrapper compound">
<ul class="simple"> <p class="caption"><span class="caption-text">Julia Tutorials</span></p>
<li><p><strong>MIPLearn proposes a flexible problem specification format,</strong> which allows users to describe their particular optimization problems to a Learning-Enhanced MIP solver, both from the MIP perspective and from the ML perspective, without making any assumptions on the problem being modeled, the mathematical formulation of the problem, or ML encoding. While the format is very flexible, some constraints are enforced to ensure that it is usable by an actual solver.</p></li> <ul>
<li><p><strong>MIPLearn provides a reference implementation of a <em>Learning-Enhanced Solver</em>,</strong> which can use the above problem specification format to automatically predict, based on previously solved instances, a number of hints to accelerate MIP performance. Currently, the reference solver is able to predict: (i) partial solutions which are likely to work well as MIP starts; (ii) an initial set of lazy constraints to enforce; (iii) variable branching priorities to accelerate the exploration of the branch-and-bound tree; (iv) the optimal objective value based on the solution to the LP relaxation. The usage of the solver is very straightforward. The most suitable ML models are automatically selected, trained, cross-validated and applied to the problem with no user intervention.</p></li> <li class="toctree-l1"><a class="reference internal" href="jump-tutorials/getting-started/">1. Getting started with MIPLearn</a></li>
<li><p><strong>MIPLearn provides a set of benchmark problems and random instance generators,</strong> covering applications from different domains, which can be used to quickly evaluate new learning-enhanced MIP techniques in a measurable and reproducible way.</p></li>
<li><p><strong>MIPLearn is customizable and extensible</strong>. For MIP and ML researchers exploring new techniques to accelerate MIP performance based on historical data, each component of the reference solver can be individually replaced, extended or customized.</p></li>
</ul> </ul>
</div> </div>
<div class="section" id="site-contents">
<h2>Site contents<a class="headerlink" href="#site-contents" title="Permalink to this headline"></a></h2>
<div class="toctree-wrapper compound"> <div class="toctree-wrapper compound">
<p class="caption"><span class="caption-text">Benchmarks</span></p>
<ul> <ul>
<li class="toctree-l1"><a class="reference internal" href="usage/"><span class="sectnum">1.</span> Using MIPLearn</a><ul> <li class="toctree-l1"><a class="reference internal" href="benchmarks/preliminaries/">1. Preliminaries</a></li>
<li class="toctree-l2"><a class="reference internal" href="usage/#installation"><span class="sectnum">1.1.</span> Installation</a></li> <li class="toctree-l1"><a class="reference internal" href="benchmarks/stab/">2. Maximum Weight Stable Set</a></li>
<li class="toctree-l2"><a class="reference internal" href="usage/#using-learningsolver"><span class="sectnum">1.2.</span> Using <code class="docutils literal notranslate"><span class="pre">LearningSolver</span></code></a></li> <li class="toctree-l1"><a class="reference internal" href="benchmarks/knapsack/">3. Multidimensional Knapsack</a></li>
<li class="toctree-l2"><a class="reference internal" href="usage/#describing-problem-instances"><span class="sectnum">1.3.</span> Describing problem instances</a></li> <li class="toctree-l1"><a class="reference internal" href="benchmarks/tsp/">4. Traveling Salesman</a></li>
<li class="toctree-l2"><a class="reference internal" href="usage/#describing-lazy-constraints"><span class="sectnum">1.4.</span> Describing lazy constraints</a></li>
<li class="toctree-l2"><a class="reference internal" href="usage/#obtaining-heuristic-solutions"><span class="sectnum">1.5.</span> Obtaining heuristic solutions</a></li>
<li class="toctree-l2"><a class="reference internal" href="usage/#scaling-up"><span class="sectnum">1.6.</span> Scaling Up</a></li>
<li class="toctree-l2"><a class="reference internal" href="usage/#running-benchmarks"><span class="sectnum">1.7.</span> Running benchmarks</a></li>
<li class="toctree-l2"><a class="reference internal" href="usage/#current-limitations"><span class="sectnum">1.8.</span> Current Limitations</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="benchmark/"><span class="sectnum">2.</span> Benchmarks</a><ul>
<li class="toctree-l2"><a class="reference internal" href="benchmark/#preliminaries"><span class="sectnum">2.1.</span> Preliminaries</a></li>
<li class="toctree-l2"><a class="reference internal" href="benchmark/#maximum-weight-stable-set-problem"><span class="sectnum">2.2.</span> Maximum Weight Stable Set Problem</a></li>
<li class="toctree-l2"><a class="reference internal" href="benchmark/#traveling-salesman-problem"><span class="sectnum">2.3.</span> Traveling Salesman Problem</a></li>
<li class="toctree-l2"><a class="reference internal" href="benchmark/#multidimensional-0-1-knapsack-problem"><span class="sectnum">2.4.</span> Multidimensional 0-1 Knapsack Problem</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="customization/"><span class="sectnum">3.</span> Customization</a><ul>
<li class="toctree-l2"><a class="reference internal" href="customization/#customizing-solver-parameters"><span class="sectnum">3.1.</span> Customizing solver parameters</a></li>
<li class="toctree-l2"><a class="reference internal" href="customization/#customizing-solver-components"><span class="sectnum">3.2.</span> Customizing solver components</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="about/"><span class="sectnum">4.</span> About</a><ul>
<li class="toctree-l2"><a class="reference internal" href="about/#authors"><span class="sectnum">4.1.</span> Authors</a></li>
<li class="toctree-l2"><a class="reference internal" href="about/#acknowledgments"><span class="sectnum">4.2.</span> Acknowledgments</a></li>
<li class="toctree-l2"><a class="reference internal" href="about/#references"><span class="sectnum">4.3.</span> References</a></li>
<li class="toctree-l2"><a class="reference internal" href="about/#license"><span class="sectnum">4.4.</span> License</a></li>
</ul>
</li>
</ul> </ul>
</div> </div>
<div class="toctree-wrapper compound">
</div>
</div> </div>
<div class="section" id="source-code"> <div class="section" id="source-code">
<h2>Source Code<a class="headerlink" href="#source-code" title="Permalink to this headline"></a></h2> <h2>Source Code<a class="headerlink" href="#source-code" title="Permalink to this headline"></a></h2>
@ -261,6 +243,59 @@ Unlike conventional MIP solvers, MIPLearn can take full advantage of very specif
<li><p><a class="reference external" href="https://github.com/ANL-CEEESA/MIPLearn">https://github.com/ANL-CEEESA/MIPLearn</a></p></li> <li><p><a class="reference external" href="https://github.com/ANL-CEEESA/MIPLearn">https://github.com/ANL-CEEESA/MIPLearn</a></p></li>
</ul> </ul>
</div> </div>
<div class="section" id="authors">
<h2>Authors<a class="headerlink" href="#authors" title="Permalink to this headline"></a></h2>
<ul class="simple">
<li><p><strong>Alinson S. Xavier,</strong> Argonne National Laboratory &lt;<a class="reference external" href="mailto:axavier&#37;&#52;&#48;anl&#46;gov">mailto:axavier<span>&#64;</span>anl<span>&#46;</span>gov</a>&gt;</p></li>
<li><p><strong>Feng Qiu,</strong> Argonne National Laboratory &lt;<a class="reference external" href="mailto:fqiu&#37;&#52;&#48;anl&#46;gov">mailto:fqiu<span>&#64;</span>anl<span>&#46;</span>gov</a>&gt;</p></li>
</ul>
</div>
<div class="section" id="acknowledgments">
<h2>Acknowledgments<a class="headerlink" href="#acknowledgments" title="Permalink to this headline"></a></h2>
<ul class="simple">
<li><p>Based upon work supported by <strong>Laboratory Directed Research and Development</strong> (LDRD) funding from Argonne National Laboratory, provided by the Director, Office of Science, of the U.S. Department of Energy under Contract No. DE-AC02-06CH11357, and the <strong>U.S. Department of Energy Advanced Grid Modeling Program</strong> under Grant DE-OE0000875.</p></li>
</ul>
</div>
<div class="section" id="references">
<h2>References<a class="headerlink" href="#references" title="Permalink to this headline"></a></h2>
<p>If you use MIPLearn in your research, or the included problem generators, we kindly request that you cite the package as follows:</p>
<ul class="simple">
<li><p><strong>Alinson S. Xavier, Feng Qiu.</strong> <em>MIPLearn: An Extensible Framework for Learning-Enhanced Optimization</em>. Zenodo (2020). DOI: <a class="reference external" href="https://doi.org/10.5281/zenodo.4287567">10.5281/zenodo.4287567</a></p></li>
</ul>
<p>If you use MIPLearn in the field of power systems optimization, we kindly request that you cite the reference below, in which the main techniques implemented in MIPLearn were first developed:</p>
<ul class="simple">
<li><p><strong>Alinson S. Xavier, Feng Qiu, Shabbir Ahmed.</strong> <em>Learning to Solve Large-Scale Unit Commitment Problems.</em> INFORMS Journal on Computing (2021). DOI: <a class="reference external" href="https://doi.org/10.1287/ijoc.2020.0976">10.1287/ijoc.2020.0976</a></p></li>
</ul>
</div>
<div class="section" id="license">
<h2>License<a class="headerlink" href="#license" title="Permalink to this headline"></a></h2>
<div class="highlight-text notranslate"><div class="highlight"><pre><span></span>MIPLearn, an extensible framework for Learning-Enhanced Mixed-Integer Optimization
Copyright © 2020, UChicago Argonne, LLC. All Rights Reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted
provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of
conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of
conditions and the following disclaimer in the documentation and/or other materials provided
with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors may be used to
endorse or promote products derived from this software without specific prior written
permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS &quot;AS IS&quot; AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
</pre></div>
</div>
</div>
</div> </div>
@ -269,7 +304,7 @@ Unlike conventional MIP solvers, MIPLearn can take full advantage of very specif
<div class='prev-next-bottom'> <div class='prev-next-bottom'>
<a class='right-next' id="next-link" href="usage/" title="next page"><span class="sectnum">1.</span> Using MIPLearn</a> <a class='right-next' id="next-link" href="jump-tutorials/getting-started/" title="next page"><span class="section-number">1. </span>Getting started with MIPLearn</a>
</div> </div>

@ -0,0 +1,29 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "ad9274ff",
"metadata": {},
"source": [
"# Abstract component\n",
"\n",
"TODO"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Julia 1.6.0",
"language": "julia",
"name": "julia-1.6"
},
"language_info": {
"file_extension": ".jl",
"mimetype": "application/julia",
"name": "julia",
"version": "1.6.0"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

@ -0,0 +1,210 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Abstract component &#8212; MIPLearn&lt;br/&gt;&lt;small&gt;0.2.0&lt;/small&gt;</title>
<link href="../../_static/css/theme.css" rel="stylesheet" />
<link href="../../_static/css/index.c5995385ac14fb8791e8eb36b4908be2.css" rel="stylesheet" />
<link rel="stylesheet"
href="../../_static/vendor/fontawesome/5.13.0/css/all.min.css">
<link rel="preload" as="font" type="font/woff2" crossorigin
href="../../_static/vendor/fontawesome/5.13.0/webfonts/fa-solid-900.woff2">
<link rel="preload" as="font" type="font/woff2" crossorigin
href="../../_static/vendor/fontawesome/5.13.0/webfonts/fa-brands-400.woff2">
<link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
<link rel="stylesheet" href="../../_static/sphinx-book-theme.acff12b8f9c144ce68a297486a2fa670.css" type="text/css" />
<link rel="stylesheet" type="text/css" href="../../_static/custom.css" />
<link rel="preload" as="script" href="../../_static/js/index.1c5a1a01449ed65a7b51.js">
<script id="documentation_options" data-url_root="../../" src="../../_static/documentation_options.js"></script>
<script src="../../_static/jquery.js"></script>
<script src="../../_static/underscore.js"></script>
<script src="../../_static/doctools.js"></script>
<script crossorigin="anonymous" integrity="sha256-Ae2Vz/4ePdIu6ZyI/5ZGsYnb+m0JlOmKPjt6XZ9JJkA=" src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.3.4/require.min.js"></script>
<script src="../../_static/sphinx-book-theme.12a9622fbb08dcb3a2a40b2c02b83a57.js"></script>
<script async="async" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.7/latest.js?config=TeX-AMS-MML_HTMLorMML"></script>
<script type="text/x-mathjax-config">MathJax.Hub.Config({"tex2jax": {"inlineMath": [["\\(", "\\)"]], "displayMath": [["\\[", "\\]"]], "processRefs": false, "processEnvironments": false}})</script>
<link rel="index" title="Index" href="../../genindex/" />
<link rel="search" title="Search" href="../../search/" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="docsearch:language" content="en" />
</head>
<body data-spy="scroll" data-target="#bd-toc-nav" data-offset="80">
<div class="container-fluid" id="banner"></div>
<div class="container-xl">
<div class="row">
<div class="col-12 col-md-3 bd-sidebar site-navigation show" id="site-navigation">
<div class="navbar-brand-box">
<a class="navbar-brand text-wrap" href="../../">
<h1 class="site-logo" id="site-title">MIPLearn<br/><small>0.2.0</small></h1>
</a>
</div><form class="bd-search d-flex align-items-center" action="../../search/" method="get">
<i class="icon fas fa-search"></i>
<input type="search" class="form-control" name="q" id="search-input" placeholder="Search the docs ..." aria-label="Search the docs ..." autocomplete="off" >
</form><nav class="bd-links" id="bd-docs-nav" aria-label="Main navigation">
<div class="bd-toc-item active">
<p class="caption">
<span class="caption-text">
Julia Tutorials
</span>
</p>
<ul class="nav bd-sidenav">
<li class="toctree-l1">
<a class="reference internal" href="../../jump-tutorials/getting-started/">
1. Getting started with MIPLearn
</a>
</li>
</ul>
<p class="caption">
<span class="caption-text">
Benchmarks
</span>
</p>
<ul class="nav bd-sidenav">
<li class="toctree-l1">
<a class="reference internal" href="../../benchmarks/preliminaries/">
1. Preliminaries
</a>
</li>
<li class="toctree-l1">
<a class="reference internal" href="../../benchmarks/stab/">
2. Maximum Weight Stable Set
</a>
</li>
<li class="toctree-l1">
<a class="reference internal" href="../../benchmarks/knapsack/">
3. Multidimensional Knapsack
</a>
</li>
<li class="toctree-l1">
<a class="reference internal" href="../../benchmarks/tsp/">
4. Traveling Salesman
</a>
</li>
</ul>
</div>
</nav> <!-- To handle the deprecated key -->
</div>
<main class="col py-md-3 pl-md-4 bd-content overflow-auto" role="main">
<div class="topbar container-xl fixed-top">
<div class="topbar-contents row">
<div class="col-12 col-md-3 bd-topbar-whitespace site-navigation show"></div>
<div class="col pl-md-4 topbar-main">
<button id="navbar-toggler" class="navbar-toggler ml-0" type="button" data-toggle="collapse"
data-toggle="tooltip" data-placement="bottom" data-target=".site-navigation" aria-controls="navbar-menu"
aria-expanded="true" aria-label="Toggle navigation" aria-controls="site-navigation"
title="Toggle navigation" data-toggle="tooltip" data-placement="left">
<i class="fas fa-bars"></i>
<i class="fas fa-arrow-left"></i>
<i class="fas fa-arrow-up"></i>
</button>
<div class="dropdown-buttons-trigger">
<button id="dropdown-buttons-trigger" class="btn btn-secondary topbarbtn" aria-label="Download this page"><i
class="fas fa-download"></i></button>
<div class="dropdown-buttons">
<!-- ipynb file if we had a myst markdown file -->
<!-- Download raw file -->
<a class="dropdown-buttons" href="../../_sources/internals/abstract-component.ipynb.txt"><button type="button"
class="btn btn-secondary topbarbtn" title="Download source file" data-toggle="tooltip"
data-placement="left">.ipynb</button></a>
<!-- Download PDF via print -->
<button type="button" id="download-print" class="btn btn-secondary topbarbtn" title="Print to PDF"
onClick="window.print()" data-toggle="tooltip" data-placement="left">.pdf</button>
</div>
</div>
<!-- Source interaction buttons -->
<!-- Full screen (wrap in <a> to have style consistency -->
<a class="full-screen-button"><button type="button" class="btn btn-secondary topbarbtn" data-toggle="tooltip"
data-placement="bottom" onclick="toggleFullScreen()" aria-label="Fullscreen mode"
title="Fullscreen mode"><i
class="fas fa-expand"></i></button></a>
<!-- Launch buttons -->
</div>
<!-- Table of contents -->
<div class="d-none d-md-block col-md-2 bd-toc show">
</div>
</div>
</div>
<div id="main-content" class="row">
<div class="col-12 col-md-9 pl-md-3 pr-md-0">
<div>
<div class="section" id="Abstract-component">
<h1>Abstract component<a class="headerlink" href="#Abstract-component" title="Permalink to this headline"></a></h1>
<p>TODO</p>
</div>
</div>
<div class='prev-next-bottom'>
</div>
</div>
</div>
<footer class="footer mt-5 mt-md-0">
<div class="container">
<p>
&copy; Copyright 2020-2021, UChicago Argonne, LLC.<br/>
</p>
</div>
</footer>
</main>
</div>
</div>
<script src="../../_static/js/index.1c5a1a01449ed65a7b51.js"></script>
</body>
</html>

@ -0,0 +1,29 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "780b4172",
"metadata": {},
"source": [
"# Training data collection\n",
"\n",
"TODO"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Julia 1.6.0",
"language": "julia",
"name": "julia-1.6"
},
"language_info": {
"file_extension": ".jl",
"mimetype": "application/julia",
"name": "julia",
"version": "1.6.0"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

@ -0,0 +1,210 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Training data collection &#8212; MIPLearn&lt;br/&gt;&lt;small&gt;0.2.0&lt;/small&gt;</title>
<link href="../../_static/css/theme.css" rel="stylesheet" />
<link href="../../_static/css/index.c5995385ac14fb8791e8eb36b4908be2.css" rel="stylesheet" />
<link rel="stylesheet"
href="../../_static/vendor/fontawesome/5.13.0/css/all.min.css">
<link rel="preload" as="font" type="font/woff2" crossorigin
href="../../_static/vendor/fontawesome/5.13.0/webfonts/fa-solid-900.woff2">
<link rel="preload" as="font" type="font/woff2" crossorigin
href="../../_static/vendor/fontawesome/5.13.0/webfonts/fa-brands-400.woff2">
<link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
<link rel="stylesheet" href="../../_static/sphinx-book-theme.acff12b8f9c144ce68a297486a2fa670.css" type="text/css" />
<link rel="stylesheet" type="text/css" href="../../_static/custom.css" />
<link rel="preload" as="script" href="../../_static/js/index.1c5a1a01449ed65a7b51.js">
<script id="documentation_options" data-url_root="../../" src="../../_static/documentation_options.js"></script>
<script src="../../_static/jquery.js"></script>
<script src="../../_static/underscore.js"></script>
<script src="../../_static/doctools.js"></script>
<script crossorigin="anonymous" integrity="sha256-Ae2Vz/4ePdIu6ZyI/5ZGsYnb+m0JlOmKPjt6XZ9JJkA=" src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.3.4/require.min.js"></script>
<script src="../../_static/sphinx-book-theme.12a9622fbb08dcb3a2a40b2c02b83a57.js"></script>
<script async="async" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.7/latest.js?config=TeX-AMS-MML_HTMLorMML"></script>
<script type="text/x-mathjax-config">MathJax.Hub.Config({"tex2jax": {"inlineMath": [["\\(", "\\)"]], "displayMath": [["\\[", "\\]"]], "processRefs": false, "processEnvironments": false}})</script>
<link rel="index" title="Index" href="../../genindex/" />
<link rel="search" title="Search" href="../../search/" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="docsearch:language" content="en" />
</head>
<body data-spy="scroll" data-target="#bd-toc-nav" data-offset="80">
<div class="container-fluid" id="banner"></div>
<div class="container-xl">
<div class="row">
<div class="col-12 col-md-3 bd-sidebar site-navigation show" id="site-navigation">
<div class="navbar-brand-box">
<a class="navbar-brand text-wrap" href="../../">
<h1 class="site-logo" id="site-title">MIPLearn<br/><small>0.2.0</small></h1>
</a>
</div><form class="bd-search d-flex align-items-center" action="../../search/" method="get">
<i class="icon fas fa-search"></i>
<input type="search" class="form-control" name="q" id="search-input" placeholder="Search the docs ..." aria-label="Search the docs ..." autocomplete="off" >
</form><nav class="bd-links" id="bd-docs-nav" aria-label="Main navigation">
<div class="bd-toc-item active">
<p class="caption">
<span class="caption-text">
Julia Tutorials
</span>
</p>
<ul class="nav bd-sidenav">
<li class="toctree-l1">
<a class="reference internal" href="../../jump-tutorials/getting-started/">
1. Getting started with MIPLearn
</a>
</li>
</ul>
<p class="caption">
<span class="caption-text">
Benchmarks
</span>
</p>
<ul class="nav bd-sidenav">
<li class="toctree-l1">
<a class="reference internal" href="../../benchmarks/preliminaries/">
1. Preliminaries
</a>
</li>
<li class="toctree-l1">
<a class="reference internal" href="../../benchmarks/stab/">
2. Maximum Weight Stable Set
</a>
</li>
<li class="toctree-l1">
<a class="reference internal" href="../../benchmarks/knapsack/">
3. Multidimensional Knapsack
</a>
</li>
<li class="toctree-l1">
<a class="reference internal" href="../../benchmarks/tsp/">
4. Traveling Salesman
</a>
</li>
</ul>
</div>
</nav> <!-- To handle the deprecated key -->
</div>
<main class="col py-md-3 pl-md-4 bd-content overflow-auto" role="main">
<div class="topbar container-xl fixed-top">
<div class="topbar-contents row">
<div class="col-12 col-md-3 bd-topbar-whitespace site-navigation show"></div>
<div class="col pl-md-4 topbar-main">
<button id="navbar-toggler" class="navbar-toggler ml-0" type="button" data-toggle="collapse"
data-toggle="tooltip" data-placement="bottom" data-target=".site-navigation" aria-controls="navbar-menu"
aria-expanded="true" aria-label="Toggle navigation" aria-controls="site-navigation"
title="Toggle navigation" data-toggle="tooltip" data-placement="left">
<i class="fas fa-bars"></i>
<i class="fas fa-arrow-left"></i>
<i class="fas fa-arrow-up"></i>
</button>
<div class="dropdown-buttons-trigger">
<button id="dropdown-buttons-trigger" class="btn btn-secondary topbarbtn" aria-label="Download this page"><i
class="fas fa-download"></i></button>
<div class="dropdown-buttons">
<!-- ipynb file if we had a myst markdown file -->
<!-- Download raw file -->
<a class="dropdown-buttons" href="../../_sources/internals/data-collection.ipynb.txt"><button type="button"
class="btn btn-secondary topbarbtn" title="Download source file" data-toggle="tooltip"
data-placement="left">.ipynb</button></a>
<!-- Download PDF via print -->
<button type="button" id="download-print" class="btn btn-secondary topbarbtn" title="Print to PDF"
onClick="window.print()" data-toggle="tooltip" data-placement="left">.pdf</button>
</div>
</div>
<!-- Source interaction buttons -->
<!-- Full screen (wrap in <a> to have style consistency -->
<a class="full-screen-button"><button type="button" class="btn btn-secondary topbarbtn" data-toggle="tooltip"
data-placement="bottom" onclick="toggleFullScreen()" aria-label="Fullscreen mode"
title="Fullscreen mode"><i
class="fas fa-expand"></i></button></a>
<!-- Launch buttons -->
</div>
<!-- Table of contents -->
<div class="d-none d-md-block col-md-2 bd-toc show">
</div>
</div>
</div>
<div id="main-content" class="row">
<div class="col-12 col-md-9 pl-md-3 pr-md-0">
<div>
<div class="section" id="Training-data-collection">
<h1>Training data collection<a class="headerlink" href="#Training-data-collection" title="Permalink to this headline"></a></h1>
<p>TODO</p>
</div>
</div>
<div class='prev-next-bottom'>
</div>
</div>
</div>
<footer class="footer mt-5 mt-md-0">
<div class="container">
<p>
&copy; Copyright 2020-2021, UChicago Argonne, LLC.<br/>
</p>
</div>
</footer>
</main>
</div>
</div>
<script src="../../_static/js/index.1c5a1a01449ed65a7b51.js"></script>
</body>
</html>

@ -0,0 +1,29 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "5e3dd4c0",
"metadata": {},
"source": [
"# Dynamic lazy constraints & user cuts\n",
"\n",
"TODO"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Julia 1.6.0",
"language": "julia",
"name": "julia-1.6"
},
"language_info": {
"file_extension": ".jl",
"mimetype": "application/julia",
"name": "julia",
"version": "1.6.0"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

@ -0,0 +1,210 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Dynamic lazy constraints &amp; user cuts &#8212; MIPLearn&lt;br/&gt;&lt;small&gt;0.2.0&lt;/small&gt;</title>
<link href="../../_static/css/theme.css" rel="stylesheet" />
<link href="../../_static/css/index.c5995385ac14fb8791e8eb36b4908be2.css" rel="stylesheet" />
<link rel="stylesheet"
href="../../_static/vendor/fontawesome/5.13.0/css/all.min.css">
<link rel="preload" as="font" type="font/woff2" crossorigin
href="../../_static/vendor/fontawesome/5.13.0/webfonts/fa-solid-900.woff2">
<link rel="preload" as="font" type="font/woff2" crossorigin
href="../../_static/vendor/fontawesome/5.13.0/webfonts/fa-brands-400.woff2">
<link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
<link rel="stylesheet" href="../../_static/sphinx-book-theme.acff12b8f9c144ce68a297486a2fa670.css" type="text/css" />
<link rel="stylesheet" type="text/css" href="../../_static/custom.css" />
<link rel="preload" as="script" href="../../_static/js/index.1c5a1a01449ed65a7b51.js">
<script id="documentation_options" data-url_root="../../" src="../../_static/documentation_options.js"></script>
<script src="../../_static/jquery.js"></script>
<script src="../../_static/underscore.js"></script>
<script src="../../_static/doctools.js"></script>
<script crossorigin="anonymous" integrity="sha256-Ae2Vz/4ePdIu6ZyI/5ZGsYnb+m0JlOmKPjt6XZ9JJkA=" src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.3.4/require.min.js"></script>
<script src="../../_static/sphinx-book-theme.12a9622fbb08dcb3a2a40b2c02b83a57.js"></script>
<script async="async" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.7/latest.js?config=TeX-AMS-MML_HTMLorMML"></script>
<script type="text/x-mathjax-config">MathJax.Hub.Config({"tex2jax": {"inlineMath": [["\\(", "\\)"]], "displayMath": [["\\[", "\\]"]], "processRefs": false, "processEnvironments": false}})</script>
<link rel="index" title="Index" href="../../genindex/" />
<link rel="search" title="Search" href="../../search/" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="docsearch:language" content="en" />
</head>
<body data-spy="scroll" data-target="#bd-toc-nav" data-offset="80">
<div class="container-fluid" id="banner"></div>
<div class="container-xl">
<div class="row">
<div class="col-12 col-md-3 bd-sidebar site-navigation show" id="site-navigation">
<div class="navbar-brand-box">
<a class="navbar-brand text-wrap" href="../../">
<h1 class="site-logo" id="site-title">MIPLearn<br/><small>0.2.0</small></h1>
</a>
</div><form class="bd-search d-flex align-items-center" action="../../search/" method="get">
<i class="icon fas fa-search"></i>
<input type="search" class="form-control" name="q" id="search-input" placeholder="Search the docs ..." aria-label="Search the docs ..." autocomplete="off" >
</form><nav class="bd-links" id="bd-docs-nav" aria-label="Main navigation">
<div class="bd-toc-item active">
<p class="caption">
<span class="caption-text">
Julia Tutorials
</span>
</p>
<ul class="nav bd-sidenav">
<li class="toctree-l1">
<a class="reference internal" href="../../jump-tutorials/getting-started/">
1. Getting started with MIPLearn
</a>
</li>
</ul>
<p class="caption">
<span class="caption-text">
Benchmarks
</span>
</p>
<ul class="nav bd-sidenav">
<li class="toctree-l1">
<a class="reference internal" href="../../benchmarks/preliminaries/">
1. Preliminaries
</a>
</li>
<li class="toctree-l1">
<a class="reference internal" href="../../benchmarks/stab/">
2. Maximum Weight Stable Set
</a>
</li>
<li class="toctree-l1">
<a class="reference internal" href="../../benchmarks/knapsack/">
3. Multidimensional Knapsack
</a>
</li>
<li class="toctree-l1">
<a class="reference internal" href="../../benchmarks/tsp/">
4. Traveling Salesman
</a>
</li>
</ul>
</div>
</nav> <!-- To handle the deprecated key -->
</div>
<main class="col py-md-3 pl-md-4 bd-content overflow-auto" role="main">
<div class="topbar container-xl fixed-top">
<div class="topbar-contents row">
<div class="col-12 col-md-3 bd-topbar-whitespace site-navigation show"></div>
<div class="col pl-md-4 topbar-main">
<button id="navbar-toggler" class="navbar-toggler ml-0" type="button" data-toggle="collapse"
data-toggle="tooltip" data-placement="bottom" data-target=".site-navigation" aria-controls="navbar-menu"
aria-expanded="true" aria-label="Toggle navigation" aria-controls="site-navigation"
title="Toggle navigation" data-toggle="tooltip" data-placement="left">
<i class="fas fa-bars"></i>
<i class="fas fa-arrow-left"></i>
<i class="fas fa-arrow-up"></i>
</button>
<div class="dropdown-buttons-trigger">
<button id="dropdown-buttons-trigger" class="btn btn-secondary topbarbtn" aria-label="Download this page"><i
class="fas fa-download"></i></button>
<div class="dropdown-buttons">
<!-- ipynb file if we had a myst markdown file -->
<!-- Download raw file -->
<a class="dropdown-buttons" href="../../_sources/internals/dynamic-lazy.ipynb.txt"><button type="button"
class="btn btn-secondary topbarbtn" title="Download source file" data-toggle="tooltip"
data-placement="left">.ipynb</button></a>
<!-- Download PDF via print -->
<button type="button" id="download-print" class="btn btn-secondary topbarbtn" title="Print to PDF"
onClick="window.print()" data-toggle="tooltip" data-placement="left">.pdf</button>
</div>
</div>
<!-- Source interaction buttons -->
<!-- Full screen (wrap in <a> to have style consistency -->
<a class="full-screen-button"><button type="button" class="btn btn-secondary topbarbtn" data-toggle="tooltip"
data-placement="bottom" onclick="toggleFullScreen()" aria-label="Fullscreen mode"
title="Fullscreen mode"><i
class="fas fa-expand"></i></button></a>
<!-- Launch buttons -->
</div>
<!-- Table of contents -->
<div class="d-none d-md-block col-md-2 bd-toc show">
</div>
</div>
</div>
<div id="main-content" class="row">
<div class="col-12 col-md-9 pl-md-3 pr-md-0">
<div>
<div class="section" id="Dynamic-lazy-constraints-&amp;-user-cuts">
<h1>Dynamic lazy constraints &amp; user cuts<a class="headerlink" href="#Dynamic-lazy-constraints-&-user-cuts" title="Permalink to this headline"></a></h1>
<p>TODO</p>
</div>
</div>
<div class='prev-next-bottom'>
</div>
</div>
</div>
<footer class="footer mt-5 mt-md-0">
<div class="container">
<p>
&copy; Copyright 2020-2021, UChicago Argonne, LLC.<br/>
</p>
</div>
</footer>
</main>
</div>
</div>
<script src="../../_static/js/index.1c5a1a01449ed65a7b51.js"></script>
</body>
</html>

@ -0,0 +1,29 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "c6d0d8dc",
"metadata": {},
"source": [
"# Primal solutions\n",
"\n",
"TODO"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Julia 1.6.0",
"language": "julia",
"name": "julia-1.6"
},
"language_info": {
"file_extension": ".jl",
"mimetype": "application/julia",
"name": "julia",
"version": "1.6.0"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

@ -0,0 +1,210 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Primal solutions &#8212; MIPLearn&lt;br/&gt;&lt;small&gt;0.2.0&lt;/small&gt;</title>
<link href="../../_static/css/theme.css" rel="stylesheet" />
<link href="../../_static/css/index.c5995385ac14fb8791e8eb36b4908be2.css" rel="stylesheet" />
<link rel="stylesheet"
href="../../_static/vendor/fontawesome/5.13.0/css/all.min.css">
<link rel="preload" as="font" type="font/woff2" crossorigin
href="../../_static/vendor/fontawesome/5.13.0/webfonts/fa-solid-900.woff2">
<link rel="preload" as="font" type="font/woff2" crossorigin
href="../../_static/vendor/fontawesome/5.13.0/webfonts/fa-brands-400.woff2">
<link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
<link rel="stylesheet" href="../../_static/sphinx-book-theme.acff12b8f9c144ce68a297486a2fa670.css" type="text/css" />
<link rel="stylesheet" type="text/css" href="../../_static/custom.css" />
<link rel="preload" as="script" href="../../_static/js/index.1c5a1a01449ed65a7b51.js">
<script id="documentation_options" data-url_root="../../" src="../../_static/documentation_options.js"></script>
<script src="../../_static/jquery.js"></script>
<script src="../../_static/underscore.js"></script>
<script src="../../_static/doctools.js"></script>
<script crossorigin="anonymous" integrity="sha256-Ae2Vz/4ePdIu6ZyI/5ZGsYnb+m0JlOmKPjt6XZ9JJkA=" src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.3.4/require.min.js"></script>
<script src="../../_static/sphinx-book-theme.12a9622fbb08dcb3a2a40b2c02b83a57.js"></script>
<script async="async" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.7/latest.js?config=TeX-AMS-MML_HTMLorMML"></script>
<script type="text/x-mathjax-config">MathJax.Hub.Config({"tex2jax": {"inlineMath": [["\\(", "\\)"]], "displayMath": [["\\[", "\\]"]], "processRefs": false, "processEnvironments": false}})</script>
<link rel="index" title="Index" href="../../genindex/" />
<link rel="search" title="Search" href="../../search/" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="docsearch:language" content="en" />
</head>
<body data-spy="scroll" data-target="#bd-toc-nav" data-offset="80">
<div class="container-fluid" id="banner"></div>
<div class="container-xl">
<div class="row">
<div class="col-12 col-md-3 bd-sidebar site-navigation show" id="site-navigation">
<div class="navbar-brand-box">
<a class="navbar-brand text-wrap" href="../../">
<h1 class="site-logo" id="site-title">MIPLearn<br/><small>0.2.0</small></h1>
</a>
</div><form class="bd-search d-flex align-items-center" action="../../search/" method="get">
<i class="icon fas fa-search"></i>
<input type="search" class="form-control" name="q" id="search-input" placeholder="Search the docs ..." aria-label="Search the docs ..." autocomplete="off" >
</form><nav class="bd-links" id="bd-docs-nav" aria-label="Main navigation">
<div class="bd-toc-item active">
<p class="caption">
<span class="caption-text">
Julia Tutorials
</span>
</p>
<ul class="nav bd-sidenav">
<li class="toctree-l1">
<a class="reference internal" href="../../jump-tutorials/getting-started/">
1. Getting started with MIPLearn
</a>
</li>
</ul>
<p class="caption">
<span class="caption-text">
Benchmarks
</span>
</p>
<ul class="nav bd-sidenav">
<li class="toctree-l1">
<a class="reference internal" href="../../benchmarks/preliminaries/">
1. Preliminaries
</a>
</li>
<li class="toctree-l1">
<a class="reference internal" href="../../benchmarks/stab/">
2. Maximum Weight Stable Set
</a>
</li>
<li class="toctree-l1">
<a class="reference internal" href="../../benchmarks/knapsack/">
3. Multidimensional Knapsack
</a>
</li>
<li class="toctree-l1">
<a class="reference internal" href="../../benchmarks/tsp/">
4. Traveling Salesman
</a>
</li>
</ul>
</div>
</nav> <!-- To handle the deprecated key -->
</div>
<main class="col py-md-3 pl-md-4 bd-content overflow-auto" role="main">
<div class="topbar container-xl fixed-top">
<div class="topbar-contents row">
<div class="col-12 col-md-3 bd-topbar-whitespace site-navigation show"></div>
<div class="col pl-md-4 topbar-main">
<button id="navbar-toggler" class="navbar-toggler ml-0" type="button" data-toggle="collapse"
data-toggle="tooltip" data-placement="bottom" data-target=".site-navigation" aria-controls="navbar-menu"
aria-expanded="true" aria-label="Toggle navigation" aria-controls="site-navigation"
title="Toggle navigation" data-toggle="tooltip" data-placement="left">
<i class="fas fa-bars"></i>
<i class="fas fa-arrow-left"></i>
<i class="fas fa-arrow-up"></i>
</button>
<div class="dropdown-buttons-trigger">
<button id="dropdown-buttons-trigger" class="btn btn-secondary topbarbtn" aria-label="Download this page"><i
class="fas fa-download"></i></button>
<div class="dropdown-buttons">
<!-- ipynb file if we had a myst markdown file -->
<!-- Download raw file -->
<a class="dropdown-buttons" href="../../_sources/internals/primal.ipynb.txt"><button type="button"
class="btn btn-secondary topbarbtn" title="Download source file" data-toggle="tooltip"
data-placement="left">.ipynb</button></a>
<!-- Download PDF via print -->
<button type="button" id="download-print" class="btn btn-secondary topbarbtn" title="Print to PDF"
onClick="window.print()" data-toggle="tooltip" data-placement="left">.pdf</button>
</div>
</div>
<!-- Source interaction buttons -->
<!-- Full screen (wrap in <a> to have style consistency -->
<a class="full-screen-button"><button type="button" class="btn btn-secondary topbarbtn" data-toggle="tooltip"
data-placement="bottom" onclick="toggleFullScreen()" aria-label="Fullscreen mode"
title="Fullscreen mode"><i
class="fas fa-expand"></i></button></a>
<!-- Launch buttons -->
</div>
<!-- Table of contents -->
<div class="d-none d-md-block col-md-2 bd-toc show">
</div>
</div>
</div>
<div id="main-content" class="row">
<div class="col-12 col-md-9 pl-md-3 pr-md-0">
<div>
<div class="section" id="Primal-solutions">
<h1>Primal solutions<a class="headerlink" href="#Primal-solutions" title="Permalink to this headline"></a></h1>
<p>TODO</p>
</div>
</div>
<div class='prev-next-bottom'>
</div>
</div>
</div>
<footer class="footer mt-5 mt-md-0">
<div class="container">
<p>
&copy; Copyright 2020-2021, UChicago Argonne, LLC.<br/>
</p>
</div>
</footer>
</main>
</div>
</div>
<script src="../../_static/js/index.1c5a1a01449ed65a7b51.js"></script>
</body>
</html>

@ -0,0 +1,29 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "ac509ea5",
"metadata": {},
"source": [
"# Solver interfaces\n",
"\n",
"TODO"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Julia 1.6.0",
"language": "julia",
"name": "julia-1.6"
},
"language_info": {
"file_extension": ".jl",
"mimetype": "application/julia",
"name": "julia",
"version": "1.6.0"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

@ -0,0 +1,210 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Solver interfaces &#8212; MIPLearn&lt;br/&gt;&lt;small&gt;0.2.0&lt;/small&gt;</title>
<link href="../../_static/css/theme.css" rel="stylesheet" />
<link href="../../_static/css/index.c5995385ac14fb8791e8eb36b4908be2.css" rel="stylesheet" />
<link rel="stylesheet"
href="../../_static/vendor/fontawesome/5.13.0/css/all.min.css">
<link rel="preload" as="font" type="font/woff2" crossorigin
href="../../_static/vendor/fontawesome/5.13.0/webfonts/fa-solid-900.woff2">
<link rel="preload" as="font" type="font/woff2" crossorigin
href="../../_static/vendor/fontawesome/5.13.0/webfonts/fa-brands-400.woff2">
<link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
<link rel="stylesheet" href="../../_static/sphinx-book-theme.acff12b8f9c144ce68a297486a2fa670.css" type="text/css" />
<link rel="stylesheet" type="text/css" href="../../_static/custom.css" />
<link rel="preload" as="script" href="../../_static/js/index.1c5a1a01449ed65a7b51.js">
<script id="documentation_options" data-url_root="../../" src="../../_static/documentation_options.js"></script>
<script src="../../_static/jquery.js"></script>
<script src="../../_static/underscore.js"></script>
<script src="../../_static/doctools.js"></script>
<script crossorigin="anonymous" integrity="sha256-Ae2Vz/4ePdIu6ZyI/5ZGsYnb+m0JlOmKPjt6XZ9JJkA=" src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.3.4/require.min.js"></script>
<script src="../../_static/sphinx-book-theme.12a9622fbb08dcb3a2a40b2c02b83a57.js"></script>
<script async="async" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.7/latest.js?config=TeX-AMS-MML_HTMLorMML"></script>
<script type="text/x-mathjax-config">MathJax.Hub.Config({"tex2jax": {"inlineMath": [["\\(", "\\)"]], "displayMath": [["\\[", "\\]"]], "processRefs": false, "processEnvironments": false}})</script>
<link rel="index" title="Index" href="../../genindex/" />
<link rel="search" title="Search" href="../../search/" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="docsearch:language" content="en" />
</head>
<body data-spy="scroll" data-target="#bd-toc-nav" data-offset="80">
<div class="container-fluid" id="banner"></div>
<div class="container-xl">
<div class="row">
<div class="col-12 col-md-3 bd-sidebar site-navigation show" id="site-navigation">
<div class="navbar-brand-box">
<a class="navbar-brand text-wrap" href="../../">
<h1 class="site-logo" id="site-title">MIPLearn<br/><small>0.2.0</small></h1>
</a>
</div><form class="bd-search d-flex align-items-center" action="../../search/" method="get">
<i class="icon fas fa-search"></i>
<input type="search" class="form-control" name="q" id="search-input" placeholder="Search the docs ..." aria-label="Search the docs ..." autocomplete="off" >
</form><nav class="bd-links" id="bd-docs-nav" aria-label="Main navigation">
<div class="bd-toc-item active">
<p class="caption">
<span class="caption-text">
Julia Tutorials
</span>
</p>
<ul class="nav bd-sidenav">
<li class="toctree-l1">
<a class="reference internal" href="../../jump-tutorials/getting-started/">
1. Getting started with MIPLearn
</a>
</li>
</ul>
<p class="caption">
<span class="caption-text">
Benchmarks
</span>
</p>
<ul class="nav bd-sidenav">
<li class="toctree-l1">
<a class="reference internal" href="../../benchmarks/preliminaries/">
1. Preliminaries
</a>
</li>
<li class="toctree-l1">
<a class="reference internal" href="../../benchmarks/stab/">
2. Maximum Weight Stable Set
</a>
</li>
<li class="toctree-l1">
<a class="reference internal" href="../../benchmarks/knapsack/">
3. Multidimensional Knapsack
</a>
</li>
<li class="toctree-l1">
<a class="reference internal" href="../../benchmarks/tsp/">
4. Traveling Salesman
</a>
</li>
</ul>
</div>
</nav> <!-- To handle the deprecated key -->
</div>
<main class="col py-md-3 pl-md-4 bd-content overflow-auto" role="main">
<div class="topbar container-xl fixed-top">
<div class="topbar-contents row">
<div class="col-12 col-md-3 bd-topbar-whitespace site-navigation show"></div>
<div class="col pl-md-4 topbar-main">
<button id="navbar-toggler" class="navbar-toggler ml-0" type="button" data-toggle="collapse"
data-toggle="tooltip" data-placement="bottom" data-target=".site-navigation" aria-controls="navbar-menu"
aria-expanded="true" aria-label="Toggle navigation" aria-controls="site-navigation"
title="Toggle navigation" data-toggle="tooltip" data-placement="left">
<i class="fas fa-bars"></i>
<i class="fas fa-arrow-left"></i>
<i class="fas fa-arrow-up"></i>
</button>
<div class="dropdown-buttons-trigger">
<button id="dropdown-buttons-trigger" class="btn btn-secondary topbarbtn" aria-label="Download this page"><i
class="fas fa-download"></i></button>
<div class="dropdown-buttons">
<!-- ipynb file if we had a myst markdown file -->
<!-- Download raw file -->
<a class="dropdown-buttons" href="../../_sources/internals/solver-interfaces.ipynb.txt"><button type="button"
class="btn btn-secondary topbarbtn" title="Download source file" data-toggle="tooltip"
data-placement="left">.ipynb</button></a>
<!-- Download PDF via print -->
<button type="button" id="download-print" class="btn btn-secondary topbarbtn" title="Print to PDF"
onClick="window.print()" data-toggle="tooltip" data-placement="left">.pdf</button>
</div>
</div>
<!-- Source interaction buttons -->
<!-- Full screen (wrap in <a> to have style consistency -->
<a class="full-screen-button"><button type="button" class="btn btn-secondary topbarbtn" data-toggle="tooltip"
data-placement="bottom" onclick="toggleFullScreen()" aria-label="Fullscreen mode"
title="Fullscreen mode"><i
class="fas fa-expand"></i></button></a>
<!-- Launch buttons -->
</div>
<!-- Table of contents -->
<div class="d-none d-md-block col-md-2 bd-toc show">
</div>
</div>
</div>
<div id="main-content" class="row">
<div class="col-12 col-md-9 pl-md-3 pr-md-0">
<div>
<div class="section" id="Solver-interfaces">
<h1>Solver interfaces<a class="headerlink" href="#Solver-interfaces" title="Permalink to this headline"></a></h1>
<p>TODO</p>
</div>
</div>
<div class='prev-next-bottom'>
</div>
</div>
</div>
<footer class="footer mt-5 mt-md-0">
<div class="container">
<p>
&copy; Copyright 2020-2021, UChicago Argonne, LLC.<br/>
</p>
</div>
</footer>
</main>
</div>
</div>
<script src="../../_static/js/index.1c5a1a01449ed65a7b51.js"></script>
</body>
</html>

@ -0,0 +1,29 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "ae350662",
"metadata": {},
"source": [
"# Static lazy constraints\n",
"\n",
"TODO"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Julia 1.6.0",
"language": "julia",
"name": "julia-1.6"
},
"language_info": {
"file_extension": ".jl",
"mimetype": "application/julia",
"name": "julia",
"version": "1.6.0"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

@ -0,0 +1,210 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Static lazy constraints &#8212; MIPLearn&lt;br/&gt;&lt;small&gt;0.2.0&lt;/small&gt;</title>
<link href="../../_static/css/theme.css" rel="stylesheet" />
<link href="../../_static/css/index.c5995385ac14fb8791e8eb36b4908be2.css" rel="stylesheet" />
<link rel="stylesheet"
href="../../_static/vendor/fontawesome/5.13.0/css/all.min.css">
<link rel="preload" as="font" type="font/woff2" crossorigin
href="../../_static/vendor/fontawesome/5.13.0/webfonts/fa-solid-900.woff2">
<link rel="preload" as="font" type="font/woff2" crossorigin
href="../../_static/vendor/fontawesome/5.13.0/webfonts/fa-brands-400.woff2">
<link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
<link rel="stylesheet" href="../../_static/sphinx-book-theme.acff12b8f9c144ce68a297486a2fa670.css" type="text/css" />
<link rel="stylesheet" type="text/css" href="../../_static/custom.css" />
<link rel="preload" as="script" href="../../_static/js/index.1c5a1a01449ed65a7b51.js">
<script id="documentation_options" data-url_root="../../" src="../../_static/documentation_options.js"></script>
<script src="../../_static/jquery.js"></script>
<script src="../../_static/underscore.js"></script>
<script src="../../_static/doctools.js"></script>
<script crossorigin="anonymous" integrity="sha256-Ae2Vz/4ePdIu6ZyI/5ZGsYnb+m0JlOmKPjt6XZ9JJkA=" src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.3.4/require.min.js"></script>
<script src="../../_static/sphinx-book-theme.12a9622fbb08dcb3a2a40b2c02b83a57.js"></script>
<script async="async" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.7/latest.js?config=TeX-AMS-MML_HTMLorMML"></script>
<script type="text/x-mathjax-config">MathJax.Hub.Config({"tex2jax": {"inlineMath": [["\\(", "\\)"]], "displayMath": [["\\[", "\\]"]], "processRefs": false, "processEnvironments": false}})</script>
<link rel="index" title="Index" href="../../genindex/" />
<link rel="search" title="Search" href="../../search/" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="docsearch:language" content="en" />
</head>
<body data-spy="scroll" data-target="#bd-toc-nav" data-offset="80">
<div class="container-fluid" id="banner"></div>
<div class="container-xl">
<div class="row">
<div class="col-12 col-md-3 bd-sidebar site-navigation show" id="site-navigation">
<div class="navbar-brand-box">
<a class="navbar-brand text-wrap" href="../../">
<h1 class="site-logo" id="site-title">MIPLearn<br/><small>0.2.0</small></h1>
</a>
</div><form class="bd-search d-flex align-items-center" action="../../search/" method="get">
<i class="icon fas fa-search"></i>
<input type="search" class="form-control" name="q" id="search-input" placeholder="Search the docs ..." aria-label="Search the docs ..." autocomplete="off" >
</form><nav class="bd-links" id="bd-docs-nav" aria-label="Main navigation">
<div class="bd-toc-item active">
<p class="caption">
<span class="caption-text">
Julia Tutorials
</span>
</p>
<ul class="nav bd-sidenav">
<li class="toctree-l1">
<a class="reference internal" href="../../jump-tutorials/getting-started/">
1. Getting started with MIPLearn
</a>
</li>
</ul>
<p class="caption">
<span class="caption-text">
Benchmarks
</span>
</p>
<ul class="nav bd-sidenav">
<li class="toctree-l1">
<a class="reference internal" href="../../benchmarks/preliminaries/">
1. Preliminaries
</a>
</li>
<li class="toctree-l1">
<a class="reference internal" href="../../benchmarks/stab/">
2. Maximum Weight Stable Set
</a>
</li>
<li class="toctree-l1">
<a class="reference internal" href="../../benchmarks/knapsack/">
3. Multidimensional Knapsack
</a>
</li>
<li class="toctree-l1">
<a class="reference internal" href="../../benchmarks/tsp/">
4. Traveling Salesman
</a>
</li>
</ul>
</div>
</nav> <!-- To handle the deprecated key -->
</div>
<main class="col py-md-3 pl-md-4 bd-content overflow-auto" role="main">
<div class="topbar container-xl fixed-top">
<div class="topbar-contents row">
<div class="col-12 col-md-3 bd-topbar-whitespace site-navigation show"></div>
<div class="col pl-md-4 topbar-main">
<button id="navbar-toggler" class="navbar-toggler ml-0" type="button" data-toggle="collapse"
data-toggle="tooltip" data-placement="bottom" data-target=".site-navigation" aria-controls="navbar-menu"
aria-expanded="true" aria-label="Toggle navigation" aria-controls="site-navigation"
title="Toggle navigation" data-toggle="tooltip" data-placement="left">
<i class="fas fa-bars"></i>
<i class="fas fa-arrow-left"></i>
<i class="fas fa-arrow-up"></i>
</button>
<div class="dropdown-buttons-trigger">
<button id="dropdown-buttons-trigger" class="btn btn-secondary topbarbtn" aria-label="Download this page"><i
class="fas fa-download"></i></button>
<div class="dropdown-buttons">
<!-- ipynb file if we had a myst markdown file -->
<!-- Download raw file -->
<a class="dropdown-buttons" href="../../_sources/internals/static-lazy.ipynb.txt"><button type="button"
class="btn btn-secondary topbarbtn" title="Download source file" data-toggle="tooltip"
data-placement="left">.ipynb</button></a>
<!-- Download PDF via print -->
<button type="button" id="download-print" class="btn btn-secondary topbarbtn" title="Print to PDF"
onClick="window.print()" data-toggle="tooltip" data-placement="left">.pdf</button>
</div>
</div>
<!-- Source interaction buttons -->
<!-- Full screen (wrap in <a> to have style consistency -->
<a class="full-screen-button"><button type="button" class="btn btn-secondary topbarbtn" data-toggle="tooltip"
data-placement="bottom" onclick="toggleFullScreen()" aria-label="Fullscreen mode"
title="Fullscreen mode"><i
class="fas fa-expand"></i></button></a>
<!-- Launch buttons -->
</div>
<!-- Table of contents -->
<div class="d-none d-md-block col-md-2 bd-toc show">
</div>
</div>
</div>
<div id="main-content" class="row">
<div class="col-12 col-md-9 pl-md-3 pr-md-0">
<div>
<div class="section" id="Static-lazy-constraints">
<h1>Static lazy constraints<a class="headerlink" href="#Static-lazy-constraints" title="Permalink to this headline"></a></h1>
<p>TODO</p>
</div>
</div>
<div class='prev-next-bottom'>
</div>
</div>
</div>
<footer class="footer mt-5 mt-md-0">
<div class="container">
<p>
&copy; Copyright 2020-2021, UChicago Argonne, LLC.<br/>
</p>
</div>
</footer>
</main>
</div>
</div>
<script src="../../_static/js/index.1c5a1a01449ed65a7b51.js"></script>
</body>
</html>

@ -0,0 +1,29 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "ea2dc06a",
"metadata": {},
"source": [
"# Customizing the ML models\n",
"\n",
"TODO"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Julia 1.6.0",
"language": "julia",
"name": "julia-1.6"
},
"language_info": {
"file_extension": ".jl",
"mimetype": "application/julia",
"name": "julia",
"version": "1.6.0"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

@ -0,0 +1,210 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Customizing the ML models &#8212; MIPLearn&lt;br/&gt;&lt;small&gt;0.2.0&lt;/small&gt;</title>
<link href="../../_static/css/theme.css" rel="stylesheet" />
<link href="../../_static/css/index.c5995385ac14fb8791e8eb36b4908be2.css" rel="stylesheet" />
<link rel="stylesheet"
href="../../_static/vendor/fontawesome/5.13.0/css/all.min.css">
<link rel="preload" as="font" type="font/woff2" crossorigin
href="../../_static/vendor/fontawesome/5.13.0/webfonts/fa-solid-900.woff2">
<link rel="preload" as="font" type="font/woff2" crossorigin
href="../../_static/vendor/fontawesome/5.13.0/webfonts/fa-brands-400.woff2">
<link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
<link rel="stylesheet" href="../../_static/sphinx-book-theme.acff12b8f9c144ce68a297486a2fa670.css" type="text/css" />
<link rel="stylesheet" type="text/css" href="../../_static/custom.css" />
<link rel="preload" as="script" href="../../_static/js/index.1c5a1a01449ed65a7b51.js">
<script id="documentation_options" data-url_root="../../" src="../../_static/documentation_options.js"></script>
<script src="../../_static/jquery.js"></script>
<script src="../../_static/underscore.js"></script>
<script src="../../_static/doctools.js"></script>
<script crossorigin="anonymous" integrity="sha256-Ae2Vz/4ePdIu6ZyI/5ZGsYnb+m0JlOmKPjt6XZ9JJkA=" src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.3.4/require.min.js"></script>
<script src="../../_static/sphinx-book-theme.12a9622fbb08dcb3a2a40b2c02b83a57.js"></script>
<script async="async" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.7/latest.js?config=TeX-AMS-MML_HTMLorMML"></script>
<script type="text/x-mathjax-config">MathJax.Hub.Config({"tex2jax": {"inlineMath": [["\\(", "\\)"]], "displayMath": [["\\[", "\\]"]], "processRefs": false, "processEnvironments": false}})</script>
<link rel="index" title="Index" href="../../genindex/" />
<link rel="search" title="Search" href="../../search/" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="docsearch:language" content="en" />
</head>
<body data-spy="scroll" data-target="#bd-toc-nav" data-offset="80">
<div class="container-fluid" id="banner"></div>
<div class="container-xl">
<div class="row">
<div class="col-12 col-md-3 bd-sidebar site-navigation show" id="site-navigation">
<div class="navbar-brand-box">
<a class="navbar-brand text-wrap" href="../../">
<h1 class="site-logo" id="site-title">MIPLearn<br/><small>0.2.0</small></h1>
</a>
</div><form class="bd-search d-flex align-items-center" action="../../search/" method="get">
<i class="icon fas fa-search"></i>
<input type="search" class="form-control" name="q" id="search-input" placeholder="Search the docs ..." aria-label="Search the docs ..." autocomplete="off" >
</form><nav class="bd-links" id="bd-docs-nav" aria-label="Main navigation">
<div class="bd-toc-item active">
<p class="caption">
<span class="caption-text">
Julia Tutorials
</span>
</p>
<ul class="nav bd-sidenav">
<li class="toctree-l1">
<a class="reference internal" href="../getting-started/">
1. Getting started with MIPLearn
</a>
</li>
</ul>
<p class="caption">
<span class="caption-text">
Benchmarks
</span>
</p>
<ul class="nav bd-sidenav">
<li class="toctree-l1">
<a class="reference internal" href="../../benchmarks/preliminaries/">
1. Preliminaries
</a>
</li>
<li class="toctree-l1">
<a class="reference internal" href="../../benchmarks/stab/">
2. Maximum Weight Stable Set
</a>
</li>
<li class="toctree-l1">
<a class="reference internal" href="../../benchmarks/knapsack/">
3. Multidimensional Knapsack
</a>
</li>
<li class="toctree-l1">
<a class="reference internal" href="../../benchmarks/tsp/">
4. Traveling Salesman
</a>
</li>
</ul>
</div>
</nav> <!-- To handle the deprecated key -->
</div>
<main class="col py-md-3 pl-md-4 bd-content overflow-auto" role="main">
<div class="topbar container-xl fixed-top">
<div class="topbar-contents row">
<div class="col-12 col-md-3 bd-topbar-whitespace site-navigation show"></div>
<div class="col pl-md-4 topbar-main">
<button id="navbar-toggler" class="navbar-toggler ml-0" type="button" data-toggle="collapse"
data-toggle="tooltip" data-placement="bottom" data-target=".site-navigation" aria-controls="navbar-menu"
aria-expanded="true" aria-label="Toggle navigation" aria-controls="site-navigation"
title="Toggle navigation" data-toggle="tooltip" data-placement="left">
<i class="fas fa-bars"></i>
<i class="fas fa-arrow-left"></i>
<i class="fas fa-arrow-up"></i>
</button>
<div class="dropdown-buttons-trigger">
<button id="dropdown-buttons-trigger" class="btn btn-secondary topbarbtn" aria-label="Download this page"><i
class="fas fa-download"></i></button>
<div class="dropdown-buttons">
<!-- ipynb file if we had a myst markdown file -->
<!-- Download raw file -->
<a class="dropdown-buttons" href="../../_sources/jump-tutorials/customizing-ml.ipynb.txt"><button type="button"
class="btn btn-secondary topbarbtn" title="Download source file" data-toggle="tooltip"
data-placement="left">.ipynb</button></a>
<!-- Download PDF via print -->
<button type="button" id="download-print" class="btn btn-secondary topbarbtn" title="Print to PDF"
onClick="window.print()" data-toggle="tooltip" data-placement="left">.pdf</button>
</div>
</div>
<!-- Source interaction buttons -->
<!-- Full screen (wrap in <a> to have style consistency -->
<a class="full-screen-button"><button type="button" class="btn btn-secondary topbarbtn" data-toggle="tooltip"
data-placement="bottom" onclick="toggleFullScreen()" aria-label="Fullscreen mode"
title="Fullscreen mode"><i
class="fas fa-expand"></i></button></a>
<!-- Launch buttons -->
</div>
<!-- Table of contents -->
<div class="d-none d-md-block col-md-2 bd-toc show">
</div>
</div>
</div>
<div id="main-content" class="row">
<div class="col-12 col-md-9 pl-md-3 pr-md-0">
<div>
<div class="section" id="Customizing-the-ML-models">
<h1>Customizing the ML models<a class="headerlink" href="#Customizing-the-ML-models" title="Permalink to this headline"></a></h1>
<p>TODO</p>
</div>
</div>
<div class='prev-next-bottom'>
</div>
</div>
</div>
<footer class="footer mt-5 mt-md-0">
<div class="container">
<p>
&copy; Copyright 2020-2021, UChicago Argonne, LLC.<br/>
</p>
</div>
</footer>
</main>
</div>
</div>
<script src="../../_static/js/index.1c5a1a01449ed65a7b51.js"></script>
</body>
</html>

@ -0,0 +1,758 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "c5a596fb",
"metadata": {},
"source": [
"# Getting started with MIPLearn\n",
"\n",
"## Introduction\n",
"\n",
"**MIPLearn** is an open source framework that uses machine learning (ML) to accelerate the performance of both commercial and open source mixed-integer programming solvers (e.g. Gurobi, CPLEX, XPRESS, Cbc or SCIP). In this tutorial, we will:\n",
"\n",
"1. Install the Julia/JuMP version of MIPLearn\n",
"2. Model a simple optimization problem using JuMP\n",
"3. Generate training data and train the ML models\n",
"4. Use the ML models together with SCIP to solve new instances\n",
"\n",
"<div class=\"alert alert-info\">\n",
"Note\n",
" \n",
"We use SCIP in this tutorial because it is a fast and widely available noncommercial MIP solver. All the steps shown here also work for Gurobi, CPLEX and XPRESS, although the performance impact might be different.\n",
" \n",
"</div>\n",
"\n",
"<div class=\"alert alert-warning\">\n",
"Warning\n",
" \n",
"MIPLearn is still in early development stage. If run into any bugs or issues, please submit a bug report in our GitHub repository. Comments, suggestions and pull requests are also very welcome!\n",
" \n",
"</div>\n"
]
},
{
"cell_type": "markdown",
"id": "1f59417f",
"metadata": {},
"source": [
"## Installing MIPLearn\n",
"\n",
"MIPLearn is available in two versions:\n",
"\n",
"- Python version, compatible with the Pyomo modeling language,\n",
"- Julia version, compatible with the JuMP modeling language.\n",
"\n",
"In this tutorial, we will demonstrate how to use and install the Julia/JuMP version of the package. The first step is to install the Julia programming language in your computer. [See the official instructions for more details](https://julialang.org/downloads/). Note that MIPLearn was developed and tested with Julia 1.6, and may not be compatible with newer versions of the language. After Julia is installed, launch its console and run the following commands to download and install the package:"
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "1ddeeb8e",
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"Path `/home/axavier/Packages/MIPLearn.jl/dev` exists and looks like the correct package. Using existing path.\n",
"\u001b[32m\u001b[1m Resolving\u001b[22m\u001b[39m package versions...\n",
"\u001b[32m\u001b[1m No Changes\u001b[22m\u001b[39m to `~/Packages/MIPLearn/dev/docs/jump-tutorials/Project.toml`\n",
"\u001b[32m\u001b[1m No Changes\u001b[22m\u001b[39m to `~/Packages/MIPLearn/dev/docs/jump-tutorials/Manifest.toml`\n"
]
}
],
"source": [
"using Pkg\n",
"Pkg.develop(PackageSpec(path=\"/home/axavier/Packages/MIPLearn.jl/dev\"))"
]
},
{
"cell_type": "markdown",
"id": "de7ab489",
"metadata": {},
"source": [
"In addition to MIPLearn itself, we will also install a few other packages that are required for this tutorial:\n",
"\n",
"- `SCIP`, a non-commercial mixed-integer programming solver\n",
"- `JuMP`, an open-source modeling language for Julia\n",
"- `Distributions`, a statistics package that we will use to generate random inputs\n",
"- `Glob`, a package that retrieves all files in a directory matching a certain pattern"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "29d29925",
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"\u001b[32m\u001b[1m Updating\u001b[22m\u001b[39m registry at `~/.julia/registries/General`\n",
"\u001b[32m\u001b[1m Updating\u001b[22m\u001b[39m git-repo `https://github.com/JuliaRegistries/General.git`\n",
"\u001b[32m\u001b[1m Resolving\u001b[22m\u001b[39m package versions...\n",
"\u001b[32m\u001b[1m No Changes\u001b[22m\u001b[39m to `~/Packages/MIPLearn/dev/docs/jump-tutorials/Project.toml`\n",
"\u001b[32m\u001b[1m No Changes\u001b[22m\u001b[39m to `~/Packages/MIPLearn/dev/docs/jump-tutorials/Manifest.toml`\n",
"\u001b[32m\u001b[1mPrecompiling\u001b[22m\u001b[39m project...\n",
"\u001b[32m ✓ \u001b[39mMIPLearn\n",
"1 dependency successfully precompiled in 10 seconds (96 already precompiled)\n"
]
}
],
"source": [
"using Pkg\n",
"Pkg.add([\n",
" PackageSpec(url=\"https://github.com/scipopt/SCIP.jl.git\", rev=\"7aa79aaa\"),\n",
" PackageSpec(name=\"JuMP\", version=\"0.21\"),\n",
" PackageSpec(name=\"Distributions\", version=\"0.25\"),\n",
" PackageSpec(name=\"Glob\", version=\"1\"),\n",
"])\n",
"using Revise"
]
},
{
"cell_type": "markdown",
"id": "88074d87",
"metadata": {},
"source": [
"<div class=\"alert alert-info\">\n",
" \n",
"Note\n",
" \n",
"In the code above, we install specific version of all packages to ensure that this tutorial keeps running in the future, even when newer (and possibly incompatible) versions of the packages are released. This is usually a recommended practice for all Julia projects.\n",
" \n",
"</div>"
]
},
{
"cell_type": "markdown",
"id": "78482747",
"metadata": {},
"source": [
"## Modeling a simple optimization problem\n",
"\n",
"To illustrate how can MIPLearn be used, we will model and solve a small optimization problem related to power systems optimization. The problem we discuss below is a simplification of the **unit commitment problem,** a practical optimization problem solved daily by electric grid operators around the world. \n",
"\n",
"Suppose that you work at a utility company, and that it is your job to decide which electrical generators should be online at a certain hour of the day, and how much power should each generator produce. More specifically, assume that your company owns $n$ generators, denoted by $g_1, \\ldots, g_n$. Each generator can either be online or offline. An online generator $g_i$ can produce between $p^\\text{min}_i$ to $p^\\text{max}_i$ megawatts of power, and it costs your company $c^\\text{fixed}_i + c^\\text{var}_i y_i$, where $y_i$ is the amount of power produced. An offline generator produces nothing, and costs nothing. You also know that the total amount of power to be produced needs to be exactly equal to the total demand $d$ (in megawatts). To minimize the costs to your company, which generators should be online, and how much power should they produce?\n",
"\n",
"This simple problem be modeled as a *mixed-integer linear optimization* problem as follows. For each generator $g_i$, let $x_i \\in \\{0,1\\}$ be a decision variable indicating whether $g_i$ is online, and let $y_i \\geq 0$ be a decision variable indicating how much power does $g_i$ produce. The problem we need to solve is given by:\n",
"\n",
"$$\n",
"\\begin{align}\n",
"\\text{minimize } \\quad & \\sum_{i=1}^n \\left( c^\\text{fix}_i x_i + c^\\text{var}_i y_i \\right) \\\\\n",
"\\text{subject to } \\quad & y_i \\leq p^\\text{max}_i x_i & i=1,\\ldots,n \\\\\n",
"& y_i \\geq p^\\text{min}_i x_i & i=1,\\ldots,n \\\\\n",
"& \\sum_{i=1}^n y_i = d \\\\\n",
"& x_i \\in \\{0,1\\} & i=1,\\ldots,n \\\\\n",
"& y_i \\geq 0 & i=1,\\ldots,n\n",
"\\end{align}\n",
"$$\n",
"\n",
"<div class=\"alert alert-info\">\n",
" \n",
"Note\n",
" \n",
"We use a simplified version of the unit commitment problem in this tutorial just to make it easier to follow. MIPLearn can also handle realistic, large-scale versions of this problem. See the benchmark sections for more details.\n",
" \n",
"</div>\n",
"\n",
"Next, let us convert this abstract mathematical formulation into a concrete optimization model, using the Julia and the JuMP modeling language. We start by defining a data structure that holds all input data:"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "ec7dbab4",
"metadata": {},
"outputs": [],
"source": [
"Base.@kwdef struct UnitCommitmentData\n",
" demand::Float64\n",
" pmin::Vector{Float64}\n",
" pmax::Vector{Float64}\n",
" cfix::Vector{Float64}\n",
" cvar::Vector{Float64}\n",
"end;"
]
},
{
"cell_type": "markdown",
"id": "c8f6a5b8",
"metadata": {},
"source": [
"Next, we create a function that converts this data into a concrete JuMP model:"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "14e84c92",
"metadata": {},
"outputs": [],
"source": [
"using JuMP\n",
"\n",
"function build_uc_model(data::UnitCommitmentData)::Model\n",
" model = Model()\n",
" n = length(data.pmin)\n",
" @variable(model, x[1:n], Bin)\n",
" @variable(model, y[1:n] >= 0)\n",
" @objective(\n",
" model,\n",
" Min,\n",
" sum(\n",
" data.cfix[i] * x[i] +\n",
" data.cvar[i] * y[i]\n",
" for i in 1:n\n",
" )\n",
" )\n",
" @constraint(model, eq_max_power[i in 1:n], y[i] <= data.pmax[i] * x[i])\n",
" @constraint(model, eq_min_power[i in 1:n], y[i] >= data.pmin[i] * x[i])\n",
" @constraint(model, eq_demand, sum(y[i] for i in 1:n) == data.demand)\n",
" return model\n",
"end;"
]
},
{
"cell_type": "markdown",
"id": "f647734f",
"metadata": {},
"source": [
"At this point, we can already use JuMP and any mixed-integer linear programming solver to find optimal solutions to any instance of this problem. To illustrate this, let us solve a small instance with three generators, using SCIP:"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "b2abe5e2",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"obj = 1320.0\n",
" x = [0.0, 1.0, 1.0]\n",
" y = [0.0, 60.0, 40.0]\n"
]
}
],
"source": [
"using SCIP\n",
"using Printf\n",
"\n",
"model = build_uc_model(\n",
" UnitCommitmentData(\n",
" demand = 100.0,\n",
" pmin = [10, 20, 30],\n",
" pmax = [50, 60, 70],\n",
" cfix = [700, 600, 500],\n",
" cvar = [1.5, 2.0, 2.5],\n",
" )\n",
")\n",
"\n",
"scip = optimizer_with_attributes(SCIP.Optimizer, \"limits/gap\" => 1e-4)\n",
"set_optimizer(model, scip)\n",
"set_silent(model)\n",
"optimize!(model)\n",
"\n",
"println(\"obj = \", objective_value(model))\n",
"println(\" x = \", round.(value.(model[:x])))\n",
"println(\" y = \", round.(value.(model[:y]), digits=2));"
]
},
{
"cell_type": "markdown",
"id": "5be976f5",
"metadata": {},
"source": [
"Running the code above, we found that the optimal solution for our small problem instance costs \\$1320. It is achieve by keeping generators 2 and 3 online and producing, respectively, 60 MW and 40 MW of power."
]
},
{
"cell_type": "markdown",
"id": "96a1f952",
"metadata": {},
"source": [
"## Generating training data\n",
"\n",
"Although SCIP could solve the small example above in a fraction of a second, it gets slower for larger and more complex versions of the problem. If this is a problem that needs to be solved frequently, as it is often the case in practice, it could make sense to spend some time upfront generating a **trained** version of SCIP, which can solve new instances (similar to the ones it was trained on) faster.\n",
"\n",
"In the following, we will use MIPLearn to train machine learning models that can be used to accelerate SCIP's performance on a particular set of instances. More specifically, MIPLearn will train a model that is able to predict the optimal solution for instances that follow a given probability distribution, then it will provide this predicted solution to SCIP as a warm start.\n",
"\n",
"Before we can train the model, we need to collect training data by solving a large number of instances. In real-world situations, we may construct these training instances based on historical data. In this tutorial, we will construct them using a random instance generator:"
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "353e6199",
"metadata": {},
"outputs": [],
"source": [
"using Distributions\n",
"using Random\n",
"\n",
"function random_uc_data(; samples::Int, n::Int, seed=42)\n",
" Random.seed!(seed)\n",
" pmin = rand(Uniform(100, 500.0), n)\n",
" pmax = pmin .* rand(Uniform(2.0, 2.5), n)\n",
" cfix = pmin .* rand(Uniform(100.0, 125.0), n)\n",
" cvar = rand(Uniform(1.25, 1.5), n)\n",
" return [\n",
" UnitCommitmentData(;\n",
" pmin,\n",
" pmax,\n",
" cfix,\n",
" cvar,\n",
" demand = sum(pmax) * rand(Uniform(0.5, 0.75)),\n",
" )\n",
" for i in 1:samples\n",
" ]\n",
"end;"
]
},
{
"cell_type": "markdown",
"id": "2140968d",
"metadata": {},
"source": [
"In this example, for simplicity, only the demands change from one instance to the next. We could also have made the prices and the production limits random. The more randomization we have in the training data, however, the more challenging it is for the machine learning models to learn solution patterns.\n",
"\n",
"Now we generate 100 instances of this problem, each one with 1,000 generators. We will use the first 90 instances for training, and the remaining 10 instances to evaluate SCIP's performance."
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "1bb24909",
"metadata": {},
"outputs": [],
"source": [
"data = random_uc_data(samples=100, n=1000);\n",
"train_data = data[1:90]\n",
"test_data = data[91:100];"
]
},
{
"cell_type": "markdown",
"id": "96bc0e42",
"metadata": {},
"source": [
"Next, we will write these data structures to individual files. MIPLearn uses files during the training process because, for large-scale optimization problems, it is often impractical to hold the entire training data, as well as the concrete JuMP models, in memory. Files also make it much easier to solve multiple instances simultaneously, potentially even on multiple machines. We will cover parallel and distributed computing in a future tutorial.\n",
"\n",
"The code below generates the files `uc/train/000001.jld2`, `uc/train/000002.jld2`, etc."
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "8ec476b1",
"metadata": {},
"outputs": [],
"source": [
"using MIPLearn\n",
"using Glob\n",
"\n",
"MIPLearn.save(data[1:90], \"uc/train/\")\n",
"MIPLearn.save(data[91:100], \"uc/test/\")\n",
"\n",
"train_files = glob(\"uc/train/*.jld2\")\n",
"test_files = glob(\"uc/test/*.jld2\");"
]
},
{
"cell_type": "markdown",
"id": "5d53a783",
"metadata": {},
"source": [
"Finally, we use `MIPLearn.LearningSolver` and `MIPLearn.solve!` to solve all the training instances. `LearningSolver` is the main component provided by MIPLearn, which integrates MIP solvers and ML. The `solve!` function can be used to solve either one or multiple instances, and requires: (i) the list of files containing the training data; and (ii) the function that converts the data structure into a concrete JuMP model:"
]
},
{
"cell_type": "code",
"execution_count": 9,
"id": "514a3b3a",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"101.279699 seconds (93.52 M allocations: 3.599 GiB, 1.23% gc time, 0.52% compilation time)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"WARNING: Dual bound 1.98665e+07 is larger than the objective of the primal solution 1.98665e+07. The solution might not be optimal.\n"
]
}
],
"source": [
"using Glob\n",
"solver = LearningSolver(scip)\n",
"@time solve!(solver, train_files, build_uc_model);"
]
},
{
"cell_type": "markdown",
"id": "72eb09f4",
"metadata": {},
"source": [
"The macro `@time` shows us how long did the code take to run. We can see that SCIP was able to solve all training instances in about 2 minutes. The solutions, and other useful training data, is stored by MIPLearn in `.h5` files, stored side-by-side with the original `.jld2` files."
]
},
{
"cell_type": "markdown",
"id": "90406b90",
"metadata": {},
"source": [
"## Solving new instances\n",
"\n",
"Now that we have training data, we can fit the ML models using `MIPLearn.fit!`, then solve the test instances with `MIPLearn.solve!`, as shown below:"
]
},
{
"cell_type": "code",
"execution_count": 10,
"id": "e4de94db",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
" 5.693951 seconds (9.33 M allocations: 334.689 MiB, 1.62% gc time)\n"
]
}
],
"source": [
"solver_ml = LearningSolver(scip)\n",
"fit!(solver_ml, train_files, build_uc_model)\n",
"@time solve!(solver_ml, test_files, build_uc_model);"
]
},
{
"cell_type": "markdown",
"id": "247c1087",
"metadata": {},
"source": [
"The trained MIP solver was able to solve all test instances in about 5 seconds. To see that ML is being helpful here, let us repeat the code above, but remove the `fit!` line:"
]
},
{
"cell_type": "code",
"execution_count": 11,
"id": "62061b12",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
" 9.829350 seconds (8.17 M allocations: 278.008 MiB, 0.47% gc time)\n"
]
}
],
"source": [
"solver_baseline = LearningSolver(scip)\n",
"@time solve!(solver_baseline, test_files, build_uc_model);"
]
},
{
"cell_type": "markdown",
"id": "8ea5c423",
"metadata": {},
"source": [
"Without the help of the ML models, SCIP took around 10 seconds to solve the same test instances, or about twice as long.\n",
"\n",
"<div class=\"alert alert-info\">\n",
"Note\n",
" \n",
"Note that is is not necessary to specify what ML models to use. MIPLearn, by default, will try a number of classical ML models and will choose the one that performs the best, based on k-fold cross validation. MIPLearn is also able to automatically collect features based on the MIP formulation of the problem and the solution to the LP relaxation, among other things, so it does not require handcrafted features. If you do want to customize the models and features, however, that is also possible, as we will see in a later tutorial.\n",
"</div>"
]
},
{
"cell_type": "markdown",
"id": "569f7c7a",
"metadata": {},
"source": [
"## Understanding the acceleration\n",
"\n",
"Let us know go a bit deeper and try to understand how exactly did MIPLearn accelerate SCIP's performance. First, we are going to solve one of the training instances again, using the trained solver, but this time using the `tee=true` parameter, so that we can see SCIP's log:"
]
},
{
"cell_type": "code",
"execution_count": 12,
"id": "46739739",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"presolving:\n",
"(round 1, fast) 861 del vars, 861 del conss, 0 add conss, 2000 chg bounds, 0 chg sides, 0 chg coeffs, 0 upgd conss, 0 impls, 0 clqs\n",
"(round 2, fast) 861 del vars, 1722 del conss, 0 add conss, 2000 chg bounds, 0 chg sides, 0 chg coeffs, 0 upgd conss, 0 impls, 0 clqs\n",
"(round 3, fast) 862 del vars, 1722 del conss, 0 add conss, 2000 chg bounds, 0 chg sides, 0 chg coeffs, 0 upgd conss, 0 impls, 0 clqs\n",
"presolving (4 rounds: 4 fast, 1 medium, 1 exhaustive):\n",
" 862 deleted vars, 1722 deleted constraints, 0 added constraints, 2000 tightened bounds, 0 added holes, 0 changed sides, 0 changed coefficients\n",
" 0 implications, 0 cliques\n",
"presolved problem has 1138 variables (0 bin, 0 int, 0 impl, 1138 cont) and 279 constraints\n",
" 279 constraints of type <linear>\n",
"Presolving Time: 0.03\n",
"\n",
" time | node | left |LP iter|LP it/n|mem/heur|mdpt |vars |cons |rows |cuts |sepa|confs|strbr| dualbound | primalbound | gap | compl. \n",
"* 0.0s| 1 | 0 | 203 | - | LP | 0 |1138 | 279 | 279 | 0 | 0 | 0 | 0 | 1.705035e+07 | 1.705035e+07 | 0.00%| unknown\n",
" 0.0s| 1 | 0 | 203 | - | 8950k | 0 |1138 | 279 | 279 | 0 | 0 | 0 | 0 | 1.705035e+07 | 1.705035e+07 | 0.00%| unknown\n",
"\n",
"SCIP Status : problem is solved [optimal solution found]\n",
"Solving Time (sec) : 0.04\n",
"Solving Nodes : 1\n",
"Primal Bound : +1.70503465600131e+07 (1 solutions)\n",
"Dual Bound : +1.70503465600131e+07\n",
"Gap : 0.00 %\n",
"\n",
"violation: integrality condition of variable <> = 0.338047247943162\n",
"all 1 solutions given by solution candidate storage are infeasible\n",
"\n",
"feasible solution found by completesol heuristic after 0.1 seconds, objective value 1.705169e+07\n",
"presolving:\n",
"(round 1, fast) 0 del vars, 0 del conss, 0 add conss, 3000 chg bounds, 0 chg sides, 0 chg coeffs, 0 upgd conss, 0 impls, 0 clqs\n",
"(round 2, exhaustive) 0 del vars, 0 del conss, 0 add conss, 3000 chg bounds, 0 chg sides, 0 chg coeffs, 1000 upgd conss, 0 impls, 0 clqs\n",
"(round 3, exhaustive) 0 del vars, 0 del conss, 0 add conss, 3000 chg bounds, 0 chg sides, 0 chg coeffs, 2000 upgd conss, 1000 impls, 0 clqs\n",
" (0.1s) probing: 51/1000 (5.1%) - 0 fixings, 0 aggregations, 0 implications, 0 bound changes\n",
" (0.1s) probing aborted: 50/50 successive totally useless probings\n",
" (0.1s) symmetry computation started: requiring (bin +, int -, cont +), (fixed: bin -, int +, cont -)\n",
" (0.1s) no symmetry present\n",
"presolving (4 rounds: 4 fast, 3 medium, 3 exhaustive):\n",
" 0 deleted vars, 0 deleted constraints, 0 added constraints, 3000 tightened bounds, 0 added holes, 0 changed sides, 0 changed coefficients\n",
" 2000 implications, 0 cliques\n",
"presolved problem has 2000 variables (1000 bin, 0 int, 0 impl, 1000 cont) and 2001 constraints\n",
" 2000 constraints of type <varbound>\n",
" 1 constraints of type <linear>\n",
"Presolving Time: 0.10\n",
"transformed 1/1 original solutions to the transformed problem space\n",
"\n",
" time | node | left |LP iter|LP it/n|mem/heur|mdpt |vars |cons |rows |cuts |sepa|confs|strbr| dualbound | primalbound | gap | compl. \n",
" 0.2s| 1 | 0 | 1201 | - | 20M | 0 |2000 |2001 |2001 | 0 | 0 | 0 | 0 | 1.705035e+07 | 1.705169e+07 | 0.01%| unknown\n",
"\n",
"SCIP Status : solving was interrupted [gap limit reached]\n",
"Solving Time (sec) : 0.21\n",
"Solving Nodes : 1\n",
"Primal Bound : +1.70516871251443e+07 (1 solutions)\n",
"Dual Bound : +1.70503465600130e+07\n",
"Gap : 0.01 %\n",
"\n"
]
}
],
"source": [
"solve!(solver_ml, test_files[1], build_uc_model, tee=true);"
]
},
{
"cell_type": "markdown",
"id": "9cdc02d0",
"metadata": {},
"source": [
"The log above is quite complicated if you have never seen it before, but the important line in the one starting with `feasible solution found [...] objective value 1.705169e+07`. This line indicates that MIPLearn was able to construct a warm start with value `1.705169e+07`. Using this warm start, SCIP then proceeded with the branch-and-cut process to either prove its optimality or find an even better solution. Very quickly, however, SCIP proved that the solution produced by MIPLearn was indeed optimal and terminated. It was able to do this without generating a single cutting plane or running any other heuristics; it could tell the optimality by the root LP relaxation alone, which was very fast. \n",
"\n",
"Let us now do the same thing again, but using the untrained solver this time:"
]
},
{
"cell_type": "code",
"execution_count": 13,
"id": "555af477",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"presolving:\n",
"(round 1, fast) 861 del vars, 861 del conss, 0 add conss, 2000 chg bounds, 0 chg sides, 0 chg coeffs, 0 upgd conss, 0 impls, 0 clqs\n",
"(round 2, fast) 861 del vars, 1722 del conss, 0 add conss, 2000 chg bounds, 0 chg sides, 0 chg coeffs, 0 upgd conss, 0 impls, 0 clqs\n",
"(round 3, fast) 862 del vars, 1722 del conss, 0 add conss, 2000 chg bounds, 0 chg sides, 0 chg coeffs, 0 upgd conss, 0 impls, 0 clqs\n",
"presolving (4 rounds: 4 fast, 1 medium, 1 exhaustive):\n",
" 862 deleted vars, 1722 deleted constraints, 0 added constraints, 2000 tightened bounds, 0 added holes, 0 changed sides, 0 changed coefficients\n",
" 0 implications, 0 cliques\n",
"presolved problem has 1138 variables (0 bin, 0 int, 0 impl, 1138 cont) and 279 constraints\n",
" 279 constraints of type <linear>\n",
"Presolving Time: 0.03\n",
"\n",
" time | node | left |LP iter|LP it/n|mem/heur|mdpt |vars |cons |rows |cuts |sepa|confs|strbr| dualbound | primalbound | gap | compl. \n",
"* 0.0s| 1 | 0 | 203 | - | LP | 0 |1138 | 279 | 279 | 0 | 0 | 0 | 0 | 1.705035e+07 | 1.705035e+07 | 0.00%| unknown\n",
" 0.0s| 1 | 0 | 203 | - | 8950k | 0 |1138 | 279 | 279 | 0 | 0 | 0 | 0 | 1.705035e+07 | 1.705035e+07 | 0.00%| unknown\n",
"\n",
"SCIP Status : problem is solved [optimal solution found]\n",
"Solving Time (sec) : 0.04\n",
"Solving Nodes : 1\n",
"Primal Bound : +1.70503465600131e+07 (1 solutions)\n",
"Dual Bound : +1.70503465600131e+07\n",
"Gap : 0.00 %\n",
"\n",
"violation: integrality condition of variable <> = 0.338047247943162\n",
"all 1 solutions given by solution candidate storage are infeasible\n",
"\n",
"presolving:\n",
"(round 1, fast) 0 del vars, 0 del conss, 0 add conss, 2000 chg bounds, 0 chg sides, 0 chg coeffs, 0 upgd conss, 0 impls, 0 clqs\n",
"(round 2, exhaustive) 0 del vars, 0 del conss, 0 add conss, 2000 chg bounds, 0 chg sides, 0 chg coeffs, 1000 upgd conss, 0 impls, 0 clqs\n",
"(round 3, exhaustive) 0 del vars, 0 del conss, 0 add conss, 2000 chg bounds, 0 chg sides, 0 chg coeffs, 2000 upgd conss, 1000 impls, 0 clqs\n",
" (0.0s) probing: 51/1000 (5.1%) - 0 fixings, 0 aggregations, 0 implications, 0 bound changes\n",
" (0.0s) probing aborted: 50/50 successive totally useless probings\n",
" (0.0s) symmetry computation started: requiring (bin +, int -, cont +), (fixed: bin -, int +, cont -)\n",
" (0.0s) no symmetry present\n",
"presolving (4 rounds: 4 fast, 3 medium, 3 exhaustive):\n",
" 0 deleted vars, 0 deleted constraints, 0 added constraints, 2000 tightened bounds, 0 added holes, 0 changed sides, 0 changed coefficients\n",
" 2000 implications, 0 cliques\n",
"presolved problem has 2000 variables (1000 bin, 0 int, 0 impl, 1000 cont) and 2001 constraints\n",
" 2000 constraints of type <varbound>\n",
" 1 constraints of type <linear>\n",
"Presolving Time: 0.03\n",
"\n",
" time | node | left |LP iter|LP it/n|mem/heur|mdpt |vars |cons |rows |cuts |sepa|confs|strbr| dualbound | primalbound | gap | compl. \n",
"p 0.0s| 1 | 0 | 1 | - | locks| 0 |2000 |2001 |2001 | 0 | 0 | 0 | 0 | 0.000000e+00 | 2.335200e+07 | Inf | unknown\n",
"p 0.0s| 1 | 0 | 2 | - | vbounds| 0 |2000 |2001 |2001 | 0 | 0 | 0 | 0 | 0.000000e+00 | 1.839873e+07 | Inf | unknown\n",
" 0.1s| 1 | 0 | 1204 | - | 20M | 0 |2000 |2001 |2001 | 0 | 0 | 0 | 0 | 1.705035e+07 | 1.839873e+07 | 7.91%| unknown\n",
" 0.1s| 1 | 0 | 1207 | - | 22M | 0 |2000 |2001 |2002 | 1 | 1 | 0 | 0 | 1.705036e+07 | 1.839873e+07 | 7.91%| unknown\n",
"r 0.1s| 1 | 0 | 1207 | - |shifting| 0 |2000 |2001 |2002 | 1 | 1 | 0 | 0 | 1.705036e+07 | 1.711399e+07 | 0.37%| unknown\n",
" 0.1s| 1 | 0 | 1209 | - | 22M | 0 |2000 |2001 |2003 | 2 | 2 | 0 | 0 | 1.705037e+07 | 1.711399e+07 | 0.37%| unknown\n",
"r 0.1s| 1 | 0 | 1209 | - |shifting| 0 |2000 |2001 |2003 | 2 | 2 | 0 | 0 | 1.705037e+07 | 1.706492e+07 | 0.09%| unknown\n",
" 0.1s| 1 | 0 | 1210 | - | 22M | 0 |2000 |2001 |2004 | 3 | 3 | 0 | 0 | 1.705037e+07 | 1.706492e+07 | 0.09%| unknown\n",
" 0.1s| 1 | 0 | 1211 | - | 23M | 0 |2000 |2001 |2005 | 4 | 4 | 0 | 0 | 1.705037e+07 | 1.706492e+07 | 0.09%| unknown\n",
" 0.1s| 1 | 0 | 1212 | - | 23M | 0 |2000 |2001 |2006 | 5 | 5 | 0 | 0 | 1.705037e+07 | 1.706492e+07 | 0.09%| unknown\n",
"r 0.1s| 1 | 0 | 1212 | - |shifting| 0 |2000 |2001 |2006 | 5 | 5 | 0 | 0 | 1.705037e+07 | 1.706228e+07 | 0.07%| unknown\n",
" 0.1s| 1 | 0 | 1214 | - | 24M | 0 |2000 |2001 |2007 | 6 | 7 | 0 | 0 | 1.705037e+07 | 1.706228e+07 | 0.07%| unknown\n",
" 0.2s| 1 | 0 | 1216 | - | 24M | 0 |2000 |2001 |2009 | 8 | 8 | 0 | 0 | 1.705037e+07 | 1.706228e+07 | 0.07%| unknown\n",
" 0.2s| 1 | 0 | 1220 | - | 25M | 0 |2000 |2001 |2011 | 10 | 9 | 0 | 0 | 1.705037e+07 | 1.706228e+07 | 0.07%| unknown\n",
" 0.2s| 1 | 0 | 1223 | - | 25M | 0 |2000 |2001 |2014 | 13 | 10 | 0 | 0 | 1.705037e+07 | 1.706228e+07 | 0.07%| unknown\n",
" time | node | left |LP iter|LP it/n|mem/heur|mdpt |vars |cons |rows |cuts |sepa|confs|strbr| dualbound | primalbound | gap | compl. \n",
" 0.2s| 1 | 0 | 1229 | - | 26M | 0 |2000 |2001 |2015 | 14 | 11 | 0 | 0 | 1.705038e+07 | 1.706228e+07 | 0.07%| unknown\n",
"r 0.2s| 1 | 0 | 1403 | - |intshift| 0 |2000 |2001 |2015 | 14 | 11 | 0 | 0 | 1.705038e+07 | 1.705687e+07 | 0.04%| unknown\n",
"L 0.6s| 1 | 0 | 1707 | - | rens| 0 |2000 |2001 |2015 | 14 | 11 | 0 | 0 | 1.705038e+07 | 1.705332e+07 | 0.02%| unknown\n",
"L 0.7s| 1 | 0 | 1707 | - | alns| 0 |2000 |2001 |2015 | 14 | 11 | 0 | 0 | 1.705038e+07 | 1.705178e+07 | 0.01%| unknown\n",
"\n",
"SCIP Status : solving was interrupted [gap limit reached]\n",
"Solving Time (sec) : 0.67\n",
"Solving Nodes : 1\n",
"Primal Bound : +1.70517823853380e+07 (13 solutions)\n",
"Dual Bound : +1.70503798271962e+07\n",
"Gap : 0.01 %\n",
"\n"
]
}
],
"source": [
"solve!(solver_baseline, test_files[1], build_uc_model, tee=true);"
]
},
{
"cell_type": "markdown",
"id": "72a52d26",
"metadata": {},
"source": [
"In this log file, notice how the line we saw before is now missing; SCIP needs to find an initial solution using its own internal heuristics. The solution SCIP initially found has value `2.335200e+07`, which is significantly worse than the one MIPLearn constructed before. SCIP then proceeds to improve this solution by generating a number of cutting planes and repeatedly running primal heuristics. In the end, it is able to find the optimal solution, as expected, but it takes longer."
]
},
{
"cell_type": "markdown",
"id": "36fb5f02",
"metadata": {},
"source": [
"## Accessing the solution\n",
"\n",
"In the example above, we used `MIPLearn.solve!` together with data files to solve both the training and the test instances. The solutions were saved to a `.h5` files in the train/test folders, and could be retrieved by reading theses files, but that is not very convenient. In this section we will use an easier method.\n",
"\n",
"We can use the function `MIPLearn.load!` to obtain a regular JuMP model:"
]
},
{
"cell_type": "code",
"execution_count": 14,
"id": "f62f28b4",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"A JuMP Model\n",
"Minimization problem with:\n",
"Variables: 2000\n",
"Objective function type: AffExpr\n",
"`AffExpr`-in-`MathOptInterface.EqualTo{Float64}`: 1 constraint\n",
"`AffExpr`-in-`MathOptInterface.GreaterThan{Float64}`: 1000 constraints\n",
"`AffExpr`-in-`MathOptInterface.LessThan{Float64}`: 1000 constraints\n",
"`VariableRef`-in-`MathOptInterface.GreaterThan{Float64}`: 1000 constraints\n",
"`VariableRef`-in-`MathOptInterface.ZeroOne`: 1000 constraints\n",
"Model mode: AUTOMATIC\n",
"CachingOptimizer state: NO_OPTIMIZER\n",
"Solver name: No optimizer attached.\n",
"Names registered in the model: eq_demand, eq_max_power, eq_min_power, x, y"
]
},
"execution_count": 14,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"model = MIPLearn.load(\"uc/test/000001.jld2\", build_uc_model)"
]
},
{
"cell_type": "markdown",
"id": "d5722dcf",
"metadata": {},
"source": [
"We can then solve this model as before, with `MIPLearn.solve!`:"
]
},
{
"cell_type": "code",
"execution_count": 15,
"id": "e49f9e60",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"obj = 1.7051217395548128e7\n",
" x = [1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0]\n",
" y = [767.11, 646.61, 230.28, 365.46, 1150.99, 1103.36, 0.0, 0.0, 0.0, 0.0]\n"
]
}
],
"source": [
"solve!(solver_ml, model)\n",
"println(\"obj = \", objective_value(model))\n",
"println(\" x = \", round.(value.(model[:x][1:10])))\n",
"println(\" y = \", round.(value.(model[:y][1:10]), digits=2))"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Julia 1.6.0",
"language": "julia",
"name": "julia-1.6"
},
"language_info": {
"file_extension": ".jl",
"mimetype": "application/julia",
"name": "julia",
"version": "1.6.0"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

File diff suppressed because it is too large Load Diff

@ -0,0 +1,29 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "18dd2957",
"metadata": {},
"source": [
"# Modeling lazy constraints\n",
"\n",
"TODO"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Julia 1.6.0",
"language": "julia",
"name": "julia-1.6"
},
"language_info": {
"file_extension": ".jl",
"mimetype": "application/julia",
"name": "julia",
"version": "1.6.0"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

@ -0,0 +1,210 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Modeling lazy constraints &#8212; MIPLearn&lt;br/&gt;&lt;small&gt;0.2.0&lt;/small&gt;</title>
<link href="../../_static/css/theme.css" rel="stylesheet" />
<link href="../../_static/css/index.c5995385ac14fb8791e8eb36b4908be2.css" rel="stylesheet" />
<link rel="stylesheet"
href="../../_static/vendor/fontawesome/5.13.0/css/all.min.css">
<link rel="preload" as="font" type="font/woff2" crossorigin
href="../../_static/vendor/fontawesome/5.13.0/webfonts/fa-solid-900.woff2">
<link rel="preload" as="font" type="font/woff2" crossorigin
href="../../_static/vendor/fontawesome/5.13.0/webfonts/fa-brands-400.woff2">
<link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
<link rel="stylesheet" href="../../_static/sphinx-book-theme.acff12b8f9c144ce68a297486a2fa670.css" type="text/css" />
<link rel="stylesheet" type="text/css" href="../../_static/custom.css" />
<link rel="preload" as="script" href="../../_static/js/index.1c5a1a01449ed65a7b51.js">
<script id="documentation_options" data-url_root="../../" src="../../_static/documentation_options.js"></script>
<script src="../../_static/jquery.js"></script>
<script src="../../_static/underscore.js"></script>
<script src="../../_static/doctools.js"></script>
<script crossorigin="anonymous" integrity="sha256-Ae2Vz/4ePdIu6ZyI/5ZGsYnb+m0JlOmKPjt6XZ9JJkA=" src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.3.4/require.min.js"></script>
<script src="../../_static/sphinx-book-theme.12a9622fbb08dcb3a2a40b2c02b83a57.js"></script>
<script async="async" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.7/latest.js?config=TeX-AMS-MML_HTMLorMML"></script>
<script type="text/x-mathjax-config">MathJax.Hub.Config({"tex2jax": {"inlineMath": [["\\(", "\\)"]], "displayMath": [["\\[", "\\]"]], "processRefs": false, "processEnvironments": false}})</script>
<link rel="index" title="Index" href="../../genindex/" />
<link rel="search" title="Search" href="../../search/" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="docsearch:language" content="en" />
</head>
<body data-spy="scroll" data-target="#bd-toc-nav" data-offset="80">
<div class="container-fluid" id="banner"></div>
<div class="container-xl">
<div class="row">
<div class="col-12 col-md-3 bd-sidebar site-navigation show" id="site-navigation">
<div class="navbar-brand-box">
<a class="navbar-brand text-wrap" href="../../">
<h1 class="site-logo" id="site-title">MIPLearn<br/><small>0.2.0</small></h1>
</a>
</div><form class="bd-search d-flex align-items-center" action="../../search/" method="get">
<i class="icon fas fa-search"></i>
<input type="search" class="form-control" name="q" id="search-input" placeholder="Search the docs ..." aria-label="Search the docs ..." autocomplete="off" >
</form><nav class="bd-links" id="bd-docs-nav" aria-label="Main navigation">
<div class="bd-toc-item active">
<p class="caption">
<span class="caption-text">
Julia Tutorials
</span>
</p>
<ul class="nav bd-sidenav">
<li class="toctree-l1">
<a class="reference internal" href="../getting-started/">
1. Getting started with MIPLearn
</a>
</li>
</ul>
<p class="caption">
<span class="caption-text">
Benchmarks
</span>
</p>
<ul class="nav bd-sidenav">
<li class="toctree-l1">
<a class="reference internal" href="../../benchmarks/preliminaries/">
1. Preliminaries
</a>
</li>
<li class="toctree-l1">
<a class="reference internal" href="../../benchmarks/stab/">
2. Maximum Weight Stable Set
</a>
</li>
<li class="toctree-l1">
<a class="reference internal" href="../../benchmarks/knapsack/">
3. Multidimensional Knapsack
</a>
</li>
<li class="toctree-l1">
<a class="reference internal" href="../../benchmarks/tsp/">
4. Traveling Salesman
</a>
</li>
</ul>
</div>
</nav> <!-- To handle the deprecated key -->
</div>
<main class="col py-md-3 pl-md-4 bd-content overflow-auto" role="main">
<div class="topbar container-xl fixed-top">
<div class="topbar-contents row">
<div class="col-12 col-md-3 bd-topbar-whitespace site-navigation show"></div>
<div class="col pl-md-4 topbar-main">
<button id="navbar-toggler" class="navbar-toggler ml-0" type="button" data-toggle="collapse"
data-toggle="tooltip" data-placement="bottom" data-target=".site-navigation" aria-controls="navbar-menu"
aria-expanded="true" aria-label="Toggle navigation" aria-controls="site-navigation"
title="Toggle navigation" data-toggle="tooltip" data-placement="left">
<i class="fas fa-bars"></i>
<i class="fas fa-arrow-left"></i>
<i class="fas fa-arrow-up"></i>
</button>
<div class="dropdown-buttons-trigger">
<button id="dropdown-buttons-trigger" class="btn btn-secondary topbarbtn" aria-label="Download this page"><i
class="fas fa-download"></i></button>
<div class="dropdown-buttons">
<!-- ipynb file if we had a myst markdown file -->
<!-- Download raw file -->
<a class="dropdown-buttons" href="../../_sources/jump-tutorials/lazy-constraints.ipynb.txt"><button type="button"
class="btn btn-secondary topbarbtn" title="Download source file" data-toggle="tooltip"
data-placement="left">.ipynb</button></a>
<!-- Download PDF via print -->
<button type="button" id="download-print" class="btn btn-secondary topbarbtn" title="Print to PDF"
onClick="window.print()" data-toggle="tooltip" data-placement="left">.pdf</button>
</div>
</div>
<!-- Source interaction buttons -->
<!-- Full screen (wrap in <a> to have style consistency -->
<a class="full-screen-button"><button type="button" class="btn btn-secondary topbarbtn" data-toggle="tooltip"
data-placement="bottom" onclick="toggleFullScreen()" aria-label="Fullscreen mode"
title="Fullscreen mode"><i
class="fas fa-expand"></i></button></a>
<!-- Launch buttons -->
</div>
<!-- Table of contents -->
<div class="d-none d-md-block col-md-2 bd-toc show">
</div>
</div>
</div>
<div id="main-content" class="row">
<div class="col-12 col-md-9 pl-md-3 pr-md-0">
<div>
<div class="section" id="Modeling-lazy-constraints">
<h1>Modeling lazy constraints<a class="headerlink" href="#Modeling-lazy-constraints" title="Permalink to this headline"></a></h1>
<p>TODO</p>
</div>
</div>
<div class='prev-next-bottom'>
</div>
</div>
</div>
<footer class="footer mt-5 mt-md-0">
<div class="container">
<p>
&copy; Copyright 2020-2021, UChicago Argonne, LLC.<br/>
</p>
</div>
</footer>
</main>
</div>
</div>
<script src="../../_static/js/index.1c5a1a01449ed65a7b51.js"></script>
</body>
</html>

@ -0,0 +1,29 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "8e6b5f28",
"metadata": {},
"source": [
"# Modeling user cuts\n",
"\n",
"TODO"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Julia 1.6.0",
"language": "julia",
"name": "julia-1.6"
},
"language_info": {
"file_extension": ".jl",
"mimetype": "application/julia",
"name": "julia",
"version": "1.6.0"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

@ -0,0 +1,210 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Modeling user cuts &#8212; MIPLearn&lt;br/&gt;&lt;small&gt;0.2.0&lt;/small&gt;</title>
<link href="../../_static/css/theme.css" rel="stylesheet" />
<link href="../../_static/css/index.c5995385ac14fb8791e8eb36b4908be2.css" rel="stylesheet" />
<link rel="stylesheet"
href="../../_static/vendor/fontawesome/5.13.0/css/all.min.css">
<link rel="preload" as="font" type="font/woff2" crossorigin
href="../../_static/vendor/fontawesome/5.13.0/webfonts/fa-solid-900.woff2">
<link rel="preload" as="font" type="font/woff2" crossorigin
href="../../_static/vendor/fontawesome/5.13.0/webfonts/fa-brands-400.woff2">
<link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
<link rel="stylesheet" href="../../_static/sphinx-book-theme.acff12b8f9c144ce68a297486a2fa670.css" type="text/css" />
<link rel="stylesheet" type="text/css" href="../../_static/custom.css" />
<link rel="preload" as="script" href="../../_static/js/index.1c5a1a01449ed65a7b51.js">
<script id="documentation_options" data-url_root="../../" src="../../_static/documentation_options.js"></script>
<script src="../../_static/jquery.js"></script>
<script src="../../_static/underscore.js"></script>
<script src="../../_static/doctools.js"></script>
<script crossorigin="anonymous" integrity="sha256-Ae2Vz/4ePdIu6ZyI/5ZGsYnb+m0JlOmKPjt6XZ9JJkA=" src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.3.4/require.min.js"></script>
<script src="../../_static/sphinx-book-theme.12a9622fbb08dcb3a2a40b2c02b83a57.js"></script>
<script async="async" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.7/latest.js?config=TeX-AMS-MML_HTMLorMML"></script>
<script type="text/x-mathjax-config">MathJax.Hub.Config({"tex2jax": {"inlineMath": [["\\(", "\\)"]], "displayMath": [["\\[", "\\]"]], "processRefs": false, "processEnvironments": false}})</script>
<link rel="index" title="Index" href="../../genindex/" />
<link rel="search" title="Search" href="../../search/" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="docsearch:language" content="en" />
</head>
<body data-spy="scroll" data-target="#bd-toc-nav" data-offset="80">
<div class="container-fluid" id="banner"></div>
<div class="container-xl">
<div class="row">
<div class="col-12 col-md-3 bd-sidebar site-navigation show" id="site-navigation">
<div class="navbar-brand-box">
<a class="navbar-brand text-wrap" href="../../">
<h1 class="site-logo" id="site-title">MIPLearn<br/><small>0.2.0</small></h1>
</a>
</div><form class="bd-search d-flex align-items-center" action="../../search/" method="get">
<i class="icon fas fa-search"></i>
<input type="search" class="form-control" name="q" id="search-input" placeholder="Search the docs ..." aria-label="Search the docs ..." autocomplete="off" >
</form><nav class="bd-links" id="bd-docs-nav" aria-label="Main navigation">
<div class="bd-toc-item active">
<p class="caption">
<span class="caption-text">
Julia Tutorials
</span>
</p>
<ul class="nav bd-sidenav">
<li class="toctree-l1">
<a class="reference internal" href="../getting-started/">
1. Getting started with MIPLearn
</a>
</li>
</ul>
<p class="caption">
<span class="caption-text">
Benchmarks
</span>
</p>
<ul class="nav bd-sidenav">
<li class="toctree-l1">
<a class="reference internal" href="../../benchmarks/preliminaries/">
1. Preliminaries
</a>
</li>
<li class="toctree-l1">
<a class="reference internal" href="../../benchmarks/stab/">
2. Maximum Weight Stable Set
</a>
</li>
<li class="toctree-l1">
<a class="reference internal" href="../../benchmarks/knapsack/">
3. Multidimensional Knapsack
</a>
</li>
<li class="toctree-l1">
<a class="reference internal" href="../../benchmarks/tsp/">
4. Traveling Salesman
</a>
</li>
</ul>
</div>
</nav> <!-- To handle the deprecated key -->
</div>
<main class="col py-md-3 pl-md-4 bd-content overflow-auto" role="main">
<div class="topbar container-xl fixed-top">
<div class="topbar-contents row">
<div class="col-12 col-md-3 bd-topbar-whitespace site-navigation show"></div>
<div class="col pl-md-4 topbar-main">
<button id="navbar-toggler" class="navbar-toggler ml-0" type="button" data-toggle="collapse"
data-toggle="tooltip" data-placement="bottom" data-target=".site-navigation" aria-controls="navbar-menu"
aria-expanded="true" aria-label="Toggle navigation" aria-controls="site-navigation"
title="Toggle navigation" data-toggle="tooltip" data-placement="left">
<i class="fas fa-bars"></i>
<i class="fas fa-arrow-left"></i>
<i class="fas fa-arrow-up"></i>
</button>
<div class="dropdown-buttons-trigger">
<button id="dropdown-buttons-trigger" class="btn btn-secondary topbarbtn" aria-label="Download this page"><i
class="fas fa-download"></i></button>
<div class="dropdown-buttons">
<!-- ipynb file if we had a myst markdown file -->
<!-- Download raw file -->
<a class="dropdown-buttons" href="../../_sources/jump-tutorials/user-cuts.ipynb.txt"><button type="button"
class="btn btn-secondary topbarbtn" title="Download source file" data-toggle="tooltip"
data-placement="left">.ipynb</button></a>
<!-- Download PDF via print -->
<button type="button" id="download-print" class="btn btn-secondary topbarbtn" title="Print to PDF"
onClick="window.print()" data-toggle="tooltip" data-placement="left">.pdf</button>
</div>
</div>
<!-- Source interaction buttons -->
<!-- Full screen (wrap in <a> to have style consistency -->
<a class="full-screen-button"><button type="button" class="btn btn-secondary topbarbtn" data-toggle="tooltip"
data-placement="bottom" onclick="toggleFullScreen()" aria-label="Fullscreen mode"
title="Fullscreen mode"><i
class="fas fa-expand"></i></button></a>
<!-- Launch buttons -->
</div>
<!-- Table of contents -->
<div class="d-none d-md-block col-md-2 bd-toc show">
</div>
</div>
</div>
<div id="main-content" class="row">
<div class="col-12 col-md-9 pl-md-3 pr-md-0">
<div>
<div class="section" id="Modeling-user-cuts">
<h1>Modeling user cuts<a class="headerlink" href="#Modeling-user-cuts" title="Permalink to this headline"></a></h1>
<p>TODO</p>
</div>
</div>
<div class='prev-next-bottom'>
</div>
</div>
</div>
<footer class="footer mt-5 mt-md-0">
<div class="container">
<p>
&copy; Copyright 2020-2021, UChicago Argonne, LLC.<br/>
</p>
</div>
</footer>
</main>
</div>
</div>
<script src="../../_static/js/index.1c5a1a01449ed65a7b51.js"></script>
</body>
</html>

Binary file not shown.

@ -33,10 +33,10 @@
<script src="../_static/jquery.js"></script> <script src="../_static/jquery.js"></script>
<script src="../_static/underscore.js"></script> <script src="../_static/underscore.js"></script>
<script src="../_static/doctools.js"></script> <script src="../_static/doctools.js"></script>
<script crossorigin="anonymous" integrity="sha256-Ae2Vz/4ePdIu6ZyI/5ZGsYnb+m0JlOmKPjt6XZ9JJkA=" src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.3.4/require.min.js"></script>
<script src="../_static/sphinx-book-theme.12a9622fbb08dcb3a2a40b2c02b83a57.js"></script> <script src="../_static/sphinx-book-theme.12a9622fbb08dcb3a2a40b2c02b83a57.js"></script>
<script src="../_static/searchtools.js"></script> <script src="../_static/searchtools.js"></script>
<script src="../_static/language_data.js"></script> <script src="../_static/language_data.js"></script>
<link rel="author" title="About these documents" href="../about/" />
<link rel="index" title="Index" href="../genindex/" /> <link rel="index" title="Index" href="../genindex/" />
<link rel="search" title="Search" href="#" /> <link rel="search" title="Search" href="#" />
<script src="../searchindex.js" defer></script> <script src="../searchindex.js" defer></script>
@ -69,37 +69,42 @@
<input type="search" class="form-control" name="q" id="search-input" placeholder="Search the docs ..." aria-label="Search the docs ..." autocomplete="off" > <input type="search" class="form-control" name="q" id="search-input" placeholder="Search the docs ..." aria-label="Search the docs ..." autocomplete="off" >
</form><nav class="bd-links" id="bd-docs-nav" aria-label="Main navigation"> </form><nav class="bd-links" id="bd-docs-nav" aria-label="Main navigation">
<div class="bd-toc-item active"> <div class="bd-toc-item active">
<ul class="nav bd-sidenav"> <p class="caption">
<span class="caption-text">
Julia Tutorials
</span>
</p>
<ul class="nav bd-sidenav">
<li class="toctree-l1"> <li class="toctree-l1">
<a class="reference internal" href="../usage/"> <a class="reference internal" href="../jump-tutorials/getting-started/">
<span class="sectnum"> 1. Getting started with MIPLearn
1.
</span>
Using MIPLearn
</a> </a>
</li> </li>
</ul>
<p class="caption">
<span class="caption-text">
Benchmarks
</span>
</p>
<ul class="nav bd-sidenav">
<li class="toctree-l1"> <li class="toctree-l1">
<a class="reference internal" href="../benchmark/"> <a class="reference internal" href="../benchmarks/preliminaries/">
<span class="sectnum"> 1. Preliminaries
2.
</span>
Benchmarks
</a> </a>
</li> </li>
<li class="toctree-l1"> <li class="toctree-l1">
<a class="reference internal" href="../customization/"> <a class="reference internal" href="../benchmarks/stab/">
<span class="sectnum"> 2. Maximum Weight Stable Set
3.
</span>
Customization
</a> </a>
</li> </li>
<li class="toctree-l1"> <li class="toctree-l1">
<a class="reference internal" href="../about/"> <a class="reference internal" href="../benchmarks/knapsack/">
<span class="sectnum"> 3. Multidimensional Knapsack
4. </a>
</span> </li>
About <li class="toctree-l1">
<a class="reference internal" href="../benchmarks/tsp/">
4. Traveling Salesman
</a> </a>
</li> </li>
</ul> </ul>
@ -133,19 +138,6 @@
<!-- Source interaction buttons --> <!-- Source interaction buttons -->
<div class="dropdown-buttons-trigger">
<button id="dropdown-buttons-trigger" class="btn btn-secondary topbarbtn"
aria-label="Connect with source repository"><i class="fab fa-github"></i></button>
<div class="dropdown-buttons sourcebuttons">
<a class="repository-button"
href="https://github.com/ANL-CEEESA/MIPLearn/"><button type="button" class="btn btn-secondary topbarbtn"
data-toggle="tooltip" data-placement="left" title="Source repository"><i
class="fab fa-github"></i>repository</button></a>
</div>
</div>
<!-- Full screen (wrap in <a> to have style consistency --> <!-- Full screen (wrap in <a> to have style consistency -->
<a class="full-screen-button"><button type="button" class="btn btn-secondary topbarbtn" data-toggle="tooltip" <a class="full-screen-button"><button type="button" class="btn btn-secondary topbarbtn" data-toggle="tooltip"

File diff suppressed because one or more lines are too long

@ -1,537 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>1. Using MIPLearn &#8212; MIPLearn&lt;br/&gt;&lt;small&gt;0.2.0&lt;/small&gt;</title>
<link href="../_static/css/theme.css" rel="stylesheet" />
<link href="../_static/css/index.c5995385ac14fb8791e8eb36b4908be2.css" rel="stylesheet" />
<link rel="stylesheet"
href="../_static/vendor/fontawesome/5.13.0/css/all.min.css">
<link rel="preload" as="font" type="font/woff2" crossorigin
href="../_static/vendor/fontawesome/5.13.0/webfonts/fa-solid-900.woff2">
<link rel="preload" as="font" type="font/woff2" crossorigin
href="../_static/vendor/fontawesome/5.13.0/webfonts/fa-brands-400.woff2">
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
<link rel="stylesheet" href="../_static/sphinx-book-theme.acff12b8f9c144ce68a297486a2fa670.css" type="text/css" />
<link rel="stylesheet" type="text/css" href="../_static/custom.css" />
<link rel="preload" as="script" href="../_static/js/index.1c5a1a01449ed65a7b51.js">
<script id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
<script src="../_static/jquery.js"></script>
<script src="../_static/underscore.js"></script>
<script src="../_static/doctools.js"></script>
<script src="../_static/sphinx-book-theme.12a9622fbb08dcb3a2a40b2c02b83a57.js"></script>
<link rel="author" title="About these documents" href="../about/" />
<link rel="index" title="Index" href="../genindex/" />
<link rel="search" title="Search" href="../search/" />
<link rel="next" title="2. Benchmarks" href="../benchmark/" />
<link rel="prev" title="MIPLearn" href="../" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="docsearch:language" content="en" />
</head>
<body data-spy="scroll" data-target="#bd-toc-nav" data-offset="80">
<div class="container-fluid" id="banner"></div>
<div class="container-xl">
<div class="row">
<div class="col-12 col-md-3 bd-sidebar site-navigation show" id="site-navigation">
<div class="navbar-brand-box">
<a class="navbar-brand text-wrap" href="../">
<h1 class="site-logo" id="site-title">MIPLearn<br/><small>0.2.0</small></h1>
</a>
</div><form class="bd-search d-flex align-items-center" action="../search/" method="get">
<i class="icon fas fa-search"></i>
<input type="search" class="form-control" name="q" id="search-input" placeholder="Search the docs ..." aria-label="Search the docs ..." autocomplete="off" >
</form><nav class="bd-links" id="bd-docs-nav" aria-label="Main navigation">
<div class="bd-toc-item active">
<ul class="current nav bd-sidenav">
<li class="toctree-l1 current active">
<a class="current reference internal" href="#">
<span class="sectnum">
1.
</span>
Using MIPLearn
</a>
</li>
<li class="toctree-l1">
<a class="reference internal" href="../benchmark/">
<span class="sectnum">
2.
</span>
Benchmarks
</a>
</li>
<li class="toctree-l1">
<a class="reference internal" href="../customization/">
<span class="sectnum">
3.
</span>
Customization
</a>
</li>
<li class="toctree-l1">
<a class="reference internal" href="../about/">
<span class="sectnum">
4.
</span>
About
</a>
</li>
</ul>
</div>
</nav> <!-- To handle the deprecated key -->
</div>
<main class="col py-md-3 pl-md-4 bd-content overflow-auto" role="main">
<div class="topbar container-xl fixed-top">
<div class="topbar-contents row">
<div class="col-12 col-md-3 bd-topbar-whitespace site-navigation show"></div>
<div class="col pl-md-4 topbar-main">
<button id="navbar-toggler" class="navbar-toggler ml-0" type="button" data-toggle="collapse"
data-toggle="tooltip" data-placement="bottom" data-target=".site-navigation" aria-controls="navbar-menu"
aria-expanded="true" aria-label="Toggle navigation" aria-controls="site-navigation"
title="Toggle navigation" data-toggle="tooltip" data-placement="left">
<i class="fas fa-bars"></i>
<i class="fas fa-arrow-left"></i>
<i class="fas fa-arrow-up"></i>
</button>
<div class="dropdown-buttons-trigger">
<button id="dropdown-buttons-trigger" class="btn btn-secondary topbarbtn" aria-label="Download this page"><i
class="fas fa-download"></i></button>
<div class="dropdown-buttons">
<!-- ipynb file if we had a myst markdown file -->
<!-- Download raw file -->
<a class="dropdown-buttons" href="../_sources/usage.md.txt"><button type="button"
class="btn btn-secondary topbarbtn" title="Download source file" data-toggle="tooltip"
data-placement="left">.md</button></a>
<!-- Download PDF via print -->
<button type="button" id="download-print" class="btn btn-secondary topbarbtn" title="Print to PDF"
onClick="window.print()" data-toggle="tooltip" data-placement="left">.pdf</button>
</div>
</div>
<!-- Source interaction buttons -->
<div class="dropdown-buttons-trigger">
<button id="dropdown-buttons-trigger" class="btn btn-secondary topbarbtn"
aria-label="Connect with source repository"><i class="fab fa-github"></i></button>
<div class="dropdown-buttons sourcebuttons">
<a class="repository-button"
href="https://github.com/ANL-CEEESA/MIPLearn/"><button type="button" class="btn btn-secondary topbarbtn"
data-toggle="tooltip" data-placement="left" title="Source repository"><i
class="fab fa-github"></i>repository</button></a>
</div>
</div>
<!-- Full screen (wrap in <a> to have style consistency -->
<a class="full-screen-button"><button type="button" class="btn btn-secondary topbarbtn" data-toggle="tooltip"
data-placement="bottom" onclick="toggleFullScreen()" aria-label="Fullscreen mode"
title="Fullscreen mode"><i
class="fas fa-expand"></i></button></a>
<!-- Launch buttons -->
</div>
<!-- Table of contents -->
<div class="d-none d-md-block col-md-2 bd-toc show">
<div class="tocsection onthispage pt-5 pb-3">
<i class="fas fa-list"></i> Contents
</div>
<nav id="bd-toc-nav">
<ul class="visible nav section-nav flex-column">
<li class="toc-h2 nav-item toc-entry">
<a class="reference internal nav-link" href="#installation">
<span class="sectnum">
1.1.
</span>
Installation
</a>
</li>
<li class="toc-h2 nav-item toc-entry">
<a class="reference internal nav-link" href="#using-learningsolver">
<span class="sectnum">
1.2.
</span>
Using
<code class="docutils literal notranslate">
<span class="pre">
LearningSolver
</span>
</code>
</a>
</li>
<li class="toc-h2 nav-item toc-entry">
<a class="reference internal nav-link" href="#describing-problem-instances">
<span class="sectnum">
1.3.
</span>
Describing problem instances
</a>
</li>
<li class="toc-h2 nav-item toc-entry">
<a class="reference internal nav-link" href="#describing-lazy-constraints">
<span class="sectnum">
1.4.
</span>
Describing lazy constraints
</a>
<ul class="nav section-nav flex-column">
<li class="toc-h3 nav-item toc-entry">
<a class="reference internal nav-link" href="#adding-lazy-constraints-through-annotations">
Adding lazy constraints through annotations
</a>
</li>
<li class="toc-h3 nav-item toc-entry">
<a class="reference internal nav-link" href="#adding-lazy-constraints-through-callbacks">
Adding lazy constraints through callbacks
</a>
</li>
</ul>
</li>
<li class="toc-h2 nav-item toc-entry">
<a class="reference internal nav-link" href="#obtaining-heuristic-solutions">
<span class="sectnum">
1.5.
</span>
Obtaining heuristic solutions
</a>
</li>
<li class="toc-h2 nav-item toc-entry">
<a class="reference internal nav-link" href="#scaling-up">
<span class="sectnum">
1.6.
</span>
Scaling Up
</a>
<ul class="nav section-nav flex-column">
<li class="toc-h3 nav-item toc-entry">
<a class="reference internal nav-link" href="#saving-and-loading-solver-state">
Saving and loading solver state
</a>
</li>
<li class="toc-h3 nav-item toc-entry">
<a class="reference internal nav-link" href="#solving-instances-in-parallel">
Solving instances in parallel
</a>
</li>
<li class="toc-h3 nav-item toc-entry">
<a class="reference internal nav-link" href="#solving-instances-from-the-disk">
Solving instances from the disk
</a>
</li>
</ul>
</li>
<li class="toc-h2 nav-item toc-entry">
<a class="reference internal nav-link" href="#running-benchmarks">
<span class="sectnum">
1.7.
</span>
Running benchmarks
</a>
</li>
<li class="toc-h2 nav-item toc-entry">
<a class="reference internal nav-link" href="#current-limitations">
<span class="sectnum">
1.8.
</span>
Current Limitations
</a>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div id="main-content" class="row">
<div class="col-12 col-md-9 pl-md-3 pr-md-0">
<div>
<div class="section" id="using-miplearn">
<h1><span class="sectnum">1.</span> Using MIPLearn<a class="headerlink" href="#using-miplearn" title="Permalink to this headline"></a></h1>
<div class="section" id="installation">
<h2><span class="sectnum">1.1.</span> Installation<a class="headerlink" href="#installation" title="Permalink to this headline"></a></h2>
<p>In these docs, we describe the Python/Pyomo version of the package, although a <a class="reference external" href="https://github.com/ANL-CEEESA/MIPLearn.jl">Julia/JuMP version</a> is also available. A mixed-integer solver is also required and its Python bindings must be properly installed. Supported solvers are currently CPLEX, Gurobi and XPRESS.</p>
<p>To install MIPLearn, run:</p>
<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span>pip3 install --upgrade <span class="nv">miplearn</span><span class="o">==</span><span class="m">0</span>.2.*
</pre></div>
</div>
<p>After installation, the package <code class="docutils literal notranslate"><span class="pre">miplearn</span></code> should become available to Python. It can be imported
as follows:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">miplearn</span>
</pre></div>
</div>
</div>
<div class="section" id="using-learningsolver">
<h2><span class="sectnum">1.2.</span> Using <code class="docutils literal notranslate"><span class="pre">LearningSolver</span></code><a class="headerlink" href="#using-learningsolver" title="Permalink to this headline"></a></h2>
<p>The main class provided by this package is <code class="docutils literal notranslate"><span class="pre">LearningSolver</span></code>, a learning-enhanced MIP solver which uses information from previously solved instances to accelerate the solution of new instances. The following example shows its basic usage:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">miplearn</span> <span class="kn">import</span> <span class="n">LearningSolver</span>
<span class="c1"># List of user-provided instances</span>
<span class="n">training_instances</span> <span class="o">=</span> <span class="p">[</span><span class="o">...</span><span class="p">]</span>
<span class="n">test_instances</span> <span class="o">=</span> <span class="p">[</span><span class="o">...</span><span class="p">]</span>
<span class="c1"># Create solver</span>
<span class="n">solver</span> <span class="o">=</span> <span class="n">LearningSolver</span><span class="p">()</span>
<span class="c1"># Solve all training instances</span>
<span class="k">for</span> <span class="n">instance</span> <span class="ow">in</span> <span class="n">training_instances</span><span class="p">:</span>
<span class="n">solver</span><span class="o">.</span><span class="n">solve</span><span class="p">(</span><span class="n">instance</span><span class="p">)</span>
<span class="c1"># Learn from training instances</span>
<span class="n">solver</span><span class="o">.</span><span class="n">fit</span><span class="p">(</span><span class="n">training_instances</span><span class="p">)</span>
<span class="c1"># Solve all test instances</span>
<span class="k">for</span> <span class="n">instance</span> <span class="ow">in</span> <span class="n">test_instances</span><span class="p">:</span>
<span class="n">solver</span><span class="o">.</span><span class="n">solve</span><span class="p">(</span><span class="n">instance</span><span class="p">)</span>
</pre></div>
</div>
<p>In this example, we have two lists of user-provided instances: <code class="docutils literal notranslate"><span class="pre">training_instances</span></code> and <code class="docutils literal notranslate"><span class="pre">test_instances</span></code>. We start by solving all training instances. Since there is no historical information available at this point, the instances will be processed from scratch, with no ML acceleration. After solving each instance, the solver stores within each <code class="docutils literal notranslate"><span class="pre">instance</span></code> object the optimal solution, the optimal objective value, and other information that can be used to accelerate future solves. After all training instances are solved, we call <code class="docutils literal notranslate"><span class="pre">solver.fit(training_instances)</span></code>. This instructs the solver to train all its internal machine-learning models based on the solutions of the (solved) trained instances. Subsequent calls to <code class="docutils literal notranslate"><span class="pre">solver.solve(instance)</span></code> will automatically use the trained Machine Learning models to accelerate the solution process.</p>
</div>
<div class="section" id="describing-problem-instances">
<h2><span class="sectnum">1.3.</span> Describing problem instances<a class="headerlink" href="#describing-problem-instances" title="Permalink to this headline"></a></h2>
<p>Instances to be solved by <code class="docutils literal notranslate"><span class="pre">LearningSolver</span></code> must derive from the abstract class <code class="docutils literal notranslate"><span class="pre">miplearn.Instance</span></code>. The following three abstract methods must be implemented:</p>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">instance.to_model()</span></code>, which returns a concrete Pyomo model corresponding to the instance;</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">instance.get_instance_features()</span></code>, which returns a 1-dimensional Numpy array of (numerical) features describing the entire instance;</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">instance.get_variable_features(var_name,</span> <span class="pre">index)</span></code>, which returns a 1-dimensional array of (numerical) features describing a particular decision variable.</p></li>
</ul>
<p>The first method is used by <code class="docutils literal notranslate"><span class="pre">LearningSolver</span></code> to construct a concrete Pyomo model, which will be provided to the internal MIP solver. The second and third methods provide an encoding of the instance, which can be used by the ML models to make predictions. In the knapsack problem, for example, an implementation may decide to provide as instance features the average weights, average prices, number of items and the size of the knapsack. The weight and the price of each individual item could be provided as variable features. See <code class="docutils literal notranslate"><span class="pre">src/python/miplearn/problems/knapsack.py</span></code> for a concrete example.</p>
<p>An optional method which can be implemented is <code class="docutils literal notranslate"><span class="pre">instance.get_variable_category(var_name,</span> <span class="pre">index)</span></code>, which returns a category (a string, an integer or any hashable type) for each decision variable. If two variables have the same category, <code class="docutils literal notranslate"><span class="pre">LearningSolver</span></code> will use the same internal ML model to predict the values of both variables. By default, all variables belong to the <code class="docutils literal notranslate"><span class="pre">&quot;default&quot;</span></code> category, and therefore only one ML model is used for all variables. If the returned category is <code class="docutils literal notranslate"><span class="pre">None</span></code>, ML predictors will ignore the variable.</p>
<p>It is not necessary to have a one-to-one correspondence between features and problem instances. One important (and deliberate) limitation of MIPLearn, however, is that <code class="docutils literal notranslate"><span class="pre">get_instance_features()</span></code> must always return arrays of same length for all relevant instances of the problem. Similarly, <code class="docutils literal notranslate"><span class="pre">get_variable_features(var_name,</span> <span class="pre">index)</span></code> must also always return arrays of same length for all variables in each category. It is up to the user to decide how to encode variable-length characteristics of the problem into fixed-length vectors. In graph problems, for example, graph embeddings can be used to reduce the (variable-length) lists of nodes and edges into a fixed-length structure that still preserves some properties of the graph. Different instance encodings may have significant impact on performance.</p>
</div>
<div class="section" id="describing-lazy-constraints">
<h2><span class="sectnum">1.4.</span> Describing lazy constraints<a class="headerlink" href="#describing-lazy-constraints" title="Permalink to this headline"></a></h2>
<p>For many MIP formulations, it is not desirable to add all constraints up-front, either because the total number of constraints is very large, or because some of the constraints, even in relatively small numbers, can still cause significant performance impact when added to the formulation. In these situations, it may be desirable to generate and add constraints incrementaly, during the solution process itself. Conventional MIP solvers typically start by solving the problem without any lazy constraints. Whenever a candidate solution is found, the solver finds all violated lazy constraints and adds them to the formulation. MIPLearn significantly accelerates this process by using ML to predict which lazy constraints should be enforced from the very beginning of the optimization process, even before a candidate solution is available.</p>
<p>MIPLearn supports two types of lazy constraints: through constraint annotations and through callbacks.</p>
<div class="section" id="adding-lazy-constraints-through-annotations">
<h3>Adding lazy constraints through annotations<a class="headerlink" href="#adding-lazy-constraints-through-annotations" title="Permalink to this headline"></a></h3>
<p>The easiest way to create lazy constraints in MIPLearn is to add them to the model (just like any regular constraints), then annotate them as lazy, as described below. Just before the optimization starts, MIPLearn removes all lazy constraints from the model and places them in a lazy constraint pool. If any trained ML models are available, MIPLearn queries these models to decide which of these constraints should be moved back into the formulation. After this step, the optimization starts, and lazy constraints from the pool are added to the model in the conventional fashion.</p>
<p>To tag a constraint as lazy, the following methods must be implemented:</p>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">instance.has_static_lazy_constraints()</span></code>, which returns <code class="docutils literal notranslate"><span class="pre">True</span></code> if the model has any annotated lazy constraints. By default, this method returns <code class="docutils literal notranslate"><span class="pre">False</span></code>.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">instance.is_constraint_lazy(cid)</span></code>, which returns <code class="docutils literal notranslate"><span class="pre">True</span></code> if the constraint with name <code class="docutils literal notranslate"><span class="pre">cid</span></code> should be treated as a lazy constraint, and <code class="docutils literal notranslate"><span class="pre">False</span></code> otherwise.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">instance.get_constraint_features(cid)</span></code>, which returns a 1-dimensional Numpy array of (numerical) features describing the constraint.</p></li>
</ul>
<p>For instances such that <code class="docutils literal notranslate"><span class="pre">has_lazy_constraints</span></code> returns <code class="docutils literal notranslate"><span class="pre">True</span></code>, MIPLearn calls <code class="docutils literal notranslate"><span class="pre">is_constraint_lazy</span></code> for each constraint in the formulation, providing the name of the constraint. For constraints such that <code class="docutils literal notranslate"><span class="pre">is_constraint_lazy</span></code> returns <code class="docutils literal notranslate"><span class="pre">True</span></code>, MIPLearn additionally calls <code class="docutils literal notranslate"><span class="pre">get_constraint_features</span></code> to gather a ML representation of each constraint. These features are used to predict which lazy constraints should be initially enforced.</p>
<p>An additional method that can be implemented is <code class="docutils literal notranslate"><span class="pre">get_lazy_constraint_category(cid)</span></code>, which returns a category (a string or any other hashable type) for each lazy constraint. Similarly to decision variable categories, if two lazy constraints have the same category, then MIPLearn will use the same internal ML model to decide whether to initially enforce them. By default, all lazy constraints belong to the <code class="docutils literal notranslate"><span class="pre">&quot;default&quot;</span></code> category, and therefore a single ML model is used.</p>
<p>!!! warning
If two lazy constraints belong to the same category, their feature vectors should have the same length.</p>
</div>
<div class="section" id="adding-lazy-constraints-through-callbacks">
<h3>Adding lazy constraints through callbacks<a class="headerlink" href="#adding-lazy-constraints-through-callbacks" title="Permalink to this headline"></a></h3>
<p>Although convenient, the method described in the previous subsection still requires the generation of all lazy constraints ahead of time, which can be prohibitively expensive. An alternative method is through a lazy constraint callbacks, described below. During the solution process, MIPLearn will repeatedly call a user-provided function to identify any violated lazy constraints. If violated constraints are identified, MIPLearn will additionally call another user-provided function to generate the constraint and add it to the formulation.</p>
<p>To describe lazy constraints through user callbacks, the following methods need to be implemented:</p>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">instance.has_dynamic_lazy_constraints()</span></code>, which returns <code class="docutils literal notranslate"><span class="pre">True</span></code> if the model has any lazy constraints generated by user callbacks. By default, this method returns <code class="docutils literal notranslate"><span class="pre">False</span></code>.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">instance.find_violated_lazy_constraints(model)</span></code>, which returns a list of identifiers corresponding to the lazy constraints found to be violated by the current solution. These identifiers should be strings, tuples or any other hashable type.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">instance.build_violated_lazy_constraints(model,</span> <span class="pre">cid)</span></code>, which returns either a list of Pyomo constraints, or a single Pyomo constraint, corresponding to the given lazy constraint identifier.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">instance.get_constraint_features(cid)</span></code>, which returns a 1-dimensional Numpy array of (numerical) features describing the constraint. If this constraint is not valid, returns <code class="docutils literal notranslate"><span class="pre">None</span></code>.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">instance.get_lazy_constraint_category(cid)</span></code>, which returns a category (a string or any other hashable type) for each lazy constraint, indicating which ML model to use. By default, returns <code class="docutils literal notranslate"><span class="pre">&quot;default&quot;</span></code>.</p></li>
</ul>
<p>Assuming that trained ML models are available, immediately after calling <code class="docutils literal notranslate"><span class="pre">solver.solve</span></code>, MIPLearn will call <code class="docutils literal notranslate"><span class="pre">get_constraint_features</span></code> for each lazy constraint identifier found in the training set. For constraints such that <code class="docutils literal notranslate"><span class="pre">get_constraint_features</span></code> returns a vector (instead of <code class="docutils literal notranslate"><span class="pre">None</span></code>), MIPLearn will call <code class="docutils literal notranslate"><span class="pre">get_constraint_category</span></code> to decide which trained ML model to use. It will then query the ML model to decide whether the constraint should be initially enforced. Assuming that the ML predicts this constraint will be necessary, MIPLearn calls <code class="docutils literal notranslate"><span class="pre">build_violated_constraints</span></code> then adds the returned list of Pyomo constraints to the model. The optimization then starts. When no trained ML models are available, this entire initial process is skipped, and MIPLearn behaves like a conventional solver.</p>
<p>After the optimization process starts, MIPLearn will periodically call <code class="docutils literal notranslate"><span class="pre">find_violated_lazy_constraints</span></code> to verify if the current solution violates any lazy constraints. If any violated lazy constraints are found, MIPLearn will call the method <code class="docutils literal notranslate"><span class="pre">build_violated_lazy_constraints</span></code> and add the returned constraints to the formulation.</p>
<div class="admonition tip">
<p class="admonition-title">Tip</p>
<p>When implementing <code class="docutils literal notranslate"><span class="pre">find_violated_lazy_constraints(self,</span> <span class="pre">model)</span></code>, the current solution may be accessed through <code class="docutils literal notranslate"><span class="pre">self.solution[var_name][index]</span></code>.</p>
</div>
</div>
</div>
<div class="section" id="obtaining-heuristic-solutions">
<h2><span class="sectnum">1.5.</span> Obtaining heuristic solutions<a class="headerlink" href="#obtaining-heuristic-solutions" title="Permalink to this headline"></a></h2>
<p>By default, <code class="docutils literal notranslate"><span class="pre">LearningSolver</span></code> uses Machine Learning to accelerate the MIP solution process, while maintaining all optimality guarantees provided by the MIP solver. In the default mode of operation, for example, predicted optimal solutions are used only as MIP starts.</p>
<p>For more significant performance benefits, <code class="docutils literal notranslate"><span class="pre">LearningSolver</span></code> can also be configured to place additional trust in the Machine Learning predictors, by using the <code class="docutils literal notranslate"><span class="pre">mode=&quot;heuristic&quot;</span></code> constructor argument. When operating in this mode, if a ML model is statistically shown (through <em>stratified k-fold cross validation</em>) to have exceptionally high accuracy, the solver may decide to restrict the search space based on its predictions. The parts of the solution which the ML models cannot predict accurately will still be explored using traditional (branch-and-bound) methods. For particular applications, this mode has been shown to quickly produce optimal or near-optimal solutions (see <a class="reference external" href="about.md#references">references</a> and <a class="reference internal" href="../benchmark/"><span class="doc std std-doc">benchmark results</span></a>).</p>
<div class="admonition danger">
<p class="admonition-title">Danger</p>
<p>The <code class="docutils literal notranslate"><span class="pre">heuristic</span></code> mode provides no optimality guarantees, and therefore should only be used if the solver is first trained on a large and representative set of training instances. Training on a small or non-representative set of instances may produce low-quality solutions, or make the solver incorrectly classify new instances as infeasible.</p>
</div>
</div>
<div class="section" id="scaling-up">
<h2><span class="sectnum">1.6.</span> Scaling Up<a class="headerlink" href="#scaling-up" title="Permalink to this headline"></a></h2>
<div class="section" id="saving-and-loading-solver-state">
<h3>Saving and loading solver state<a class="headerlink" href="#saving-and-loading-solver-state" title="Permalink to this headline"></a></h3>
<p>After solving a large number of training instances, it may be desirable to save the current state of <code class="docutils literal notranslate"><span class="pre">LearningSolver</span></code> to disk, so that the solver can still use the acquired knowledge after the application restarts. This can be accomplished by using the the utility functions <code class="docutils literal notranslate"><span class="pre">write_pickle_gz</span></code> and <code class="docutils literal notranslate"><span class="pre">read_pickle_gz</span></code>, as the following example illustrates:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">miplearn</span> <span class="kn">import</span> <span class="n">LearningSolver</span><span class="p">,</span> <span class="n">write_pickle_gz</span><span class="p">,</span> <span class="n">read_pickle_gz</span>
<span class="c1"># Solve training instances</span>
<span class="n">training_instances</span> <span class="o">=</span> <span class="p">[</span><span class="o">...</span><span class="p">]</span>
<span class="n">solver</span> <span class="o">=</span> <span class="n">LearningSolver</span><span class="p">()</span>
<span class="k">for</span> <span class="n">instance</span> <span class="ow">in</span> <span class="n">training_instances</span><span class="p">:</span>
<span class="n">solver</span><span class="o">.</span><span class="n">solve</span><span class="p">(</span><span class="n">instance</span><span class="p">)</span>
<span class="c1"># Train machine-learning models</span>
<span class="n">solver</span><span class="o">.</span><span class="n">fit</span><span class="p">(</span><span class="n">training_instances</span><span class="p">)</span>
<span class="c1"># Save trained solver to disk</span>
<span class="n">write_pickle_gz</span><span class="p">(</span><span class="n">solver</span><span class="p">,</span> <span class="s2">&quot;solver.pkl.gz&quot;</span><span class="p">)</span>
<span class="c1"># Application restarts...</span>
<span class="c1"># Load trained solver from disk</span>
<span class="n">solver</span> <span class="o">=</span> <span class="n">read_pickle_gz</span><span class="p">(</span><span class="s2">&quot;solver.pkl.gz&quot;</span><span class="p">)</span>
<span class="c1"># Solve additional instances</span>
<span class="n">test_instances</span> <span class="o">=</span> <span class="p">[</span><span class="o">...</span><span class="p">]</span>
<span class="k">for</span> <span class="n">instance</span> <span class="ow">in</span> <span class="n">test_instances</span><span class="p">:</span>
<span class="n">solver</span><span class="o">.</span><span class="n">solve</span><span class="p">(</span><span class="n">instance</span><span class="p">)</span>
</pre></div>
</div>
</div>
<div class="section" id="solving-instances-in-parallel">
<h3>Solving instances in parallel<a class="headerlink" href="#solving-instances-in-parallel" title="Permalink to this headline"></a></h3>
<p>In many situations, instances can be solved in parallel to accelerate the training process. <code class="docutils literal notranslate"><span class="pre">LearningSolver</span></code> provides the method <code class="docutils literal notranslate"><span class="pre">parallel_solve(instances)</span></code> to easily achieve this:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">miplearn</span> <span class="kn">import</span> <span class="n">LearningSolver</span>
<span class="n">training_instances</span> <span class="o">=</span> <span class="p">[</span><span class="o">...</span><span class="p">]</span>
<span class="n">solver</span> <span class="o">=</span> <span class="n">LearningSolver</span><span class="p">()</span>
<span class="n">solver</span><span class="o">.</span><span class="n">parallel_solve</span><span class="p">(</span><span class="n">training_instances</span><span class="p">,</span> <span class="n">n_jobs</span><span class="o">=</span><span class="mi">4</span><span class="p">)</span>
<span class="n">solver</span><span class="o">.</span><span class="n">fit</span><span class="p">(</span><span class="n">training_instances</span><span class="p">)</span>
<span class="c1"># Test phase...</span>
<span class="n">test_instances</span> <span class="o">=</span> <span class="p">[</span><span class="o">...</span><span class="p">]</span>
<span class="n">solver</span><span class="o">.</span><span class="n">parallel_solve</span><span class="p">(</span><span class="n">test_instances</span><span class="p">)</span>
</pre></div>
</div>
</div>
<div class="section" id="solving-instances-from-the-disk">
<h3>Solving instances from the disk<a class="headerlink" href="#solving-instances-from-the-disk" title="Permalink to this headline"></a></h3>
<p>In all examples above, we have assumed that instances are available as Python objects, stored in memory. When problem instances are very large, or when there is a large number of problem instances, this approach may require an excessive amount of memory. To reduce memory requirements, MIPLearn can also operate on instances that are stored on disk, through the <code class="docutils literal notranslate"><span class="pre">PickleGzInstance</span></code> class, as the next example illustrates.</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">pickle</span>
<span class="kn">from</span> <span class="nn">miplearn</span> <span class="kn">import</span> <span class="p">(</span>
<span class="n">LearningSolver</span><span class="p">,</span>
<span class="n">PickleGzInstance</span><span class="p">,</span>
<span class="n">write_pickle_gz</span><span class="p">,</span>
<span class="p">)</span>
<span class="c1"># Construct and pickle 600 problem instances</span>
<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">600</span><span class="p">):</span>
<span class="n">instance</span> <span class="o">=</span> <span class="n">MyProblemInstance</span><span class="p">([</span><span class="o">...</span><span class="p">])</span>
<span class="n">write_pickle_gz</span><span class="p">(</span><span class="n">instance</span><span class="p">,</span> <span class="s2">&quot;instance_</span><span class="si">%03d</span><span class="s2">.pkl&quot;</span> <span class="o">%</span> <span class="n">i</span><span class="p">)</span>
<span class="c1"># Split instances into training and test</span>
<span class="n">test_instances</span> <span class="o">=</span> <span class="p">[</span><span class="n">PickleGzInstance</span><span class="p">(</span><span class="s2">&quot;instance_</span><span class="si">%03d</span><span class="s2">.pkl&quot;</span> <span class="o">%</span> <span class="n">i</span><span class="p">)</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">500</span><span class="p">)]</span>
<span class="n">train_instances</span> <span class="o">=</span> <span class="p">[</span><span class="n">PickleGzInstance</span><span class="p">(</span><span class="s2">&quot;instance_</span><span class="si">%03d</span><span class="s2">.pkl&quot;</span> <span class="o">%</span> <span class="n">i</span><span class="p">)</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">500</span><span class="p">,</span> <span class="mi">600</span><span class="p">)]</span>
<span class="c1"># Create solver</span>
<span class="n">solver</span> <span class="o">=</span> <span class="n">LearningSolver</span><span class="p">([</span><span class="o">...</span><span class="p">])</span>
<span class="c1"># Solve training instances </span>
<span class="n">solver</span><span class="o">.</span><span class="n">parallel_solve</span><span class="p">(</span><span class="n">train_instances</span><span class="p">,</span> <span class="n">n_jobs</span><span class="o">=</span><span class="mi">4</span><span class="p">)</span>
<span class="c1"># Train ML models</span>
<span class="n">solver</span><span class="o">.</span><span class="n">fit</span><span class="p">(</span><span class="n">train_instances</span><span class="p">)</span>
<span class="c1"># Solve test instances </span>
<span class="n">solver</span><span class="o">.</span><span class="n">parallel_solve</span><span class="p">(</span><span class="n">test_instances</span><span class="p">,</span> <span class="n">n_jobs</span><span class="o">=</span><span class="mi">4</span><span class="p">)</span>
</pre></div>
</div>
<p>By default, <code class="docutils literal notranslate"><span class="pre">solve</span></code> and <code class="docutils literal notranslate"><span class="pre">parallel_solve</span></code> modify files in place. That is, after the instances are loaded from disk and solved, MIPLearn writes them back to the disk, overwriting the original files. To discard the modifications instead, use <code class="docutils literal notranslate"><span class="pre">LearningSolver(...,</span> <span class="pre">discard_outputs=True)</span></code>. This can be useful, for example, during benchmarks.</p>
</div>
</div>
<div class="section" id="running-benchmarks">
<h2><span class="sectnum">1.7.</span> Running benchmarks<a class="headerlink" href="#running-benchmarks" title="Permalink to this headline"></a></h2>
<p>MIPLearn provides the utility class <code class="docutils literal notranslate"><span class="pre">BenchmarkRunner</span></code>, which simplifies the task of comparing the performance of different solvers. The snippet below shows its basic usage:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">miplearn</span> <span class="kn">import</span> <span class="n">BenchmarkRunner</span><span class="p">,</span> <span class="n">LearningSolver</span>
<span class="c1"># Create train and test instances</span>
<span class="n">train_instances</span> <span class="o">=</span> <span class="p">[</span><span class="o">...</span><span class="p">]</span>
<span class="n">test_instances</span> <span class="o">=</span> <span class="p">[</span><span class="o">...</span><span class="p">]</span>
<span class="c1"># Training phase...</span>
<span class="n">training_solver</span> <span class="o">=</span> <span class="n">LearningSolver</span><span class="p">(</span><span class="o">...</span><span class="p">)</span>
<span class="n">training_solver</span><span class="o">.</span><span class="n">parallel_solve</span><span class="p">(</span><span class="n">train_instances</span><span class="p">,</span> <span class="n">n_jobs</span><span class="o">=</span><span class="mi">10</span><span class="p">)</span>
<span class="c1"># Test phase...</span>
<span class="n">benchmark</span> <span class="o">=</span> <span class="n">BenchmarkRunner</span><span class="p">({</span>
<span class="s2">&quot;Baseline&quot;</span><span class="p">:</span> <span class="n">LearningSolver</span><span class="p">(</span><span class="o">...</span><span class="p">),</span>
<span class="s2">&quot;Strategy A&quot;</span><span class="p">:</span> <span class="n">LearningSolver</span><span class="p">(</span><span class="o">...</span><span class="p">),</span>
<span class="s2">&quot;Strategy B&quot;</span><span class="p">:</span> <span class="n">LearningSolver</span><span class="p">(</span><span class="o">...</span><span class="p">),</span>
<span class="s2">&quot;Strategy C&quot;</span><span class="p">:</span> <span class="n">LearningSolver</span><span class="p">(</span><span class="o">...</span><span class="p">),</span>
<span class="p">})</span>
<span class="n">benchmark</span><span class="o">.</span><span class="n">fit</span><span class="p">(</span><span class="n">train_instances</span><span class="p">)</span>
<span class="n">benchmark</span><span class="o">.</span><span class="n">parallel_solve</span><span class="p">(</span><span class="n">test_instances</span><span class="p">,</span> <span class="n">n_jobs</span><span class="o">=</span><span class="mi">5</span><span class="p">)</span>
<span class="n">benchmark</span><span class="o">.</span><span class="n">write_csv</span><span class="p">(</span><span class="s2">&quot;results.csv&quot;</span><span class="p">)</span>
</pre></div>
</div>
<p>The method <code class="docutils literal notranslate"><span class="pre">fit</span></code> trains the ML models for each individual solver. The method <code class="docutils literal notranslate"><span class="pre">parallel_solve</span></code> solves the test instances in parallel, and collects solver statistics such as running time and optimal value. Finally, <code class="docutils literal notranslate"><span class="pre">write_csv</span></code> produces a table of results. The columns in the CSV file depend on the components added to the solver.</p>
</div>
<div class="section" id="current-limitations">
<h2><span class="sectnum">1.8.</span> Current Limitations<a class="headerlink" href="#current-limitations" title="Permalink to this headline"></a></h2>
<ul class="simple">
<li><p>Only binary and continuous decision variables are currently supported. General integer variables are not currently supported by some solver components.</p></li>
</ul>
</div>
</div>
</div>
<div class='prev-next-bottom'>
<a class='left-prev' id="prev-link" href="../" title="previous page">MIPLearn</a>
<a class='right-next' id="next-link" href="../benchmark/" title="next page"><span class="sectnum">2.</span> Benchmarks</a>
</div>
</div>
</div>
<footer class="footer mt-5 mt-md-0">
<div class="container">
<p>
&copy; Copyright 2020-2021, UChicago Argonne, LLC.<br/>
</p>
</div>
</footer>
</main>
</div>
</div>
<script src="../_static/js/index.1c5a1a01449ed65a7b51.js"></script>
</body>
</html>
Loading…
Cancel
Save