|
|
|
|
|
<!DOCTYPE html>
|
|
|
|
|
|
|
|
|
<html lang="en" data-content_root="../../" >
|
|
|
|
|
|
<head>
|
|
|
<meta charset="utf-8" />
|
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
|
|
|
|
<title>8. Primal Components — MIPLearn 0.4</title>
|
|
|
|
|
|
|
|
|
|
|
|
<script data-cfasync="false">
|
|
|
document.documentElement.dataset.mode = localStorage.getItem("mode") || "";
|
|
|
document.documentElement.dataset.theme = localStorage.getItem("theme") || "";
|
|
|
</script>
|
|
|
|
|
|
<!-- Loaded before other Sphinx assets -->
|
|
|
<link href="../../_static/styles/theme.css?digest=dfe6caa3a7d634c4db9b" rel="stylesheet" />
|
|
|
<link href="../../_static/styles/bootstrap.css?digest=dfe6caa3a7d634c4db9b" rel="stylesheet" />
|
|
|
<link href="../../_static/styles/pydata-sphinx-theme.css?digest=dfe6caa3a7d634c4db9b" rel="stylesheet" />
|
|
|
|
|
|
|
|
|
<link href="../../_static/vendor/fontawesome/6.5.2/css/all.min.css?digest=dfe6caa3a7d634c4db9b" rel="stylesheet" />
|
|
|
<link rel="preload" as="font" type="font/woff2" crossorigin href="../../_static/vendor/fontawesome/6.5.2/webfonts/fa-solid-900.woff2" />
|
|
|
<link rel="preload" as="font" type="font/woff2" crossorigin href="../../_static/vendor/fontawesome/6.5.2/webfonts/fa-brands-400.woff2" />
|
|
|
<link rel="preload" as="font" type="font/woff2" crossorigin href="../../_static/vendor/fontawesome/6.5.2/webfonts/fa-regular-400.woff2" />
|
|
|
|
|
|
<link rel="stylesheet" type="text/css" href="../../_static/pygments.css?v=8f2a1f02" />
|
|
|
<link rel="stylesheet" type="text/css" href="../../_static/styles/sphinx-book-theme.css?v=eba8b062" />
|
|
|
<link rel="stylesheet" type="text/css" href="../../_static/nbsphinx-code-cells.css?v=2aa19091" />
|
|
|
<link rel="stylesheet" type="text/css" href="../../_static/custom.css?v=f8244a84" />
|
|
|
|
|
|
<!-- Pre-loaded scripts that we'll load fully later -->
|
|
|
<link rel="preload" as="script" href="../../_static/scripts/bootstrap.js?digest=dfe6caa3a7d634c4db9b" />
|
|
|
<link rel="preload" as="script" href="../../_static/scripts/pydata-sphinx-theme.js?digest=dfe6caa3a7d634c4db9b" />
|
|
|
<script src="../../_static/vendor/fontawesome/6.5.2/js/all.min.js?digest=dfe6caa3a7d634c4db9b"></script>
|
|
|
|
|
|
<script src="../../_static/documentation_options.js?v=a51ad17b"></script>
|
|
|
<script src="../../_static/doctools.js?v=9bcbadda"></script>
|
|
|
<script src="../../_static/sphinx_highlight.js?v=dc90522c"></script>
|
|
|
<script src="../../_static/scripts/sphinx-book-theme.js?v=887ef09a"></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>window.MathJax = {"tex": {"inlineMath": [["$", "$"], ["\\(", "\\)"]], "processEscapes": true}, "options": {"ignoreHtmlClass": "tex2jax_ignore|mathjax_ignore|document", "processHtmlClass": "tex2jax_process|mathjax_process|math|output_area"}}</script>
|
|
|
<script defer="defer" src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script>
|
|
|
<script>DOCUMENTATION_OPTIONS.pagename = 'guide/primal';</script>
|
|
|
<link rel="index" title="Index" href="../../genindex/" />
|
|
|
<link rel="search" title="Search" href="../../search/" />
|
|
|
<link rel="next" title="9. Learning Solver" href="../solvers/" />
|
|
|
<link rel="prev" title="7. Feature Extractors" href="../features/" />
|
|
|
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
|
|
<meta name="docsearch:language" content="en"/>
|
|
|
</head>
|
|
|
|
|
|
|
|
|
<body data-bs-spy="scroll" data-bs-target=".bd-toc-nav" data-offset="180" data-bs-root-margin="0px 0px -60%" data-default-mode="">
|
|
|
|
|
|
|
|
|
|
|
|
<div id="pst-skip-link" class="skip-link d-print-none"><a href="#main-content">Skip to main content</a></div>
|
|
|
|
|
|
<div id="pst-scroll-pixel-helper"></div>
|
|
|
|
|
|
<button type="button" class="btn rounded-pill" id="pst-back-to-top">
|
|
|
<i class="fa-solid fa-arrow-up"></i>Back to top</button>
|
|
|
|
|
|
|
|
|
<input type="checkbox"
|
|
|
class="sidebar-toggle"
|
|
|
id="pst-primary-sidebar-checkbox"/>
|
|
|
<label class="overlay overlay-primary" for="pst-primary-sidebar-checkbox"></label>
|
|
|
|
|
|
<input type="checkbox"
|
|
|
class="sidebar-toggle"
|
|
|
id="pst-secondary-sidebar-checkbox"/>
|
|
|
<label class="overlay overlay-secondary" for="pst-secondary-sidebar-checkbox"></label>
|
|
|
|
|
|
<div class="search-button__wrapper">
|
|
|
<div class="search-button__overlay"></div>
|
|
|
<div class="search-button__search-container">
|
|
|
<form class="bd-search d-flex align-items-center"
|
|
|
action="../../search/"
|
|
|
method="get">
|
|
|
<i class="fa-solid fa-magnifying-glass"></i>
|
|
|
<input type="search"
|
|
|
class="form-control"
|
|
|
name="q"
|
|
|
id="search-input"
|
|
|
placeholder="Search..."
|
|
|
aria-label="Search..."
|
|
|
autocomplete="off"
|
|
|
autocorrect="off"
|
|
|
autocapitalize="off"
|
|
|
spellcheck="false"/>
|
|
|
<span class="search-button__kbd-shortcut"><kbd class="kbd-shortcut__modifier">Ctrl</kbd>+<kbd>K</kbd></span>
|
|
|
</form></div>
|
|
|
</div>
|
|
|
|
|
|
<div class="pst-async-banner-revealer d-none">
|
|
|
<aside id="bd-header-version-warning" class="d-none d-print-none" aria-label="Version warning"></aside>
|
|
|
</div>
|
|
|
|
|
|
|
|
|
<header class="bd-header navbar navbar-expand-lg bd-navbar d-print-none">
|
|
|
</header>
|
|
|
|
|
|
|
|
|
<div class="bd-container">
|
|
|
<div class="bd-container__inner bd-page-width">
|
|
|
|
|
|
|
|
|
|
|
|
<div class="bd-sidebar-primary bd-sidebar">
|
|
|
|
|
|
|
|
|
|
|
|
<div class="sidebar-header-items sidebar-primary__section">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="sidebar-primary-items__start sidebar-primary__section">
|
|
|
<div class="sidebar-primary-item">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<a class="navbar-brand logo" href="../../">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<p class="title logo__title">MIPLearn 0.4</p>
|
|
|
|
|
|
</a></div>
|
|
|
<div class="sidebar-primary-item">
|
|
|
|
|
|
<script>
|
|
|
document.write(`
|
|
|
<button class="btn search-button-field search-button__button" title="Search" aria-label="Search" data-bs-placement="bottom" data-bs-toggle="tooltip">
|
|
|
<i class="fa-solid fa-magnifying-glass"></i>
|
|
|
<span class="search-button__default-text">Search</span>
|
|
|
<span class="search-button__kbd-shortcut"><kbd class="kbd-shortcut__modifier">Ctrl</kbd>+<kbd class="kbd-shortcut__modifier">K</kbd></span>
|
|
|
</button>
|
|
|
`);
|
|
|
</script></div>
|
|
|
<div class="sidebar-primary-item"><nav class="bd-links bd-docs-nav" aria-label="Main">
|
|
|
<div class="bd-toc-item navbar-nav active">
|
|
|
<p aria-level="2" class="caption" role="heading"><span class="caption-text">Tutorials</span></p>
|
|
|
<ul class="nav bd-sidenav">
|
|
|
<li class="toctree-l1"><a class="reference internal" href="../../tutorials/getting-started-pyomo/">1. Getting started (Pyomo)</a></li>
|
|
|
<li class="toctree-l1"><a class="reference internal" href="../../tutorials/getting-started-gurobipy/">2. Getting started (Gurobipy)</a></li>
|
|
|
<li class="toctree-l1"><a class="reference internal" href="../../tutorials/getting-started-jump/">3. Getting started (JuMP)</a></li>
|
|
|
<li class="toctree-l1"><a class="reference internal" href="../../tutorials/cuts-gurobipy/">4. User cuts and lazy constraints</a></li>
|
|
|
</ul>
|
|
|
<p aria-level="2" class="caption" role="heading"><span class="caption-text">User Guide</span></p>
|
|
|
<ul class="current nav bd-sidenav">
|
|
|
<li class="toctree-l1"><a class="reference internal" href="../problems/">5. Benchmark Problems</a></li>
|
|
|
<li class="toctree-l1"><a class="reference internal" href="../collectors/">6. Training Data Collectors</a></li>
|
|
|
<li class="toctree-l1"><a class="reference internal" href="../features/">7. Feature Extractors</a></li>
|
|
|
<li class="toctree-l1 current active"><a class="current reference internal" href="#">8. Primal Components</a></li>
|
|
|
<li class="toctree-l1"><a class="reference internal" href="../solvers/">9. Learning Solver</a></li>
|
|
|
</ul>
|
|
|
<p aria-level="2" class="caption" role="heading"><span class="caption-text">Python API Reference</span></p>
|
|
|
<ul class="nav bd-sidenav">
|
|
|
<li class="toctree-l1"><a class="reference internal" href="../../api/problems/">10. Benchmark Problems</a></li>
|
|
|
<li class="toctree-l1"><a class="reference internal" href="../../api/collectors/">11. Collectors & Extractors</a></li>
|
|
|
<li class="toctree-l1"><a class="reference internal" href="../../api/components/">12. Components</a></li>
|
|
|
<li class="toctree-l1"><a class="reference internal" href="../../api/solvers/">13. Solvers</a></li>
|
|
|
<li class="toctree-l1"><a class="reference internal" href="../../api/helpers/">14. Helpers</a></li>
|
|
|
</ul>
|
|
|
|
|
|
</div>
|
|
|
</nav></div>
|
|
|
</div>
|
|
|
|
|
|
|
|
|
<div class="sidebar-primary-items__end sidebar-primary__section">
|
|
|
</div>
|
|
|
|
|
|
<div id="rtd-footer-container"></div>
|
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<main id="main-content" class="bd-main" role="main">
|
|
|
|
|
|
|
|
|
|
|
|
<div class="sbt-scroll-pixel-helper"></div>
|
|
|
|
|
|
<div class="bd-content">
|
|
|
<div class="bd-article-container">
|
|
|
|
|
|
<div class="bd-header-article d-print-none">
|
|
|
<div class="header-article-items header-article__inner">
|
|
|
|
|
|
<div class="header-article-items__start">
|
|
|
|
|
|
<div class="header-article-item"><button class="sidebar-toggle primary-toggle btn btn-sm" title="Toggle primary sidebar" data-bs-placement="bottom" data-bs-toggle="tooltip">
|
|
|
<span class="fa-solid fa-bars"></span>
|
|
|
</button></div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
<div class="header-article-items__end">
|
|
|
|
|
|
<div class="header-article-item">
|
|
|
|
|
|
<div class="article-header-buttons">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<div class="dropdown dropdown-download-buttons">
|
|
|
<button class="btn dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false" aria-label="Download this page">
|
|
|
<i class="fas fa-download"></i>
|
|
|
</button>
|
|
|
<ul class="dropdown-menu">
|
|
|
|
|
|
|
|
|
|
|
|
<li><a href="../../_sources/guide/primal.ipynb" target="_blank"
|
|
|
class="btn btn-sm btn-download-source-button dropdown-item"
|
|
|
title="Download source file"
|
|
|
data-bs-placement="left" data-bs-toggle="tooltip"
|
|
|
>
|
|
|
|
|
|
|
|
|
<span class="btn__icon-container">
|
|
|
<i class="fas fa-file"></i>
|
|
|
</span>
|
|
|
<span class="btn__text-container">.ipynb</span>
|
|
|
</a>
|
|
|
</li>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<li>
|
|
|
<button onclick="window.print()"
|
|
|
class="btn btn-sm btn-download-pdf-button dropdown-item"
|
|
|
title="Print to PDF"
|
|
|
data-bs-placement="left" data-bs-toggle="tooltip"
|
|
|
>
|
|
|
|
|
|
|
|
|
<span class="btn__icon-container">
|
|
|
<i class="fas fa-file-pdf"></i>
|
|
|
</span>
|
|
|
<span class="btn__text-container">.pdf</span>
|
|
|
</button>
|
|
|
</li>
|
|
|
|
|
|
</ul>
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<button onclick="toggleFullScreen()"
|
|
|
class="btn btn-sm btn-fullscreen-button"
|
|
|
title="Fullscreen mode"
|
|
|
data-bs-placement="bottom" data-bs-toggle="tooltip"
|
|
|
>
|
|
|
|
|
|
|
|
|
<span class="btn__icon-container">
|
|
|
<i class="fas fa-expand"></i>
|
|
|
</span>
|
|
|
|
|
|
</button>
|
|
|
|
|
|
|
|
|
|
|
|
<script>
|
|
|
document.write(`
|
|
|
<button class="btn btn-sm nav-link pst-navbar-icon theme-switch-button" title="light/dark" aria-label="light/dark" data-bs-placement="bottom" data-bs-toggle="tooltip">
|
|
|
<i class="theme-switch fa-solid fa-sun fa-lg" data-mode="light"></i>
|
|
|
<i class="theme-switch fa-solid fa-moon fa-lg" data-mode="dark"></i>
|
|
|
<i class="theme-switch fa-solid fa-circle-half-stroke fa-lg" data-mode="auto"></i>
|
|
|
</button>
|
|
|
`);
|
|
|
</script>
|
|
|
|
|
|
|
|
|
<script>
|
|
|
document.write(`
|
|
|
<button class="btn btn-sm pst-navbar-icon search-button search-button__button" title="Search" aria-label="Search" data-bs-placement="bottom" data-bs-toggle="tooltip">
|
|
|
<i class="fa-solid fa-magnifying-glass fa-lg"></i>
|
|
|
</button>
|
|
|
`);
|
|
|
</script>
|
|
|
<button class="sidebar-toggle secondary-toggle btn btn-sm" title="Toggle secondary sidebar" data-bs-placement="bottom" data-bs-toggle="tooltip">
|
|
|
<span class="fa-solid fa-list"></span>
|
|
|
</button>
|
|
|
</div></div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div id="jb-print-docs-body" class="onlyprint">
|
|
|
<h1>Primal Components</h1>
|
|
|
<!-- Table of contents -->
|
|
|
<div id="print-main-content">
|
|
|
<div id="jb-print-toc">
|
|
|
|
|
|
<div>
|
|
|
<h2> Contents </h2>
|
|
|
</div>
|
|
|
<nav aria-label="Page">
|
|
|
<ul class="visible nav section-nav flex-column">
|
|
|
<li class="toc-h2 nav-item toc-entry"><a class="reference internal nav-link" href="#Primal-component-actions">8.1. Primal component actions</a></li>
|
|
|
<li class="toc-h2 nav-item toc-entry"><a class="reference internal nav-link" href="#Memorizing-primal-component">8.2. Memorizing primal component</a><ul class="nav section-nav flex-column">
|
|
|
<li class="toc-h3 nav-item toc-entry"><a class="reference internal nav-link" href="#Examples">Examples</a></li>
|
|
|
</ul>
|
|
|
</li>
|
|
|
<li class="toc-h2 nav-item toc-entry"><a class="reference internal nav-link" href="#Independent-vars-primal-component">8.3. Independent vars primal component</a><ul class="nav section-nav flex-column">
|
|
|
<li class="toc-h3 nav-item toc-entry"><a class="reference internal nav-link" href="#id1">Examples</a></li>
|
|
|
</ul>
|
|
|
</li>
|
|
|
<li class="toc-h2 nav-item toc-entry"><a class="reference internal nav-link" href="#Joint-vars-primal-component">8.4. Joint vars primal component</a><ul class="nav section-nav flex-column">
|
|
|
<li class="toc-h3 nav-item toc-entry"><a class="reference internal nav-link" href="#id2">Examples</a></li>
|
|
|
</ul>
|
|
|
</li>
|
|
|
<li class="toc-h2 nav-item toc-entry"><a class="reference internal nav-link" href="#Expert-primal-component">8.5. Expert primal component</a><ul class="nav section-nav flex-column">
|
|
|
<li class="toc-h3 nav-item toc-entry"><a class="reference internal nav-link" href="#Example">Example</a></li>
|
|
|
</ul>
|
|
|
</li>
|
|
|
</ul>
|
|
|
</nav>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div id="searchbox"></div>
|
|
|
<article class="bd-article">
|
|
|
|
|
|
<section id="Primal-Components">
|
|
|
<h1><span class="section-number">8. </span>Primal Components<a class="headerlink" href="#Primal-Components" title="Link to this heading">#</a></h1>
|
|
|
<p>In MIPLearn, a <strong>primal component</strong> is class that uses machine learning to predict a (potentially partial) assignment of values to the decision variables of the problem. Predicting high-quality primal solutions may be beneficial, as they allow the MIP solver to prune potentially large portions of the search space. Alternatively, if proof of optimality is not required, the MIP solver can be used to complete the partial solution generated by the machine learning model and and double-check its
|
|
|
feasibility. MIPLearn allows both of these usage patterns.</p>
|
|
|
<p>In this page, we describe the four primal components currently included in MIPLearn, which employ machine learning in different ways. Each component is highly configurable, and accepts an user-provided machine learning model, which it uses for all predictions. Each component can also be configured to provide the solution to the solver in multiple ways, depending on whether proof of optimality is required.</p>
|
|
|
<section id="Primal-component-actions">
|
|
|
<h2><span class="section-number">8.1. </span>Primal component actions<a class="headerlink" href="#Primal-component-actions" title="Link to this heading">#</a></h2>
|
|
|
<p>Before presenting the primal components themselves, we briefly discuss the three ways a solution may be provided to the solver. Each approach has benefits and limitations, which we also discuss in this section. All primal components can be configured to use any of the following approaches.</p>
|
|
|
<p>The first approach is to provide the solution to the solver as a <strong>warm start</strong>. This is implemented by the class <a class="reference external" href="../../api/components/#miplearn.components.primal.actions.SetWarmStart">SetWarmStart</a>. The main advantage is that this method maintains all optimality and feasibility guarantees of the MIP solver, while still providing significant performance benefits for various classes of problems. If the machine learning model is able to predict multiple solutions, it is also possible to set
|
|
|
multiple warm starts. In this case, the solver evaluates each warm start, discards the infeasible ones, then proceeds with the one that has the best objective value. The main disadvantage of this approach, compared to the next two, is that it provides relatively modest speedups for most problem classes, and no speedup at all for many others, even when the machine learning predictions are 100% accurate.</p>
|
|
|
<p>The second approach is to <strong>fix the decision variables</strong> to their predicted values, then solve a restricted optimization problem on the remaining variables. This approach is implemented by the class <code class="docutils literal notranslate"><span class="pre">FixVariables</span></code>. The main advantage is its potential speedup: if machine learning can accurately predict values for a significant portion of the decision variables, then the MIP solver can typically complete the solution in a small fraction of the time it would take to find the same solution from
|
|
|
scratch. The main disadvantage of this approach is that it loses optimality guarantees; that is, the complete solution found by the MIP solver may no longer be globally optimal. Also, if the machine learning predictions are not sufficiently accurate, there might not even be a feasible assignment for the variables that were left free.</p>
|
|
|
<p>Finally, the third approach, which tries to strike a balance between the two previous ones, is to <strong>enforce proximity</strong> to a given solution. This strategy is implemented by the class <code class="docutils literal notranslate"><span class="pre">EnforceProximity</span></code>. More precisely, given values <span class="math notranslate nohighlight">\(\bar{x}_1,\ldots,\bar{x}_n\)</span> for a subset of binary decision variables <span class="math notranslate nohighlight">\(x_1,\ldots,x_n\)</span>, this approach adds the constraint</p>
|
|
|
<div class="math notranslate nohighlight">
|
|
|
\[\sum_{i : \bar{x}_i=0} x_i + \sum_{i : \bar{x}_i=1} \left(1 - x_i\right) \leq k,\]</div>
|
|
|
<p>to the problem, where <span class="math notranslate nohighlight">\(k\)</span> is a user-defined parameter, which indicates how many of the predicted variables are allowed to deviate from the machine learning suggestion. The main advantage of this approach, compared to fixing variables, is its tolerance to lower-quality machine learning predictions. Its main disadvantage is that it typically leads to smaller speedups, especially for larger values of <span class="math notranslate nohighlight">\(k\)</span>. This approach also loses optimality guarantees.</p>
|
|
|
</section>
|
|
|
<section id="Memorizing-primal-component">
|
|
|
<h2><span class="section-number">8.2. </span>Memorizing primal component<a class="headerlink" href="#Memorizing-primal-component" title="Link to this heading">#</a></h2>
|
|
|
<p>A simple machine learning strategy for the prediction of primal solutions is to memorize all distinct solutions seen during training, then try to predict, during inference time, which of those memorized solutions are most likely to be feasible and to provide a good objective value for the current instance. The most promising solutions may alternatively be combined into a single partial solution, which is then provided to the MIP solver. Both variations of this strategy are implemented by the
|
|
|
<code class="docutils literal notranslate"><span class="pre">MemorizingPrimalComponent</span></code> class. Note that it is only applicable if the problem size, and in fact if the meaning of the decision variables, remains the same across problem instances.</p>
|
|
|
<p>More precisely, let <span class="math notranslate nohighlight">\(I_1,\ldots,I_n\)</span> be the training instances, and let <span class="math notranslate nohighlight">\(\bar{x}^1,\ldots,\bar{x}^n\)</span> be their respective optimal solutions. Given a new instance <span class="math notranslate nohighlight">\(I_{n+1}\)</span>, <code class="docutils literal notranslate"><span class="pre">MemorizingPrimalComponent</span></code> expects a user-provided binary classifier that assigns (through the <code class="docutils literal notranslate"><span class="pre">predict_proba</span></code> method, following scikit-learn’s conventions) a score <span class="math notranslate nohighlight">\(\delta_i\)</span> to each solution <span class="math notranslate nohighlight">\(\bar{x}^i\)</span>, such that solutions with higher score are more likely to be good solutions for
|
|
|
<span class="math notranslate nohighlight">\(I_{n+1}\)</span>. The features provided to the classifier are the instance features computed by an user-provided extractor. Given these scores, the component then performs one of the following to actions, as decided by the user:</p>
|
|
|
<ol class="arabic">
|
|
|
<li><p>Selects the top <span class="math notranslate nohighlight">\(k\)</span> solutions with the highest scores and provides them to the solver; this is implemented by <code class="docutils literal notranslate"><span class="pre">SelectTopSolutions</span></code>, and it is typically used with the <code class="docutils literal notranslate"><span class="pre">SetWarmStart</span></code> action.</p></li>
|
|
|
<li><p>Merges the top <span class="math notranslate nohighlight">\(k\)</span> solutions into a single partial solution, then provides it to the solver. This is implemented by <code class="docutils literal notranslate"><span class="pre">MergeTopSolutions</span></code>. More precisely, suppose that the machine learning regressor ordered the solutions in the sequence <span class="math notranslate nohighlight">\(\bar{x}^{i_1},\ldots,\bar{x}^{i_n}\)</span>, with the most promising solutions appearing first, and with ties being broken arbitrarily. The component starts by keeping only the <span class="math notranslate nohighlight">\(k\)</span> most promising solutions <span class="math notranslate nohighlight">\(\bar{x}^{i_1},\ldots,\bar{x}^{i_k}\)</span>.
|
|
|
Then it computes, for each binary decision variable <span class="math notranslate nohighlight">\(x_l\)</span>, its average assigned value <span class="math notranslate nohighlight">\(\tilde{x}_l\)</span>:</p>
|
|
|
<div class="math notranslate nohighlight">
|
|
|
\[\tilde{x}_l = \frac{1}{k} \sum_{j=1}^k \bar{x}^{i_j}_l.\]</div>
|
|
|
<p>Finally, the component constructs a merged solution <span class="math notranslate nohighlight">\(y\)</span>, defined as:</p>
|
|
|
<div class="math notranslate nohighlight">
|
|
|
\[\begin{split}y_j = \begin{cases}
|
|
|
0 & \text{ if } \tilde{x}_l \le \theta_0 \\
|
|
|
1 & \text{ if } \tilde{x}_l \ge \theta_1 \\
|
|
|
\square & \text{otherwise,}
|
|
|
\end{cases}\end{split}\]</div>
|
|
|
<p>where <span class="math notranslate nohighlight">\(\theta_0\)</span> and <span class="math notranslate nohighlight">\(\theta_1\)</span> are user-specified parameters, and where <span class="math notranslate nohighlight">\(\square\)</span> indicates that the variable is left undefined. The solution <span class="math notranslate nohighlight">\(y\)</span> is then provided by the solver using any of the three approaches defined in the previous section.</p>
|
|
|
</li>
|
|
|
</ol>
|
|
|
<p>The above specification of <code class="docutils literal notranslate"><span class="pre">MemorizingPrimalComponent</span></code> is meant to be as general as possible. Simpler strategies can be implemented by configuring this component in specific ways. For example, a simpler approach employed in the literature is to collect all optimal solutions, then provide the entire list of solutions to the solver as warm starts, without any filtering or post-processing. This strategy can be implemented with <code class="docutils literal notranslate"><span class="pre">MemorizingPrimalComponent</span></code> by using a model that returns a constant
|
|
|
value for all solutions (e.g. <a class="reference external" href="https://scikit-learn.org/stable/modules/generated/sklearn.dummy.DummyClassifier.html">scikit-learn’s DummyClassifier</a>), then selecting the top <span class="math notranslate nohighlight">\(n\)</span> (instead of <span class="math notranslate nohighlight">\(k\)</span>) solutions. See example below. Another simple approach is taking the solution to the most similar instance, and using it, by itself, as a warm start. This can be implemented by using a model that computes distances between the current instance and the training ones (e.g. <a class="reference external" href="https://scikit-learn.org/stable/modules/generated/sklearn.neighbors.KNeighborsClassifier.html">scikit-learn’s
|
|
|
KNeighborsClassifier</a>), then select the solution to the nearest one. See also example below. More complex strategies, of course, can also be configured.</p>
|
|
|
<section id="Examples">
|
|
|
<h3>Examples<a class="headerlink" href="#Examples" title="Link to this heading">#</a></h3>
|
|
|
<div class="nbinput nblast docutils container">
|
|
|
<div class="prompt highlight-none notranslate"><div class="highlight"><pre><span></span>[1]:
|
|
|
</pre></div>
|
|
|
</div>
|
|
|
<div class="input_area highlight-ipython3 notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span><span class="w"> </span><span class="nn">sklearn.dummy</span><span class="w"> </span><span class="kn">import</span> <span class="n">DummyClassifier</span>
|
|
|
<span class="kn">from</span><span class="w"> </span><span class="nn">sklearn.neighbors</span><span class="w"> </span><span class="kn">import</span> <span class="n">KNeighborsClassifier</span>
|
|
|
|
|
|
<span class="kn">from</span><span class="w"> </span><span class="nn">miplearn.components.primal.actions</span><span class="w"> </span><span class="kn">import</span> <span class="p">(</span>
|
|
|
<span class="n">SetWarmStart</span><span class="p">,</span>
|
|
|
<span class="n">FixVariables</span><span class="p">,</span>
|
|
|
<span class="n">EnforceProximity</span><span class="p">,</span>
|
|
|
<span class="p">)</span>
|
|
|
<span class="kn">from</span><span class="w"> </span><span class="nn">miplearn.components.primal.mem</span><span class="w"> </span><span class="kn">import</span> <span class="p">(</span>
|
|
|
<span class="n">MemorizingPrimalComponent</span><span class="p">,</span>
|
|
|
<span class="n">SelectTopSolutions</span><span class="p">,</span>
|
|
|
<span class="n">MergeTopSolutions</span><span class="p">,</span>
|
|
|
<span class="p">)</span>
|
|
|
<span class="kn">from</span><span class="w"> </span><span class="nn">miplearn.extractors.dummy</span><span class="w"> </span><span class="kn">import</span> <span class="n">DummyExtractor</span>
|
|
|
<span class="kn">from</span><span class="w"> </span><span class="nn">miplearn.extractors.fields</span><span class="w"> </span><span class="kn">import</span> <span class="n">H5FieldsExtractor</span>
|
|
|
|
|
|
<span class="c1"># Configures a memorizing primal component that collects</span>
|
|
|
<span class="c1"># all distinct solutions seen during training and provides</span>
|
|
|
<span class="c1"># them to the solver without any filtering or post-processing.</span>
|
|
|
<span class="n">comp1</span> <span class="o">=</span> <span class="n">MemorizingPrimalComponent</span><span class="p">(</span>
|
|
|
<span class="n">clf</span><span class="o">=</span><span class="n">DummyClassifier</span><span class="p">(),</span>
|
|
|
<span class="n">extractor</span><span class="o">=</span><span class="n">DummyExtractor</span><span class="p">(),</span>
|
|
|
<span class="n">constructor</span><span class="o">=</span><span class="n">SelectTopSolutions</span><span class="p">(</span><span class="mi">1_000_000</span><span class="p">),</span>
|
|
|
<span class="n">action</span><span class="o">=</span><span class="n">SetWarmStart</span><span class="p">(),</span>
|
|
|
<span class="p">)</span>
|
|
|
|
|
|
<span class="c1"># Configures a memorizing primal component that finds the</span>
|
|
|
<span class="c1"># training instance with the closest objective function, then</span>
|
|
|
<span class="c1"># fixes the decision variables to the values they assumed</span>
|
|
|
<span class="c1"># at the optimal solution for that instance.</span>
|
|
|
<span class="n">comp2</span> <span class="o">=</span> <span class="n">MemorizingPrimalComponent</span><span class="p">(</span>
|
|
|
<span class="n">clf</span><span class="o">=</span><span class="n">KNeighborsClassifier</span><span class="p">(</span><span class="n">n_neighbors</span><span class="o">=</span><span class="mi">1</span><span class="p">),</span>
|
|
|
<span class="n">extractor</span><span class="o">=</span><span class="n">H5FieldsExtractor</span><span class="p">(</span>
|
|
|
<span class="n">instance_fields</span><span class="o">=</span><span class="p">[</span><span class="s2">"static_var_obj_coeffs"</span><span class="p">],</span>
|
|
|
<span class="p">),</span>
|
|
|
<span class="n">constructor</span><span class="o">=</span><span class="n">SelectTopSolutions</span><span class="p">(</span><span class="mi">1</span><span class="p">),</span>
|
|
|
<span class="n">action</span><span class="o">=</span><span class="n">FixVariables</span><span class="p">(),</span>
|
|
|
<span class="p">)</span>
|
|
|
|
|
|
<span class="c1"># Configures a memorizing primal component that finds the distinct</span>
|
|
|
<span class="c1"># solutions to the 10 most similar training problem instances,</span>
|
|
|
<span class="c1"># selects the 3 solutions that were most often optimal to these</span>
|
|
|
<span class="c1"># training instances, combines them into a single partial solution,</span>
|
|
|
<span class="c1"># then enforces proximity, allowing at most 3 variables to deviate</span>
|
|
|
<span class="c1"># from the machine learning suggestion.</span>
|
|
|
<span class="n">comp3</span> <span class="o">=</span> <span class="n">MemorizingPrimalComponent</span><span class="p">(</span>
|
|
|
<span class="n">clf</span><span class="o">=</span><span class="n">KNeighborsClassifier</span><span class="p">(</span><span class="n">n_neighbors</span><span class="o">=</span><span class="mi">10</span><span class="p">),</span>
|
|
|
<span class="n">extractor</span><span class="o">=</span><span class="n">H5FieldsExtractor</span><span class="p">(</span><span class="n">instance_fields</span><span class="o">=</span><span class="p">[</span><span class="s2">"static_var_obj_coeffs"</span><span class="p">]),</span>
|
|
|
<span class="n">constructor</span><span class="o">=</span><span class="n">MergeTopSolutions</span><span class="p">(</span><span class="n">k</span><span class="o">=</span><span class="mi">3</span><span class="p">,</span> <span class="n">thresholds</span><span class="o">=</span><span class="p">[</span><span class="mf">0.25</span><span class="p">,</span> <span class="mf">0.75</span><span class="p">]),</span>
|
|
|
<span class="n">action</span><span class="o">=</span><span class="n">EnforceProximity</span><span class="p">(</span><span class="mi">3</span><span class="p">),</span>
|
|
|
<span class="p">)</span>
|
|
|
</pre></div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</section>
|
|
|
</section>
|
|
|
<section id="Independent-vars-primal-component">
|
|
|
<h2><span class="section-number">8.3. </span>Independent vars primal component<a class="headerlink" href="#Independent-vars-primal-component" title="Link to this heading">#</a></h2>
|
|
|
<p>Instead of memorizing previously-seen primal solutions, it is also natural to use machine learning models to directly predict the values of the decision variables, constructing a solution from scratch. This approach has the benefit of potentially constructing novel high-quality solutions, never observed in the training data. Two variations of this strategy are supported by MIPLearn: (i) predicting the values of the decision variables independently, using multiple ML models; or (ii) predicting
|
|
|
the values jointly, with a single model. We describe the first variation in this section, and the second variation in the next section.</p>
|
|
|
<p>Let <span class="math notranslate nohighlight">\(I_1,\ldots,I_n\)</span> be the training instances, and let <span class="math notranslate nohighlight">\(\bar{x}^1,\ldots,\bar{x}^n\)</span> be their respective optimal solutions. For each binary decision variable <span class="math notranslate nohighlight">\(x_j\)</span>, the component <code class="docutils literal notranslate"><span class="pre">IndependentVarsPrimalComponent</span></code> creates a copy of a user-provided binary classifier and trains it to predict the optimal value of <span class="math notranslate nohighlight">\(x_j\)</span>, given <span class="math notranslate nohighlight">\(\bar{x}^1_j,\ldots,\bar{x}^n_j\)</span> as training labels. The features provided to the model are the variable features computed by an user-provided
|
|
|
extractor. During inference time, the component uses these <span class="math notranslate nohighlight">\(n\)</span> binary classifiers to construct a solution and provides it to the solver using one of the available actions.</p>
|
|
|
<p>Three issues often arise in practice when using this approach:</p>
|
|
|
<ol class="arabic simple">
|
|
|
<li><p>For certain binary variables <span class="math notranslate nohighlight">\(x_j\)</span>, it is frequently the case that its optimal value is either always zero or always one in the training dataset, which poses problems to some standard scikit-learn classifiers, since they do not expect a single class. The wrapper <code class="docutils literal notranslate"><span class="pre">SingleClassFix</span></code> can be used to fix this issue (see example below).</p></li>
|
|
|
<li><p>It is also frequently the case that machine learning classifier can only reliably predict the values of some variables with high accuracy, not all of them. In this situation, instead of computing a complete primal solution, it may be more beneficial to construct a partial solution containing values only for the variables for which the ML made a high-confidence prediction. The meta-classifier <code class="docutils literal notranslate"><span class="pre">MinProbabilityClassifier</span></code> can be used for this purpose. It asks the base classifier for the
|
|
|
probability of the value being zero or one (using the <code class="docutils literal notranslate"><span class="pre">predict_proba</span></code> method) and erases from the primal solution all values whose probabilities are below a given threshold.</p></li>
|
|
|
<li><p>To make multiple copies of the provided ML classifier, MIPLearn uses the standard <code class="docutils literal notranslate"><span class="pre">sklearn.base.clone</span></code> method, which may not be suitable for classifiers from other frameworks. To handle this, it is possible to override the clone function using the <code class="docutils literal notranslate"><span class="pre">clone_fn</span></code> constructor argument.</p></li>
|
|
|
</ol>
|
|
|
<section id="id1">
|
|
|
<h3>Examples<a class="headerlink" href="#id1" title="Link to this heading">#</a></h3>
|
|
|
<div class="nbinput nblast docutils container">
|
|
|
<div class="prompt highlight-none notranslate"><div class="highlight"><pre><span></span>[2]:
|
|
|
</pre></div>
|
|
|
</div>
|
|
|
<div class="input_area highlight-ipython3 notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span><span class="w"> </span><span class="nn">sklearn.linear_model</span><span class="w"> </span><span class="kn">import</span> <span class="n">LogisticRegression</span>
|
|
|
<span class="kn">from</span><span class="w"> </span><span class="nn">miplearn.classifiers.minprob</span><span class="w"> </span><span class="kn">import</span> <span class="n">MinProbabilityClassifier</span>
|
|
|
<span class="kn">from</span><span class="w"> </span><span class="nn">miplearn.classifiers.singleclass</span><span class="w"> </span><span class="kn">import</span> <span class="n">SingleClassFix</span>
|
|
|
<span class="kn">from</span><span class="w"> </span><span class="nn">miplearn.components.primal.indep</span><span class="w"> </span><span class="kn">import</span> <span class="n">IndependentVarsPrimalComponent</span>
|
|
|
<span class="kn">from</span><span class="w"> </span><span class="nn">miplearn.extractors.AlvLouWeh2017</span><span class="w"> </span><span class="kn">import</span> <span class="n">AlvLouWeh2017Extractor</span>
|
|
|
<span class="kn">from</span><span class="w"> </span><span class="nn">miplearn.components.primal.actions</span><span class="w"> </span><span class="kn">import</span> <span class="n">SetWarmStart</span>
|
|
|
|
|
|
<span class="c1"># Configures a primal component that independently predicts the value of each</span>
|
|
|
<span class="c1"># binary variable using logistic regression and provides it to the solver as</span>
|
|
|
<span class="c1"># warm start. Erases predictions with probability less than 99%; applies</span>
|
|
|
<span class="c1"># single-class fix; and uses AlvLouWeh2017 features.</span>
|
|
|
<span class="n">comp</span> <span class="o">=</span> <span class="n">IndependentVarsPrimalComponent</span><span class="p">(</span>
|
|
|
<span class="n">base_clf</span><span class="o">=</span><span class="n">SingleClassFix</span><span class="p">(</span>
|
|
|
<span class="n">MinProbabilityClassifier</span><span class="p">(</span>
|
|
|
<span class="n">base_clf</span><span class="o">=</span><span class="n">LogisticRegression</span><span class="p">(),</span>
|
|
|
<span class="n">thresholds</span><span class="o">=</span><span class="p">[</span><span class="mf">0.99</span><span class="p">,</span> <span class="mf">0.99</span><span class="p">],</span>
|
|
|
<span class="p">),</span>
|
|
|
<span class="p">),</span>
|
|
|
<span class="n">extractor</span><span class="o">=</span><span class="n">AlvLouWeh2017Extractor</span><span class="p">(),</span>
|
|
|
<span class="n">action</span><span class="o">=</span><span class="n">SetWarmStart</span><span class="p">(),</span>
|
|
|
<span class="p">)</span>
|
|
|
</pre></div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</section>
|
|
|
</section>
|
|
|
<section id="Joint-vars-primal-component">
|
|
|
<h2><span class="section-number">8.4. </span>Joint vars primal component<a class="headerlink" href="#Joint-vars-primal-component" title="Link to this heading">#</a></h2>
|
|
|
<p>In the previous subsection, we used multiple machine learning models to independently predict the values of the binary decision variables. When these values are correlated, an alternative approach is to jointly predict the values of all binary variables using a single machine learning model. This strategy is implemented by <code class="docutils literal notranslate"><span class="pre">JointVarsPrimalComponent</span></code>. Compared to the previous ones, this component is much more straightforwad. It simply extracts instance features, using the user-provided feature
|
|
|
extractor, then directly trains the user-provided binary classifier (using the <code class="docutils literal notranslate"><span class="pre">fit</span></code> method), without making any copies. The trained classifier is then used to predict entire solutions (using the <code class="docutils literal notranslate"><span class="pre">predict</span></code> method), which are given to the solver using one of the previously discussed methods. In the example below, we illustrate the usage of this component with a simple feed-forward neural network.</p>
|
|
|
<p><code class="docutils literal notranslate"><span class="pre">JointVarsPrimalComponent</span></code> can also be used to implement strategies that use multiple machine learning models, but not indepedently. For example, a common strategy in multioutput prediction is building a <em>classifier chain</em>. In this approach, the first decision variable is predicted using the instance features alone; but the <span class="math notranslate nohighlight">\(n\)</span>-th decision variable is predicted using the instance features plus the predicted values of the <span class="math notranslate nohighlight">\(n-1\)</span> previous variables. This can be easily implemented
|
|
|
using scikit-learn’s <code class="docutils literal notranslate"><span class="pre">ClassifierChain</span></code> estimator, as shown in the example below.</p>
|
|
|
<section id="id2">
|
|
|
<h3>Examples<a class="headerlink" href="#id2" title="Link to this heading">#</a></h3>
|
|
|
<div class="nbinput nblast docutils container">
|
|
|
<div class="prompt highlight-none notranslate"><div class="highlight"><pre><span></span>[3]:
|
|
|
</pre></div>
|
|
|
</div>
|
|
|
<div class="input_area highlight-ipython3 notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span><span class="w"> </span><span class="nn">sklearn.multioutput</span><span class="w"> </span><span class="kn">import</span> <span class="n">ClassifierChain</span>
|
|
|
<span class="kn">from</span><span class="w"> </span><span class="nn">sklearn.neural_network</span><span class="w"> </span><span class="kn">import</span> <span class="n">MLPClassifier</span>
|
|
|
<span class="kn">from</span><span class="w"> </span><span class="nn">miplearn.components.primal.joint</span><span class="w"> </span><span class="kn">import</span> <span class="n">JointVarsPrimalComponent</span>
|
|
|
<span class="kn">from</span><span class="w"> </span><span class="nn">miplearn.extractors.fields</span><span class="w"> </span><span class="kn">import</span> <span class="n">H5FieldsExtractor</span>
|
|
|
<span class="kn">from</span><span class="w"> </span><span class="nn">miplearn.components.primal.actions</span><span class="w"> </span><span class="kn">import</span> <span class="n">SetWarmStart</span>
|
|
|
|
|
|
<span class="c1"># Configures a primal component that uses a feedforward neural network</span>
|
|
|
<span class="c1"># to jointly predict the values of the binary variables, based on the</span>
|
|
|
<span class="c1"># objective cost function, and provides the solution to the solver as</span>
|
|
|
<span class="c1"># a warm start.</span>
|
|
|
<span class="n">comp</span> <span class="o">=</span> <span class="n">JointVarsPrimalComponent</span><span class="p">(</span>
|
|
|
<span class="n">clf</span><span class="o">=</span><span class="n">MLPClassifier</span><span class="p">(),</span>
|
|
|
<span class="n">extractor</span><span class="o">=</span><span class="n">H5FieldsExtractor</span><span class="p">(</span>
|
|
|
<span class="n">instance_fields</span><span class="o">=</span><span class="p">[</span><span class="s2">"static_var_obj_coeffs"</span><span class="p">],</span>
|
|
|
<span class="p">),</span>
|
|
|
<span class="n">action</span><span class="o">=</span><span class="n">SetWarmStart</span><span class="p">(),</span>
|
|
|
<span class="p">)</span>
|
|
|
|
|
|
<span class="c1"># Configures a primal component that uses a chain of logistic regression</span>
|
|
|
<span class="c1"># models to jointly predict the values of the binary variables, based on</span>
|
|
|
<span class="c1"># the objective function.</span>
|
|
|
<span class="n">comp</span> <span class="o">=</span> <span class="n">JointVarsPrimalComponent</span><span class="p">(</span>
|
|
|
<span class="n">clf</span><span class="o">=</span><span class="n">ClassifierChain</span><span class="p">(</span><span class="n">SingleClassFix</span><span class="p">(</span><span class="n">LogisticRegression</span><span class="p">())),</span>
|
|
|
<span class="n">extractor</span><span class="o">=</span><span class="n">H5FieldsExtractor</span><span class="p">(</span>
|
|
|
<span class="n">instance_fields</span><span class="o">=</span><span class="p">[</span><span class="s2">"static_var_obj_coeffs"</span><span class="p">],</span>
|
|
|
<span class="p">),</span>
|
|
|
<span class="n">action</span><span class="o">=</span><span class="n">SetWarmStart</span><span class="p">(),</span>
|
|
|
<span class="p">)</span>
|
|
|
</pre></div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</section>
|
|
|
</section>
|
|
|
<section id="Expert-primal-component">
|
|
|
<h2><span class="section-number">8.5. </span>Expert primal component<a class="headerlink" href="#Expert-primal-component" title="Link to this heading">#</a></h2>
|
|
|
<p>Before spending time and effort choosing a machine learning strategy and tweaking its parameters, it is usually a good idea to evaluate what would be the performance impact of the model if its predictions were 100% accurate. This is especially important for the prediction of warm starts, since they are not always very beneficial. To simplify this task, MIPLearn provides <code class="docutils literal notranslate"><span class="pre">ExpertPrimalComponent</span></code>, a component which simply loads the optimal solution from the HDF5 file, assuming that it has already
|
|
|
been computed, then directly provides it to the solver using one of the available methods. This component is useful in benchmarks, to evaluate how close to the best theoretical performance the machine learning components are.</p>
|
|
|
<section id="Example">
|
|
|
<h3>Example<a class="headerlink" href="#Example" title="Link to this heading">#</a></h3>
|
|
|
<div class="nbinput nblast docutils container">
|
|
|
<div class="prompt highlight-none notranslate"><div class="highlight"><pre><span></span>[4]:
|
|
|
</pre></div>
|
|
|
</div>
|
|
|
<div class="input_area highlight-ipython3 notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span><span class="w"> </span><span class="nn">miplearn.components.primal.expert</span><span class="w"> </span><span class="kn">import</span> <span class="n">ExpertPrimalComponent</span>
|
|
|
<span class="kn">from</span><span class="w"> </span><span class="nn">miplearn.components.primal.actions</span><span class="w"> </span><span class="kn">import</span> <span class="n">SetWarmStart</span>
|
|
|
|
|
|
<span class="c1"># Configures an expert primal component, which reads a pre-computed</span>
|
|
|
<span class="c1"># optimal solution from the HDF5 file and provides it to the solver</span>
|
|
|
<span class="c1"># as warm start.</span>
|
|
|
<span class="n">comp</span> <span class="o">=</span> <span class="n">ExpertPrimalComponent</span><span class="p">(</span><span class="n">action</span><span class="o">=</span><span class="n">SetWarmStart</span><span class="p">())</span>
|
|
|
</pre></div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</section>
|
|
|
</section>
|
|
|
</section>
|
|
|
|
|
|
|
|
|
</article>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<footer class="prev-next-footer d-print-none">
|
|
|
|
|
|
<div class="prev-next-area">
|
|
|
<a class="left-prev"
|
|
|
href="../features/"
|
|
|
title="previous page">
|
|
|
<i class="fa-solid fa-angle-left"></i>
|
|
|
<div class="prev-next-info">
|
|
|
<p class="prev-next-subtitle">previous</p>
|
|
|
<p class="prev-next-title"><span class="section-number">7. </span>Feature Extractors</p>
|
|
|
</div>
|
|
|
</a>
|
|
|
<a class="right-next"
|
|
|
href="../solvers/"
|
|
|
title="next page">
|
|
|
<div class="prev-next-info">
|
|
|
<p class="prev-next-subtitle">next</p>
|
|
|
<p class="prev-next-title"><span class="section-number">9. </span>Learning Solver</p>
|
|
|
</div>
|
|
|
<i class="fa-solid fa-angle-right"></i>
|
|
|
</a>
|
|
|
</div>
|
|
|
</footer>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div class="bd-sidebar-secondary bd-toc"><div class="sidebar-secondary-items sidebar-secondary__inner">
|
|
|
|
|
|
|
|
|
<div class="sidebar-secondary-item">
|
|
|
<div class="page-toc tocsection onthispage">
|
|
|
<i class="fa-solid fa-list"></i> Contents
|
|
|
</div>
|
|
|
<nav class="bd-toc-nav page-toc">
|
|
|
<ul class="visible nav section-nav flex-column">
|
|
|
<li class="toc-h2 nav-item toc-entry"><a class="reference internal nav-link" href="#Primal-component-actions">8.1. Primal component actions</a></li>
|
|
|
<li class="toc-h2 nav-item toc-entry"><a class="reference internal nav-link" href="#Memorizing-primal-component">8.2. Memorizing primal component</a><ul class="nav section-nav flex-column">
|
|
|
<li class="toc-h3 nav-item toc-entry"><a class="reference internal nav-link" href="#Examples">Examples</a></li>
|
|
|
</ul>
|
|
|
</li>
|
|
|
<li class="toc-h2 nav-item toc-entry"><a class="reference internal nav-link" href="#Independent-vars-primal-component">8.3. Independent vars primal component</a><ul class="nav section-nav flex-column">
|
|
|
<li class="toc-h3 nav-item toc-entry"><a class="reference internal nav-link" href="#id1">Examples</a></li>
|
|
|
</ul>
|
|
|
</li>
|
|
|
<li class="toc-h2 nav-item toc-entry"><a class="reference internal nav-link" href="#Joint-vars-primal-component">8.4. Joint vars primal component</a><ul class="nav section-nav flex-column">
|
|
|
<li class="toc-h3 nav-item toc-entry"><a class="reference internal nav-link" href="#id2">Examples</a></li>
|
|
|
</ul>
|
|
|
</li>
|
|
|
<li class="toc-h2 nav-item toc-entry"><a class="reference internal nav-link" href="#Expert-primal-component">8.5. Expert primal component</a><ul class="nav section-nav flex-column">
|
|
|
<li class="toc-h3 nav-item toc-entry"><a class="reference internal nav-link" href="#Example">Example</a></li>
|
|
|
</ul>
|
|
|
</li>
|
|
|
</ul>
|
|
|
</nav></div>
|
|
|
|
|
|
</div></div>
|
|
|
|
|
|
|
|
|
</div>
|
|
|
<footer class="bd-footer-content">
|
|
|
|
|
|
<div class="bd-footer-content__inner container">
|
|
|
|
|
|
<div class="footer-item">
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="footer-item">
|
|
|
|
|
|
|
|
|
<p class="copyright">
|
|
|
|
|
|
© Copyright 2020-2023, UChicago Argonne, LLC.
|
|
|
<br/>
|
|
|
|
|
|
</p>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="footer-item">
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="footer-item">
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
</footer>
|
|
|
|
|
|
|
|
|
</main>
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
<!-- Scripts loaded after <body> so the DOM is not blocked -->
|
|
|
<script src="../../_static/scripts/bootstrap.js?digest=dfe6caa3a7d634c4db9b"></script>
|
|
|
<script src="../../_static/scripts/pydata-sphinx-theme.js?digest=dfe6caa3a7d634c4db9b"></script>
|
|
|
|
|
|
<footer class="bd-footer">
|
|
|
</footer>
|
|
|
</body>
|
|
|
</html> |