Update 0.2 docs

This commit is contained in:
2021-01-22 07:43:55 -06:00
parent 144523a5c0
commit 92c5116964
35 changed files with 5 additions and 5917 deletions

View File

@@ -78,10 +78,6 @@ class _RedirectOutput:
<dd>
<section class="desc"></section>
</dd>
<dt><code class="name"><a title="miplearn.solvers.tests" href="tests/index.html">miplearn.solvers.tests</a></code></dt>
<dd>
<section class="desc"></section>
</dd>
</dl>
</section>
<section>
@@ -108,7 +104,6 @@ class _RedirectOutput:
<li><code><a title="miplearn.solvers.internal" href="internal.html">miplearn.solvers.internal</a></code></li>
<li><code><a title="miplearn.solvers.learning" href="learning.html">miplearn.solvers.learning</a></code></li>
<li><code><a title="miplearn.solvers.pyomo" href="pyomo/index.html">miplearn.solvers.pyomo</a></code></li>
<li><code><a title="miplearn.solvers.tests" href="tests/index.html">miplearn.solvers.tests</a></code></li>
</ul>
</li>
</ul>

View File

@@ -1,250 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" />
<meta name="generator" content="pdoc 0.7.5" />
<title>miplearn.solvers.tests API documentation</title>
<meta name="description" content="" />
<link href='https://cdnjs.cloudflare.com/ajax/libs/normalize/8.0.0/normalize.min.css' rel='stylesheet'>
<link href='https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/8.0.0/sanitize.min.css' rel='stylesheet'>
<link href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/github.min.css" rel="stylesheet">
<style>.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:30px;overflow:hidden}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:1em 0 .50em 0}h3{font-size:1.4em;margin:25px 0 10px 0}h4{margin:0;font-size:105%}a{color:#058;text-decoration:none;transition:color .3s ease-in-out}a:hover{color:#e82}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900}pre code{background:#f8f8f8;font-size:.8em;line-height:1.4em}code{background:#f2f2f1;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{background:#f8f8f8;border:0;border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0;padding:1ex}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{font-weight:bold}#index h4 + ul{margin-bottom:.6em}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-weight:bold;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}.admonition{padding:.1em .5em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style>
<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.item .name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul{padding-left:1.5em}.toc > ul > li{margin-top:.5em}}</style>
<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style>
</head>
<body>
<main>
<article id="content">
<header>
<h1 class="title">Module <code>miplearn.solvers.tests</code></h1>
</header>
<section id="section-intro">
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python"># MIPLearn: Extensible Framework for Learning-Enhanced Mixed-Integer Optimization
# Copyright (C) 2020, UChicago Argonne, LLC. All rights reserved.
# Released under the modified BSD license. See COPYING.md for more details.
from inspect import isclass
from typing import List, Callable, Any
from pyomo import environ as pe
from miplearn.instance import Instance
from miplearn.problems.knapsack import KnapsackInstance, GurobiKnapsackInstance
from miplearn.solvers.gurobi import GurobiSolver
from miplearn.solvers.internal import InternalSolver
from miplearn.solvers.pyomo.base import BasePyomoSolver
from miplearn.solvers.pyomo.gurobi import GurobiPyomoSolver
from miplearn.solvers.pyomo.xpress import XpressPyomoSolver
class InfeasiblePyomoInstance(Instance):
def to_model(self) -&gt; pe.ConcreteModel:
model = pe.ConcreteModel()
model.x = pe.Var([0], domain=pe.Binary)
model.OBJ = pe.Objective(expr=model.x[0], sense=pe.maximize)
model.eq = pe.Constraint(expr=model.x[0] &gt;= 2)
return model
class InfeasibleGurobiInstance(Instance):
def to_model(self) -&gt; Any:
import gurobipy as gp
from gurobipy import GRB
model = gp.Model()
x = model.addVars(1, vtype=GRB.BINARY, name=&#34;x&#34;)
model.addConstr(x[0] &gt;= 2)
model.setObjective(x[0])
return model
def _is_subclass_or_instance(obj, parent_class):
return isinstance(obj, parent_class) or (
isclass(obj) and issubclass(obj, parent_class)
)
def _get_knapsack_instance(solver):
if _is_subclass_or_instance(solver, BasePyomoSolver):
return KnapsackInstance(
weights=[23.0, 26.0, 20.0, 18.0],
prices=[505.0, 352.0, 458.0, 220.0],
capacity=67.0,
)
if _is_subclass_or_instance(solver, GurobiSolver):
return GurobiKnapsackInstance(
weights=[23.0, 26.0, 20.0, 18.0],
prices=[505.0, 352.0, 458.0, 220.0],
capacity=67.0,
)
assert False
def _get_infeasible_instance(solver):
if _is_subclass_or_instance(solver, BasePyomoSolver):
return InfeasiblePyomoInstance()
if _is_subclass_or_instance(solver, GurobiSolver):
return InfeasibleGurobiInstance()
def _get_internal_solvers() -&gt; List[Callable[[], InternalSolver]]:
return [GurobiPyomoSolver, GurobiSolver, XpressPyomoSolver]</code></pre>
</details>
</section>
<section>
<h2 class="section-title" id="header-submodules">Sub-modules</h2>
<dl>
<dt><code class="name"><a title="miplearn.solvers.tests.test_internal_solver" href="test_internal_solver.html">miplearn.solvers.tests.test_internal_solver</a></code></dt>
<dd>
<section class="desc"></section>
</dd>
<dt><code class="name"><a title="miplearn.solvers.tests.test_lazy_cb" href="test_lazy_cb.html">miplearn.solvers.tests.test_lazy_cb</a></code></dt>
<dd>
<section class="desc"></section>
</dd>
<dt><code class="name"><a title="miplearn.solvers.tests.test_learning_solver" href="test_learning_solver.html">miplearn.solvers.tests.test_learning_solver</a></code></dt>
<dd>
<section class="desc"></section>
</dd>
</dl>
</section>
<section>
</section>
<section>
</section>
<section>
<h2 class="section-title" id="header-classes">Classes</h2>
<dl>
<dt id="miplearn.solvers.tests.InfeasibleGurobiInstance"><code class="flex name class">
<span>class <span class="ident">InfeasibleGurobiInstance</span></span>
</code></dt>
<dd>
<section class="desc"><p>Abstract class holding all the data necessary to generate a concrete model of the
problem.</p>
<p>In the knapsack problem, for example, this class could hold the number of items,
their weights and costs, as well as the size of the knapsack. Objects
implementing this class are able to convert themselves into a concrete
optimization model, which can be optimized by a solver, or into arrays of
features, which can be provided as inputs to machine learning models.</p></section>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">class InfeasibleGurobiInstance(Instance):
def to_model(self) -&gt; Any:
import gurobipy as gp
from gurobipy import GRB
model = gp.Model()
x = model.addVars(1, vtype=GRB.BINARY, name=&#34;x&#34;)
model.addConstr(x[0] &gt;= 2)
model.setObjective(x[0])
return model</code></pre>
</details>
<h3>Ancestors</h3>
<ul class="hlist">
<li><a title="miplearn.instance.Instance" href="../../instance.html#miplearn.instance.Instance">Instance</a></li>
<li>abc.ABC</li>
</ul>
<h3>Inherited members</h3>
<ul class="hlist">
<li><code><b><a title="miplearn.instance.Instance" href="../../instance.html#miplearn.instance.Instance">Instance</a></b></code>:
<ul class="hlist">
<li><code><a title="miplearn.instance.Instance.build_lazy_constraint" href="../../instance.html#miplearn.instance.Instance.build_lazy_constraint">build_lazy_constraint</a></code></li>
<li><code><a title="miplearn.instance.Instance.find_violated_lazy_constraints" href="../../instance.html#miplearn.instance.Instance.find_violated_lazy_constraints">find_violated_lazy_constraints</a></code></li>
<li><code><a title="miplearn.instance.Instance.get_instance_features" href="../../instance.html#miplearn.instance.Instance.get_instance_features">get_instance_features</a></code></li>
<li><code><a title="miplearn.instance.Instance.get_variable_category" href="../../instance.html#miplearn.instance.Instance.get_variable_category">get_variable_category</a></code></li>
<li><code><a title="miplearn.instance.Instance.get_variable_features" href="../../instance.html#miplearn.instance.Instance.get_variable_features">get_variable_features</a></code></li>
<li><code><a title="miplearn.instance.Instance.to_model" href="../../instance.html#miplearn.instance.Instance.to_model">to_model</a></code></li>
</ul>
</li>
</ul>
</dd>
<dt id="miplearn.solvers.tests.InfeasiblePyomoInstance"><code class="flex name class">
<span>class <span class="ident">InfeasiblePyomoInstance</span></span>
</code></dt>
<dd>
<section class="desc"><p>Abstract class holding all the data necessary to generate a concrete model of the
problem.</p>
<p>In the knapsack problem, for example, this class could hold the number of items,
their weights and costs, as well as the size of the knapsack. Objects
implementing this class are able to convert themselves into a concrete
optimization model, which can be optimized by a solver, or into arrays of
features, which can be provided as inputs to machine learning models.</p></section>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">class InfeasiblePyomoInstance(Instance):
def to_model(self) -&gt; pe.ConcreteModel:
model = pe.ConcreteModel()
model.x = pe.Var([0], domain=pe.Binary)
model.OBJ = pe.Objective(expr=model.x[0], sense=pe.maximize)
model.eq = pe.Constraint(expr=model.x[0] &gt;= 2)
return model</code></pre>
</details>
<h3>Ancestors</h3>
<ul class="hlist">
<li><a title="miplearn.instance.Instance" href="../../instance.html#miplearn.instance.Instance">Instance</a></li>
<li>abc.ABC</li>
</ul>
<h3>Inherited members</h3>
<ul class="hlist">
<li><code><b><a title="miplearn.instance.Instance" href="../../instance.html#miplearn.instance.Instance">Instance</a></b></code>:
<ul class="hlist">
<li><code><a title="miplearn.instance.Instance.build_lazy_constraint" href="../../instance.html#miplearn.instance.Instance.build_lazy_constraint">build_lazy_constraint</a></code></li>
<li><code><a title="miplearn.instance.Instance.find_violated_lazy_constraints" href="../../instance.html#miplearn.instance.Instance.find_violated_lazy_constraints">find_violated_lazy_constraints</a></code></li>
<li><code><a title="miplearn.instance.Instance.get_instance_features" href="../../instance.html#miplearn.instance.Instance.get_instance_features">get_instance_features</a></code></li>
<li><code><a title="miplearn.instance.Instance.get_variable_category" href="../../instance.html#miplearn.instance.Instance.get_variable_category">get_variable_category</a></code></li>
<li><code><a title="miplearn.instance.Instance.get_variable_features" href="../../instance.html#miplearn.instance.Instance.get_variable_features">get_variable_features</a></code></li>
<li><code><a title="miplearn.instance.Instance.to_model" href="../../instance.html#miplearn.instance.Instance.to_model">to_model</a></code></li>
</ul>
</li>
</ul>
</dd>
</dl>
</section>
</article>
<nav id="sidebar">
<h1>Index</h1>
<div class="toc">
<ul></ul>
</div>
<ul id="index">
<li><h3>Super-module</h3>
<ul>
<li><code><a title="miplearn.solvers" href="../index.html">miplearn.solvers</a></code></li>
</ul>
</li>
<li><h3><a href="#header-submodules">Sub-modules</a></h3>
<ul>
<li><code><a title="miplearn.solvers.tests.test_internal_solver" href="test_internal_solver.html">miplearn.solvers.tests.test_internal_solver</a></code></li>
<li><code><a title="miplearn.solvers.tests.test_lazy_cb" href="test_lazy_cb.html">miplearn.solvers.tests.test_lazy_cb</a></code></li>
<li><code><a title="miplearn.solvers.tests.test_learning_solver" href="test_learning_solver.html">miplearn.solvers.tests.test_learning_solver</a></code></li>
</ul>
</li>
<li><h3><a href="#header-classes">Classes</a></h3>
<ul>
<li>
<h4><code><a title="miplearn.solvers.tests.InfeasibleGurobiInstance" href="#miplearn.solvers.tests.InfeasibleGurobiInstance">InfeasibleGurobiInstance</a></code></h4>
</li>
<li>
<h4><code><a title="miplearn.solvers.tests.InfeasiblePyomoInstance" href="#miplearn.solvers.tests.InfeasiblePyomoInstance">InfeasiblePyomoInstance</a></code></h4>
</li>
</ul>
</li>
</ul>
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc"><cite>pdoc</cite> 0.7.5</a>.</p>
</footer>
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/highlight.min.js"></script>
<script>hljs.initHighlightingOnLoad()</script>
</body>
</html>

View File

@@ -1,543 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" />
<meta name="generator" content="pdoc 0.7.5" />
<title>miplearn.solvers.tests.test_internal_solver API documentation</title>
<meta name="description" content="" />
<link href='https://cdnjs.cloudflare.com/ajax/libs/normalize/8.0.0/normalize.min.css' rel='stylesheet'>
<link href='https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/8.0.0/sanitize.min.css' rel='stylesheet'>
<link href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/github.min.css" rel="stylesheet">
<style>.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:30px;overflow:hidden}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:1em 0 .50em 0}h3{font-size:1.4em;margin:25px 0 10px 0}h4{margin:0;font-size:105%}a{color:#058;text-decoration:none;transition:color .3s ease-in-out}a:hover{color:#e82}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900}pre code{background:#f8f8f8;font-size:.8em;line-height:1.4em}code{background:#f2f2f1;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{background:#f8f8f8;border:0;border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0;padding:1ex}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{font-weight:bold}#index h4 + ul{margin-bottom:.6em}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-weight:bold;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}.admonition{padding:.1em .5em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style>
<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.item .name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul{padding-left:1.5em}.toc > ul > li{margin-top:.5em}}</style>
<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style>
</head>
<body>
<main>
<article id="content">
<header>
<h1 class="title">Module <code>miplearn.solvers.tests.test_internal_solver</code></h1>
</header>
<section id="section-intro">
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python"># MIPLearn: Extensible Framework for Learning-Enhanced Mixed-Integer Optimization
# Copyright (C) 2020, UChicago Argonne, LLC. All rights reserved.
# Released under the modified BSD license. See COPYING.md for more details.
import logging
from io import StringIO
from warnings import warn
import pyomo.environ as pe
from miplearn.solvers import _RedirectOutput
from miplearn.solvers.gurobi import GurobiSolver
from miplearn.solvers.pyomo.base import BasePyomoSolver
from miplearn.solvers.tests import (
_get_knapsack_instance,
_get_internal_solvers,
_get_infeasible_instance,
)
logger = logging.getLogger(__name__)
def test_redirect_output():
import sys
original_stdout = sys.stdout
io = StringIO()
with _RedirectOutput([io]):
print(&#34;Hello world&#34;)
assert sys.stdout == original_stdout
assert io.getvalue() == &#34;Hello world\n&#34;
def test_internal_solver_warm_starts():
for solver_class in _get_internal_solvers():
logger.info(&#34;Solver: %s&#34; % solver_class)
instance = _get_knapsack_instance(solver_class)
model = instance.to_model()
solver = solver_class()
solver.set_instance(instance, model)
solver.set_warm_start(
{
&#34;x&#34;: {
0: 1.0,
1: 0.0,
2: 0.0,
3: 1.0,
}
}
)
stats = solver.solve(tee=True)
if stats[&#34;Warm start value&#34;] is not None:
assert stats[&#34;Warm start value&#34;] == 725.0
else:
warn(f&#34;{solver_class.__name__} should set warm start value&#34;)
solver.set_warm_start(
{
&#34;x&#34;: {
0: 1.0,
1: 1.0,
2: 1.0,
3: 1.0,
}
}
)
stats = solver.solve(tee=True)
assert stats[&#34;Warm start value&#34;] is None
solver.fix(
{
&#34;x&#34;: {
0: 1.0,
1: 0.0,
2: 0.0,
3: 1.0,
}
}
)
stats = solver.solve(tee=True)
assert stats[&#34;Lower bound&#34;] == 725.0
assert stats[&#34;Upper bound&#34;] == 725.0
def test_internal_solver():
for solver_class in _get_internal_solvers():
logger.info(&#34;Solver: %s&#34; % solver_class)
instance = _get_knapsack_instance(solver_class)
model = instance.to_model()
solver = solver_class()
solver.set_instance(instance, model)
stats = solver.solve_lp()
assert not solver.is_infeasible()
assert round(stats[&#34;Optimal value&#34;], 3) == 1287.923
assert len(stats[&#34;Log&#34;]) &gt; 100
solution = solver.get_solution()
assert round(solution[&#34;x&#34;][0], 3) == 1.000
assert round(solution[&#34;x&#34;][1], 3) == 0.923
assert round(solution[&#34;x&#34;][2], 3) == 1.000
assert round(solution[&#34;x&#34;][3], 3) == 0.000
stats = solver.solve(tee=True)
assert not solver.is_infeasible()
assert len(stats[&#34;Log&#34;]) &gt; 100
assert stats[&#34;Lower bound&#34;] == 1183.0
assert stats[&#34;Upper bound&#34;] == 1183.0
assert stats[&#34;Sense&#34;] == &#34;max&#34;
assert isinstance(stats[&#34;Wallclock time&#34;], float)
solution = solver.get_solution()
assert solution[&#34;x&#34;][0] == 1.0
assert solution[&#34;x&#34;][1] == 0.0
assert solution[&#34;x&#34;][2] == 1.0
assert solution[&#34;x&#34;][3] == 1.0
# Add a brand new constraint
if isinstance(solver, BasePyomoSolver):
model.cut = pe.Constraint(expr=model.x[0] &lt;= 0.0, name=&#34;cut&#34;)
solver.add_constraint(model.cut)
elif isinstance(solver, GurobiSolver):
x = model.getVarByName(&#34;x[0]&#34;)
solver.add_constraint(x &lt;= 0.0, name=&#34;cut&#34;)
else:
raise Exception(&#34;Illegal state&#34;)
# New constraint should affect solution and should be listed in
# constraint ids
assert solver.get_constraint_ids() == [&#34;eq_capacity&#34;, &#34;cut&#34;]
stats = solver.solve()
assert stats[&#34;Lower bound&#34;] == 1030.0
assert solver.get_sense() == &#34;max&#34;
assert solver.get_constraint_sense(&#34;cut&#34;) == &#34;&lt;&#34;
assert solver.get_constraint_sense(&#34;eq_capacity&#34;) == &#34;&lt;&#34;
# Verify slacks
assert solver.get_inequality_slacks() == {
&#34;cut&#34;: 0.0,
&#34;eq_capacity&#34;: 3.0,
}
if isinstance(solver, GurobiSolver):
# Extract the new constraint
cobj = solver.extract_constraint(&#34;cut&#34;)
# New constraint should no longer affect solution and should no longer
# be listed in constraint ids
assert solver.get_constraint_ids() == [&#34;eq_capacity&#34;]
stats = solver.solve()
assert stats[&#34;Lower bound&#34;] == 1183.0
# New constraint should not be satisfied by current solution
assert not solver.is_constraint_satisfied(cobj)
# Re-add constraint
solver.add_constraint(cobj)
# Constraint should affect solution again
assert solver.get_constraint_ids() == [&#34;eq_capacity&#34;, &#34;cut&#34;]
stats = solver.solve()
assert stats[&#34;Lower bound&#34;] == 1030.0
# New constraint should now be satisfied
assert solver.is_constraint_satisfied(cobj)
# Relax problem and make cut into an equality constraint
solver.relax()
solver.set_constraint_sense(&#34;cut&#34;, &#34;=&#34;)
stats = solver.solve()
assert round(stats[&#34;Lower bound&#34;]) == 1030.0
assert round(solver.get_dual(&#34;eq_capacity&#34;)) == 0.0
def test_relax():
for solver_class in _get_internal_solvers():
instance = _get_knapsack_instance(solver_class)
solver = solver_class()
solver.set_instance(instance)
solver.relax()
stats = solver.solve()
assert round(stats[&#34;Lower bound&#34;]) == 1288.0
def test_infeasible_instance():
for solver_class in _get_internal_solvers():
instance = _get_infeasible_instance(solver_class)
solver = solver_class()
solver.set_instance(instance)
stats = solver.solve()
assert solver.is_infeasible()
assert solver.get_solution() is None
assert stats[&#34;Upper bound&#34;] is None
assert stats[&#34;Lower bound&#34;] is None
stats = solver.solve_lp()
assert solver.get_solution() is None
assert stats[&#34;Optimal value&#34;] is None
assert solver.get_value(&#34;x&#34;, 0) is None
def test_iteration_cb():
for solver_class in _get_internal_solvers():
logger.info(&#34;Solver: %s&#34; % solver_class)
instance = _get_knapsack_instance(solver_class)
solver = solver_class()
solver.set_instance(instance)
count = 0
def custom_iteration_cb():
nonlocal count
count += 1
return count &lt; 5
solver.solve(iteration_cb=custom_iteration_cb)
assert count == 5</code></pre>
</details>
</section>
<section>
</section>
<section>
</section>
<section>
<h2 class="section-title" id="header-functions">Functions</h2>
<dl>
<dt id="miplearn.solvers.tests.test_internal_solver.test_infeasible_instance"><code class="name flex">
<span>def <span class="ident">test_infeasible_instance</span></span>(<span>)</span>
</code></dt>
<dd>
<section class="desc"></section>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">def test_infeasible_instance():
for solver_class in _get_internal_solvers():
instance = _get_infeasible_instance(solver_class)
solver = solver_class()
solver.set_instance(instance)
stats = solver.solve()
assert solver.is_infeasible()
assert solver.get_solution() is None
assert stats[&#34;Upper bound&#34;] is None
assert stats[&#34;Lower bound&#34;] is None
stats = solver.solve_lp()
assert solver.get_solution() is None
assert stats[&#34;Optimal value&#34;] is None
assert solver.get_value(&#34;x&#34;, 0) is None</code></pre>
</details>
</dd>
<dt id="miplearn.solvers.tests.test_internal_solver.test_internal_solver"><code class="name flex">
<span>def <span class="ident">test_internal_solver</span></span>(<span>)</span>
</code></dt>
<dd>
<section class="desc"></section>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">def test_internal_solver():
for solver_class in _get_internal_solvers():
logger.info(&#34;Solver: %s&#34; % solver_class)
instance = _get_knapsack_instance(solver_class)
model = instance.to_model()
solver = solver_class()
solver.set_instance(instance, model)
stats = solver.solve_lp()
assert not solver.is_infeasible()
assert round(stats[&#34;Optimal value&#34;], 3) == 1287.923
assert len(stats[&#34;Log&#34;]) &gt; 100
solution = solver.get_solution()
assert round(solution[&#34;x&#34;][0], 3) == 1.000
assert round(solution[&#34;x&#34;][1], 3) == 0.923
assert round(solution[&#34;x&#34;][2], 3) == 1.000
assert round(solution[&#34;x&#34;][3], 3) == 0.000
stats = solver.solve(tee=True)
assert not solver.is_infeasible()
assert len(stats[&#34;Log&#34;]) &gt; 100
assert stats[&#34;Lower bound&#34;] == 1183.0
assert stats[&#34;Upper bound&#34;] == 1183.0
assert stats[&#34;Sense&#34;] == &#34;max&#34;
assert isinstance(stats[&#34;Wallclock time&#34;], float)
solution = solver.get_solution()
assert solution[&#34;x&#34;][0] == 1.0
assert solution[&#34;x&#34;][1] == 0.0
assert solution[&#34;x&#34;][2] == 1.0
assert solution[&#34;x&#34;][3] == 1.0
# Add a brand new constraint
if isinstance(solver, BasePyomoSolver):
model.cut = pe.Constraint(expr=model.x[0] &lt;= 0.0, name=&#34;cut&#34;)
solver.add_constraint(model.cut)
elif isinstance(solver, GurobiSolver):
x = model.getVarByName(&#34;x[0]&#34;)
solver.add_constraint(x &lt;= 0.0, name=&#34;cut&#34;)
else:
raise Exception(&#34;Illegal state&#34;)
# New constraint should affect solution and should be listed in
# constraint ids
assert solver.get_constraint_ids() == [&#34;eq_capacity&#34;, &#34;cut&#34;]
stats = solver.solve()
assert stats[&#34;Lower bound&#34;] == 1030.0
assert solver.get_sense() == &#34;max&#34;
assert solver.get_constraint_sense(&#34;cut&#34;) == &#34;&lt;&#34;
assert solver.get_constraint_sense(&#34;eq_capacity&#34;) == &#34;&lt;&#34;
# Verify slacks
assert solver.get_inequality_slacks() == {
&#34;cut&#34;: 0.0,
&#34;eq_capacity&#34;: 3.0,
}
if isinstance(solver, GurobiSolver):
# Extract the new constraint
cobj = solver.extract_constraint(&#34;cut&#34;)
# New constraint should no longer affect solution and should no longer
# be listed in constraint ids
assert solver.get_constraint_ids() == [&#34;eq_capacity&#34;]
stats = solver.solve()
assert stats[&#34;Lower bound&#34;] == 1183.0
# New constraint should not be satisfied by current solution
assert not solver.is_constraint_satisfied(cobj)
# Re-add constraint
solver.add_constraint(cobj)
# Constraint should affect solution again
assert solver.get_constraint_ids() == [&#34;eq_capacity&#34;, &#34;cut&#34;]
stats = solver.solve()
assert stats[&#34;Lower bound&#34;] == 1030.0
# New constraint should now be satisfied
assert solver.is_constraint_satisfied(cobj)
# Relax problem and make cut into an equality constraint
solver.relax()
solver.set_constraint_sense(&#34;cut&#34;, &#34;=&#34;)
stats = solver.solve()
assert round(stats[&#34;Lower bound&#34;]) == 1030.0
assert round(solver.get_dual(&#34;eq_capacity&#34;)) == 0.0</code></pre>
</details>
</dd>
<dt id="miplearn.solvers.tests.test_internal_solver.test_internal_solver_warm_starts"><code class="name flex">
<span>def <span class="ident">test_internal_solver_warm_starts</span></span>(<span>)</span>
</code></dt>
<dd>
<section class="desc"></section>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">def test_internal_solver_warm_starts():
for solver_class in _get_internal_solvers():
logger.info(&#34;Solver: %s&#34; % solver_class)
instance = _get_knapsack_instance(solver_class)
model = instance.to_model()
solver = solver_class()
solver.set_instance(instance, model)
solver.set_warm_start(
{
&#34;x&#34;: {
0: 1.0,
1: 0.0,
2: 0.0,
3: 1.0,
}
}
)
stats = solver.solve(tee=True)
if stats[&#34;Warm start value&#34;] is not None:
assert stats[&#34;Warm start value&#34;] == 725.0
else:
warn(f&#34;{solver_class.__name__} should set warm start value&#34;)
solver.set_warm_start(
{
&#34;x&#34;: {
0: 1.0,
1: 1.0,
2: 1.0,
3: 1.0,
}
}
)
stats = solver.solve(tee=True)
assert stats[&#34;Warm start value&#34;] is None
solver.fix(
{
&#34;x&#34;: {
0: 1.0,
1: 0.0,
2: 0.0,
3: 1.0,
}
}
)
stats = solver.solve(tee=True)
assert stats[&#34;Lower bound&#34;] == 725.0
assert stats[&#34;Upper bound&#34;] == 725.0</code></pre>
</details>
</dd>
<dt id="miplearn.solvers.tests.test_internal_solver.test_iteration_cb"><code class="name flex">
<span>def <span class="ident">test_iteration_cb</span></span>(<span>)</span>
</code></dt>
<dd>
<section class="desc"></section>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">def test_iteration_cb():
for solver_class in _get_internal_solvers():
logger.info(&#34;Solver: %s&#34; % solver_class)
instance = _get_knapsack_instance(solver_class)
solver = solver_class()
solver.set_instance(instance)
count = 0
def custom_iteration_cb():
nonlocal count
count += 1
return count &lt; 5
solver.solve(iteration_cb=custom_iteration_cb)
assert count == 5</code></pre>
</details>
</dd>
<dt id="miplearn.solvers.tests.test_internal_solver.test_redirect_output"><code class="name flex">
<span>def <span class="ident">test_redirect_output</span></span>(<span>)</span>
</code></dt>
<dd>
<section class="desc"></section>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">def test_redirect_output():
import sys
original_stdout = sys.stdout
io = StringIO()
with _RedirectOutput([io]):
print(&#34;Hello world&#34;)
assert sys.stdout == original_stdout
assert io.getvalue() == &#34;Hello world\n&#34;</code></pre>
</details>
</dd>
<dt id="miplearn.solvers.tests.test_internal_solver.test_relax"><code class="name flex">
<span>def <span class="ident">test_relax</span></span>(<span>)</span>
</code></dt>
<dd>
<section class="desc"></section>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">def test_relax():
for solver_class in _get_internal_solvers():
instance = _get_knapsack_instance(solver_class)
solver = solver_class()
solver.set_instance(instance)
solver.relax()
stats = solver.solve()
assert round(stats[&#34;Lower bound&#34;]) == 1288.0</code></pre>
</details>
</dd>
</dl>
</section>
<section>
</section>
</article>
<nav id="sidebar">
<h1>Index</h1>
<div class="toc">
<ul></ul>
</div>
<ul id="index">
<li><h3>Super-module</h3>
<ul>
<li><code><a title="miplearn.solvers.tests" href="index.html">miplearn.solvers.tests</a></code></li>
</ul>
</li>
<li><h3><a href="#header-functions">Functions</a></h3>
<ul class="">
<li><code><a title="miplearn.solvers.tests.test_internal_solver.test_infeasible_instance" href="#miplearn.solvers.tests.test_internal_solver.test_infeasible_instance">test_infeasible_instance</a></code></li>
<li><code><a title="miplearn.solvers.tests.test_internal_solver.test_internal_solver" href="#miplearn.solvers.tests.test_internal_solver.test_internal_solver">test_internal_solver</a></code></li>
<li><code><a title="miplearn.solvers.tests.test_internal_solver.test_internal_solver_warm_starts" href="#miplearn.solvers.tests.test_internal_solver.test_internal_solver_warm_starts">test_internal_solver_warm_starts</a></code></li>
<li><code><a title="miplearn.solvers.tests.test_internal_solver.test_iteration_cb" href="#miplearn.solvers.tests.test_internal_solver.test_iteration_cb">test_iteration_cb</a></code></li>
<li><code><a title="miplearn.solvers.tests.test_internal_solver.test_redirect_output" href="#miplearn.solvers.tests.test_internal_solver.test_redirect_output">test_redirect_output</a></code></li>
<li><code><a title="miplearn.solvers.tests.test_internal_solver.test_relax" href="#miplearn.solvers.tests.test_internal_solver.test_relax">test_relax</a></code></li>
</ul>
</li>
</ul>
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc"><cite>pdoc</cite> 0.7.5</a>.</p>
</footer>
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/highlight.min.js"></script>
<script>hljs.initHighlightingOnLoad()</script>
</body>
</html>

View File

@@ -1,119 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" />
<meta name="generator" content="pdoc 0.7.5" />
<title>miplearn.solvers.tests.test_lazy_cb API documentation</title>
<meta name="description" content="" />
<link href='https://cdnjs.cloudflare.com/ajax/libs/normalize/8.0.0/normalize.min.css' rel='stylesheet'>
<link href='https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/8.0.0/sanitize.min.css' rel='stylesheet'>
<link href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/github.min.css" rel="stylesheet">
<style>.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:30px;overflow:hidden}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:1em 0 .50em 0}h3{font-size:1.4em;margin:25px 0 10px 0}h4{margin:0;font-size:105%}a{color:#058;text-decoration:none;transition:color .3s ease-in-out}a:hover{color:#e82}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900}pre code{background:#f8f8f8;font-size:.8em;line-height:1.4em}code{background:#f2f2f1;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{background:#f8f8f8;border:0;border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0;padding:1ex}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{font-weight:bold}#index h4 + ul{margin-bottom:.6em}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-weight:bold;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}.admonition{padding:.1em .5em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style>
<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.item .name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul{padding-left:1.5em}.toc > ul > li{margin-top:.5em}}</style>
<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style>
</head>
<body>
<main>
<article id="content">
<header>
<h1 class="title">Module <code>miplearn.solvers.tests.test_lazy_cb</code></h1>
</header>
<section id="section-intro">
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python"># MIPLearn: Extensible Framework for Learning-Enhanced Mixed-Integer Optimization
# Copyright (C) 2020, UChicago Argonne, LLC. All rights reserved.
# Released under the modified BSD license. See COPYING.md for more details.
import logging
from miplearn.solvers.gurobi import GurobiSolver
from miplearn.solvers.tests import _get_knapsack_instance
logger = logging.getLogger(__name__)
def test_lazy_cb():
solver = GurobiSolver()
instance = _get_knapsack_instance(solver)
model = instance.to_model()
def lazy_cb(cb_solver, cb_model):
logger.info(&#34;x[0] = %.f&#34; % cb_solver.get_value(&#34;x&#34;, 0))
cobj = (cb_model.getVarByName(&#34;x[0]&#34;) * 1.0, &#34;&lt;&#34;, 0.0, &#34;cut&#34;)
if not cb_solver.is_constraint_satisfied(cobj):
cb_solver.add_constraint(cobj)
solver.set_instance(instance, model)
solver.solve(lazy_cb=lazy_cb)
solution = solver.get_solution()
assert solution[&#34;x&#34;][0] == 0.0</code></pre>
</details>
</section>
<section>
</section>
<section>
</section>
<section>
<h2 class="section-title" id="header-functions">Functions</h2>
<dl>
<dt id="miplearn.solvers.tests.test_lazy_cb.test_lazy_cb"><code class="name flex">
<span>def <span class="ident">test_lazy_cb</span></span>(<span>)</span>
</code></dt>
<dd>
<section class="desc"></section>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">def test_lazy_cb():
solver = GurobiSolver()
instance = _get_knapsack_instance(solver)
model = instance.to_model()
def lazy_cb(cb_solver, cb_model):
logger.info(&#34;x[0] = %.f&#34; % cb_solver.get_value(&#34;x&#34;, 0))
cobj = (cb_model.getVarByName(&#34;x[0]&#34;) * 1.0, &#34;&lt;&#34;, 0.0, &#34;cut&#34;)
if not cb_solver.is_constraint_satisfied(cobj):
cb_solver.add_constraint(cobj)
solver.set_instance(instance, model)
solver.solve(lazy_cb=lazy_cb)
solution = solver.get_solution()
assert solution[&#34;x&#34;][0] == 0.0</code></pre>
</details>
</dd>
</dl>
</section>
<section>
</section>
</article>
<nav id="sidebar">
<h1>Index</h1>
<div class="toc">
<ul></ul>
</div>
<ul id="index">
<li><h3>Super-module</h3>
<ul>
<li><code><a title="miplearn.solvers.tests" href="index.html">miplearn.solvers.tests</a></code></li>
</ul>
</li>
<li><h3><a href="#header-functions">Functions</a></h3>
<ul class="">
<li><code><a title="miplearn.solvers.tests.test_lazy_cb.test_lazy_cb" href="#miplearn.solvers.tests.test_lazy_cb.test_lazy_cb">test_lazy_cb</a></code></li>
</ul>
</li>
</ul>
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc"><cite>pdoc</cite> 0.7.5</a>.</p>
</footer>
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/highlight.min.js"></script>
<script>hljs.initHighlightingOnLoad()</script>
</body>
</html>

View File

@@ -1,395 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" />
<meta name="generator" content="pdoc 0.7.5" />
<title>miplearn.solvers.tests.test_learning_solver API documentation</title>
<meta name="description" content="" />
<link href='https://cdnjs.cloudflare.com/ajax/libs/normalize/8.0.0/normalize.min.css' rel='stylesheet'>
<link href='https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/8.0.0/sanitize.min.css' rel='stylesheet'>
<link href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/github.min.css" rel="stylesheet">
<style>.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:30px;overflow:hidden}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:1em 0 .50em 0}h3{font-size:1.4em;margin:25px 0 10px 0}h4{margin:0;font-size:105%}a{color:#058;text-decoration:none;transition:color .3s ease-in-out}a:hover{color:#e82}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900}pre code{background:#f8f8f8;font-size:.8em;line-height:1.4em}code{background:#f2f2f1;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{background:#f8f8f8;border:0;border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0;padding:1ex}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{font-weight:bold}#index h4 + ul{margin-bottom:.6em}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-weight:bold;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}.admonition{padding:.1em .5em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style>
<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.item .name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul{padding-left:1.5em}.toc > ul > li{margin-top:.5em}}</style>
<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style>
</head>
<body>
<main>
<article id="content">
<header>
<h1 class="title">Module <code>miplearn.solvers.tests.test_learning_solver</code></h1>
</header>
<section id="section-intro">
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python"># MIPLearn: Extensible Framework for Learning-Enhanced Mixed-Integer Optimization
# Copyright (C) 2020, UChicago Argonne, LLC. All rights reserved.
# Released under the modified BSD license. See COPYING.md for more details.
import logging
import pickle
import tempfile
import os
from miplearn.solvers.gurobi import GurobiSolver
from miplearn.solvers.learning import LearningSolver
from miplearn.solvers.tests import _get_knapsack_instance, _get_internal_solvers
logger = logging.getLogger(__name__)
def test_learning_solver():
for mode in [&#34;exact&#34;, &#34;heuristic&#34;]:
for internal_solver in _get_internal_solvers():
logger.info(&#34;Solver: %s&#34; % internal_solver)
instance = _get_knapsack_instance(internal_solver)
solver = LearningSolver(
solver=internal_solver,
mode=mode,
)
solver.solve(instance)
data = instance.training_data[0]
assert data[&#34;Solution&#34;][&#34;x&#34;][0] == 1.0
assert data[&#34;Solution&#34;][&#34;x&#34;][1] == 0.0
assert data[&#34;Solution&#34;][&#34;x&#34;][2] == 1.0
assert data[&#34;Solution&#34;][&#34;x&#34;][3] == 1.0
assert data[&#34;Lower bound&#34;] == 1183.0
assert data[&#34;Upper bound&#34;] == 1183.0
assert round(data[&#34;LP solution&#34;][&#34;x&#34;][0], 3) == 1.000
assert round(data[&#34;LP solution&#34;][&#34;x&#34;][1], 3) == 0.923
assert round(data[&#34;LP solution&#34;][&#34;x&#34;][2], 3) == 1.000
assert round(data[&#34;LP solution&#34;][&#34;x&#34;][3], 3) == 0.000
assert round(data[&#34;LP value&#34;], 3) == 1287.923
assert len(data[&#34;MIP log&#34;]) &gt; 100
solver.fit([instance])
solver.solve(instance)
# Assert solver is picklable
with tempfile.TemporaryFile() as file:
pickle.dump(solver, file)
def test_solve_without_lp():
for internal_solver in _get_internal_solvers():
logger.info(&#34;Solver: %s&#34; % internal_solver)
instance = _get_knapsack_instance(internal_solver)
solver = LearningSolver(
solver=internal_solver,
solve_lp_first=False,
)
solver.solve(instance)
solver.fit([instance])
solver.solve(instance)
def test_parallel_solve():
for internal_solver in _get_internal_solvers():
instances = [_get_knapsack_instance(internal_solver) for _ in range(10)]
solver = LearningSolver(solver=internal_solver)
results = solver.parallel_solve(instances, n_jobs=3)
assert len(results) == 10
for instance in instances:
data = instance.training_data[0]
assert len(data[&#34;Solution&#34;][&#34;x&#34;].keys()) == 4
def test_solve_fit_from_disk():
for internal_solver in _get_internal_solvers():
# Create instances and pickle them
filenames = []
for k in range(3):
instance = _get_knapsack_instance(internal_solver)
with tempfile.NamedTemporaryFile(suffix=&#34;.pkl&#34;, delete=False) as file:
filenames += [file.name]
pickle.dump(instance, file)
# Test: solve
solver = LearningSolver(solver=internal_solver)
solver.solve(filenames[0])
with open(filenames[0], &#34;rb&#34;) as file:
instance = pickle.load(file)
assert len(instance.training_data) &gt; 0
# Test: parallel_solve
solver.parallel_solve(filenames)
for filename in filenames:
with open(filename, &#34;rb&#34;) as file:
instance = pickle.load(file)
assert len(instance.training_data) &gt; 0
# Test: solve (with specified output)
output = [f + &#34;.out&#34; for f in filenames]
solver.solve(
filenames[0],
output_filename=output[0],
)
assert os.path.isfile(output[0])
# Test: parallel_solve (with specified output)
solver.parallel_solve(
filenames,
output_filenames=output,
)
for filename in output:
assert os.path.isfile(filename)
# Delete temporary files
for filename in filenames:
os.remove(filename)
for filename in output:
os.remove(filename)
def test_simulate_perfect():
internal_solver = GurobiSolver
instance = _get_knapsack_instance(internal_solver)
with tempfile.NamedTemporaryFile(suffix=&#34;.pkl&#34;, delete=False) as tmp:
pickle.dump(instance, tmp)
tmp.flush()
solver = LearningSolver(
solver=internal_solver,
simulate_perfect=True,
)
stats = solver.solve(tmp.name)
assert stats[&#34;Lower bound&#34;] == stats[&#34;Predicted LB&#34;]
def test_gap():
assert LearningSolver._compute_gap(ub=0.0, lb=0.0) == 0.0
assert LearningSolver._compute_gap(ub=1.0, lb=0.5) == 0.5
assert LearningSolver._compute_gap(ub=1.0, lb=1.0) == 0.0
assert LearningSolver._compute_gap(ub=1.0, lb=-1.0) is None
assert LearningSolver._compute_gap(ub=1.0, lb=None) is None
assert LearningSolver._compute_gap(ub=None, lb=1.0) is None
assert LearningSolver._compute_gap(ub=None, lb=None) is None</code></pre>
</details>
</section>
<section>
</section>
<section>
</section>
<section>
<h2 class="section-title" id="header-functions">Functions</h2>
<dl>
<dt id="miplearn.solvers.tests.test_learning_solver.test_gap"><code class="name flex">
<span>def <span class="ident">test_gap</span></span>(<span>)</span>
</code></dt>
<dd>
<section class="desc"></section>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">def test_gap():
assert LearningSolver._compute_gap(ub=0.0, lb=0.0) == 0.0
assert LearningSolver._compute_gap(ub=1.0, lb=0.5) == 0.5
assert LearningSolver._compute_gap(ub=1.0, lb=1.0) == 0.0
assert LearningSolver._compute_gap(ub=1.0, lb=-1.0) is None
assert LearningSolver._compute_gap(ub=1.0, lb=None) is None
assert LearningSolver._compute_gap(ub=None, lb=1.0) is None
assert LearningSolver._compute_gap(ub=None, lb=None) is None</code></pre>
</details>
</dd>
<dt id="miplearn.solvers.tests.test_learning_solver.test_learning_solver"><code class="name flex">
<span>def <span class="ident">test_learning_solver</span></span>(<span>)</span>
</code></dt>
<dd>
<section class="desc"></section>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">def test_learning_solver():
for mode in [&#34;exact&#34;, &#34;heuristic&#34;]:
for internal_solver in _get_internal_solvers():
logger.info(&#34;Solver: %s&#34; % internal_solver)
instance = _get_knapsack_instance(internal_solver)
solver = LearningSolver(
solver=internal_solver,
mode=mode,
)
solver.solve(instance)
data = instance.training_data[0]
assert data[&#34;Solution&#34;][&#34;x&#34;][0] == 1.0
assert data[&#34;Solution&#34;][&#34;x&#34;][1] == 0.0
assert data[&#34;Solution&#34;][&#34;x&#34;][2] == 1.0
assert data[&#34;Solution&#34;][&#34;x&#34;][3] == 1.0
assert data[&#34;Lower bound&#34;] == 1183.0
assert data[&#34;Upper bound&#34;] == 1183.0
assert round(data[&#34;LP solution&#34;][&#34;x&#34;][0], 3) == 1.000
assert round(data[&#34;LP solution&#34;][&#34;x&#34;][1], 3) == 0.923
assert round(data[&#34;LP solution&#34;][&#34;x&#34;][2], 3) == 1.000
assert round(data[&#34;LP solution&#34;][&#34;x&#34;][3], 3) == 0.000
assert round(data[&#34;LP value&#34;], 3) == 1287.923
assert len(data[&#34;MIP log&#34;]) &gt; 100
solver.fit([instance])
solver.solve(instance)
# Assert solver is picklable
with tempfile.TemporaryFile() as file:
pickle.dump(solver, file)</code></pre>
</details>
</dd>
<dt id="miplearn.solvers.tests.test_learning_solver.test_parallel_solve"><code class="name flex">
<span>def <span class="ident">test_parallel_solve</span></span>(<span>)</span>
</code></dt>
<dd>
<section class="desc"></section>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">def test_parallel_solve():
for internal_solver in _get_internal_solvers():
instances = [_get_knapsack_instance(internal_solver) for _ in range(10)]
solver = LearningSolver(solver=internal_solver)
results = solver.parallel_solve(instances, n_jobs=3)
assert len(results) == 10
for instance in instances:
data = instance.training_data[0]
assert len(data[&#34;Solution&#34;][&#34;x&#34;].keys()) == 4</code></pre>
</details>
</dd>
<dt id="miplearn.solvers.tests.test_learning_solver.test_simulate_perfect"><code class="name flex">
<span>def <span class="ident">test_simulate_perfect</span></span>(<span>)</span>
</code></dt>
<dd>
<section class="desc"></section>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">def test_simulate_perfect():
internal_solver = GurobiSolver
instance = _get_knapsack_instance(internal_solver)
with tempfile.NamedTemporaryFile(suffix=&#34;.pkl&#34;, delete=False) as tmp:
pickle.dump(instance, tmp)
tmp.flush()
solver = LearningSolver(
solver=internal_solver,
simulate_perfect=True,
)
stats = solver.solve(tmp.name)
assert stats[&#34;Lower bound&#34;] == stats[&#34;Predicted LB&#34;]</code></pre>
</details>
</dd>
<dt id="miplearn.solvers.tests.test_learning_solver.test_solve_fit_from_disk"><code class="name flex">
<span>def <span class="ident">test_solve_fit_from_disk</span></span>(<span>)</span>
</code></dt>
<dd>
<section class="desc"></section>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">def test_solve_fit_from_disk():
for internal_solver in _get_internal_solvers():
# Create instances and pickle them
filenames = []
for k in range(3):
instance = _get_knapsack_instance(internal_solver)
with tempfile.NamedTemporaryFile(suffix=&#34;.pkl&#34;, delete=False) as file:
filenames += [file.name]
pickle.dump(instance, file)
# Test: solve
solver = LearningSolver(solver=internal_solver)
solver.solve(filenames[0])
with open(filenames[0], &#34;rb&#34;) as file:
instance = pickle.load(file)
assert len(instance.training_data) &gt; 0
# Test: parallel_solve
solver.parallel_solve(filenames)
for filename in filenames:
with open(filename, &#34;rb&#34;) as file:
instance = pickle.load(file)
assert len(instance.training_data) &gt; 0
# Test: solve (with specified output)
output = [f + &#34;.out&#34; for f in filenames]
solver.solve(
filenames[0],
output_filename=output[0],
)
assert os.path.isfile(output[0])
# Test: parallel_solve (with specified output)
solver.parallel_solve(
filenames,
output_filenames=output,
)
for filename in output:
assert os.path.isfile(filename)
# Delete temporary files
for filename in filenames:
os.remove(filename)
for filename in output:
os.remove(filename)</code></pre>
</details>
</dd>
<dt id="miplearn.solvers.tests.test_learning_solver.test_solve_without_lp"><code class="name flex">
<span>def <span class="ident">test_solve_without_lp</span></span>(<span>)</span>
</code></dt>
<dd>
<section class="desc"></section>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">def test_solve_without_lp():
for internal_solver in _get_internal_solvers():
logger.info(&#34;Solver: %s&#34; % internal_solver)
instance = _get_knapsack_instance(internal_solver)
solver = LearningSolver(
solver=internal_solver,
solve_lp_first=False,
)
solver.solve(instance)
solver.fit([instance])
solver.solve(instance)</code></pre>
</details>
</dd>
</dl>
</section>
<section>
</section>
</article>
<nav id="sidebar">
<h1>Index</h1>
<div class="toc">
<ul></ul>
</div>
<ul id="index">
<li><h3>Super-module</h3>
<ul>
<li><code><a title="miplearn.solvers.tests" href="index.html">miplearn.solvers.tests</a></code></li>
</ul>
</li>
<li><h3><a href="#header-functions">Functions</a></h3>
<ul class="">
<li><code><a title="miplearn.solvers.tests.test_learning_solver.test_gap" href="#miplearn.solvers.tests.test_learning_solver.test_gap">test_gap</a></code></li>
<li><code><a title="miplearn.solvers.tests.test_learning_solver.test_learning_solver" href="#miplearn.solvers.tests.test_learning_solver.test_learning_solver">test_learning_solver</a></code></li>
<li><code><a title="miplearn.solvers.tests.test_learning_solver.test_parallel_solve" href="#miplearn.solvers.tests.test_learning_solver.test_parallel_solve">test_parallel_solve</a></code></li>
<li><code><a title="miplearn.solvers.tests.test_learning_solver.test_simulate_perfect" href="#miplearn.solvers.tests.test_learning_solver.test_simulate_perfect">test_simulate_perfect</a></code></li>
<li><code><a title="miplearn.solvers.tests.test_learning_solver.test_solve_fit_from_disk" href="#miplearn.solvers.tests.test_learning_solver.test_solve_fit_from_disk">test_solve_fit_from_disk</a></code></li>
<li><code><a title="miplearn.solvers.tests.test_learning_solver.test_solve_without_lp" href="#miplearn.solvers.tests.test_learning_solver.test_solve_without_lp">test_solve_without_lp</a></code></li>
</ul>
</li>
</ul>
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc"><cite>pdoc</cite> 0.7.5</a>.</p>
</footer>
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/highlight.min.js"></script>
<script>hljs.initHighlightingOnLoad()</script>
</body>
</html>