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

@@ -36,10 +36,6 @@
<dd>
<section class="desc"></section>
</dd>
<dt><code class="name"><a title="miplearn.components.steps.tests" href="tests/index.html">miplearn.components.steps.tests</a></code></dt>
<dd>
<section class="desc"></section>
</dd>
</dl>
</section>
<section>
@@ -65,7 +61,6 @@
<li><code><a title="miplearn.components.steps.convert_tight" href="convert_tight.html">miplearn.components.steps.convert_tight</a></code></li>
<li><code><a title="miplearn.components.steps.drop_redundant" href="drop_redundant.html">miplearn.components.steps.drop_redundant</a></code></li>
<li><code><a title="miplearn.components.steps.relax_integrality" href="relax_integrality.html">miplearn.components.steps.relax_integrality</a></code></li>
<li><code><a title="miplearn.components.steps.tests" href="tests/index.html">miplearn.components.steps.tests</a></code></li>
</ul>
</li>
</ul>

View File

@@ -1,70 +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.components.steps.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.components.steps.tests</code></h1>
</header>
<section id="section-intro">
</section>
<section>
<h2 class="section-title" id="header-submodules">Sub-modules</h2>
<dl>
<dt><code class="name"><a title="miplearn.components.steps.tests.test_convert_tight" href="test_convert_tight.html">miplearn.components.steps.tests.test_convert_tight</a></code></dt>
<dd>
<section class="desc"></section>
</dd>
<dt><code class="name"><a title="miplearn.components.steps.tests.test_drop_redundant" href="test_drop_redundant.html">miplearn.components.steps.tests.test_drop_redundant</a></code></dt>
<dd>
<section class="desc"></section>
</dd>
</dl>
</section>
<section>
</section>
<section>
</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.components.steps" href="../index.html">miplearn.components.steps</a></code></li>
</ul>
</li>
<li><h3><a href="#header-submodules">Sub-modules</a></h3>
<ul>
<li><code><a title="miplearn.components.steps.tests.test_convert_tight" href="test_convert_tight.html">miplearn.components.steps.tests.test_convert_tight</a></code></li>
<li><code><a title="miplearn.components.steps.tests.test_drop_redundant" href="test_drop_redundant.html">miplearn.components.steps.tests.test_drop_redundant</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,385 +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.components.steps.tests.test_convert_tight 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.components.steps.tests.test_convert_tight</code></h1>
</header>
<section id="section-intro">
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">from unittest.mock import Mock
from miplearn.classifiers import Classifier
from miplearn.components.steps.convert_tight import ConvertTightIneqsIntoEqsStep
from miplearn.components.steps.relax_integrality import RelaxIntegralityStep
from miplearn.instance import Instance
from miplearn.problems.knapsack import GurobiKnapsackInstance
from miplearn.solvers.gurobi import GurobiSolver
from miplearn.solvers.learning import LearningSolver
def test_convert_tight_usage():
instance = GurobiKnapsackInstance(
weights=[3.0, 5.0, 10.0],
prices=[1.0, 1.0, 1.0],
capacity=16.0,
)
solver = LearningSolver(
solver=GurobiSolver,
components=[
RelaxIntegralityStep(),
ConvertTightIneqsIntoEqsStep(),
],
)
# Solve original problem
stats = solver.solve(instance)
original_upper_bound = stats[&#34;Upper bound&#34;]
# Should collect training data
assert instance.training_data[0][&#34;slacks&#34;][&#34;eq_capacity&#34;] == 0.0
# Fit and resolve
solver.fit([instance])
stats = solver.solve(instance)
# Objective value should be the same
assert stats[&#34;Upper bound&#34;] == original_upper_bound
assert stats[&#34;ConvertTight: Inf iterations&#34;] == 0
assert stats[&#34;ConvertTight: Subopt iterations&#34;] == 0
class SampleInstance(Instance):
def to_model(self):
import gurobipy as grb
m = grb.Model(&#34;model&#34;)
x1 = m.addVar(name=&#34;x1&#34;)
x2 = m.addVar(name=&#34;x2&#34;)
m.setObjective(x1 + 2 * x2, grb.GRB.MAXIMIZE)
m.addConstr(x1 &lt;= 2, name=&#34;c1&#34;)
m.addConstr(x2 &lt;= 2, name=&#34;c2&#34;)
m.addConstr(x1 + x2 &lt;= 3, name=&#34;c2&#34;)
return m
def test_convert_tight_infeasibility():
comp = ConvertTightIneqsIntoEqsStep()
comp.classifiers = {
&#34;c1&#34;: Mock(spec=Classifier),
&#34;c2&#34;: Mock(spec=Classifier),
&#34;c3&#34;: Mock(spec=Classifier),
}
comp.classifiers[&#34;c1&#34;].predict_proba = Mock(return_value=[[0, 1]])
comp.classifiers[&#34;c2&#34;].predict_proba = Mock(return_value=[[0, 1]])
comp.classifiers[&#34;c3&#34;].predict_proba = Mock(return_value=[[1, 0]])
solver = LearningSolver(
solver=GurobiSolver,
components=[comp],
solve_lp_first=False,
)
instance = SampleInstance()
stats = solver.solve(instance)
assert stats[&#34;Upper bound&#34;] == 5.0
assert stats[&#34;ConvertTight: Inf iterations&#34;] == 1
assert stats[&#34;ConvertTight: Subopt iterations&#34;] == 0
def test_convert_tight_suboptimality():
comp = ConvertTightIneqsIntoEqsStep(check_optimality=True)
comp.classifiers = {
&#34;c1&#34;: Mock(spec=Classifier),
&#34;c2&#34;: Mock(spec=Classifier),
&#34;c3&#34;: Mock(spec=Classifier),
}
comp.classifiers[&#34;c1&#34;].predict_proba = Mock(return_value=[[0, 1]])
comp.classifiers[&#34;c2&#34;].predict_proba = Mock(return_value=[[1, 0]])
comp.classifiers[&#34;c3&#34;].predict_proba = Mock(return_value=[[0, 1]])
solver = LearningSolver(
solver=GurobiSolver,
components=[comp],
solve_lp_first=False,
)
instance = SampleInstance()
stats = solver.solve(instance)
assert stats[&#34;Upper bound&#34;] == 5.0
assert stats[&#34;ConvertTight: Inf iterations&#34;] == 0
assert stats[&#34;ConvertTight: Subopt iterations&#34;] == 1
def test_convert_tight_optimal():
comp = ConvertTightIneqsIntoEqsStep()
comp.classifiers = {
&#34;c1&#34;: Mock(spec=Classifier),
&#34;c2&#34;: Mock(spec=Classifier),
&#34;c3&#34;: Mock(spec=Classifier),
}
comp.classifiers[&#34;c1&#34;].predict_proba = Mock(return_value=[[1, 0]])
comp.classifiers[&#34;c2&#34;].predict_proba = Mock(return_value=[[0, 1]])
comp.classifiers[&#34;c3&#34;].predict_proba = Mock(return_value=[[0, 1]])
solver = LearningSolver(
solver=GurobiSolver,
components=[comp],
solve_lp_first=False,
)
instance = SampleInstance()
stats = solver.solve(instance)
assert stats[&#34;Upper bound&#34;] == 5.0
assert stats[&#34;ConvertTight: Inf iterations&#34;] == 0
assert stats[&#34;ConvertTight: Subopt iterations&#34;] == 0</code></pre>
</details>
</section>
<section>
</section>
<section>
</section>
<section>
<h2 class="section-title" id="header-functions">Functions</h2>
<dl>
<dt id="miplearn.components.steps.tests.test_convert_tight.test_convert_tight_infeasibility"><code class="name flex">
<span>def <span class="ident">test_convert_tight_infeasibility</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_convert_tight_infeasibility():
comp = ConvertTightIneqsIntoEqsStep()
comp.classifiers = {
&#34;c1&#34;: Mock(spec=Classifier),
&#34;c2&#34;: Mock(spec=Classifier),
&#34;c3&#34;: Mock(spec=Classifier),
}
comp.classifiers[&#34;c1&#34;].predict_proba = Mock(return_value=[[0, 1]])
comp.classifiers[&#34;c2&#34;].predict_proba = Mock(return_value=[[0, 1]])
comp.classifiers[&#34;c3&#34;].predict_proba = Mock(return_value=[[1, 0]])
solver = LearningSolver(
solver=GurobiSolver,
components=[comp],
solve_lp_first=False,
)
instance = SampleInstance()
stats = solver.solve(instance)
assert stats[&#34;Upper bound&#34;] == 5.0
assert stats[&#34;ConvertTight: Inf iterations&#34;] == 1
assert stats[&#34;ConvertTight: Subopt iterations&#34;] == 0</code></pre>
</details>
</dd>
<dt id="miplearn.components.steps.tests.test_convert_tight.test_convert_tight_optimal"><code class="name flex">
<span>def <span class="ident">test_convert_tight_optimal</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_convert_tight_optimal():
comp = ConvertTightIneqsIntoEqsStep()
comp.classifiers = {
&#34;c1&#34;: Mock(spec=Classifier),
&#34;c2&#34;: Mock(spec=Classifier),
&#34;c3&#34;: Mock(spec=Classifier),
}
comp.classifiers[&#34;c1&#34;].predict_proba = Mock(return_value=[[1, 0]])
comp.classifiers[&#34;c2&#34;].predict_proba = Mock(return_value=[[0, 1]])
comp.classifiers[&#34;c3&#34;].predict_proba = Mock(return_value=[[0, 1]])
solver = LearningSolver(
solver=GurobiSolver,
components=[comp],
solve_lp_first=False,
)
instance = SampleInstance()
stats = solver.solve(instance)
assert stats[&#34;Upper bound&#34;] == 5.0
assert stats[&#34;ConvertTight: Inf iterations&#34;] == 0
assert stats[&#34;ConvertTight: Subopt iterations&#34;] == 0</code></pre>
</details>
</dd>
<dt id="miplearn.components.steps.tests.test_convert_tight.test_convert_tight_suboptimality"><code class="name flex">
<span>def <span class="ident">test_convert_tight_suboptimality</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_convert_tight_suboptimality():
comp = ConvertTightIneqsIntoEqsStep(check_optimality=True)
comp.classifiers = {
&#34;c1&#34;: Mock(spec=Classifier),
&#34;c2&#34;: Mock(spec=Classifier),
&#34;c3&#34;: Mock(spec=Classifier),
}
comp.classifiers[&#34;c1&#34;].predict_proba = Mock(return_value=[[0, 1]])
comp.classifiers[&#34;c2&#34;].predict_proba = Mock(return_value=[[1, 0]])
comp.classifiers[&#34;c3&#34;].predict_proba = Mock(return_value=[[0, 1]])
solver = LearningSolver(
solver=GurobiSolver,
components=[comp],
solve_lp_first=False,
)
instance = SampleInstance()
stats = solver.solve(instance)
assert stats[&#34;Upper bound&#34;] == 5.0
assert stats[&#34;ConvertTight: Inf iterations&#34;] == 0
assert stats[&#34;ConvertTight: Subopt iterations&#34;] == 1</code></pre>
</details>
</dd>
<dt id="miplearn.components.steps.tests.test_convert_tight.test_convert_tight_usage"><code class="name flex">
<span>def <span class="ident">test_convert_tight_usage</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_convert_tight_usage():
instance = GurobiKnapsackInstance(
weights=[3.0, 5.0, 10.0],
prices=[1.0, 1.0, 1.0],
capacity=16.0,
)
solver = LearningSolver(
solver=GurobiSolver,
components=[
RelaxIntegralityStep(),
ConvertTightIneqsIntoEqsStep(),
],
)
# Solve original problem
stats = solver.solve(instance)
original_upper_bound = stats[&#34;Upper bound&#34;]
# Should collect training data
assert instance.training_data[0][&#34;slacks&#34;][&#34;eq_capacity&#34;] == 0.0
# Fit and resolve
solver.fit([instance])
stats = solver.solve(instance)
# Objective value should be the same
assert stats[&#34;Upper bound&#34;] == original_upper_bound
assert stats[&#34;ConvertTight: Inf iterations&#34;] == 0
assert stats[&#34;ConvertTight: Subopt iterations&#34;] == 0</code></pre>
</details>
</dd>
</dl>
</section>
<section>
<h2 class="section-title" id="header-classes">Classes</h2>
<dl>
<dt id="miplearn.components.steps.tests.test_convert_tight.SampleInstance"><code class="flex name class">
<span>class <span class="ident">SampleInstance</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 SampleInstance(Instance):
def to_model(self):
import gurobipy as grb
m = grb.Model(&#34;model&#34;)
x1 = m.addVar(name=&#34;x1&#34;)
x2 = m.addVar(name=&#34;x2&#34;)
m.setObjective(x1 + 2 * x2, grb.GRB.MAXIMIZE)
m.addConstr(x1 &lt;= 2, name=&#34;c1&#34;)
m.addConstr(x2 &lt;= 2, name=&#34;c2&#34;)
m.addConstr(x1 + x2 &lt;= 3, name=&#34;c2&#34;)
return m</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.components.steps.tests" href="index.html">miplearn.components.steps.tests</a></code></li>
</ul>
</li>
<li><h3><a href="#header-functions">Functions</a></h3>
<ul class="">
<li><code><a title="miplearn.components.steps.tests.test_convert_tight.test_convert_tight_infeasibility" href="#miplearn.components.steps.tests.test_convert_tight.test_convert_tight_infeasibility">test_convert_tight_infeasibility</a></code></li>
<li><code><a title="miplearn.components.steps.tests.test_convert_tight.test_convert_tight_optimal" href="#miplearn.components.steps.tests.test_convert_tight.test_convert_tight_optimal">test_convert_tight_optimal</a></code></li>
<li><code><a title="miplearn.components.steps.tests.test_convert_tight.test_convert_tight_suboptimality" href="#miplearn.components.steps.tests.test_convert_tight.test_convert_tight_suboptimality">test_convert_tight_suboptimality</a></code></li>
<li><code><a title="miplearn.components.steps.tests.test_convert_tight.test_convert_tight_usage" href="#miplearn.components.steps.tests.test_convert_tight.test_convert_tight_usage">test_convert_tight_usage</a></code></li>
</ul>
</li>
<li><h3><a href="#header-classes">Classes</a></h3>
<ul>
<li>
<h4><code><a title="miplearn.components.steps.tests.test_convert_tight.SampleInstance" href="#miplearn.components.steps.tests.test_convert_tight.SampleInstance">SampleInstance</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,764 +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.components.steps.tests.test_drop_redundant 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.components.steps.tests.test_drop_redundant</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 unittest.mock import Mock, call
import numpy as np
from miplearn.classifiers import Classifier
from miplearn.components.relaxation import DropRedundantInequalitiesStep
from miplearn.instance import Instance
from miplearn.solvers.internal import InternalSolver
from miplearn.solvers.learning import LearningSolver
def _setup():
solver = Mock(spec=LearningSolver)
internal = solver.internal_solver = Mock(spec=InternalSolver)
internal.get_constraint_ids = Mock(return_value=[&#34;c1&#34;, &#34;c2&#34;, &#34;c3&#34;, &#34;c4&#34;])
internal.get_inequality_slacks = Mock(
side_effect=lambda: {
&#34;c1&#34;: 0.5,
&#34;c2&#34;: 0.0,
&#34;c3&#34;: 0.0,
&#34;c4&#34;: 1.4,
}
)
internal.extract_constraint = Mock(side_effect=lambda cid: &#34;&lt;%s&gt;&#34; % cid)
internal.is_constraint_satisfied = Mock(return_value=False)
instance = Mock(spec=Instance)
instance.get_constraint_features = Mock(
side_effect=lambda cid: {
&#34;c2&#34;: np.array([1.0, 0.0]),
&#34;c3&#34;: np.array([0.5, 0.5]),
&#34;c4&#34;: np.array([1.0]),
}[cid]
)
instance.get_constraint_category = Mock(
side_effect=lambda cid: {
&#34;c1&#34;: None,
&#34;c2&#34;: &#34;type-a&#34;,
&#34;c3&#34;: &#34;type-a&#34;,
&#34;c4&#34;: &#34;type-b&#34;,
}[cid]
)
classifiers = {
&#34;type-a&#34;: Mock(spec=Classifier),
&#34;type-b&#34;: Mock(spec=Classifier),
}
classifiers[&#34;type-a&#34;].predict_proba = Mock(
return_value=np.array(
[
[0.20, 0.80],
[0.05, 0.95],
]
)
)
classifiers[&#34;type-b&#34;].predict_proba = Mock(
return_value=np.array(
[
[0.02, 0.98],
]
)
)
return solver, internal, instance, classifiers
def test_drop_redundant():
solver, internal, instance, classifiers = _setup()
component = DropRedundantInequalitiesStep()
component.classifiers = classifiers
# LearningSolver calls before_solve
component.before_solve(solver, instance, None)
# Should query list of constraints
internal.get_constraint_ids.assert_called_once()
# Should query category and features for each constraint in the model
assert instance.get_constraint_category.call_count == 4
instance.get_constraint_category.assert_has_calls(
[
call(&#34;c1&#34;),
call(&#34;c2&#34;),
call(&#34;c3&#34;),
call(&#34;c4&#34;),
]
)
# For constraint with non-null categories, should ask for features
assert instance.get_constraint_features.call_count == 3
instance.get_constraint_features.assert_has_calls(
[
call(&#34;c2&#34;),
call(&#34;c3&#34;),
call(&#34;c4&#34;),
]
)
# Should ask ML to predict whether constraint should be removed
type_a_actual = component.classifiers[&#34;type-a&#34;].predict_proba.call_args[0][0]
type_b_actual = component.classifiers[&#34;type-b&#34;].predict_proba.call_args[0][0]
np.testing.assert_array_equal(type_a_actual, np.array([[1.0, 0.0], [0.5, 0.5]]))
np.testing.assert_array_equal(type_b_actual, np.array([[1.0]]))
# Should ask internal solver to remove constraints predicted as redundant
assert internal.extract_constraint.call_count == 2
internal.extract_constraint.assert_has_calls(
[
call(&#34;c3&#34;),
call(&#34;c4&#34;),
]
)
# LearningSolver calls after_solve
training_data = {}
component.after_solve(solver, instance, None, {}, training_data)
# Should query slack for all inequalities
internal.get_inequality_slacks.assert_called_once()
# Should store constraint slacks in instance object
assert training_data[&#34;slacks&#34;] == {
&#34;c1&#34;: 0.5,
&#34;c2&#34;: 0.0,
&#34;c3&#34;: 0.0,
&#34;c4&#34;: 1.4,
}
def test_drop_redundant_with_check_feasibility():
solver, internal, instance, classifiers = _setup()
component = DropRedundantInequalitiesStep(
check_feasibility=True,
violation_tolerance=1e-3,
)
component.classifiers = classifiers
# LearningSolver call before_solve
component.before_solve(solver, instance, None)
# Assert constraints are extracted
assert internal.extract_constraint.call_count == 2
internal.extract_constraint.assert_has_calls(
[
call(&#34;c3&#34;),
call(&#34;c4&#34;),
]
)
# LearningSolver calls iteration_cb (first time)
should_repeat = component.iteration_cb(solver, instance, None)
# Should ask LearningSolver to repeat
assert should_repeat
# Should ask solver if removed constraints are satisfied (mock always returns false)
internal.is_constraint_satisfied.assert_has_calls(
[
call(&#34;&lt;c3&gt;&#34;, 1e-3),
call(&#34;&lt;c4&gt;&#34;, 1e-3),
]
)
# Should add constraints back to LP relaxation
internal.add_constraint.assert_has_calls([call(&#34;&lt;c3&gt;&#34;), call(&#34;&lt;c4&gt;&#34;)])
# LearningSolver calls iteration_cb (second time)
should_repeat = component.iteration_cb(solver, instance, None)
assert not should_repeat
def test_x_y_fit_predict_evaluate():
instances = [Mock(spec=Instance), Mock(spec=Instance)]
component = DropRedundantInequalitiesStep(slack_tolerance=0.05, threshold=0.80)
component.classifiers = {
&#34;type-a&#34;: Mock(spec=Classifier),
&#34;type-b&#34;: Mock(spec=Classifier),
}
component.classifiers[&#34;type-a&#34;].predict_proba = Mock(
return_value=[
np.array([0.20, 0.80]),
]
)
component.classifiers[&#34;type-b&#34;].predict_proba = Mock(
return_value=np.array(
[
[0.50, 0.50],
[0.05, 0.95],
]
)
)
# First mock instance
instances[0].training_data = [
{
&#34;slacks&#34;: {
&#34;c1&#34;: 0.00,
&#34;c2&#34;: 0.05,
&#34;c3&#34;: 0.00,
&#34;c4&#34;: 30.0,
}
}
]
instances[0].get_constraint_category = Mock(
side_effect=lambda cid: {
&#34;c1&#34;: None,
&#34;c2&#34;: &#34;type-a&#34;,
&#34;c3&#34;: &#34;type-a&#34;,
&#34;c4&#34;: &#34;type-b&#34;,
}[cid]
)
instances[0].get_constraint_features = Mock(
side_effect=lambda cid: {
&#34;c2&#34;: np.array([1.0, 0.0]),
&#34;c3&#34;: np.array([0.5, 0.5]),
&#34;c4&#34;: np.array([1.0]),
}[cid]
)
# Second mock instance
instances[1].training_data = [
{
&#34;slacks&#34;: {
&#34;c1&#34;: 0.00,
&#34;c3&#34;: 0.30,
&#34;c4&#34;: 0.00,
&#34;c5&#34;: 0.00,
}
}
]
instances[1].get_constraint_category = Mock(
side_effect=lambda cid: {
&#34;c1&#34;: None,
&#34;c3&#34;: &#34;type-a&#34;,
&#34;c4&#34;: &#34;type-b&#34;,
&#34;c5&#34;: &#34;type-b&#34;,
}[cid]
)
instances[1].get_constraint_features = Mock(
side_effect=lambda cid: {
&#34;c3&#34;: np.array([0.3, 0.4]),
&#34;c4&#34;: np.array([0.7]),
&#34;c5&#34;: np.array([0.8]),
}[cid]
)
expected_x = {
&#34;type-a&#34;: np.array(
[
[1.0, 0.0],
[0.5, 0.5],
[0.3, 0.4],
]
),
&#34;type-b&#34;: np.array(
[
[1.0],
[0.7],
[0.8],
]
),
}
expected_y = {
&#34;type-a&#34;: np.array([[0], [0], [1]]),
&#34;type-b&#34;: np.array([[1], [0], [0]]),
}
# Should build X and Y matrices correctly
actual_x = component.x(instances)
actual_y = component.y(instances)
for category in [&#34;type-a&#34;, &#34;type-b&#34;]:
np.testing.assert_array_equal(actual_x[category], expected_x[category])
np.testing.assert_array_equal(actual_y[category], expected_y[category])
# Should pass along X and Y matrices to classifiers
component.fit(instances)
for category in [&#34;type-a&#34;, &#34;type-b&#34;]:
actual_x = component.classifiers[category].fit.call_args[0][0]
actual_y = component.classifiers[category].fit.call_args[0][1]
np.testing.assert_array_equal(actual_x, expected_x[category])
np.testing.assert_array_equal(actual_y, expected_y[category])
assert component.predict(expected_x) == {&#34;type-a&#34;: [[1]], &#34;type-b&#34;: [[0], [1]]}
ev = component.evaluate(instances[1])
assert ev[&#34;True positive&#34;] == 1
assert ev[&#34;True negative&#34;] == 1
assert ev[&#34;False positive&#34;] == 1
assert ev[&#34;False negative&#34;] == 0
def test_x_multiple_solves():
instance = Mock(spec=Instance)
instance.training_data = [
{
&#34;slacks&#34;: {
&#34;c1&#34;: 0.00,
&#34;c2&#34;: 0.05,
&#34;c3&#34;: 0.00,
&#34;c4&#34;: 30.0,
}
},
{
&#34;slacks&#34;: {
&#34;c1&#34;: 0.00,
&#34;c2&#34;: 0.00,
&#34;c3&#34;: 1.00,
&#34;c4&#34;: 0.0,
}
},
]
instance.get_constraint_category = Mock(
side_effect=lambda cid: {
&#34;c1&#34;: None,
&#34;c2&#34;: &#34;type-a&#34;,
&#34;c3&#34;: &#34;type-a&#34;,
&#34;c4&#34;: &#34;type-b&#34;,
}[cid]
)
instance.get_constraint_features = Mock(
side_effect=lambda cid: {
&#34;c2&#34;: np.array([1.0, 0.0]),
&#34;c3&#34;: np.array([0.5, 0.5]),
&#34;c4&#34;: np.array([1.0]),
}[cid]
)
expected_x = {
&#34;type-a&#34;: np.array(
[
[1.0, 0.0],
[0.5, 0.5],
[1.0, 0.0],
[0.5, 0.5],
]
),
&#34;type-b&#34;: np.array(
[
[1.0],
[1.0],
]
),
}
expected_y = {
&#34;type-a&#34;: np.array([[1], [0], [0], [1]]),
&#34;type-b&#34;: np.array([[1], [0]]),
}
# Should build X and Y matrices correctly
component = DropRedundantInequalitiesStep()
actual_x = component.x([instance])
actual_y = component.y([instance])
print(actual_x)
for category in [&#34;type-a&#34;, &#34;type-b&#34;]:
np.testing.assert_array_equal(actual_x[category], expected_x[category])
np.testing.assert_array_equal(actual_y[category], expected_y[category])</code></pre>
</details>
</section>
<section>
</section>
<section>
</section>
<section>
<h2 class="section-title" id="header-functions">Functions</h2>
<dl>
<dt id="miplearn.components.steps.tests.test_drop_redundant.test_drop_redundant"><code class="name flex">
<span>def <span class="ident">test_drop_redundant</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_drop_redundant():
solver, internal, instance, classifiers = _setup()
component = DropRedundantInequalitiesStep()
component.classifiers = classifiers
# LearningSolver calls before_solve
component.before_solve(solver, instance, None)
# Should query list of constraints
internal.get_constraint_ids.assert_called_once()
# Should query category and features for each constraint in the model
assert instance.get_constraint_category.call_count == 4
instance.get_constraint_category.assert_has_calls(
[
call(&#34;c1&#34;),
call(&#34;c2&#34;),
call(&#34;c3&#34;),
call(&#34;c4&#34;),
]
)
# For constraint with non-null categories, should ask for features
assert instance.get_constraint_features.call_count == 3
instance.get_constraint_features.assert_has_calls(
[
call(&#34;c2&#34;),
call(&#34;c3&#34;),
call(&#34;c4&#34;),
]
)
# Should ask ML to predict whether constraint should be removed
type_a_actual = component.classifiers[&#34;type-a&#34;].predict_proba.call_args[0][0]
type_b_actual = component.classifiers[&#34;type-b&#34;].predict_proba.call_args[0][0]
np.testing.assert_array_equal(type_a_actual, np.array([[1.0, 0.0], [0.5, 0.5]]))
np.testing.assert_array_equal(type_b_actual, np.array([[1.0]]))
# Should ask internal solver to remove constraints predicted as redundant
assert internal.extract_constraint.call_count == 2
internal.extract_constraint.assert_has_calls(
[
call(&#34;c3&#34;),
call(&#34;c4&#34;),
]
)
# LearningSolver calls after_solve
training_data = {}
component.after_solve(solver, instance, None, {}, training_data)
# Should query slack for all inequalities
internal.get_inequality_slacks.assert_called_once()
# Should store constraint slacks in instance object
assert training_data[&#34;slacks&#34;] == {
&#34;c1&#34;: 0.5,
&#34;c2&#34;: 0.0,
&#34;c3&#34;: 0.0,
&#34;c4&#34;: 1.4,
}</code></pre>
</details>
</dd>
<dt id="miplearn.components.steps.tests.test_drop_redundant.test_drop_redundant_with_check_feasibility"><code class="name flex">
<span>def <span class="ident">test_drop_redundant_with_check_feasibility</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_drop_redundant_with_check_feasibility():
solver, internal, instance, classifiers = _setup()
component = DropRedundantInequalitiesStep(
check_feasibility=True,
violation_tolerance=1e-3,
)
component.classifiers = classifiers
# LearningSolver call before_solve
component.before_solve(solver, instance, None)
# Assert constraints are extracted
assert internal.extract_constraint.call_count == 2
internal.extract_constraint.assert_has_calls(
[
call(&#34;c3&#34;),
call(&#34;c4&#34;),
]
)
# LearningSolver calls iteration_cb (first time)
should_repeat = component.iteration_cb(solver, instance, None)
# Should ask LearningSolver to repeat
assert should_repeat
# Should ask solver if removed constraints are satisfied (mock always returns false)
internal.is_constraint_satisfied.assert_has_calls(
[
call(&#34;&lt;c3&gt;&#34;, 1e-3),
call(&#34;&lt;c4&gt;&#34;, 1e-3),
]
)
# Should add constraints back to LP relaxation
internal.add_constraint.assert_has_calls([call(&#34;&lt;c3&gt;&#34;), call(&#34;&lt;c4&gt;&#34;)])
# LearningSolver calls iteration_cb (second time)
should_repeat = component.iteration_cb(solver, instance, None)
assert not should_repeat</code></pre>
</details>
</dd>
<dt id="miplearn.components.steps.tests.test_drop_redundant.test_x_multiple_solves"><code class="name flex">
<span>def <span class="ident">test_x_multiple_solves</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_x_multiple_solves():
instance = Mock(spec=Instance)
instance.training_data = [
{
&#34;slacks&#34;: {
&#34;c1&#34;: 0.00,
&#34;c2&#34;: 0.05,
&#34;c3&#34;: 0.00,
&#34;c4&#34;: 30.0,
}
},
{
&#34;slacks&#34;: {
&#34;c1&#34;: 0.00,
&#34;c2&#34;: 0.00,
&#34;c3&#34;: 1.00,
&#34;c4&#34;: 0.0,
}
},
]
instance.get_constraint_category = Mock(
side_effect=lambda cid: {
&#34;c1&#34;: None,
&#34;c2&#34;: &#34;type-a&#34;,
&#34;c3&#34;: &#34;type-a&#34;,
&#34;c4&#34;: &#34;type-b&#34;,
}[cid]
)
instance.get_constraint_features = Mock(
side_effect=lambda cid: {
&#34;c2&#34;: np.array([1.0, 0.0]),
&#34;c3&#34;: np.array([0.5, 0.5]),
&#34;c4&#34;: np.array([1.0]),
}[cid]
)
expected_x = {
&#34;type-a&#34;: np.array(
[
[1.0, 0.0],
[0.5, 0.5],
[1.0, 0.0],
[0.5, 0.5],
]
),
&#34;type-b&#34;: np.array(
[
[1.0],
[1.0],
]
),
}
expected_y = {
&#34;type-a&#34;: np.array([[1], [0], [0], [1]]),
&#34;type-b&#34;: np.array([[1], [0]]),
}
# Should build X and Y matrices correctly
component = DropRedundantInequalitiesStep()
actual_x = component.x([instance])
actual_y = component.y([instance])
print(actual_x)
for category in [&#34;type-a&#34;, &#34;type-b&#34;]:
np.testing.assert_array_equal(actual_x[category], expected_x[category])
np.testing.assert_array_equal(actual_y[category], expected_y[category])</code></pre>
</details>
</dd>
<dt id="miplearn.components.steps.tests.test_drop_redundant.test_x_y_fit_predict_evaluate"><code class="name flex">
<span>def <span class="ident">test_x_y_fit_predict_evaluate</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_x_y_fit_predict_evaluate():
instances = [Mock(spec=Instance), Mock(spec=Instance)]
component = DropRedundantInequalitiesStep(slack_tolerance=0.05, threshold=0.80)
component.classifiers = {
&#34;type-a&#34;: Mock(spec=Classifier),
&#34;type-b&#34;: Mock(spec=Classifier),
}
component.classifiers[&#34;type-a&#34;].predict_proba = Mock(
return_value=[
np.array([0.20, 0.80]),
]
)
component.classifiers[&#34;type-b&#34;].predict_proba = Mock(
return_value=np.array(
[
[0.50, 0.50],
[0.05, 0.95],
]
)
)
# First mock instance
instances[0].training_data = [
{
&#34;slacks&#34;: {
&#34;c1&#34;: 0.00,
&#34;c2&#34;: 0.05,
&#34;c3&#34;: 0.00,
&#34;c4&#34;: 30.0,
}
}
]
instances[0].get_constraint_category = Mock(
side_effect=lambda cid: {
&#34;c1&#34;: None,
&#34;c2&#34;: &#34;type-a&#34;,
&#34;c3&#34;: &#34;type-a&#34;,
&#34;c4&#34;: &#34;type-b&#34;,
}[cid]
)
instances[0].get_constraint_features = Mock(
side_effect=lambda cid: {
&#34;c2&#34;: np.array([1.0, 0.0]),
&#34;c3&#34;: np.array([0.5, 0.5]),
&#34;c4&#34;: np.array([1.0]),
}[cid]
)
# Second mock instance
instances[1].training_data = [
{
&#34;slacks&#34;: {
&#34;c1&#34;: 0.00,
&#34;c3&#34;: 0.30,
&#34;c4&#34;: 0.00,
&#34;c5&#34;: 0.00,
}
}
]
instances[1].get_constraint_category = Mock(
side_effect=lambda cid: {
&#34;c1&#34;: None,
&#34;c3&#34;: &#34;type-a&#34;,
&#34;c4&#34;: &#34;type-b&#34;,
&#34;c5&#34;: &#34;type-b&#34;,
}[cid]
)
instances[1].get_constraint_features = Mock(
side_effect=lambda cid: {
&#34;c3&#34;: np.array([0.3, 0.4]),
&#34;c4&#34;: np.array([0.7]),
&#34;c5&#34;: np.array([0.8]),
}[cid]
)
expected_x = {
&#34;type-a&#34;: np.array(
[
[1.0, 0.0],
[0.5, 0.5],
[0.3, 0.4],
]
),
&#34;type-b&#34;: np.array(
[
[1.0],
[0.7],
[0.8],
]
),
}
expected_y = {
&#34;type-a&#34;: np.array([[0], [0], [1]]),
&#34;type-b&#34;: np.array([[1], [0], [0]]),
}
# Should build X and Y matrices correctly
actual_x = component.x(instances)
actual_y = component.y(instances)
for category in [&#34;type-a&#34;, &#34;type-b&#34;]:
np.testing.assert_array_equal(actual_x[category], expected_x[category])
np.testing.assert_array_equal(actual_y[category], expected_y[category])
# Should pass along X and Y matrices to classifiers
component.fit(instances)
for category in [&#34;type-a&#34;, &#34;type-b&#34;]:
actual_x = component.classifiers[category].fit.call_args[0][0]
actual_y = component.classifiers[category].fit.call_args[0][1]
np.testing.assert_array_equal(actual_x, expected_x[category])
np.testing.assert_array_equal(actual_y, expected_y[category])
assert component.predict(expected_x) == {&#34;type-a&#34;: [[1]], &#34;type-b&#34;: [[0], [1]]}
ev = component.evaluate(instances[1])
assert ev[&#34;True positive&#34;] == 1
assert ev[&#34;True negative&#34;] == 1
assert ev[&#34;False positive&#34;] == 1
assert ev[&#34;False negative&#34;] == 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.components.steps.tests" href="index.html">miplearn.components.steps.tests</a></code></li>
</ul>
</li>
<li><h3><a href="#header-functions">Functions</a></h3>
<ul class="">
<li><code><a title="miplearn.components.steps.tests.test_drop_redundant.test_drop_redundant" href="#miplearn.components.steps.tests.test_drop_redundant.test_drop_redundant">test_drop_redundant</a></code></li>
<li><code><a title="miplearn.components.steps.tests.test_drop_redundant.test_drop_redundant_with_check_feasibility" href="#miplearn.components.steps.tests.test_drop_redundant.test_drop_redundant_with_check_feasibility">test_drop_redundant_with_check_feasibility</a></code></li>
<li><code><a title="miplearn.components.steps.tests.test_drop_redundant.test_x_multiple_solves" href="#miplearn.components.steps.tests.test_drop_redundant.test_x_multiple_solves">test_x_multiple_solves</a></code></li>
<li><code><a title="miplearn.components.steps.tests.test_drop_redundant.test_x_y_fit_predict_evaluate" href="#miplearn.components.steps.tests.test_drop_redundant.test_x_y_fit_predict_evaluate">test_x_y_fit_predict_evaluate</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>