Update docs

docs
Alinson S. Xavier 4 years ago
parent ac2ee48599
commit 95556c02a2

@ -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)

@ -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)
```

@ -11,7 +11,7 @@ Instances
UnitCommitment.jl provides a large collection of benchmark instances collected UnitCommitment.jl provides a large collection of benchmark instances collected
from the literature and converted to a [common data format](format.md). In some cases, as indicated below, the original instances have been extended, with realistic parameters, using data-driven methods. from the literature and converted to a [common data format](format.md). In some cases, as indicated below, the original instances have been extended, with realistic parameters, using data-driven methods.
If you use these instances in your research, we request that you cite UnitCommitment.jl [UCJL], as well as the original sources. If you use these instances in your research, we request that you cite UnitCommitment.jl, as well as the original sources.
Raw instances files are [available at our GitHub repository](https://github.com/ANL-CEEESA/UnitCommitment.jl/tree/dev/instances). Benchmark instances can also be loaded with Raw instances files are [available at our GitHub repository](https://github.com/ANL-CEEESA/UnitCommitment.jl/tree/dev/instances). Benchmark instances can also be loaded with
`UnitCommitment.read_benchmark(name)`, as explained in the [usage section](usage.md). `UnitCommitment.read_benchmark(name)`, as explained in the [usage section](usage.md).

@ -190,12 +190,6 @@ JuMP.set_objective_coefficient(
UnitCommitment.optimize!(model) UnitCommitment.optimize!(model)
``` ```
### Adding components to a bus
One of the most common modifications to a unit commitment model is adding a new customized system component to a bus. The script below shows how to add
References References
---------- ----------
* [KnOsWa20] **Bernard Knueven, James Ostrowski and Jean-Paul Watson.** "On Mixed-Integer Programming Formulations for the Unit Commitment Problem". INFORMS Journal on Computing (2020). [DOI: 10.1287/ijoc.2019.0944](https://doi.org/10.1287/ijoc.2019.0944) * [KnOsWa20] **Bernard Knueven, James Ostrowski and Jean-Paul Watson.** "On Mixed-Integer Programming Formulations for the Unit Commitment Problem". INFORMS Journal on Computing (2020). [DOI: 10.1287/ijoc.2019.0944](https://doi.org/10.1287/ijoc.2019.0944)

@ -53,7 +53,7 @@ model = UnitCommitment.build_model(
UnitCommitment.optimize!(model) UnitCommitment.optimize!(model)
# Extract solution and write it to a file # Extract solution and write it to a file
solution = UnitCommitment.get_solution(model) solution = UnitCommitment.solution(model)
open("/path/to/output.json", "w") do file open("/path/to/output.json", "w") do file
JSON.print(file, solution, 2) JSON.print(file, solution, 2)
end end

@ -1,472 +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; UnitCommitment.jl&lt;br/&gt;&lt;small&gt;0.2&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="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">UnitCommitment.jl<br/><small>0.2</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="nav bd-sidenav">
<li class="toctree-l1">
<a class="reference internal" href="../usage/">
<span class="sectnum">
1.
</span>
Usage
</a>
</li>
<li class="toctree-l1">
<a class="reference internal" href="../format/">
<span class="sectnum">
2.
</span>
Data Format
</a>
</li>
<li class="toctree-l1">
<a class="reference internal" href="../instances/">
<span class="sectnum">
3.
</span>
Instances
</a>
</li>
<li class="toctree-l1">
<a class="reference internal" href="../model/">
<span class="sectnum">
4.
</span>
JuMP Model
</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/UnitCommitment.jl/"><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'>
</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,427 +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; UnitCommitment.jl&lt;br/&gt;&lt;small&gt;0.2&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="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">UnitCommitment.jl<br/><small>0.2</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="nav bd-sidenav">
<li class="toctree-l1">
<a class="reference internal" href="../usage/">
<span class="sectnum">
1.
</span>
Usage
</a>
</li>
<li class="toctree-l1">
<a class="reference internal" href="../format/">
<span class="sectnum">
2.
</span>
Data Format
</a>
</li>
<li class="toctree-l1">
<a class="reference internal" href="../instances/">
<span class="sectnum">
3.
</span>
Instances
</a>
</li>
<li class="toctree-l1">
<a class="reference internal" href="../model/">
<span class="sectnum">
4.
</span>
JuMP Model
</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/UnitCommitment.jl/"><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'>
</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>

@ -271,7 +271,7 @@
<h1><span class="sectnum">3.</span> Instances<a class="headerlink" href="#instances" title="Permalink to this headline"></a></h1> <h1><span class="sectnum">3.</span> Instances<a class="headerlink" href="#instances" title="Permalink to this headline"></a></h1>
<p>UnitCommitment.jl provides a large collection of benchmark instances collected <p>UnitCommitment.jl provides a large collection of benchmark instances collected
from the literature and converted to a <a class="reference internal" href="../format/"><span class="doc std std-doc">common data format</span></a>. In some cases, as indicated below, the original instances have been extended, with realistic parameters, using data-driven methods. from the literature and converted to a <a class="reference internal" href="../format/"><span class="doc std std-doc">common data format</span></a>. In some cases, as indicated below, the original instances have been extended, with realistic parameters, using data-driven methods.
If you use these instances in your research, we request that you cite UnitCommitment.jl [UCJL], as well as the original sources.</p> If you use these instances in your research, we request that you cite UnitCommitment.jl, as well as the original sources.</p>
<p>Raw instances files are <a class="reference external" href="https://github.com/ANL-CEEESA/UnitCommitment.jl/tree/dev/instances">available at our GitHub repository</a>. Benchmark instances can also be loaded with <p>Raw instances files are <a class="reference external" href="https://github.com/ANL-CEEESA/UnitCommitment.jl/tree/dev/instances">available at our GitHub repository</a>. Benchmark instances can also be loaded with
<code class="docutils literal notranslate"><span class="pre">UnitCommitment.read_benchmark(name)</span></code>, as explained in the <a class="reference internal" href="../usage/"><span class="doc std std-doc">usage section</span></a>.</p> <code class="docutils literal notranslate"><span class="pre">UnitCommitment.read_benchmark(name)</span></code>, as explained in the <a class="reference internal" href="../usage/"><span class="doc std std-doc">usage section</span></a>.</p>
<div class="section" id="matpower"> <div class="section" id="matpower">

@ -242,11 +242,6 @@
Modifying the model Modifying the model
</a> </a>
</li> </li>
<li class="toc-h3 nav-item toc-entry">
<a class="reference internal nav-link" href="#adding-components-to-a-bus">
Adding components to a bus
</a>
</li>
</ul> </ul>
</li> </li>
<li class="toc-h2 nav-item toc-entry"> <li class="toc-h2 nav-item toc-entry">
@ -527,10 +522,6 @@
</pre></div> </pre></div>
</div> </div>
</div> </div>
<div class="section" id="adding-components-to-a-bus">
<h3>Adding components to a bus<a class="headerlink" href="#adding-components-to-a-bus" title="Permalink to this headline"></a></h3>
<p>One of the most common modifications to a unit commitment model is adding a new customized system component to a bus. The script below shows how to add</p>
</div>
</div> </div>
<div class="section" id="references"> <div class="section" id="references">
<h2><span class="sectnum">4.5.</span> References<a class="headerlink" href="#references" title="Permalink to this headline"></a></h2> <h2><span class="sectnum">4.5.</span> References<a class="headerlink" href="#references" title="Permalink to this headline"></a></h2>

Binary file not shown.

File diff suppressed because one or more lines are too long

@ -278,7 +278,7 @@
<span class="n">UnitCommitment</span><span class="o">.</span><span class="n">optimize!</span><span class="p">(</span><span class="n">model</span><span class="p">)</span> <span class="n">UnitCommitment</span><span class="o">.</span><span class="n">optimize!</span><span class="p">(</span><span class="n">model</span><span class="p">)</span>
<span class="c"># Extract solution and write it to a file</span> <span class="c"># Extract solution and write it to a file</span>
<span class="n">solution</span> <span class="o">=</span> <span class="n">UnitCommitment</span><span class="o">.</span><span class="n">get_solution</span><span class="p">(</span><span class="n">model</span><span class="p">)</span> <span class="n">solution</span> <span class="o">=</span> <span class="n">UnitCommitment</span><span class="o">.</span><span class="n">solution</span><span class="p">(</span><span class="n">model</span><span class="p">)</span>
<span class="n">open</span><span class="p">(</span><span class="s">&quot;/path/to/output.json&quot;</span><span class="p">,</span> <span class="s">&quot;w&quot;</span><span class="p">)</span> <span class="k">do</span> <span class="n">file</span> <span class="n">open</span><span class="p">(</span><span class="s">&quot;/path/to/output.json&quot;</span><span class="p">,</span> <span class="s">&quot;w&quot;</span><span class="p">)</span> <span class="k">do</span> <span class="n">file</span>
<span class="n">JSON</span><span class="o">.</span><span class="n">print</span><span class="p">(</span><span class="n">file</span><span class="p">,</span> <span class="n">solution</span><span class="p">,</span> <span class="mi">2</span><span class="p">)</span> <span class="n">JSON</span><span class="o">.</span><span class="n">print</span><span class="p">(</span><span class="n">file</span><span class="p">,</span> <span class="n">solution</span><span class="p">,</span> <span class="mi">2</span><span class="p">)</span>
<span class="k">end</span> <span class="k">end</span>

Loading…
Cancel
Save