parent
144523a5c0
commit
92c5116964
@ -1,88 +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.classifiers.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.classifiers.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.</code></pre>
|
|
||||||
</details>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
<h2 class="section-title" id="header-submodules">Sub-modules</h2>
|
|
||||||
<dl>
|
|
||||||
<dt><code class="name"><a title="miplearn.classifiers.tests.test_counting" href="test_counting.html">miplearn.classifiers.tests.test_counting</a></code></dt>
|
|
||||||
<dd>
|
|
||||||
<section class="desc"></section>
|
|
||||||
</dd>
|
|
||||||
<dt><code class="name"><a title="miplearn.classifiers.tests.test_cv" href="test_cv.html">miplearn.classifiers.tests.test_cv</a></code></dt>
|
|
||||||
<dd>
|
|
||||||
<section class="desc"></section>
|
|
||||||
</dd>
|
|
||||||
<dt><code class="name"><a title="miplearn.classifiers.tests.test_evaluator" href="test_evaluator.html">miplearn.classifiers.tests.test_evaluator</a></code></dt>
|
|
||||||
<dd>
|
|
||||||
<section class="desc"></section>
|
|
||||||
</dd>
|
|
||||||
<dt><code class="name"><a title="miplearn.classifiers.tests.test_threshold" href="test_threshold.html">miplearn.classifiers.tests.test_threshold</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.classifiers" href="../index.html">miplearn.classifiers</a></code></li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
<li><h3><a href="#header-submodules">Sub-modules</a></h3>
|
|
||||||
<ul>
|
|
||||||
<li><code><a title="miplearn.classifiers.tests.test_counting" href="test_counting.html">miplearn.classifiers.tests.test_counting</a></code></li>
|
|
||||||
<li><code><a title="miplearn.classifiers.tests.test_cv" href="test_cv.html">miplearn.classifiers.tests.test_cv</a></code></li>
|
|
||||||
<li><code><a title="miplearn.classifiers.tests.test_evaluator" href="test_evaluator.html">miplearn.classifiers.tests.test_evaluator</a></code></li>
|
|
||||||
<li><code><a title="miplearn.classifiers.tests.test_threshold" href="test_threshold.html">miplearn.classifiers.tests.test_threshold</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>
|
|
@ -1,101 +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.classifiers.tests.test_counting 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.classifiers.tests.test_counting</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 numpy as np
|
|
||||||
from numpy.linalg import norm
|
|
||||||
|
|
||||||
from miplearn.classifiers.counting import CountingClassifier
|
|
||||||
|
|
||||||
E = 0.1
|
|
||||||
|
|
||||||
|
|
||||||
def test_counting():
|
|
||||||
clf = CountingClassifier()
|
|
||||||
clf.fit(np.zeros((8, 25)), [0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0])
|
|
||||||
expected_proba = np.array([[0.375, 0.625], [0.375, 0.625]])
|
|
||||||
actual_proba = clf.predict_proba(np.zeros((2, 25)))
|
|
||||||
assert norm(actual_proba - expected_proba) < E</code></pre>
|
|
||||||
</details>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
<h2 class="section-title" id="header-functions">Functions</h2>
|
|
||||||
<dl>
|
|
||||||
<dt id="miplearn.classifiers.tests.test_counting.test_counting"><code class="name flex">
|
|
||||||
<span>def <span class="ident">test_counting</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_counting():
|
|
||||||
clf = CountingClassifier()
|
|
||||||
clf.fit(np.zeros((8, 25)), [0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0])
|
|
||||||
expected_proba = np.array([[0.375, 0.625], [0.375, 0.625]])
|
|
||||||
actual_proba = clf.predict_proba(np.zeros((2, 25)))
|
|
||||||
assert norm(actual_proba - expected_proba) < E</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.classifiers.tests" href="index.html">miplearn.classifiers.tests</a></code></li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
<li><h3><a href="#header-functions">Functions</a></h3>
|
|
||||||
<ul class="">
|
|
||||||
<li><code><a title="miplearn.classifiers.tests.test_counting.test_counting" href="#miplearn.classifiers.tests.test_counting.test_counting">test_counting</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>
|
|
@ -1,161 +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.classifiers.tests.test_cv 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.classifiers.tests.test_cv</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 numpy as np
|
|
||||||
from numpy.linalg import norm
|
|
||||||
from sklearn.preprocessing import StandardScaler
|
|
||||||
from sklearn.svm import SVC
|
|
||||||
|
|
||||||
from miplearn.classifiers.cv import CrossValidatedClassifier
|
|
||||||
|
|
||||||
E = 0.1
|
|
||||||
|
|
||||||
|
|
||||||
def test_cv():
|
|
||||||
# Training set: label is true if point is inside a 2D circle
|
|
||||||
x_train = np.array([[x1, x2] for x1 in range(-10, 11) for x2 in range(-10, 11)])
|
|
||||||
x_train = StandardScaler().fit_transform(x_train)
|
|
||||||
n_samples = x_train.shape[0]
|
|
||||||
|
|
||||||
y_train = np.array(
|
|
||||||
[
|
|
||||||
1.0 if x1 * x1 + x2 * x2 <= 100 else 0.0
|
|
||||||
for x1 in range(-10, 11)
|
|
||||||
for x2 in range(-10, 11)
|
|
||||||
]
|
|
||||||
)
|
|
||||||
|
|
||||||
# Support vector machines with linear kernels do not perform well on this
|
|
||||||
# data set, so predictor should return the given constant.
|
|
||||||
clf = CrossValidatedClassifier(
|
|
||||||
classifier=SVC(probability=True, random_state=42),
|
|
||||||
threshold=0.90,
|
|
||||||
constant=0.0,
|
|
||||||
cv=30,
|
|
||||||
)
|
|
||||||
clf.fit(x_train, y_train)
|
|
||||||
assert norm(np.zeros(n_samples) - clf.predict(x_train)) < E
|
|
||||||
|
|
||||||
# Support vector machines with quadratic kernels perform almost perfectly
|
|
||||||
# on this data set, so predictor should return their prediction.
|
|
||||||
clf = CrossValidatedClassifier(
|
|
||||||
classifier=SVC(probability=True, kernel="poly", degree=2, random_state=42),
|
|
||||||
threshold=0.90,
|
|
||||||
cv=30,
|
|
||||||
)
|
|
||||||
clf.fit(x_train, y_train)
|
|
||||||
print(y_train - clf.predict(x_train))
|
|
||||||
assert norm(y_train - clf.predict(x_train)) < E</code></pre>
|
|
||||||
</details>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
<h2 class="section-title" id="header-functions">Functions</h2>
|
|
||||||
<dl>
|
|
||||||
<dt id="miplearn.classifiers.tests.test_cv.test_cv"><code class="name flex">
|
|
||||||
<span>def <span class="ident">test_cv</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_cv():
|
|
||||||
# Training set: label is true if point is inside a 2D circle
|
|
||||||
x_train = np.array([[x1, x2] for x1 in range(-10, 11) for x2 in range(-10, 11)])
|
|
||||||
x_train = StandardScaler().fit_transform(x_train)
|
|
||||||
n_samples = x_train.shape[0]
|
|
||||||
|
|
||||||
y_train = np.array(
|
|
||||||
[
|
|
||||||
1.0 if x1 * x1 + x2 * x2 <= 100 else 0.0
|
|
||||||
for x1 in range(-10, 11)
|
|
||||||
for x2 in range(-10, 11)
|
|
||||||
]
|
|
||||||
)
|
|
||||||
|
|
||||||
# Support vector machines with linear kernels do not perform well on this
|
|
||||||
# data set, so predictor should return the given constant.
|
|
||||||
clf = CrossValidatedClassifier(
|
|
||||||
classifier=SVC(probability=True, random_state=42),
|
|
||||||
threshold=0.90,
|
|
||||||
constant=0.0,
|
|
||||||
cv=30,
|
|
||||||
)
|
|
||||||
clf.fit(x_train, y_train)
|
|
||||||
assert norm(np.zeros(n_samples) - clf.predict(x_train)) < E
|
|
||||||
|
|
||||||
# Support vector machines with quadratic kernels perform almost perfectly
|
|
||||||
# on this data set, so predictor should return their prediction.
|
|
||||||
clf = CrossValidatedClassifier(
|
|
||||||
classifier=SVC(probability=True, kernel="poly", degree=2, random_state=42),
|
|
||||||
threshold=0.90,
|
|
||||||
cv=30,
|
|
||||||
)
|
|
||||||
clf.fit(x_train, y_train)
|
|
||||||
print(y_train - clf.predict(x_train))
|
|
||||||
assert norm(y_train - clf.predict(x_train)) < E</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.classifiers.tests" href="index.html">miplearn.classifiers.tests</a></code></li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
<li><h3><a href="#header-functions">Functions</a></h3>
|
|
||||||
<ul class="">
|
|
||||||
<li><code><a title="miplearn.classifiers.tests.test_cv.test_cv" href="#miplearn.classifiers.tests.test_cv.test_cv">test_cv</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>
|
|
@ -1,107 +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.classifiers.tests.test_evaluator 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.classifiers.tests.test_evaluator</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 numpy as np
|
|
||||||
from sklearn.neighbors import KNeighborsClassifier
|
|
||||||
|
|
||||||
from miplearn.classifiers.evaluator import ClassifierEvaluator
|
|
||||||
|
|
||||||
|
|
||||||
def test_evaluator():
|
|
||||||
clf_a = KNeighborsClassifier(n_neighbors=1)
|
|
||||||
clf_b = KNeighborsClassifier(n_neighbors=2)
|
|
||||||
x_train = np.array([[0, 0], [1, 0]])
|
|
||||||
y_train = np.array([0, 1])
|
|
||||||
clf_a.fit(x_train, y_train)
|
|
||||||
clf_b.fit(x_train, y_train)
|
|
||||||
ev = ClassifierEvaluator()
|
|
||||||
assert ev.evaluate(clf_a, x_train, y_train) == 1.0
|
|
||||||
assert ev.evaluate(clf_b, x_train, y_train) == 0.5</code></pre>
|
|
||||||
</details>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
<h2 class="section-title" id="header-functions">Functions</h2>
|
|
||||||
<dl>
|
|
||||||
<dt id="miplearn.classifiers.tests.test_evaluator.test_evaluator"><code class="name flex">
|
|
||||||
<span>def <span class="ident">test_evaluator</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_evaluator():
|
|
||||||
clf_a = KNeighborsClassifier(n_neighbors=1)
|
|
||||||
clf_b = KNeighborsClassifier(n_neighbors=2)
|
|
||||||
x_train = np.array([[0, 0], [1, 0]])
|
|
||||||
y_train = np.array([0, 1])
|
|
||||||
clf_a.fit(x_train, y_train)
|
|
||||||
clf_b.fit(x_train, y_train)
|
|
||||||
ev = ClassifierEvaluator()
|
|
||||||
assert ev.evaluate(clf_a, x_train, y_train) == 1.0
|
|
||||||
assert ev.evaluate(clf_b, x_train, y_train) == 0.5</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.classifiers.tests" href="index.html">miplearn.classifiers.tests</a></code></li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
<li><h3><a href="#header-functions">Functions</a></h3>
|
|
||||||
<ul class="">
|
|
||||||
<li><code><a title="miplearn.classifiers.tests.test_evaluator.test_evaluator" href="#miplearn.classifiers.tests.test_evaluator.test_evaluator">test_evaluator</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>
|
|
@ -1,141 +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.classifiers.tests.test_threshold 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.classifiers.tests.test_threshold</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
|
|
||||||
|
|
||||||
import numpy as np
|
|
||||||
|
|
||||||
from miplearn.classifiers import Classifier
|
|
||||||
from miplearn.classifiers.threshold import MinPrecisionThreshold
|
|
||||||
|
|
||||||
|
|
||||||
def test_threshold_dynamic():
|
|
||||||
clf = Mock(spec=Classifier)
|
|
||||||
clf.predict_proba = Mock(
|
|
||||||
return_value=np.array(
|
|
||||||
[
|
|
||||||
[0.10, 0.90],
|
|
||||||
[0.10, 0.90],
|
|
||||||
[0.20, 0.80],
|
|
||||||
[0.30, 0.70],
|
|
||||||
]
|
|
||||||
)
|
|
||||||
)
|
|
||||||
x_train = np.array([0, 1, 2, 3])
|
|
||||||
y_train = np.array([1, 1, 0, 0])
|
|
||||||
|
|
||||||
threshold = MinPrecisionThreshold(min_precision=1.0)
|
|
||||||
assert threshold.find(clf, x_train, y_train) == 0.90
|
|
||||||
|
|
||||||
threshold = MinPrecisionThreshold(min_precision=0.65)
|
|
||||||
assert threshold.find(clf, x_train, y_train) == 0.80
|
|
||||||
|
|
||||||
threshold = MinPrecisionThreshold(min_precision=0.50)
|
|
||||||
assert threshold.find(clf, x_train, y_train) == 0.70
|
|
||||||
|
|
||||||
threshold = MinPrecisionThreshold(min_precision=0.00)
|
|
||||||
assert threshold.find(clf, x_train, y_train) == 0.70</code></pre>
|
|
||||||
</details>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
<h2 class="section-title" id="header-functions">Functions</h2>
|
|
||||||
<dl>
|
|
||||||
<dt id="miplearn.classifiers.tests.test_threshold.test_threshold_dynamic"><code class="name flex">
|
|
||||||
<span>def <span class="ident">test_threshold_dynamic</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_threshold_dynamic():
|
|
||||||
clf = Mock(spec=Classifier)
|
|
||||||
clf.predict_proba = Mock(
|
|
||||||
return_value=np.array(
|
|
||||||
[
|
|
||||||
[0.10, 0.90],
|
|
||||||
[0.10, 0.90],
|
|
||||||
[0.20, 0.80],
|
|
||||||
[0.30, 0.70],
|
|
||||||
]
|
|
||||||
)
|
|
||||||
)
|
|
||||||
x_train = np.array([0, 1, 2, 3])
|
|
||||||
y_train = np.array([1, 1, 0, 0])
|
|
||||||
|
|
||||||
threshold = MinPrecisionThreshold(min_precision=1.0)
|
|
||||||
assert threshold.find(clf, x_train, y_train) == 0.90
|
|
||||||
|
|
||||||
threshold = MinPrecisionThreshold(min_precision=0.65)
|
|
||||||
assert threshold.find(clf, x_train, y_train) == 0.80
|
|
||||||
|
|
||||||
threshold = MinPrecisionThreshold(min_precision=0.50)
|
|
||||||
assert threshold.find(clf, x_train, y_train) == 0.70
|
|
||||||
|
|
||||||
threshold = MinPrecisionThreshold(min_precision=0.00)
|
|
||||||
assert threshold.find(clf, x_train, y_train) == 0.70</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.classifiers.tests" href="index.html">miplearn.classifiers.tests</a></code></li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
<li><h3><a href="#header-functions">Functions</a></h3>
|
|
||||||
<ul class="">
|
|
||||||
<li><code><a title="miplearn.classifiers.tests.test_threshold.test_threshold_dynamic" href="#miplearn.classifiers.tests.test_threshold.test_threshold_dynamic">test_threshold_dynamic</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>
|
|
@ -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>
|
|
@ -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["Upper bound"]
|
|
||||||
|
|
||||||
# Should collect training data
|
|
||||||
assert instance.training_data[0]["slacks"]["eq_capacity"] == 0.0
|
|
||||||
|
|
||||||
# Fit and resolve
|
|
||||||
solver.fit([instance])
|
|
||||||
stats = solver.solve(instance)
|
|
||||||
|
|
||||||
# Objective value should be the same
|
|
||||||
assert stats["Upper bound"] == original_upper_bound
|
|
||||||
assert stats["ConvertTight: Inf iterations"] == 0
|
|
||||||
assert stats["ConvertTight: Subopt iterations"] == 0
|
|
||||||
|
|
||||||
|
|
||||||
class SampleInstance(Instance):
|
|
||||||
def to_model(self):
|
|
||||||
import gurobipy as grb
|
|
||||||
|
|
||||||
m = grb.Model("model")
|
|
||||||
x1 = m.addVar(name="x1")
|
|
||||||
x2 = m.addVar(name="x2")
|
|
||||||
m.setObjective(x1 + 2 * x2, grb.GRB.MAXIMIZE)
|
|
||||||
m.addConstr(x1 <= 2, name="c1")
|
|
||||||
m.addConstr(x2 <= 2, name="c2")
|
|
||||||
m.addConstr(x1 + x2 <= 3, name="c2")
|
|
||||||
return m
|
|
||||||
|
|
||||||
|
|
||||||
def test_convert_tight_infeasibility():
|
|
||||||
comp = ConvertTightIneqsIntoEqsStep()
|
|
||||||
comp.classifiers = {
|
|
||||||
"c1": Mock(spec=Classifier),
|
|
||||||
"c2": Mock(spec=Classifier),
|
|
||||||
"c3": Mock(spec=Classifier),
|
|
||||||
}
|
|
||||||
comp.classifiers["c1"].predict_proba = Mock(return_value=[[0, 1]])
|
|
||||||
comp.classifiers["c2"].predict_proba = Mock(return_value=[[0, 1]])
|
|
||||||
comp.classifiers["c3"].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["Upper bound"] == 5.0
|
|
||||||
assert stats["ConvertTight: Inf iterations"] == 1
|
|
||||||
assert stats["ConvertTight: Subopt iterations"] == 0
|
|
||||||
|
|
||||||
|
|
||||||
def test_convert_tight_suboptimality():
|
|
||||||
comp = ConvertTightIneqsIntoEqsStep(check_optimality=True)
|
|
||||||
comp.classifiers = {
|
|
||||||
"c1": Mock(spec=Classifier),
|
|
||||||
"c2": Mock(spec=Classifier),
|
|
||||||
"c3": Mock(spec=Classifier),
|
|
||||||
}
|
|
||||||
comp.classifiers["c1"].predict_proba = Mock(return_value=[[0, 1]])
|
|
||||||
comp.classifiers["c2"].predict_proba = Mock(return_value=[[1, 0]])
|
|
||||||
comp.classifiers["c3"].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["Upper bound"] == 5.0
|
|
||||||
assert stats["ConvertTight: Inf iterations"] == 0
|
|
||||||
assert stats["ConvertTight: Subopt iterations"] == 1
|
|
||||||
|
|
||||||
|
|
||||||
def test_convert_tight_optimal():
|
|
||||||
comp = ConvertTightIneqsIntoEqsStep()
|
|
||||||
comp.classifiers = {
|
|
||||||
"c1": Mock(spec=Classifier),
|
|
||||||
"c2": Mock(spec=Classifier),
|
|
||||||
"c3": Mock(spec=Classifier),
|
|
||||||
}
|
|
||||||
comp.classifiers["c1"].predict_proba = Mock(return_value=[[1, 0]])
|
|
||||||
comp.classifiers["c2"].predict_proba = Mock(return_value=[[0, 1]])
|
|
||||||
comp.classifiers["c3"].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["Upper bound"] == 5.0
|
|
||||||
assert stats["ConvertTight: Inf iterations"] == 0
|
|
||||||
assert stats["ConvertTight: Subopt iterations"] == 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 = {
|
|
||||||
"c1": Mock(spec=Classifier),
|
|
||||||
"c2": Mock(spec=Classifier),
|
|
||||||
"c3": Mock(spec=Classifier),
|
|
||||||
}
|
|
||||||
comp.classifiers["c1"].predict_proba = Mock(return_value=[[0, 1]])
|
|
||||||
comp.classifiers["c2"].predict_proba = Mock(return_value=[[0, 1]])
|
|
||||||
comp.classifiers["c3"].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["Upper bound"] == 5.0
|
|
||||||
assert stats["ConvertTight: Inf iterations"] == 1
|
|
||||||
assert stats["ConvertTight: Subopt iterations"] == 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 = {
|
|
||||||
"c1": Mock(spec=Classifier),
|
|
||||||
"c2": Mock(spec=Classifier),
|
|
||||||
"c3": Mock(spec=Classifier),
|
|
||||||
}
|
|
||||||
comp.classifiers["c1"].predict_proba = Mock(return_value=[[1, 0]])
|
|
||||||
comp.classifiers["c2"].predict_proba = Mock(return_value=[[0, 1]])
|
|
||||||
comp.classifiers["c3"].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["Upper bound"] == 5.0
|
|
||||||
assert stats["ConvertTight: Inf iterations"] == 0
|
|
||||||
assert stats["ConvertTight: Subopt iterations"] == 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 = {
|
|
||||||
"c1": Mock(spec=Classifier),
|
|
||||||
"c2": Mock(spec=Classifier),
|
|
||||||
"c3": Mock(spec=Classifier),
|
|
||||||
}
|
|
||||||
comp.classifiers["c1"].predict_proba = Mock(return_value=[[0, 1]])
|
|
||||||
comp.classifiers["c2"].predict_proba = Mock(return_value=[[1, 0]])
|
|
||||||
comp.classifiers["c3"].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["Upper bound"] == 5.0
|
|
||||||
assert stats["ConvertTight: Inf iterations"] == 0
|
|
||||||
assert stats["ConvertTight: Subopt iterations"] == 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["Upper bound"]
|
|
||||||
|
|
||||||
# Should collect training data
|
|
||||||
assert instance.training_data[0]["slacks"]["eq_capacity"] == 0.0
|
|
||||||
|
|
||||||
# Fit and resolve
|
|
||||||
solver.fit([instance])
|
|
||||||
stats = solver.solve(instance)
|
|
||||||
|
|
||||||
# Objective value should be the same
|
|
||||||
assert stats["Upper bound"] == original_upper_bound
|
|
||||||
assert stats["ConvertTight: Inf iterations"] == 0
|
|
||||||
assert stats["ConvertTight: Subopt iterations"] == 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("model")
|
|
||||||
x1 = m.addVar(name="x1")
|
|
||||||
x2 = m.addVar(name="x2")
|
|
||||||
m.setObjective(x1 + 2 * x2, grb.GRB.MAXIMIZE)
|
|
||||||
m.addConstr(x1 <= 2, name="c1")
|
|
||||||
m.addConstr(x2 <= 2, name="c2")
|
|
||||||
m.addConstr(x1 + x2 <= 3, name="c2")
|
|
||||||
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>
|
|
@ -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=["c1", "c2", "c3", "c4"])
|
|
||||||
internal.get_inequality_slacks = Mock(
|
|
||||||
side_effect=lambda: {
|
|
||||||
"c1": 0.5,
|
|
||||||
"c2": 0.0,
|
|
||||||
"c3": 0.0,
|
|
||||||
"c4": 1.4,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
internal.extract_constraint = Mock(side_effect=lambda cid: "<%s>" % cid)
|
|
||||||
internal.is_constraint_satisfied = Mock(return_value=False)
|
|
||||||
|
|
||||||
instance = Mock(spec=Instance)
|
|
||||||
instance.get_constraint_features = Mock(
|
|
||||||
side_effect=lambda cid: {
|
|
||||||
"c2": np.array([1.0, 0.0]),
|
|
||||||
"c3": np.array([0.5, 0.5]),
|
|
||||||
"c4": np.array([1.0]),
|
|
||||||
}[cid]
|
|
||||||
)
|
|
||||||
instance.get_constraint_category = Mock(
|
|
||||||
side_effect=lambda cid: {
|
|
||||||
"c1": None,
|
|
||||||
"c2": "type-a",
|
|
||||||
"c3": "type-a",
|
|
||||||
"c4": "type-b",
|
|
||||||
}[cid]
|
|
||||||
)
|
|
||||||
|
|
||||||
classifiers = {
|
|
||||||
"type-a": Mock(spec=Classifier),
|
|
||||||
"type-b": Mock(spec=Classifier),
|
|
||||||
}
|
|
||||||
classifiers["type-a"].predict_proba = Mock(
|
|
||||||
return_value=np.array(
|
|
||||||
[
|
|
||||||
[0.20, 0.80],
|
|
||||||
[0.05, 0.95],
|
|
||||||
]
|
|
||||||
)
|
|
||||||
)
|
|
||||||
classifiers["type-b"].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("c1"),
|
|
||||||
call("c2"),
|
|
||||||
call("c3"),
|
|
||||||
call("c4"),
|
|
||||||
]
|
|
||||||
)
|
|
||||||
|
|
||||||
# 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("c2"),
|
|
||||||
call("c3"),
|
|
||||||
call("c4"),
|
|
||||||
]
|
|
||||||
)
|
|
||||||
|
|
||||||
# Should ask ML to predict whether constraint should be removed
|
|
||||||
type_a_actual = component.classifiers["type-a"].predict_proba.call_args[0][0]
|
|
||||||
type_b_actual = component.classifiers["type-b"].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("c3"),
|
|
||||||
call("c4"),
|
|
||||||
]
|
|
||||||
)
|
|
||||||
|
|
||||||
# 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["slacks"] == {
|
|
||||||
"c1": 0.5,
|
|
||||||
"c2": 0.0,
|
|
||||||
"c3": 0.0,
|
|
||||||
"c4": 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("c3"),
|
|
||||||
call("c4"),
|
|
||||||
]
|
|
||||||
)
|
|
||||||
|
|
||||||
# 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("<c3>", 1e-3),
|
|
||||||
call("<c4>", 1e-3),
|
|
||||||
]
|
|
||||||
)
|
|
||||||
|
|
||||||
# Should add constraints back to LP relaxation
|
|
||||||
internal.add_constraint.assert_has_calls([call("<c3>"), call("<c4>")])
|
|
||||||
|
|
||||||
# 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 = {
|
|
||||||
"type-a": Mock(spec=Classifier),
|
|
||||||
"type-b": Mock(spec=Classifier),
|
|
||||||
}
|
|
||||||
component.classifiers["type-a"].predict_proba = Mock(
|
|
||||||
return_value=[
|
|
||||||
np.array([0.20, 0.80]),
|
|
||||||
]
|
|
||||||
)
|
|
||||||
component.classifiers["type-b"].predict_proba = Mock(
|
|
||||||
return_value=np.array(
|
|
||||||
[
|
|
||||||
[0.50, 0.50],
|
|
||||||
[0.05, 0.95],
|
|
||||||
]
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
# First mock instance
|
|
||||||
instances[0].training_data = [
|
|
||||||
{
|
|
||||||
"slacks": {
|
|
||||||
"c1": 0.00,
|
|
||||||
"c2": 0.05,
|
|
||||||
"c3": 0.00,
|
|
||||||
"c4": 30.0,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
instances[0].get_constraint_category = Mock(
|
|
||||||
side_effect=lambda cid: {
|
|
||||||
"c1": None,
|
|
||||||
"c2": "type-a",
|
|
||||||
"c3": "type-a",
|
|
||||||
"c4": "type-b",
|
|
||||||
}[cid]
|
|
||||||
)
|
|
||||||
instances[0].get_constraint_features = Mock(
|
|
||||||
side_effect=lambda cid: {
|
|
||||||
"c2": np.array([1.0, 0.0]),
|
|
||||||
"c3": np.array([0.5, 0.5]),
|
|
||||||
"c4": np.array([1.0]),
|
|
||||||
}[cid]
|
|
||||||
)
|
|
||||||
|
|
||||||
# Second mock instance
|
|
||||||
instances[1].training_data = [
|
|
||||||
{
|
|
||||||
"slacks": {
|
|
||||||
"c1": 0.00,
|
|
||||||
"c3": 0.30,
|
|
||||||
"c4": 0.00,
|
|
||||||
"c5": 0.00,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
instances[1].get_constraint_category = Mock(
|
|
||||||
side_effect=lambda cid: {
|
|
||||||
"c1": None,
|
|
||||||
"c3": "type-a",
|
|
||||||
"c4": "type-b",
|
|
||||||
"c5": "type-b",
|
|
||||||
}[cid]
|
|
||||||
)
|
|
||||||
instances[1].get_constraint_features = Mock(
|
|
||||||
side_effect=lambda cid: {
|
|
||||||
"c3": np.array([0.3, 0.4]),
|
|
||||||
"c4": np.array([0.7]),
|
|
||||||
"c5": np.array([0.8]),
|
|
||||||
}[cid]
|
|
||||||
)
|
|
||||||
|
|
||||||
expected_x = {
|
|
||||||
"type-a": np.array(
|
|
||||||
[
|
|
||||||
[1.0, 0.0],
|
|
||||||
[0.5, 0.5],
|
|
||||||
[0.3, 0.4],
|
|
||||||
]
|
|
||||||
),
|
|
||||||
"type-b": np.array(
|
|
||||||
[
|
|
||||||
[1.0],
|
|
||||||
[0.7],
|
|
||||||
[0.8],
|
|
||||||
]
|
|
||||||
),
|
|
||||||
}
|
|
||||||
expected_y = {
|
|
||||||
"type-a": np.array([[0], [0], [1]]),
|
|
||||||
"type-b": 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 ["type-a", "type-b"]:
|
|
||||||
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 ["type-a", "type-b"]:
|
|
||||||
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) == {"type-a": [[1]], "type-b": [[0], [1]]}
|
|
||||||
|
|
||||||
ev = component.evaluate(instances[1])
|
|
||||||
assert ev["True positive"] == 1
|
|
||||||
assert ev["True negative"] == 1
|
|
||||||
assert ev["False positive"] == 1
|
|
||||||
assert ev["False negative"] == 0
|
|
||||||
|
|
||||||
|
|
||||||
def test_x_multiple_solves():
|
|
||||||
instance = Mock(spec=Instance)
|
|
||||||
instance.training_data = [
|
|
||||||
{
|
|
||||||
"slacks": {
|
|
||||||
"c1": 0.00,
|
|
||||||
"c2": 0.05,
|
|
||||||
"c3": 0.00,
|
|
||||||
"c4": 30.0,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"slacks": {
|
|
||||||
"c1": 0.00,
|
|
||||||
"c2": 0.00,
|
|
||||||
"c3": 1.00,
|
|
||||||
"c4": 0.0,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
]
|
|
||||||
instance.get_constraint_category = Mock(
|
|
||||||
side_effect=lambda cid: {
|
|
||||||
"c1": None,
|
|
||||||
"c2": "type-a",
|
|
||||||
"c3": "type-a",
|
|
||||||
"c4": "type-b",
|
|
||||||
}[cid]
|
|
||||||
)
|
|
||||||
instance.get_constraint_features = Mock(
|
|
||||||
side_effect=lambda cid: {
|
|
||||||
"c2": np.array([1.0, 0.0]),
|
|
||||||
"c3": np.array([0.5, 0.5]),
|
|
||||||
"c4": np.array([1.0]),
|
|
||||||
}[cid]
|
|
||||||
)
|
|
||||||
|
|
||||||
expected_x = {
|
|
||||||
"type-a": np.array(
|
|
||||||
[
|
|
||||||
[1.0, 0.0],
|
|
||||||
[0.5, 0.5],
|
|
||||||
[1.0, 0.0],
|
|
||||||
[0.5, 0.5],
|
|
||||||
]
|
|
||||||
),
|
|
||||||
"type-b": np.array(
|
|
||||||
[
|
|
||||||
[1.0],
|
|
||||||
[1.0],
|
|
||||||
]
|
|
||||||
),
|
|
||||||
}
|
|
||||||
|
|
||||||
expected_y = {
|
|
||||||
"type-a": np.array([[1], [0], [0], [1]]),
|
|
||||||
"type-b": 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 ["type-a", "type-b"]:
|
|
||||||
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("c1"),
|
|
||||||
call("c2"),
|
|
||||||
call("c3"),
|
|
||||||
call("c4"),
|
|
||||||
]
|
|
||||||
)
|
|
||||||
|
|
||||||
# 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("c2"),
|
|
||||||
call("c3"),
|
|
||||||
call("c4"),
|
|
||||||
]
|
|
||||||
)
|
|
||||||
|
|
||||||
# Should ask ML to predict whether constraint should be removed
|
|
||||||
type_a_actual = component.classifiers["type-a"].predict_proba.call_args[0][0]
|
|
||||||
type_b_actual = component.classifiers["type-b"].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("c3"),
|
|
||||||
call("c4"),
|
|
||||||
]
|
|
||||||
)
|
|
||||||
|
|
||||||
# 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["slacks"] == {
|
|
||||||
"c1": 0.5,
|
|
||||||
"c2": 0.0,
|
|
||||||
"c3": 0.0,
|
|
||||||
"c4": 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("c3"),
|
|
||||||
call("c4"),
|
|
||||||
]
|
|
||||||
)
|
|
||||||
|
|
||||||
# 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("<c3>", 1e-3),
|
|
||||||
call("<c4>", 1e-3),
|
|
||||||
]
|
|
||||||
)
|
|
||||||
|
|
||||||
# Should add constraints back to LP relaxation
|
|
||||||
internal.add_constraint.assert_has_calls([call("<c3>"), call("<c4>")])
|
|
||||||
|
|
||||||
# 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 = [
|
|
||||||
{
|
|
||||||
"slacks": {
|
|
||||||
"c1": 0.00,
|
|
||||||
"c2": 0.05,
|
|
||||||
"c3": 0.00,
|
|
||||||
"c4": 30.0,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"slacks": {
|
|
||||||
"c1": 0.00,
|
|
||||||
"c2": 0.00,
|
|
||||||
"c3": 1.00,
|
|
||||||
"c4": 0.0,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
]
|
|
||||||
instance.get_constraint_category = Mock(
|
|
||||||
side_effect=lambda cid: {
|
|
||||||
"c1": None,
|
|
||||||
"c2": "type-a",
|
|
||||||
"c3": "type-a",
|
|
||||||
"c4": "type-b",
|
|
||||||
}[cid]
|
|
||||||
)
|
|
||||||
instance.get_constraint_features = Mock(
|
|
||||||
side_effect=lambda cid: {
|
|
||||||
"c2": np.array([1.0, 0.0]),
|
|
||||||
"c3": np.array([0.5, 0.5]),
|
|
||||||
"c4": np.array([1.0]),
|
|
||||||
}[cid]
|
|
||||||
)
|
|
||||||
|
|
||||||
expected_x = {
|
|
||||||
"type-a": np.array(
|
|
||||||
[
|
|
||||||
[1.0, 0.0],
|
|
||||||
[0.5, 0.5],
|
|
||||||
[1.0, 0.0],
|
|
||||||
[0.5, 0.5],
|
|
||||||
]
|
|
||||||
),
|
|
||||||
"type-b": np.array(
|
|
||||||
[
|
|
||||||
[1.0],
|
|
||||||
[1.0],
|
|
||||||
]
|
|
||||||
),
|
|
||||||
}
|
|
||||||
|
|
||||||
expected_y = {
|
|
||||||
"type-a": np.array([[1], [0], [0], [1]]),
|
|
||||||
"type-b": 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 ["type-a", "type-b"]:
|
|
||||||
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 = {
|
|
||||||
"type-a": Mock(spec=Classifier),
|
|
||||||
"type-b": Mock(spec=Classifier),
|
|
||||||
}
|
|
||||||
component.classifiers["type-a"].predict_proba = Mock(
|
|
||||||
return_value=[
|
|
||||||
np.array([0.20, 0.80]),
|
|
||||||
]
|
|
||||||
)
|
|
||||||
component.classifiers["type-b"].predict_proba = Mock(
|
|
||||||
return_value=np.array(
|
|
||||||
[
|
|
||||||
[0.50, 0.50],
|
|
||||||
[0.05, 0.95],
|
|
||||||
]
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
# First mock instance
|
|
||||||
instances[0].training_data = [
|
|
||||||
{
|
|
||||||
"slacks": {
|
|
||||||
"c1": 0.00,
|
|
||||||
"c2": 0.05,
|
|
||||||
"c3": 0.00,
|
|
||||||
"c4": 30.0,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
instances[0].get_constraint_category = Mock(
|
|
||||||
side_effect=lambda cid: {
|
|
||||||
"c1": None,
|
|
||||||
"c2": "type-a",
|
|
||||||
"c3": "type-a",
|
|
||||||
"c4": "type-b",
|
|
||||||
}[cid]
|
|
||||||
)
|
|
||||||
instances[0].get_constraint_features = Mock(
|
|
||||||
side_effect=lambda cid: {
|
|
||||||
"c2": np.array([1.0, 0.0]),
|
|
||||||
"c3": np.array([0.5, 0.5]),
|
|
||||||
"c4": np.array([1.0]),
|
|
||||||
}[cid]
|
|
||||||
)
|
|
||||||
|
|
||||||
# Second mock instance
|
|
||||||
instances[1].training_data = [
|
|
||||||
{
|
|
||||||
"slacks": {
|
|
||||||
"c1": 0.00,
|
|
||||||
"c3": 0.30,
|
|
||||||
"c4": 0.00,
|
|
||||||
"c5": 0.00,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
instances[1].get_constraint_category = Mock(
|
|
||||||
side_effect=lambda cid: {
|
|
||||||
"c1": None,
|
|
||||||
"c3": "type-a",
|
|
||||||
"c4": "type-b",
|
|
||||||
"c5": "type-b",
|
|
||||||
}[cid]
|
|
||||||
)
|
|
||||||
instances[1].get_constraint_features = Mock(
|
|
||||||
side_effect=lambda cid: {
|
|
||||||
"c3": np.array([0.3, 0.4]),
|
|
||||||
"c4": np.array([0.7]),
|
|
||||||
"c5": np.array([0.8]),
|
|
||||||
}[cid]
|
|
||||||
)
|
|
||||||
|
|
||||||
expected_x = {
|
|
||||||
"type-a": np.array(
|
|
||||||
[
|
|
||||||
[1.0, 0.0],
|
|
||||||
[0.5, 0.5],
|
|
||||||
[0.3, 0.4],
|
|
||||||
]
|
|
||||||
),
|
|
||||||
"type-b": np.array(
|
|
||||||
[
|
|
||||||
[1.0],
|
|
||||||
[0.7],
|
|
||||||
[0.8],
|
|
||||||
]
|
|
||||||
),
|
|
||||||
}
|
|
||||||
expected_y = {
|
|
||||||
"type-a": np.array([[0], [0], [1]]),
|
|
||||||
"type-b": 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 ["type-a", "type-b"]:
|
|
||||||
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 ["type-a", "type-b"]:
|
|
||||||
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) == {"type-a": [[1]], "type-b": [[0], [1]]}
|
|
||||||
|
|
||||||
ev = component.evaluate(instances[1])
|
|
||||||
assert ev["True positive"] == 1
|
|
||||||
assert ev["True negative"] == 1
|
|
||||||
assert ev["False positive"] == 1
|
|
||||||
assert ev["False negative"] == 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>
|
|
@ -1,93 +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.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.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.</code></pre>
|
|
||||||
</details>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
<h2 class="section-title" id="header-submodules">Sub-modules</h2>
|
|
||||||
<dl>
|
|
||||||
<dt><code class="name"><a title="miplearn.components.tests.test_composite" href="test_composite.html">miplearn.components.tests.test_composite</a></code></dt>
|
|
||||||
<dd>
|
|
||||||
<section class="desc"></section>
|
|
||||||
</dd>
|
|
||||||
<dt><code class="name"><a title="miplearn.components.tests.test_lazy_dynamic" href="test_lazy_dynamic.html">miplearn.components.tests.test_lazy_dynamic</a></code></dt>
|
|
||||||
<dd>
|
|
||||||
<section class="desc"></section>
|
|
||||||
</dd>
|
|
||||||
<dt><code class="name"><a title="miplearn.components.tests.test_lazy_static" href="test_lazy_static.html">miplearn.components.tests.test_lazy_static</a></code></dt>
|
|
||||||
<dd>
|
|
||||||
<section class="desc"></section>
|
|
||||||
</dd>
|
|
||||||
<dt><code class="name"><a title="miplearn.components.tests.test_objective" href="test_objective.html">miplearn.components.tests.test_objective</a></code></dt>
|
|
||||||
<dd>
|
|
||||||
<section class="desc"></section>
|
|
||||||
</dd>
|
|
||||||
<dt><code class="name"><a title="miplearn.components.tests.test_primal" href="test_primal.html">miplearn.components.tests.test_primal</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" href="../index.html">miplearn.components</a></code></li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
<li><h3><a href="#header-submodules">Sub-modules</a></h3>
|
|
||||||
<ul>
|
|
||||||
<li><code><a title="miplearn.components.tests.test_composite" href="test_composite.html">miplearn.components.tests.test_composite</a></code></li>
|
|
||||||
<li><code><a title="miplearn.components.tests.test_lazy_dynamic" href="test_lazy_dynamic.html">miplearn.components.tests.test_lazy_dynamic</a></code></li>
|
|
||||||
<li><code><a title="miplearn.components.tests.test_lazy_static" href="test_lazy_static.html">miplearn.components.tests.test_lazy_static</a></code></li>
|
|
||||||
<li><code><a title="miplearn.components.tests.test_objective" href="test_objective.html">miplearn.components.tests.test_objective</a></code></li>
|
|
||||||
<li><code><a title="miplearn.components.tests.test_primal" href="test_primal.html">miplearn.components.tests.test_primal</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>
|
|
@ -1,179 +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.tests.test_composite 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.tests.test_composite</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
|
|
||||||
|
|
||||||
from miplearn.components.component import Component
|
|
||||||
from miplearn.components.composite import CompositeComponent
|
|
||||||
from miplearn.instance import Instance
|
|
||||||
from miplearn.solvers.learning import LearningSolver
|
|
||||||
|
|
||||||
|
|
||||||
def test_composite():
|
|
||||||
solver, instance, model = (
|
|
||||||
Mock(spec=LearningSolver),
|
|
||||||
Mock(spec=Instance),
|
|
||||||
Mock(),
|
|
||||||
)
|
|
||||||
|
|
||||||
c1 = Mock(spec=Component)
|
|
||||||
c2 = Mock(spec=Component)
|
|
||||||
cc = CompositeComponent([c1, c2])
|
|
||||||
|
|
||||||
# Should broadcast before_solve
|
|
||||||
cc.before_solve(solver, instance, model)
|
|
||||||
c1.before_solve.assert_has_calls([call(solver, instance, model)])
|
|
||||||
c2.before_solve.assert_has_calls([call(solver, instance, model)])
|
|
||||||
|
|
||||||
# Should broadcast after_solve
|
|
||||||
cc.after_solve(solver, instance, model, {}, {})
|
|
||||||
c1.after_solve.assert_has_calls([call(solver, instance, model, {}, {})])
|
|
||||||
c2.after_solve.assert_has_calls([call(solver, instance, model, {}, {})])
|
|
||||||
|
|
||||||
# Should broadcast fit
|
|
||||||
cc.fit([1, 2, 3])
|
|
||||||
c1.fit.assert_has_calls([call([1, 2, 3])])
|
|
||||||
c2.fit.assert_has_calls([call([1, 2, 3])])
|
|
||||||
|
|
||||||
# Should broadcast lazy_cb
|
|
||||||
cc.lazy_cb(solver, instance, model)
|
|
||||||
c1.lazy_cb.assert_has_calls([call(solver, instance, model)])
|
|
||||||
c2.lazy_cb.assert_has_calls([call(solver, instance, model)])
|
|
||||||
|
|
||||||
# Should broadcast iteration_cb
|
|
||||||
cc.iteration_cb(solver, instance, model)
|
|
||||||
c1.iteration_cb.assert_has_calls([call(solver, instance, model)])
|
|
||||||
c2.iteration_cb.assert_has_calls([call(solver, instance, model)])
|
|
||||||
|
|
||||||
# If at least one child component returns true, iteration_cb should return True
|
|
||||||
c1.iteration_cb = Mock(return_value=True)
|
|
||||||
c2.iteration_cb = Mock(return_value=False)
|
|
||||||
assert cc.iteration_cb(solver, instance, model)
|
|
||||||
|
|
||||||
# If all children return False, iteration_cb should return False
|
|
||||||
c1.iteration_cb = Mock(return_value=False)
|
|
||||||
c2.iteration_cb = Mock(return_value=False)
|
|
||||||
assert not cc.iteration_cb(solver, instance, model)</code></pre>
|
|
||||||
</details>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
<h2 class="section-title" id="header-functions">Functions</h2>
|
|
||||||
<dl>
|
|
||||||
<dt id="miplearn.components.tests.test_composite.test_composite"><code class="name flex">
|
|
||||||
<span>def <span class="ident">test_composite</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_composite():
|
|
||||||
solver, instance, model = (
|
|
||||||
Mock(spec=LearningSolver),
|
|
||||||
Mock(spec=Instance),
|
|
||||||
Mock(),
|
|
||||||
)
|
|
||||||
|
|
||||||
c1 = Mock(spec=Component)
|
|
||||||
c2 = Mock(spec=Component)
|
|
||||||
cc = CompositeComponent([c1, c2])
|
|
||||||
|
|
||||||
# Should broadcast before_solve
|
|
||||||
cc.before_solve(solver, instance, model)
|
|
||||||
c1.before_solve.assert_has_calls([call(solver, instance, model)])
|
|
||||||
c2.before_solve.assert_has_calls([call(solver, instance, model)])
|
|
||||||
|
|
||||||
# Should broadcast after_solve
|
|
||||||
cc.after_solve(solver, instance, model, {}, {})
|
|
||||||
c1.after_solve.assert_has_calls([call(solver, instance, model, {}, {})])
|
|
||||||
c2.after_solve.assert_has_calls([call(solver, instance, model, {}, {})])
|
|
||||||
|
|
||||||
# Should broadcast fit
|
|
||||||
cc.fit([1, 2, 3])
|
|
||||||
c1.fit.assert_has_calls([call([1, 2, 3])])
|
|
||||||
c2.fit.assert_has_calls([call([1, 2, 3])])
|
|
||||||
|
|
||||||
# Should broadcast lazy_cb
|
|
||||||
cc.lazy_cb(solver, instance, model)
|
|
||||||
c1.lazy_cb.assert_has_calls([call(solver, instance, model)])
|
|
||||||
c2.lazy_cb.assert_has_calls([call(solver, instance, model)])
|
|
||||||
|
|
||||||
# Should broadcast iteration_cb
|
|
||||||
cc.iteration_cb(solver, instance, model)
|
|
||||||
c1.iteration_cb.assert_has_calls([call(solver, instance, model)])
|
|
||||||
c2.iteration_cb.assert_has_calls([call(solver, instance, model)])
|
|
||||||
|
|
||||||
# If at least one child component returns true, iteration_cb should return True
|
|
||||||
c1.iteration_cb = Mock(return_value=True)
|
|
||||||
c2.iteration_cb = Mock(return_value=False)
|
|
||||||
assert cc.iteration_cb(solver, instance, model)
|
|
||||||
|
|
||||||
# If all children return False, iteration_cb should return False
|
|
||||||
c1.iteration_cb = Mock(return_value=False)
|
|
||||||
c2.iteration_cb = Mock(return_value=False)
|
|
||||||
assert not cc.iteration_cb(solver, instance, model)</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.tests" href="index.html">miplearn.components.tests</a></code></li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
<li><h3><a href="#header-functions">Functions</a></h3>
|
|
||||||
<ul class="">
|
|
||||||
<li><code><a title="miplearn.components.tests.test_composite.test_composite" href="#miplearn.components.tests.test_composite.test_composite">test_composite</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>
|
|
@ -1,365 +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.tests.test_lazy_dynamic 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.tests.test_lazy_dynamic</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
|
|
||||||
|
|
||||||
import numpy as np
|
|
||||||
from numpy.linalg import norm
|
|
||||||
|
|
||||||
from miplearn.classifiers import Classifier
|
|
||||||
from miplearn.components.lazy_dynamic import DynamicLazyConstraintsComponent
|
|
||||||
from miplearn.solvers.internal import InternalSolver
|
|
||||||
from miplearn.solvers.learning import LearningSolver
|
|
||||||
from miplearn.tests import get_test_pyomo_instances
|
|
||||||
|
|
||||||
E = 0.1
|
|
||||||
|
|
||||||
|
|
||||||
def test_lazy_fit():
|
|
||||||
instances, models = get_test_pyomo_instances()
|
|
||||||
instances[0].found_violated_lazy_constraints = ["a", "b"]
|
|
||||||
instances[1].found_violated_lazy_constraints = ["b", "c"]
|
|
||||||
classifier = Mock(spec=Classifier)
|
|
||||||
component = DynamicLazyConstraintsComponent(classifier=classifier)
|
|
||||||
|
|
||||||
component.fit(instances)
|
|
||||||
|
|
||||||
# Should create one classifier for each violation
|
|
||||||
assert "a" in component.classifiers
|
|
||||||
assert "b" in component.classifiers
|
|
||||||
assert "c" in component.classifiers
|
|
||||||
|
|
||||||
# Should provide correct x_train to each classifier
|
|
||||||
expected_x_train_a = np.array([[67.0, 21.75, 1287.92], [70.0, 23.75, 1199.83]])
|
|
||||||
expected_x_train_b = np.array([[67.0, 21.75, 1287.92], [70.0, 23.75, 1199.83]])
|
|
||||||
expected_x_train_c = np.array([[67.0, 21.75, 1287.92], [70.0, 23.75, 1199.83]])
|
|
||||||
actual_x_train_a = component.classifiers["a"].fit.call_args[0][0]
|
|
||||||
actual_x_train_b = component.classifiers["b"].fit.call_args[0][0]
|
|
||||||
actual_x_train_c = component.classifiers["c"].fit.call_args[0][0]
|
|
||||||
assert norm(expected_x_train_a - actual_x_train_a) < E
|
|
||||||
assert norm(expected_x_train_b - actual_x_train_b) < E
|
|
||||||
assert norm(expected_x_train_c - actual_x_train_c) < E
|
|
||||||
|
|
||||||
# Should provide correct y_train to each classifier
|
|
||||||
expected_y_train_a = np.array([1.0, 0.0])
|
|
||||||
expected_y_train_b = np.array([1.0, 1.0])
|
|
||||||
expected_y_train_c = np.array([0.0, 1.0])
|
|
||||||
actual_y_train_a = component.classifiers["a"].fit.call_args[0][1]
|
|
||||||
actual_y_train_b = component.classifiers["b"].fit.call_args[0][1]
|
|
||||||
actual_y_train_c = component.classifiers["c"].fit.call_args[0][1]
|
|
||||||
assert norm(expected_y_train_a - actual_y_train_a) < E
|
|
||||||
assert norm(expected_y_train_b - actual_y_train_b) < E
|
|
||||||
assert norm(expected_y_train_c - actual_y_train_c) < E
|
|
||||||
|
|
||||||
|
|
||||||
def test_lazy_before():
|
|
||||||
instances, models = get_test_pyomo_instances()
|
|
||||||
instances[0].build_lazy_constraint = Mock(return_value="c1")
|
|
||||||
solver = LearningSolver()
|
|
||||||
solver.internal_solver = Mock(spec=InternalSolver)
|
|
||||||
component = DynamicLazyConstraintsComponent(threshold=0.10)
|
|
||||||
component.classifiers = {"a": Mock(spec=Classifier), "b": Mock(spec=Classifier)}
|
|
||||||
component.classifiers["a"].predict_proba = Mock(return_value=[[0.95, 0.05]])
|
|
||||||
component.classifiers["b"].predict_proba = Mock(return_value=[[0.02, 0.80]])
|
|
||||||
|
|
||||||
component.before_solve(solver, instances[0], models[0])
|
|
||||||
|
|
||||||
# Should ask classifier likelihood of each constraint being violated
|
|
||||||
expected_x_test_a = np.array([[67.0, 21.75, 1287.92]])
|
|
||||||
expected_x_test_b = np.array([[67.0, 21.75, 1287.92]])
|
|
||||||
actual_x_test_a = component.classifiers["a"].predict_proba.call_args[0][0]
|
|
||||||
actual_x_test_b = component.classifiers["b"].predict_proba.call_args[0][0]
|
|
||||||
assert norm(expected_x_test_a - actual_x_test_a) < E
|
|
||||||
assert norm(expected_x_test_b - actual_x_test_b) < E
|
|
||||||
|
|
||||||
# Should ask instance to generate cut for constraints whose likelihood
|
|
||||||
# of being violated exceeds the threshold
|
|
||||||
instances[0].build_lazy_constraint.assert_called_once_with(models[0], "b")
|
|
||||||
|
|
||||||
# Should ask internal solver to add generated constraint
|
|
||||||
solver.internal_solver.add_constraint.assert_called_once_with("c1")
|
|
||||||
|
|
||||||
|
|
||||||
def test_lazy_evaluate():
|
|
||||||
instances, models = get_test_pyomo_instances()
|
|
||||||
component = DynamicLazyConstraintsComponent()
|
|
||||||
component.classifiers = {
|
|
||||||
"a": Mock(spec=Classifier),
|
|
||||||
"b": Mock(spec=Classifier),
|
|
||||||
"c": Mock(spec=Classifier),
|
|
||||||
}
|
|
||||||
component.classifiers["a"].predict_proba = Mock(return_value=[[1.0, 0.0]])
|
|
||||||
component.classifiers["b"].predict_proba = Mock(return_value=[[0.0, 1.0]])
|
|
||||||
component.classifiers["c"].predict_proba = Mock(return_value=[[0.0, 1.0]])
|
|
||||||
|
|
||||||
instances[0].found_violated_lazy_constraints = ["a", "b", "c"]
|
|
||||||
instances[1].found_violated_lazy_constraints = ["b", "d"]
|
|
||||||
assert component.evaluate(instances) == {
|
|
||||||
0: {
|
|
||||||
"Accuracy": 0.75,
|
|
||||||
"F1 score": 0.8,
|
|
||||||
"Precision": 1.0,
|
|
||||||
"Recall": 2 / 3.0,
|
|
||||||
"Predicted positive": 2,
|
|
||||||
"Predicted negative": 2,
|
|
||||||
"Condition positive": 3,
|
|
||||||
"Condition negative": 1,
|
|
||||||
"False negative": 1,
|
|
||||||
"False positive": 0,
|
|
||||||
"True negative": 1,
|
|
||||||
"True positive": 2,
|
|
||||||
"Predicted positive (%)": 50.0,
|
|
||||||
"Predicted negative (%)": 50.0,
|
|
||||||
"Condition positive (%)": 75.0,
|
|
||||||
"Condition negative (%)": 25.0,
|
|
||||||
"False negative (%)": 25.0,
|
|
||||||
"False positive (%)": 0,
|
|
||||||
"True negative (%)": 25.0,
|
|
||||||
"True positive (%)": 50.0,
|
|
||||||
},
|
|
||||||
1: {
|
|
||||||
"Accuracy": 0.5,
|
|
||||||
"F1 score": 0.5,
|
|
||||||
"Precision": 0.5,
|
|
||||||
"Recall": 0.5,
|
|
||||||
"Predicted positive": 2,
|
|
||||||
"Predicted negative": 2,
|
|
||||||
"Condition positive": 2,
|
|
||||||
"Condition negative": 2,
|
|
||||||
"False negative": 1,
|
|
||||||
"False positive": 1,
|
|
||||||
"True negative": 1,
|
|
||||||
"True positive": 1,
|
|
||||||
"Predicted positive (%)": 50.0,
|
|
||||||
"Predicted negative (%)": 50.0,
|
|
||||||
"Condition positive (%)": 50.0,
|
|
||||||
"Condition negative (%)": 50.0,
|
|
||||||
"False negative (%)": 25.0,
|
|
||||||
"False positive (%)": 25.0,
|
|
||||||
"True negative (%)": 25.0,
|
|
||||||
"True positive (%)": 25.0,
|
|
||||||
},
|
|
||||||
}</code></pre>
|
|
||||||
</details>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
<h2 class="section-title" id="header-functions">Functions</h2>
|
|
||||||
<dl>
|
|
||||||
<dt id="miplearn.components.tests.test_lazy_dynamic.test_lazy_before"><code class="name flex">
|
|
||||||
<span>def <span class="ident">test_lazy_before</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_before():
|
|
||||||
instances, models = get_test_pyomo_instances()
|
|
||||||
instances[0].build_lazy_constraint = Mock(return_value="c1")
|
|
||||||
solver = LearningSolver()
|
|
||||||
solver.internal_solver = Mock(spec=InternalSolver)
|
|
||||||
component = DynamicLazyConstraintsComponent(threshold=0.10)
|
|
||||||
component.classifiers = {"a": Mock(spec=Classifier), "b": Mock(spec=Classifier)}
|
|
||||||
component.classifiers["a"].predict_proba = Mock(return_value=[[0.95, 0.05]])
|
|
||||||
component.classifiers["b"].predict_proba = Mock(return_value=[[0.02, 0.80]])
|
|
||||||
|
|
||||||
component.before_solve(solver, instances[0], models[0])
|
|
||||||
|
|
||||||
# Should ask classifier likelihood of each constraint being violated
|
|
||||||
expected_x_test_a = np.array([[67.0, 21.75, 1287.92]])
|
|
||||||
expected_x_test_b = np.array([[67.0, 21.75, 1287.92]])
|
|
||||||
actual_x_test_a = component.classifiers["a"].predict_proba.call_args[0][0]
|
|
||||||
actual_x_test_b = component.classifiers["b"].predict_proba.call_args[0][0]
|
|
||||||
assert norm(expected_x_test_a - actual_x_test_a) < E
|
|
||||||
assert norm(expected_x_test_b - actual_x_test_b) < E
|
|
||||||
|
|
||||||
# Should ask instance to generate cut for constraints whose likelihood
|
|
||||||
# of being violated exceeds the threshold
|
|
||||||
instances[0].build_lazy_constraint.assert_called_once_with(models[0], "b")
|
|
||||||
|
|
||||||
# Should ask internal solver to add generated constraint
|
|
||||||
solver.internal_solver.add_constraint.assert_called_once_with("c1")</code></pre>
|
|
||||||
</details>
|
|
||||||
</dd>
|
|
||||||
<dt id="miplearn.components.tests.test_lazy_dynamic.test_lazy_evaluate"><code class="name flex">
|
|
||||||
<span>def <span class="ident">test_lazy_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_lazy_evaluate():
|
|
||||||
instances, models = get_test_pyomo_instances()
|
|
||||||
component = DynamicLazyConstraintsComponent()
|
|
||||||
component.classifiers = {
|
|
||||||
"a": Mock(spec=Classifier),
|
|
||||||
"b": Mock(spec=Classifier),
|
|
||||||
"c": Mock(spec=Classifier),
|
|
||||||
}
|
|
||||||
component.classifiers["a"].predict_proba = Mock(return_value=[[1.0, 0.0]])
|
|
||||||
component.classifiers["b"].predict_proba = Mock(return_value=[[0.0, 1.0]])
|
|
||||||
component.classifiers["c"].predict_proba = Mock(return_value=[[0.0, 1.0]])
|
|
||||||
|
|
||||||
instances[0].found_violated_lazy_constraints = ["a", "b", "c"]
|
|
||||||
instances[1].found_violated_lazy_constraints = ["b", "d"]
|
|
||||||
assert component.evaluate(instances) == {
|
|
||||||
0: {
|
|
||||||
"Accuracy": 0.75,
|
|
||||||
"F1 score": 0.8,
|
|
||||||
"Precision": 1.0,
|
|
||||||
"Recall": 2 / 3.0,
|
|
||||||
"Predicted positive": 2,
|
|
||||||
"Predicted negative": 2,
|
|
||||||
"Condition positive": 3,
|
|
||||||
"Condition negative": 1,
|
|
||||||
"False negative": 1,
|
|
||||||
"False positive": 0,
|
|
||||||
"True negative": 1,
|
|
||||||
"True positive": 2,
|
|
||||||
"Predicted positive (%)": 50.0,
|
|
||||||
"Predicted negative (%)": 50.0,
|
|
||||||
"Condition positive (%)": 75.0,
|
|
||||||
"Condition negative (%)": 25.0,
|
|
||||||
"False negative (%)": 25.0,
|
|
||||||
"False positive (%)": 0,
|
|
||||||
"True negative (%)": 25.0,
|
|
||||||
"True positive (%)": 50.0,
|
|
||||||
},
|
|
||||||
1: {
|
|
||||||
"Accuracy": 0.5,
|
|
||||||
"F1 score": 0.5,
|
|
||||||
"Precision": 0.5,
|
|
||||||
"Recall": 0.5,
|
|
||||||
"Predicted positive": 2,
|
|
||||||
"Predicted negative": 2,
|
|
||||||
"Condition positive": 2,
|
|
||||||
"Condition negative": 2,
|
|
||||||
"False negative": 1,
|
|
||||||
"False positive": 1,
|
|
||||||
"True negative": 1,
|
|
||||||
"True positive": 1,
|
|
||||||
"Predicted positive (%)": 50.0,
|
|
||||||
"Predicted negative (%)": 50.0,
|
|
||||||
"Condition positive (%)": 50.0,
|
|
||||||
"Condition negative (%)": 50.0,
|
|
||||||
"False negative (%)": 25.0,
|
|
||||||
"False positive (%)": 25.0,
|
|
||||||
"True negative (%)": 25.0,
|
|
||||||
"True positive (%)": 25.0,
|
|
||||||
},
|
|
||||||
}</code></pre>
|
|
||||||
</details>
|
|
||||||
</dd>
|
|
||||||
<dt id="miplearn.components.tests.test_lazy_dynamic.test_lazy_fit"><code class="name flex">
|
|
||||||
<span>def <span class="ident">test_lazy_fit</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_fit():
|
|
||||||
instances, models = get_test_pyomo_instances()
|
|
||||||
instances[0].found_violated_lazy_constraints = ["a", "b"]
|
|
||||||
instances[1].found_violated_lazy_constraints = ["b", "c"]
|
|
||||||
classifier = Mock(spec=Classifier)
|
|
||||||
component = DynamicLazyConstraintsComponent(classifier=classifier)
|
|
||||||
|
|
||||||
component.fit(instances)
|
|
||||||
|
|
||||||
# Should create one classifier for each violation
|
|
||||||
assert "a" in component.classifiers
|
|
||||||
assert "b" in component.classifiers
|
|
||||||
assert "c" in component.classifiers
|
|
||||||
|
|
||||||
# Should provide correct x_train to each classifier
|
|
||||||
expected_x_train_a = np.array([[67.0, 21.75, 1287.92], [70.0, 23.75, 1199.83]])
|
|
||||||
expected_x_train_b = np.array([[67.0, 21.75, 1287.92], [70.0, 23.75, 1199.83]])
|
|
||||||
expected_x_train_c = np.array([[67.0, 21.75, 1287.92], [70.0, 23.75, 1199.83]])
|
|
||||||
actual_x_train_a = component.classifiers["a"].fit.call_args[0][0]
|
|
||||||
actual_x_train_b = component.classifiers["b"].fit.call_args[0][0]
|
|
||||||
actual_x_train_c = component.classifiers["c"].fit.call_args[0][0]
|
|
||||||
assert norm(expected_x_train_a - actual_x_train_a) < E
|
|
||||||
assert norm(expected_x_train_b - actual_x_train_b) < E
|
|
||||||
assert norm(expected_x_train_c - actual_x_train_c) < E
|
|
||||||
|
|
||||||
# Should provide correct y_train to each classifier
|
|
||||||
expected_y_train_a = np.array([1.0, 0.0])
|
|
||||||
expected_y_train_b = np.array([1.0, 1.0])
|
|
||||||
expected_y_train_c = np.array([0.0, 1.0])
|
|
||||||
actual_y_train_a = component.classifiers["a"].fit.call_args[0][1]
|
|
||||||
actual_y_train_b = component.classifiers["b"].fit.call_args[0][1]
|
|
||||||
actual_y_train_c = component.classifiers["c"].fit.call_args[0][1]
|
|
||||||
assert norm(expected_y_train_a - actual_y_train_a) < E
|
|
||||||
assert norm(expected_y_train_b - actual_y_train_b) < E
|
|
||||||
assert norm(expected_y_train_c - actual_y_train_c) < E</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.tests" href="index.html">miplearn.components.tests</a></code></li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
<li><h3><a href="#header-functions">Functions</a></h3>
|
|
||||||
<ul class="">
|
|
||||||
<li><code><a title="miplearn.components.tests.test_lazy_dynamic.test_lazy_before" href="#miplearn.components.tests.test_lazy_dynamic.test_lazy_before">test_lazy_before</a></code></li>
|
|
||||||
<li><code><a title="miplearn.components.tests.test_lazy_dynamic.test_lazy_evaluate" href="#miplearn.components.tests.test_lazy_dynamic.test_lazy_evaluate">test_lazy_evaluate</a></code></li>
|
|
||||||
<li><code><a title="miplearn.components.tests.test_lazy_dynamic.test_lazy_fit" href="#miplearn.components.tests.test_lazy_dynamic.test_lazy_fit">test_lazy_fit</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>
|
|
@ -1,538 +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.tests.test_lazy_static 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.tests.test_lazy_static</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
|
|
||||||
|
|
||||||
from miplearn.classifiers import Classifier
|
|
||||||
from miplearn.components.lazy_static import StaticLazyConstraintsComponent
|
|
||||||
from miplearn.instance import Instance
|
|
||||||
from miplearn.solvers.internal import InternalSolver
|
|
||||||
from miplearn.solvers.learning import LearningSolver
|
|
||||||
|
|
||||||
|
|
||||||
def test_usage_with_solver():
|
|
||||||
solver = Mock(spec=LearningSolver)
|
|
||||||
solver.use_lazy_cb = False
|
|
||||||
solver.gap_tolerance = 1e-4
|
|
||||||
|
|
||||||
internal = solver.internal_solver = Mock(spec=InternalSolver)
|
|
||||||
internal.get_constraint_ids = Mock(return_value=["c1", "c2", "c3", "c4"])
|
|
||||||
internal.extract_constraint = Mock(side_effect=lambda cid: "<%s>" % cid)
|
|
||||||
internal.is_constraint_satisfied = Mock(return_value=False)
|
|
||||||
|
|
||||||
instance = Mock(spec=Instance)
|
|
||||||
instance.has_static_lazy_constraints = Mock(return_value=True)
|
|
||||||
instance.is_constraint_lazy = Mock(
|
|
||||||
side_effect=lambda cid: {
|
|
||||||
"c1": False,
|
|
||||||
"c2": True,
|
|
||||||
"c3": True,
|
|
||||||
"c4": True,
|
|
||||||
}[cid]
|
|
||||||
)
|
|
||||||
instance.get_constraint_features = Mock(
|
|
||||||
side_effect=lambda cid: {
|
|
||||||
"c2": [1.0, 0.0],
|
|
||||||
"c3": [0.5, 0.5],
|
|
||||||
"c4": [1.0],
|
|
||||||
}[cid]
|
|
||||||
)
|
|
||||||
instance.get_constraint_category = Mock(
|
|
||||||
side_effect=lambda cid: {
|
|
||||||
"c2": "type-a",
|
|
||||||
"c3": "type-a",
|
|
||||||
"c4": "type-b",
|
|
||||||
}[cid]
|
|
||||||
)
|
|
||||||
|
|
||||||
component = StaticLazyConstraintsComponent(
|
|
||||||
threshold=0.90,
|
|
||||||
use_two_phase_gap=False,
|
|
||||||
violation_tolerance=1.0,
|
|
||||||
)
|
|
||||||
component.classifiers = {
|
|
||||||
"type-a": Mock(spec=Classifier),
|
|
||||||
"type-b": Mock(spec=Classifier),
|
|
||||||
}
|
|
||||||
component.classifiers["type-a"].predict_proba = Mock(
|
|
||||||
return_value=[
|
|
||||||
[0.20, 0.80],
|
|
||||||
[0.05, 0.95],
|
|
||||||
]
|
|
||||||
)
|
|
||||||
component.classifiers["type-b"].predict_proba = Mock(
|
|
||||||
return_value=[
|
|
||||||
[0.02, 0.98],
|
|
||||||
]
|
|
||||||
)
|
|
||||||
|
|
||||||
# LearningSolver calls before_solve
|
|
||||||
component.before_solve(solver, instance, None)
|
|
||||||
|
|
||||||
# Should ask if instance has static lazy constraints
|
|
||||||
instance.has_static_lazy_constraints.assert_called_once()
|
|
||||||
|
|
||||||
# Should ask internal solver for a list of constraints in the model
|
|
||||||
internal.get_constraint_ids.assert_called_once()
|
|
||||||
|
|
||||||
# Should ask if each constraint in the model is lazy
|
|
||||||
instance.is_constraint_lazy.assert_has_calls(
|
|
||||||
[
|
|
||||||
call("c1"),
|
|
||||||
call("c2"),
|
|
||||||
call("c3"),
|
|
||||||
call("c4"),
|
|
||||||
]
|
|
||||||
)
|
|
||||||
|
|
||||||
# For the lazy ones, should ask for features
|
|
||||||
instance.get_constraint_features.assert_has_calls(
|
|
||||||
[
|
|
||||||
call("c2"),
|
|
||||||
call("c3"),
|
|
||||||
call("c4"),
|
|
||||||
]
|
|
||||||
)
|
|
||||||
|
|
||||||
# Should also ask for categories
|
|
||||||
assert instance.get_constraint_category.call_count == 3
|
|
||||||
instance.get_constraint_category.assert_has_calls(
|
|
||||||
[
|
|
||||||
call("c2"),
|
|
||||||
call("c3"),
|
|
||||||
call("c4"),
|
|
||||||
]
|
|
||||||
)
|
|
||||||
|
|
||||||
# Should ask internal solver to remove constraints identified as lazy
|
|
||||||
assert internal.extract_constraint.call_count == 3
|
|
||||||
internal.extract_constraint.assert_has_calls(
|
|
||||||
[
|
|
||||||
call("c2"),
|
|
||||||
call("c3"),
|
|
||||||
call("c4"),
|
|
||||||
]
|
|
||||||
)
|
|
||||||
|
|
||||||
# Should ask ML to predict whether each lazy constraint should be enforced
|
|
||||||
component.classifiers["type-a"].predict_proba.assert_called_once_with(
|
|
||||||
[[1.0, 0.0], [0.5, 0.5]]
|
|
||||||
)
|
|
||||||
component.classifiers["type-b"].predict_proba.assert_called_once_with([[1.0]])
|
|
||||||
|
|
||||||
# For the ones that should be enforced, should ask solver to re-add them
|
|
||||||
# to the formulation. The remaining ones should remain in the pool.
|
|
||||||
assert internal.add_constraint.call_count == 2
|
|
||||||
internal.add_constraint.assert_has_calls(
|
|
||||||
[
|
|
||||||
call("<c3>"),
|
|
||||||
call("<c4>"),
|
|
||||||
]
|
|
||||||
)
|
|
||||||
internal.add_constraint.reset_mock()
|
|
||||||
|
|
||||||
# LearningSolver calls after_iteration (first time)
|
|
||||||
should_repeat = component.iteration_cb(solver, instance, None)
|
|
||||||
assert should_repeat
|
|
||||||
|
|
||||||
# Should ask internal solver to verify if constraints in the pool are
|
|
||||||
# satisfied and add the ones that are not
|
|
||||||
internal.is_constraint_satisfied.assert_called_once_with("<c2>", tol=1.0)
|
|
||||||
internal.is_constraint_satisfied.reset_mock()
|
|
||||||
internal.add_constraint.assert_called_once_with("<c2>")
|
|
||||||
internal.add_constraint.reset_mock()
|
|
||||||
|
|
||||||
# LearningSolver calls after_iteration (second time)
|
|
||||||
should_repeat = component.iteration_cb(solver, instance, None)
|
|
||||||
assert not should_repeat
|
|
||||||
|
|
||||||
# The lazy constraint pool should be empty by now, so no calls should be made
|
|
||||||
internal.is_constraint_satisfied.assert_not_called()
|
|
||||||
internal.add_constraint.assert_not_called()
|
|
||||||
|
|
||||||
# Should update instance object
|
|
||||||
assert instance.found_violated_lazy_constraints == ["c3", "c4", "c2"]
|
|
||||||
|
|
||||||
|
|
||||||
def test_fit():
|
|
||||||
instance_1 = Mock(spec=Instance)
|
|
||||||
instance_1.found_violated_lazy_constraints = ["c1", "c2", "c4", "c5"]
|
|
||||||
instance_1.get_constraint_category = Mock(
|
|
||||||
side_effect=lambda cid: {
|
|
||||||
"c1": "type-a",
|
|
||||||
"c2": "type-a",
|
|
||||||
"c3": "type-a",
|
|
||||||
"c4": "type-b",
|
|
||||||
"c5": "type-b",
|
|
||||||
}[cid]
|
|
||||||
)
|
|
||||||
instance_1.get_constraint_features = Mock(
|
|
||||||
side_effect=lambda cid: {
|
|
||||||
"c1": [1, 1],
|
|
||||||
"c2": [1, 2],
|
|
||||||
"c3": [1, 3],
|
|
||||||
"c4": [1, 4, 0],
|
|
||||||
"c5": [1, 5, 0],
|
|
||||||
}[cid]
|
|
||||||
)
|
|
||||||
|
|
||||||
instance_2 = Mock(spec=Instance)
|
|
||||||
instance_2.found_violated_lazy_constraints = ["c2", "c3", "c4"]
|
|
||||||
instance_2.get_constraint_category = Mock(
|
|
||||||
side_effect=lambda cid: {
|
|
||||||
"c1": "type-a",
|
|
||||||
"c2": "type-a",
|
|
||||||
"c3": "type-a",
|
|
||||||
"c4": "type-b",
|
|
||||||
"c5": "type-b",
|
|
||||||
}[cid]
|
|
||||||
)
|
|
||||||
instance_2.get_constraint_features = Mock(
|
|
||||||
side_effect=lambda cid: {
|
|
||||||
"c1": [2, 1],
|
|
||||||
"c2": [2, 2],
|
|
||||||
"c3": [2, 3],
|
|
||||||
"c4": [2, 4, 0],
|
|
||||||
"c5": [2, 5, 0],
|
|
||||||
}[cid]
|
|
||||||
)
|
|
||||||
|
|
||||||
instances = [instance_1, instance_2]
|
|
||||||
component = StaticLazyConstraintsComponent()
|
|
||||||
component.classifiers = {
|
|
||||||
"type-a": Mock(spec=Classifier),
|
|
||||||
"type-b": Mock(spec=Classifier),
|
|
||||||
}
|
|
||||||
|
|
||||||
expected_constraints = {
|
|
||||||
"type-a": ["c1", "c2", "c3"],
|
|
||||||
"type-b": ["c4", "c5"],
|
|
||||||
}
|
|
||||||
expected_x = {
|
|
||||||
"type-a": [[1, 1], [1, 2], [1, 3], [2, 1], [2, 2], [2, 3]],
|
|
||||||
"type-b": [[1, 4, 0], [1, 5, 0], [2, 4, 0], [2, 5, 0]],
|
|
||||||
}
|
|
||||||
expected_y = {
|
|
||||||
"type-a": [[0, 1], [0, 1], [1, 0], [1, 0], [0, 1], [0, 1]],
|
|
||||||
"type-b": [[0, 1], [0, 1], [0, 1], [1, 0]],
|
|
||||||
}
|
|
||||||
assert component._collect_constraints(instances) == expected_constraints
|
|
||||||
assert component.x(instances) == expected_x
|
|
||||||
assert component.y(instances) == expected_y
|
|
||||||
|
|
||||||
component.fit(instances)
|
|
||||||
component.classifiers["type-a"].fit.assert_called_once_with(
|
|
||||||
expected_x["type-a"],
|
|
||||||
expected_y["type-a"],
|
|
||||||
)
|
|
||||||
component.classifiers["type-b"].fit.assert_called_once_with(
|
|
||||||
expected_x["type-b"],
|
|
||||||
expected_y["type-b"],
|
|
||||||
)</code></pre>
|
|
||||||
</details>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
<h2 class="section-title" id="header-functions">Functions</h2>
|
|
||||||
<dl>
|
|
||||||
<dt id="miplearn.components.tests.test_lazy_static.test_fit"><code class="name flex">
|
|
||||||
<span>def <span class="ident">test_fit</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_fit():
|
|
||||||
instance_1 = Mock(spec=Instance)
|
|
||||||
instance_1.found_violated_lazy_constraints = ["c1", "c2", "c4", "c5"]
|
|
||||||
instance_1.get_constraint_category = Mock(
|
|
||||||
side_effect=lambda cid: {
|
|
||||||
"c1": "type-a",
|
|
||||||
"c2": "type-a",
|
|
||||||
"c3": "type-a",
|
|
||||||
"c4": "type-b",
|
|
||||||
"c5": "type-b",
|
|
||||||
}[cid]
|
|
||||||
)
|
|
||||||
instance_1.get_constraint_features = Mock(
|
|
||||||
side_effect=lambda cid: {
|
|
||||||
"c1": [1, 1],
|
|
||||||
"c2": [1, 2],
|
|
||||||
"c3": [1, 3],
|
|
||||||
"c4": [1, 4, 0],
|
|
||||||
"c5": [1, 5, 0],
|
|
||||||
}[cid]
|
|
||||||
)
|
|
||||||
|
|
||||||
instance_2 = Mock(spec=Instance)
|
|
||||||
instance_2.found_violated_lazy_constraints = ["c2", "c3", "c4"]
|
|
||||||
instance_2.get_constraint_category = Mock(
|
|
||||||
side_effect=lambda cid: {
|
|
||||||
"c1": "type-a",
|
|
||||||
"c2": "type-a",
|
|
||||||
"c3": "type-a",
|
|
||||||
"c4": "type-b",
|
|
||||||
"c5": "type-b",
|
|
||||||
}[cid]
|
|
||||||
)
|
|
||||||
instance_2.get_constraint_features = Mock(
|
|
||||||
side_effect=lambda cid: {
|
|
||||||
"c1": [2, 1],
|
|
||||||
"c2": [2, 2],
|
|
||||||
"c3": [2, 3],
|
|
||||||
"c4": [2, 4, 0],
|
|
||||||
"c5": [2, 5, 0],
|
|
||||||
}[cid]
|
|
||||||
)
|
|
||||||
|
|
||||||
instances = [instance_1, instance_2]
|
|
||||||
component = StaticLazyConstraintsComponent()
|
|
||||||
component.classifiers = {
|
|
||||||
"type-a": Mock(spec=Classifier),
|
|
||||||
"type-b": Mock(spec=Classifier),
|
|
||||||
}
|
|
||||||
|
|
||||||
expected_constraints = {
|
|
||||||
"type-a": ["c1", "c2", "c3"],
|
|
||||||
"type-b": ["c4", "c5"],
|
|
||||||
}
|
|
||||||
expected_x = {
|
|
||||||
"type-a": [[1, 1], [1, 2], [1, 3], [2, 1], [2, 2], [2, 3]],
|
|
||||||
"type-b": [[1, 4, 0], [1, 5, 0], [2, 4, 0], [2, 5, 0]],
|
|
||||||
}
|
|
||||||
expected_y = {
|
|
||||||
"type-a": [[0, 1], [0, 1], [1, 0], [1, 0], [0, 1], [0, 1]],
|
|
||||||
"type-b": [[0, 1], [0, 1], [0, 1], [1, 0]],
|
|
||||||
}
|
|
||||||
assert component._collect_constraints(instances) == expected_constraints
|
|
||||||
assert component.x(instances) == expected_x
|
|
||||||
assert component.y(instances) == expected_y
|
|
||||||
|
|
||||||
component.fit(instances)
|
|
||||||
component.classifiers["type-a"].fit.assert_called_once_with(
|
|
||||||
expected_x["type-a"],
|
|
||||||
expected_y["type-a"],
|
|
||||||
)
|
|
||||||
component.classifiers["type-b"].fit.assert_called_once_with(
|
|
||||||
expected_x["type-b"],
|
|
||||||
expected_y["type-b"],
|
|
||||||
)</code></pre>
|
|
||||||
</details>
|
|
||||||
</dd>
|
|
||||||
<dt id="miplearn.components.tests.test_lazy_static.test_usage_with_solver"><code class="name flex">
|
|
||||||
<span>def <span class="ident">test_usage_with_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_usage_with_solver():
|
|
||||||
solver = Mock(spec=LearningSolver)
|
|
||||||
solver.use_lazy_cb = False
|
|
||||||
solver.gap_tolerance = 1e-4
|
|
||||||
|
|
||||||
internal = solver.internal_solver = Mock(spec=InternalSolver)
|
|
||||||
internal.get_constraint_ids = Mock(return_value=["c1", "c2", "c3", "c4"])
|
|
||||||
internal.extract_constraint = Mock(side_effect=lambda cid: "<%s>" % cid)
|
|
||||||
internal.is_constraint_satisfied = Mock(return_value=False)
|
|
||||||
|
|
||||||
instance = Mock(spec=Instance)
|
|
||||||
instance.has_static_lazy_constraints = Mock(return_value=True)
|
|
||||||
instance.is_constraint_lazy = Mock(
|
|
||||||
side_effect=lambda cid: {
|
|
||||||
"c1": False,
|
|
||||||
"c2": True,
|
|
||||||
"c3": True,
|
|
||||||
"c4": True,
|
|
||||||
}[cid]
|
|
||||||
)
|
|
||||||
instance.get_constraint_features = Mock(
|
|
||||||
side_effect=lambda cid: {
|
|
||||||
"c2": [1.0, 0.0],
|
|
||||||
"c3": [0.5, 0.5],
|
|
||||||
"c4": [1.0],
|
|
||||||
}[cid]
|
|
||||||
)
|
|
||||||
instance.get_constraint_category = Mock(
|
|
||||||
side_effect=lambda cid: {
|
|
||||||
"c2": "type-a",
|
|
||||||
"c3": "type-a",
|
|
||||||
"c4": "type-b",
|
|
||||||
}[cid]
|
|
||||||
)
|
|
||||||
|
|
||||||
component = StaticLazyConstraintsComponent(
|
|
||||||
threshold=0.90,
|
|
||||||
use_two_phase_gap=False,
|
|
||||||
violation_tolerance=1.0,
|
|
||||||
)
|
|
||||||
component.classifiers = {
|
|
||||||
"type-a": Mock(spec=Classifier),
|
|
||||||
"type-b": Mock(spec=Classifier),
|
|
||||||
}
|
|
||||||
component.classifiers["type-a"].predict_proba = Mock(
|
|
||||||
return_value=[
|
|
||||||
[0.20, 0.80],
|
|
||||||
[0.05, 0.95],
|
|
||||||
]
|
|
||||||
)
|
|
||||||
component.classifiers["type-b"].predict_proba = Mock(
|
|
||||||
return_value=[
|
|
||||||
[0.02, 0.98],
|
|
||||||
]
|
|
||||||
)
|
|
||||||
|
|
||||||
# LearningSolver calls before_solve
|
|
||||||
component.before_solve(solver, instance, None)
|
|
||||||
|
|
||||||
# Should ask if instance has static lazy constraints
|
|
||||||
instance.has_static_lazy_constraints.assert_called_once()
|
|
||||||
|
|
||||||
# Should ask internal solver for a list of constraints in the model
|
|
||||||
internal.get_constraint_ids.assert_called_once()
|
|
||||||
|
|
||||||
# Should ask if each constraint in the model is lazy
|
|
||||||
instance.is_constraint_lazy.assert_has_calls(
|
|
||||||
[
|
|
||||||
call("c1"),
|
|
||||||
call("c2"),
|
|
||||||
call("c3"),
|
|
||||||
call("c4"),
|
|
||||||
]
|
|
||||||
)
|
|
||||||
|
|
||||||
# For the lazy ones, should ask for features
|
|
||||||
instance.get_constraint_features.assert_has_calls(
|
|
||||||
[
|
|
||||||
call("c2"),
|
|
||||||
call("c3"),
|
|
||||||
call("c4"),
|
|
||||||
]
|
|
||||||
)
|
|
||||||
|
|
||||||
# Should also ask for categories
|
|
||||||
assert instance.get_constraint_category.call_count == 3
|
|
||||||
instance.get_constraint_category.assert_has_calls(
|
|
||||||
[
|
|
||||||
call("c2"),
|
|
||||||
call("c3"),
|
|
||||||
call("c4"),
|
|
||||||
]
|
|
||||||
)
|
|
||||||
|
|
||||||
# Should ask internal solver to remove constraints identified as lazy
|
|
||||||
assert internal.extract_constraint.call_count == 3
|
|
||||||
internal.extract_constraint.assert_has_calls(
|
|
||||||
[
|
|
||||||
call("c2"),
|
|
||||||
call("c3"),
|
|
||||||
call("c4"),
|
|
||||||
]
|
|
||||||
)
|
|
||||||
|
|
||||||
# Should ask ML to predict whether each lazy constraint should be enforced
|
|
||||||
component.classifiers["type-a"].predict_proba.assert_called_once_with(
|
|
||||||
[[1.0, 0.0], [0.5, 0.5]]
|
|
||||||
)
|
|
||||||
component.classifiers["type-b"].predict_proba.assert_called_once_with([[1.0]])
|
|
||||||
|
|
||||||
# For the ones that should be enforced, should ask solver to re-add them
|
|
||||||
# to the formulation. The remaining ones should remain in the pool.
|
|
||||||
assert internal.add_constraint.call_count == 2
|
|
||||||
internal.add_constraint.assert_has_calls(
|
|
||||||
[
|
|
||||||
call("<c3>"),
|
|
||||||
call("<c4>"),
|
|
||||||
]
|
|
||||||
)
|
|
||||||
internal.add_constraint.reset_mock()
|
|
||||||
|
|
||||||
# LearningSolver calls after_iteration (first time)
|
|
||||||
should_repeat = component.iteration_cb(solver, instance, None)
|
|
||||||
assert should_repeat
|
|
||||||
|
|
||||||
# Should ask internal solver to verify if constraints in the pool are
|
|
||||||
# satisfied and add the ones that are not
|
|
||||||
internal.is_constraint_satisfied.assert_called_once_with("<c2>", tol=1.0)
|
|
||||||
internal.is_constraint_satisfied.reset_mock()
|
|
||||||
internal.add_constraint.assert_called_once_with("<c2>")
|
|
||||||
internal.add_constraint.reset_mock()
|
|
||||||
|
|
||||||
# LearningSolver calls after_iteration (second time)
|
|
||||||
should_repeat = component.iteration_cb(solver, instance, None)
|
|
||||||
assert not should_repeat
|
|
||||||
|
|
||||||
# The lazy constraint pool should be empty by now, so no calls should be made
|
|
||||||
internal.is_constraint_satisfied.assert_not_called()
|
|
||||||
internal.add_constraint.assert_not_called()
|
|
||||||
|
|
||||||
# Should update instance object
|
|
||||||
assert instance.found_violated_lazy_constraints == ["c3", "c4", "c2"]</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.tests" href="index.html">miplearn.components.tests</a></code></li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
<li><h3><a href="#header-functions">Functions</a></h3>
|
|
||||||
<ul class="">
|
|
||||||
<li><code><a title="miplearn.components.tests.test_lazy_static.test_fit" href="#miplearn.components.tests.test_lazy_static.test_fit">test_fit</a></code></li>
|
|
||||||
<li><code><a title="miplearn.components.tests.test_lazy_static.test_usage_with_solver" href="#miplearn.components.tests.test_lazy_static.test_usage_with_solver">test_usage_with_solver</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>
|
|
@ -1,174 +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.tests.test_objective 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.tests.test_objective</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
|
|
||||||
|
|
||||||
import numpy as np
|
|
||||||
|
|
||||||
from miplearn.classifiers import Regressor
|
|
||||||
from miplearn.components.objective import ObjectiveValueComponent
|
|
||||||
from miplearn.tests import get_test_pyomo_instances
|
|
||||||
|
|
||||||
|
|
||||||
def test_usage():
|
|
||||||
instances, models = get_test_pyomo_instances()
|
|
||||||
comp = ObjectiveValueComponent()
|
|
||||||
comp.fit(instances)
|
|
||||||
assert instances[0].training_data[0]["Lower bound"] == 1183.0
|
|
||||||
assert instances[0].training_data[0]["Upper bound"] == 1183.0
|
|
||||||
assert np.round(comp.predict(instances), 2).tolist() == [
|
|
||||||
[1183.0, 1183.0],
|
|
||||||
[1070.0, 1070.0],
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
def test_obj_evaluate():
|
|
||||||
instances, models = get_test_pyomo_instances()
|
|
||||||
reg = Mock(spec=Regressor)
|
|
||||||
reg.predict = Mock(return_value=np.array([1000.0, 1000.0]))
|
|
||||||
comp = ObjectiveValueComponent(regressor=reg)
|
|
||||||
comp.fit(instances)
|
|
||||||
ev = comp.evaluate(instances)
|
|
||||||
assert ev == {
|
|
||||||
"Lower bound": {
|
|
||||||
"Explained variance": 0.0,
|
|
||||||
"Max error": 183.0,
|
|
||||||
"Mean absolute error": 126.5,
|
|
||||||
"Mean squared error": 19194.5,
|
|
||||||
"Median absolute error": 126.5,
|
|
||||||
"R2": -5.012843605607331,
|
|
||||||
},
|
|
||||||
"Upper bound": {
|
|
||||||
"Explained variance": 0.0,
|
|
||||||
"Max error": 183.0,
|
|
||||||
"Mean absolute error": 126.5,
|
|
||||||
"Mean squared error": 19194.5,
|
|
||||||
"Median absolute error": 126.5,
|
|
||||||
"R2": -5.012843605607331,
|
|
||||||
},
|
|
||||||
}</code></pre>
|
|
||||||
</details>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
<h2 class="section-title" id="header-functions">Functions</h2>
|
|
||||||
<dl>
|
|
||||||
<dt id="miplearn.components.tests.test_objective.test_obj_evaluate"><code class="name flex">
|
|
||||||
<span>def <span class="ident">test_obj_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_obj_evaluate():
|
|
||||||
instances, models = get_test_pyomo_instances()
|
|
||||||
reg = Mock(spec=Regressor)
|
|
||||||
reg.predict = Mock(return_value=np.array([1000.0, 1000.0]))
|
|
||||||
comp = ObjectiveValueComponent(regressor=reg)
|
|
||||||
comp.fit(instances)
|
|
||||||
ev = comp.evaluate(instances)
|
|
||||||
assert ev == {
|
|
||||||
"Lower bound": {
|
|
||||||
"Explained variance": 0.0,
|
|
||||||
"Max error": 183.0,
|
|
||||||
"Mean absolute error": 126.5,
|
|
||||||
"Mean squared error": 19194.5,
|
|
||||||
"Median absolute error": 126.5,
|
|
||||||
"R2": -5.012843605607331,
|
|
||||||
},
|
|
||||||
"Upper bound": {
|
|
||||||
"Explained variance": 0.0,
|
|
||||||
"Max error": 183.0,
|
|
||||||
"Mean absolute error": 126.5,
|
|
||||||
"Mean squared error": 19194.5,
|
|
||||||
"Median absolute error": 126.5,
|
|
||||||
"R2": -5.012843605607331,
|
|
||||||
},
|
|
||||||
}</code></pre>
|
|
||||||
</details>
|
|
||||||
</dd>
|
|
||||||
<dt id="miplearn.components.tests.test_objective.test_usage"><code class="name flex">
|
|
||||||
<span>def <span class="ident">test_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_usage():
|
|
||||||
instances, models = get_test_pyomo_instances()
|
|
||||||
comp = ObjectiveValueComponent()
|
|
||||||
comp.fit(instances)
|
|
||||||
assert instances[0].training_data[0]["Lower bound"] == 1183.0
|
|
||||||
assert instances[0].training_data[0]["Upper bound"] == 1183.0
|
|
||||||
assert np.round(comp.predict(instances), 2).tolist() == [
|
|
||||||
[1183.0, 1183.0],
|
|
||||||
[1070.0, 1070.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.tests" href="index.html">miplearn.components.tests</a></code></li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
<li><h3><a href="#header-functions">Functions</a></h3>
|
|
||||||
<ul class="">
|
|
||||||
<li><code><a title="miplearn.components.tests.test_objective.test_obj_evaluate" href="#miplearn.components.tests.test_objective.test_obj_evaluate">test_obj_evaluate</a></code></li>
|
|
||||||
<li><code><a title="miplearn.components.tests.test_objective.test_usage" href="#miplearn.components.tests.test_objective.test_usage">test_usage</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>
|
|
@ -1,306 +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.tests.test_primal 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.tests.test_primal</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
|
|
||||||
|
|
||||||
import numpy as np
|
|
||||||
|
|
||||||
from miplearn.classifiers import Classifier
|
|
||||||
from miplearn.components.primal import PrimalSolutionComponent
|
|
||||||
from miplearn.tests import get_test_pyomo_instances
|
|
||||||
|
|
||||||
|
|
||||||
def test_predict():
|
|
||||||
instances, models = get_test_pyomo_instances()
|
|
||||||
comp = PrimalSolutionComponent()
|
|
||||||
comp.fit(instances)
|
|
||||||
solution = comp.predict(instances[0])
|
|
||||||
assert "x" in solution
|
|
||||||
assert 0 in solution["x"]
|
|
||||||
assert 1 in solution["x"]
|
|
||||||
assert 2 in solution["x"]
|
|
||||||
assert 3 in solution["x"]
|
|
||||||
|
|
||||||
|
|
||||||
def test_evaluate():
|
|
||||||
instances, models = get_test_pyomo_instances()
|
|
||||||
clf_zero = Mock(spec=Classifier)
|
|
||||||
clf_zero.predict_proba = Mock(
|
|
||||||
return_value=np.array(
|
|
||||||
[
|
|
||||||
[0.0, 1.0], # x[0]
|
|
||||||
[0.0, 1.0], # x[1]
|
|
||||||
[1.0, 0.0], # x[2]
|
|
||||||
[1.0, 0.0], # x[3]
|
|
||||||
]
|
|
||||||
)
|
|
||||||
)
|
|
||||||
clf_one = Mock(spec=Classifier)
|
|
||||||
clf_one.predict_proba = Mock(
|
|
||||||
return_value=np.array(
|
|
||||||
[
|
|
||||||
[1.0, 0.0], # x[0] instances[0]
|
|
||||||
[1.0, 0.0], # x[1] instances[0]
|
|
||||||
[0.0, 1.0], # x[2] instances[0]
|
|
||||||
[1.0, 0.0], # x[3] instances[0]
|
|
||||||
]
|
|
||||||
)
|
|
||||||
)
|
|
||||||
comp = PrimalSolutionComponent(classifier=[clf_zero, clf_one], threshold=0.50)
|
|
||||||
comp.fit(instances[:1])
|
|
||||||
assert comp.predict(instances[0]) == {"x": {0: 0, 1: 0, 2: 1, 3: None}}
|
|
||||||
assert instances[0].training_data[0]["Solution"] == {"x": {0: 1, 1: 0, 2: 1, 3: 1}}
|
|
||||||
ev = comp.evaluate(instances[:1])
|
|
||||||
assert ev == {
|
|
||||||
"Fix one": {
|
|
||||||
0: {
|
|
||||||
"Accuracy": 0.5,
|
|
||||||
"Condition negative": 1,
|
|
||||||
"Condition negative (%)": 25.0,
|
|
||||||
"Condition positive": 3,
|
|
||||||
"Condition positive (%)": 75.0,
|
|
||||||
"F1 score": 0.5,
|
|
||||||
"False negative": 2,
|
|
||||||
"False negative (%)": 50.0,
|
|
||||||
"False positive": 0,
|
|
||||||
"False positive (%)": 0.0,
|
|
||||||
"Precision": 1.0,
|
|
||||||
"Predicted negative": 3,
|
|
||||||
"Predicted negative (%)": 75.0,
|
|
||||||
"Predicted positive": 1,
|
|
||||||
"Predicted positive (%)": 25.0,
|
|
||||||
"Recall": 0.3333333333333333,
|
|
||||||
"True negative": 1,
|
|
||||||
"True negative (%)": 25.0,
|
|
||||||
"True positive": 1,
|
|
||||||
"True positive (%)": 25.0,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"Fix zero": {
|
|
||||||
0: {
|
|
||||||
"Accuracy": 0.75,
|
|
||||||
"Condition negative": 3,
|
|
||||||
"Condition negative (%)": 75.0,
|
|
||||||
"Condition positive": 1,
|
|
||||||
"Condition positive (%)": 25.0,
|
|
||||||
"F1 score": 0.6666666666666666,
|
|
||||||
"False negative": 0,
|
|
||||||
"False negative (%)": 0.0,
|
|
||||||
"False positive": 1,
|
|
||||||
"False positive (%)": 25.0,
|
|
||||||
"Precision": 0.5,
|
|
||||||
"Predicted negative": 2,
|
|
||||||
"Predicted negative (%)": 50.0,
|
|
||||||
"Predicted positive": 2,
|
|
||||||
"Predicted positive (%)": 50.0,
|
|
||||||
"Recall": 1.0,
|
|
||||||
"True negative": 2,
|
|
||||||
"True negative (%)": 50.0,
|
|
||||||
"True positive": 1,
|
|
||||||
"True positive (%)": 25.0,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def test_primal_parallel_fit():
|
|
||||||
instances, models = get_test_pyomo_instances()
|
|
||||||
comp = PrimalSolutionComponent()
|
|
||||||
comp.fit(instances, n_jobs=2)
|
|
||||||
assert len(comp.classifiers) == 2</code></pre>
|
|
||||||
</details>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
<h2 class="section-title" id="header-functions">Functions</h2>
|
|
||||||
<dl>
|
|
||||||
<dt id="miplearn.components.tests.test_primal.test_evaluate"><code class="name flex">
|
|
||||||
<span>def <span class="ident">test_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_evaluate():
|
|
||||||
instances, models = get_test_pyomo_instances()
|
|
||||||
clf_zero = Mock(spec=Classifier)
|
|
||||||
clf_zero.predict_proba = Mock(
|
|
||||||
return_value=np.array(
|
|
||||||
[
|
|
||||||
[0.0, 1.0], # x[0]
|
|
||||||
[0.0, 1.0], # x[1]
|
|
||||||
[1.0, 0.0], # x[2]
|
|
||||||
[1.0, 0.0], # x[3]
|
|
||||||
]
|
|
||||||
)
|
|
||||||
)
|
|
||||||
clf_one = Mock(spec=Classifier)
|
|
||||||
clf_one.predict_proba = Mock(
|
|
||||||
return_value=np.array(
|
|
||||||
[
|
|
||||||
[1.0, 0.0], # x[0] instances[0]
|
|
||||||
[1.0, 0.0], # x[1] instances[0]
|
|
||||||
[0.0, 1.0], # x[2] instances[0]
|
|
||||||
[1.0, 0.0], # x[3] instances[0]
|
|
||||||
]
|
|
||||||
)
|
|
||||||
)
|
|
||||||
comp = PrimalSolutionComponent(classifier=[clf_zero, clf_one], threshold=0.50)
|
|
||||||
comp.fit(instances[:1])
|
|
||||||
assert comp.predict(instances[0]) == {"x": {0: 0, 1: 0, 2: 1, 3: None}}
|
|
||||||
assert instances[0].training_data[0]["Solution"] == {"x": {0: 1, 1: 0, 2: 1, 3: 1}}
|
|
||||||
ev = comp.evaluate(instances[:1])
|
|
||||||
assert ev == {
|
|
||||||
"Fix one": {
|
|
||||||
0: {
|
|
||||||
"Accuracy": 0.5,
|
|
||||||
"Condition negative": 1,
|
|
||||||
"Condition negative (%)": 25.0,
|
|
||||||
"Condition positive": 3,
|
|
||||||
"Condition positive (%)": 75.0,
|
|
||||||
"F1 score": 0.5,
|
|
||||||
"False negative": 2,
|
|
||||||
"False negative (%)": 50.0,
|
|
||||||
"False positive": 0,
|
|
||||||
"False positive (%)": 0.0,
|
|
||||||
"Precision": 1.0,
|
|
||||||
"Predicted negative": 3,
|
|
||||||
"Predicted negative (%)": 75.0,
|
|
||||||
"Predicted positive": 1,
|
|
||||||
"Predicted positive (%)": 25.0,
|
|
||||||
"Recall": 0.3333333333333333,
|
|
||||||
"True negative": 1,
|
|
||||||
"True negative (%)": 25.0,
|
|
||||||
"True positive": 1,
|
|
||||||
"True positive (%)": 25.0,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"Fix zero": {
|
|
||||||
0: {
|
|
||||||
"Accuracy": 0.75,
|
|
||||||
"Condition negative": 3,
|
|
||||||
"Condition negative (%)": 75.0,
|
|
||||||
"Condition positive": 1,
|
|
||||||
"Condition positive (%)": 25.0,
|
|
||||||
"F1 score": 0.6666666666666666,
|
|
||||||
"False negative": 0,
|
|
||||||
"False negative (%)": 0.0,
|
|
||||||
"False positive": 1,
|
|
||||||
"False positive (%)": 25.0,
|
|
||||||
"Precision": 0.5,
|
|
||||||
"Predicted negative": 2,
|
|
||||||
"Predicted negative (%)": 50.0,
|
|
||||||
"Predicted positive": 2,
|
|
||||||
"Predicted positive (%)": 50.0,
|
|
||||||
"Recall": 1.0,
|
|
||||||
"True negative": 2,
|
|
||||||
"True negative (%)": 50.0,
|
|
||||||
"True positive": 1,
|
|
||||||
"True positive (%)": 25.0,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}</code></pre>
|
|
||||||
</details>
|
|
||||||
</dd>
|
|
||||||
<dt id="miplearn.components.tests.test_primal.test_predict"><code class="name flex">
|
|
||||||
<span>def <span class="ident">test_predict</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_predict():
|
|
||||||
instances, models = get_test_pyomo_instances()
|
|
||||||
comp = PrimalSolutionComponent()
|
|
||||||
comp.fit(instances)
|
|
||||||
solution = comp.predict(instances[0])
|
|
||||||
assert "x" in solution
|
|
||||||
assert 0 in solution["x"]
|
|
||||||
assert 1 in solution["x"]
|
|
||||||
assert 2 in solution["x"]
|
|
||||||
assert 3 in solution["x"]</code></pre>
|
|
||||||
</details>
|
|
||||||
</dd>
|
|
||||||
<dt id="miplearn.components.tests.test_primal.test_primal_parallel_fit"><code class="name flex">
|
|
||||||
<span>def <span class="ident">test_primal_parallel_fit</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_primal_parallel_fit():
|
|
||||||
instances, models = get_test_pyomo_instances()
|
|
||||||
comp = PrimalSolutionComponent()
|
|
||||||
comp.fit(instances, n_jobs=2)
|
|
||||||
assert len(comp.classifiers) == 2</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.tests" href="index.html">miplearn.components.tests</a></code></li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
<li><h3><a href="#header-functions">Functions</a></h3>
|
|
||||||
<ul class="">
|
|
||||||
<li><code><a title="miplearn.components.tests.test_primal.test_evaluate" href="#miplearn.components.tests.test_primal.test_evaluate">test_evaluate</a></code></li>
|
|
||||||
<li><code><a title="miplearn.components.tests.test_primal.test_predict" href="#miplearn.components.tests.test_primal.test_predict">test_predict</a></code></li>
|
|
||||||
<li><code><a title="miplearn.components.tests.test_primal.test_primal_parallel_fit" href="#miplearn.components.tests.test_primal.test_primal_parallel_fit">test_primal_parallel_fit</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>
|
|
@ -1,83 +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.problems.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.problems.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.</code></pre>
|
|
||||||
</details>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
<h2 class="section-title" id="header-submodules">Sub-modules</h2>
|
|
||||||
<dl>
|
|
||||||
<dt><code class="name"><a title="miplearn.problems.tests.test_knapsack" href="test_knapsack.html">miplearn.problems.tests.test_knapsack</a></code></dt>
|
|
||||||
<dd>
|
|
||||||
<section class="desc"></section>
|
|
||||||
</dd>
|
|
||||||
<dt><code class="name"><a title="miplearn.problems.tests.test_stab" href="test_stab.html">miplearn.problems.tests.test_stab</a></code></dt>
|
|
||||||
<dd>
|
|
||||||
<section class="desc"></section>
|
|
||||||
</dd>
|
|
||||||
<dt><code class="name"><a title="miplearn.problems.tests.test_tsp" href="test_tsp.html">miplearn.problems.tests.test_tsp</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.problems" href="../index.html">miplearn.problems</a></code></li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
<li><h3><a href="#header-submodules">Sub-modules</a></h3>
|
|
||||||
<ul>
|
|
||||||
<li><code><a title="miplearn.problems.tests.test_knapsack" href="test_knapsack.html">miplearn.problems.tests.test_knapsack</a></code></li>
|
|
||||||
<li><code><a title="miplearn.problems.tests.test_stab" href="test_stab.html">miplearn.problems.tests.test_stab</a></code></li>
|
|
||||||
<li><code><a title="miplearn.problems.tests.test_tsp" href="test_tsp.html">miplearn.problems.tests.test_tsp</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>
|
|
@ -1,115 +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.problems.tests.test_knapsack 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.problems.tests.test_knapsack</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 numpy as np
|
|
||||||
from scipy.stats import uniform, randint
|
|
||||||
|
|
||||||
from miplearn.problems.knapsack import MultiKnapsackGenerator
|
|
||||||
|
|
||||||
|
|
||||||
def test_knapsack_generator():
|
|
||||||
gen = MultiKnapsackGenerator(
|
|
||||||
n=randint(low=100, high=101),
|
|
||||||
m=randint(low=30, high=31),
|
|
||||||
w=randint(low=0, high=1000),
|
|
||||||
K=randint(low=500, high=501),
|
|
||||||
u=uniform(loc=1.0, scale=1.0),
|
|
||||||
alpha=uniform(loc=0.50, scale=0.0),
|
|
||||||
)
|
|
||||||
instances = gen.generate(100)
|
|
||||||
w_sum = sum(instance.weights for instance in instances) / len(instances)
|
|
||||||
b_sum = sum(instance.capacities for instance in instances) / len(instances)
|
|
||||||
assert round(np.mean(w_sum), -1) == 500.0
|
|
||||||
assert round(np.mean(b_sum), -3) == 25000.0</code></pre>
|
|
||||||
</details>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
<h2 class="section-title" id="header-functions">Functions</h2>
|
|
||||||
<dl>
|
|
||||||
<dt id="miplearn.problems.tests.test_knapsack.test_knapsack_generator"><code class="name flex">
|
|
||||||
<span>def <span class="ident">test_knapsack_generator</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_knapsack_generator():
|
|
||||||
gen = MultiKnapsackGenerator(
|
|
||||||
n=randint(low=100, high=101),
|
|
||||||
m=randint(low=30, high=31),
|
|
||||||
w=randint(low=0, high=1000),
|
|
||||||
K=randint(low=500, high=501),
|
|
||||||
u=uniform(loc=1.0, scale=1.0),
|
|
||||||
alpha=uniform(loc=0.50, scale=0.0),
|
|
||||||
)
|
|
||||||
instances = gen.generate(100)
|
|
||||||
w_sum = sum(instance.weights for instance in instances) / len(instances)
|
|
||||||
b_sum = sum(instance.capacities for instance in instances) / len(instances)
|
|
||||||
assert round(np.mean(w_sum), -1) == 500.0
|
|
||||||
assert round(np.mean(b_sum), -3) == 25000.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.problems.tests" href="index.html">miplearn.problems.tests</a></code></li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
<li><h3><a href="#header-functions">Functions</a></h3>
|
|
||||||
<ul class="">
|
|
||||||
<li><code><a title="miplearn.problems.tests.test_knapsack.test_knapsack_generator" href="#miplearn.problems.tests.test_knapsack.test_knapsack_generator">test_knapsack_generator</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>
|
|
@ -1,191 +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.problems.tests.test_stab 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.problems.tests.test_stab</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 networkx as nx
|
|
||||||
import numpy as np
|
|
||||||
from scipy.stats import uniform, randint
|
|
||||||
|
|
||||||
from miplearn.problems.stab import MaxWeightStableSetInstance
|
|
||||||
from miplearn.solvers.learning import LearningSolver
|
|
||||||
|
|
||||||
|
|
||||||
def test_stab():
|
|
||||||
graph = nx.cycle_graph(5)
|
|
||||||
weights = [1.0, 1.0, 1.0, 1.0, 1.0]
|
|
||||||
instance = MaxWeightStableSetInstance(graph, weights)
|
|
||||||
solver = LearningSolver()
|
|
||||||
stats = solver.solve(instance)
|
|
||||||
assert stats["Lower bound"] == 2.0
|
|
||||||
|
|
||||||
|
|
||||||
def test_stab_generator_fixed_graph():
|
|
||||||
np.random.seed(42)
|
|
||||||
from miplearn.problems.stab import MaxWeightStableSetGenerator
|
|
||||||
|
|
||||||
gen = MaxWeightStableSetGenerator(
|
|
||||||
w=uniform(loc=50.0, scale=10.0),
|
|
||||||
n=randint(low=10, high=11),
|
|
||||||
p=uniform(loc=0.05, scale=0.0),
|
|
||||||
fix_graph=True,
|
|
||||||
)
|
|
||||||
instances = gen.generate(1_000)
|
|
||||||
weights = np.array([instance.weights for instance in instances])
|
|
||||||
weights_avg_actual = np.round(np.average(weights, axis=0))
|
|
||||||
weights_avg_expected = [55.0] * 10
|
|
||||||
assert list(weights_avg_actual) == weights_avg_expected
|
|
||||||
|
|
||||||
|
|
||||||
def test_stab_generator_random_graph():
|
|
||||||
np.random.seed(42)
|
|
||||||
from miplearn.problems.stab import MaxWeightStableSetGenerator
|
|
||||||
|
|
||||||
gen = MaxWeightStableSetGenerator(
|
|
||||||
w=uniform(loc=50.0, scale=10.0),
|
|
||||||
n=randint(low=30, high=41),
|
|
||||||
p=uniform(loc=0.5, scale=0.0),
|
|
||||||
fix_graph=False,
|
|
||||||
)
|
|
||||||
instances = gen.generate(1_000)
|
|
||||||
n_nodes = [instance.graph.number_of_nodes() for instance in instances]
|
|
||||||
n_edges = [instance.graph.number_of_edges() for instance in instances]
|
|
||||||
assert np.round(np.mean(n_nodes)) == 35.0
|
|
||||||
assert np.round(np.mean(n_edges), -1) == 300.0</code></pre>
|
|
||||||
</details>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
<h2 class="section-title" id="header-functions">Functions</h2>
|
|
||||||
<dl>
|
|
||||||
<dt id="miplearn.problems.tests.test_stab.test_stab"><code class="name flex">
|
|
||||||
<span>def <span class="ident">test_stab</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_stab():
|
|
||||||
graph = nx.cycle_graph(5)
|
|
||||||
weights = [1.0, 1.0, 1.0, 1.0, 1.0]
|
|
||||||
instance = MaxWeightStableSetInstance(graph, weights)
|
|
||||||
solver = LearningSolver()
|
|
||||||
stats = solver.solve(instance)
|
|
||||||
assert stats["Lower bound"] == 2.0</code></pre>
|
|
||||||
</details>
|
|
||||||
</dd>
|
|
||||||
<dt id="miplearn.problems.tests.test_stab.test_stab_generator_fixed_graph"><code class="name flex">
|
|
||||||
<span>def <span class="ident">test_stab_generator_fixed_graph</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_stab_generator_fixed_graph():
|
|
||||||
np.random.seed(42)
|
|
||||||
from miplearn.problems.stab import MaxWeightStableSetGenerator
|
|
||||||
|
|
||||||
gen = MaxWeightStableSetGenerator(
|
|
||||||
w=uniform(loc=50.0, scale=10.0),
|
|
||||||
n=randint(low=10, high=11),
|
|
||||||
p=uniform(loc=0.05, scale=0.0),
|
|
||||||
fix_graph=True,
|
|
||||||
)
|
|
||||||
instances = gen.generate(1_000)
|
|
||||||
weights = np.array([instance.weights for instance in instances])
|
|
||||||
weights_avg_actual = np.round(np.average(weights, axis=0))
|
|
||||||
weights_avg_expected = [55.0] * 10
|
|
||||||
assert list(weights_avg_actual) == weights_avg_expected</code></pre>
|
|
||||||
</details>
|
|
||||||
</dd>
|
|
||||||
<dt id="miplearn.problems.tests.test_stab.test_stab_generator_random_graph"><code class="name flex">
|
|
||||||
<span>def <span class="ident">test_stab_generator_random_graph</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_stab_generator_random_graph():
|
|
||||||
np.random.seed(42)
|
|
||||||
from miplearn.problems.stab import MaxWeightStableSetGenerator
|
|
||||||
|
|
||||||
gen = MaxWeightStableSetGenerator(
|
|
||||||
w=uniform(loc=50.0, scale=10.0),
|
|
||||||
n=randint(low=30, high=41),
|
|
||||||
p=uniform(loc=0.5, scale=0.0),
|
|
||||||
fix_graph=False,
|
|
||||||
)
|
|
||||||
instances = gen.generate(1_000)
|
|
||||||
n_nodes = [instance.graph.number_of_nodes() for instance in instances]
|
|
||||||
n_edges = [instance.graph.number_of_edges() for instance in instances]
|
|
||||||
assert np.round(np.mean(n_nodes)) == 35.0
|
|
||||||
assert np.round(np.mean(n_edges), -1) == 300.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.problems.tests" href="index.html">miplearn.problems.tests</a></code></li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
<li><h3><a href="#header-functions">Functions</a></h3>
|
|
||||||
<ul class="">
|
|
||||||
<li><code><a title="miplearn.problems.tests.test_stab.test_stab" href="#miplearn.problems.tests.test_stab.test_stab">test_stab</a></code></li>
|
|
||||||
<li><code><a title="miplearn.problems.tests.test_stab.test_stab_generator_fixed_graph" href="#miplearn.problems.tests.test_stab.test_stab_generator_fixed_graph">test_stab_generator_fixed_graph</a></code></li>
|
|
||||||
<li><code><a title="miplearn.problems.tests.test_stab.test_stab_generator_random_graph" href="#miplearn.problems.tests.test_stab.test_stab_generator_random_graph">test_stab_generator_random_graph</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>
|
|
@ -1,242 +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.problems.tests.test_tsp 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.problems.tests.test_tsp</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 numpy as np
|
|
||||||
from numpy.linalg import norm
|
|
||||||
from scipy.spatial.distance import pdist, squareform
|
|
||||||
from scipy.stats import uniform, randint
|
|
||||||
|
|
||||||
from miplearn.problems.tsp import TravelingSalesmanGenerator, TravelingSalesmanInstance
|
|
||||||
from miplearn.solvers.learning import LearningSolver
|
|
||||||
|
|
||||||
|
|
||||||
def test_generator():
|
|
||||||
instances = TravelingSalesmanGenerator(
|
|
||||||
x=uniform(loc=0.0, scale=1000.0),
|
|
||||||
y=uniform(loc=0.0, scale=1000.0),
|
|
||||||
n=randint(low=100, high=101),
|
|
||||||
gamma=uniform(loc=0.95, scale=0.1),
|
|
||||||
fix_cities=True,
|
|
||||||
).generate(100)
|
|
||||||
assert len(instances) == 100
|
|
||||||
assert instances[0].n_cities == 100
|
|
||||||
assert norm(instances[0].distances - instances[0].distances.T) < 1e-6
|
|
||||||
d = [instance.distances[0, 1] for instance in instances]
|
|
||||||
assert np.std(d) > 0
|
|
||||||
|
|
||||||
|
|
||||||
def test_instance():
|
|
||||||
n_cities = 4
|
|
||||||
distances = np.array(
|
|
||||||
[
|
|
||||||
[0.0, 1.0, 2.0, 1.0],
|
|
||||||
[1.0, 0.0, 1.0, 2.0],
|
|
||||||
[2.0, 1.0, 0.0, 1.0],
|
|
||||||
[1.0, 2.0, 1.0, 0.0],
|
|
||||||
]
|
|
||||||
)
|
|
||||||
instance = TravelingSalesmanInstance(n_cities, distances)
|
|
||||||
solver = LearningSolver()
|
|
||||||
stats = solver.solve(instance)
|
|
||||||
x = instance.training_data[0]["Solution"]["x"]
|
|
||||||
assert x[0, 1] == 1.0
|
|
||||||
assert x[0, 2] == 0.0
|
|
||||||
assert x[0, 3] == 1.0
|
|
||||||
assert x[1, 2] == 1.0
|
|
||||||
assert x[1, 3] == 0.0
|
|
||||||
assert x[2, 3] == 1.0
|
|
||||||
assert stats["Lower bound"] == 4.0
|
|
||||||
assert stats["Upper bound"] == 4.0
|
|
||||||
|
|
||||||
|
|
||||||
def test_subtour():
|
|
||||||
n_cities = 6
|
|
||||||
cities = np.array(
|
|
||||||
[
|
|
||||||
[0.0, 0.0],
|
|
||||||
[1.0, 0.0],
|
|
||||||
[2.0, 0.0],
|
|
||||||
[3.0, 0.0],
|
|
||||||
[0.0, 1.0],
|
|
||||||
[3.0, 1.0],
|
|
||||||
]
|
|
||||||
)
|
|
||||||
distances = squareform(pdist(cities))
|
|
||||||
instance = TravelingSalesmanInstance(n_cities, distances)
|
|
||||||
solver = LearningSolver()
|
|
||||||
solver.solve(instance)
|
|
||||||
assert hasattr(instance, "found_violated_lazy_constraints")
|
|
||||||
assert hasattr(instance, "found_violated_user_cuts")
|
|
||||||
x = instance.training_data[0]["Solution"]["x"]
|
|
||||||
assert x[0, 1] == 1.0
|
|
||||||
assert x[0, 4] == 1.0
|
|
||||||
assert x[1, 2] == 1.0
|
|
||||||
assert x[2, 3] == 1.0
|
|
||||||
assert x[3, 5] == 1.0
|
|
||||||
assert x[4, 5] == 1.0
|
|
||||||
solver.fit([instance])
|
|
||||||
solver.solve(instance)</code></pre>
|
|
||||||
</details>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
<h2 class="section-title" id="header-functions">Functions</h2>
|
|
||||||
<dl>
|
|
||||||
<dt id="miplearn.problems.tests.test_tsp.test_generator"><code class="name flex">
|
|
||||||
<span>def <span class="ident">test_generator</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_generator():
|
|
||||||
instances = TravelingSalesmanGenerator(
|
|
||||||
x=uniform(loc=0.0, scale=1000.0),
|
|
||||||
y=uniform(loc=0.0, scale=1000.0),
|
|
||||||
n=randint(low=100, high=101),
|
|
||||||
gamma=uniform(loc=0.95, scale=0.1),
|
|
||||||
fix_cities=True,
|
|
||||||
).generate(100)
|
|
||||||
assert len(instances) == 100
|
|
||||||
assert instances[0].n_cities == 100
|
|
||||||
assert norm(instances[0].distances - instances[0].distances.T) < 1e-6
|
|
||||||
d = [instance.distances[0, 1] for instance in instances]
|
|
||||||
assert np.std(d) > 0</code></pre>
|
|
||||||
</details>
|
|
||||||
</dd>
|
|
||||||
<dt id="miplearn.problems.tests.test_tsp.test_instance"><code class="name flex">
|
|
||||||
<span>def <span class="ident">test_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_instance():
|
|
||||||
n_cities = 4
|
|
||||||
distances = np.array(
|
|
||||||
[
|
|
||||||
[0.0, 1.0, 2.0, 1.0],
|
|
||||||
[1.0, 0.0, 1.0, 2.0],
|
|
||||||
[2.0, 1.0, 0.0, 1.0],
|
|
||||||
[1.0, 2.0, 1.0, 0.0],
|
|
||||||
]
|
|
||||||
)
|
|
||||||
instance = TravelingSalesmanInstance(n_cities, distances)
|
|
||||||
solver = LearningSolver()
|
|
||||||
stats = solver.solve(instance)
|
|
||||||
x = instance.training_data[0]["Solution"]["x"]
|
|
||||||
assert x[0, 1] == 1.0
|
|
||||||
assert x[0, 2] == 0.0
|
|
||||||
assert x[0, 3] == 1.0
|
|
||||||
assert x[1, 2] == 1.0
|
|
||||||
assert x[1, 3] == 0.0
|
|
||||||
assert x[2, 3] == 1.0
|
|
||||||
assert stats["Lower bound"] == 4.0
|
|
||||||
assert stats["Upper bound"] == 4.0</code></pre>
|
|
||||||
</details>
|
|
||||||
</dd>
|
|
||||||
<dt id="miplearn.problems.tests.test_tsp.test_subtour"><code class="name flex">
|
|
||||||
<span>def <span class="ident">test_subtour</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_subtour():
|
|
||||||
n_cities = 6
|
|
||||||
cities = np.array(
|
|
||||||
[
|
|
||||||
[0.0, 0.0],
|
|
||||||
[1.0, 0.0],
|
|
||||||
[2.0, 0.0],
|
|
||||||
[3.0, 0.0],
|
|
||||||
[0.0, 1.0],
|
|
||||||
[3.0, 1.0],
|
|
||||||
]
|
|
||||||
)
|
|
||||||
distances = squareform(pdist(cities))
|
|
||||||
instance = TravelingSalesmanInstance(n_cities, distances)
|
|
||||||
solver = LearningSolver()
|
|
||||||
solver.solve(instance)
|
|
||||||
assert hasattr(instance, "found_violated_lazy_constraints")
|
|
||||||
assert hasattr(instance, "found_violated_user_cuts")
|
|
||||||
x = instance.training_data[0]["Solution"]["x"]
|
|
||||||
assert x[0, 1] == 1.0
|
|
||||||
assert x[0, 4] == 1.0
|
|
||||||
assert x[1, 2] == 1.0
|
|
||||||
assert x[2, 3] == 1.0
|
|
||||||
assert x[3, 5] == 1.0
|
|
||||||
assert x[4, 5] == 1.0
|
|
||||||
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.problems.tests" href="index.html">miplearn.problems.tests</a></code></li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
<li><h3><a href="#header-functions">Functions</a></h3>
|
|
||||||
<ul class="">
|
|
||||||
<li><code><a title="miplearn.problems.tests.test_tsp.test_generator" href="#miplearn.problems.tests.test_tsp.test_generator">test_generator</a></code></li>
|
|
||||||
<li><code><a title="miplearn.problems.tests.test_tsp.test_instance" href="#miplearn.problems.tests.test_tsp.test_instance">test_instance</a></code></li>
|
|
||||||
<li><code><a title="miplearn.problems.tests.test_tsp.test_subtour" href="#miplearn.problems.tests.test_tsp.test_subtour">test_subtour</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>
|
|
@ -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) -> 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] >= 2)
|
|
||||||
return model
|
|
||||||
|
|
||||||
|
|
||||||
class InfeasibleGurobiInstance(Instance):
|
|
||||||
def to_model(self) -> Any:
|
|
||||||
import gurobipy as gp
|
|
||||||
from gurobipy import GRB
|
|
||||||
|
|
||||||
model = gp.Model()
|
|
||||||
x = model.addVars(1, vtype=GRB.BINARY, name="x")
|
|
||||||
model.addConstr(x[0] >= 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() -> 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) -> Any:
|
|
||||||
import gurobipy as gp
|
|
||||||
from gurobipy import GRB
|
|
||||||
|
|
||||||
model = gp.Model()
|
|
||||||
x = model.addVars(1, vtype=GRB.BINARY, name="x")
|
|
||||||
model.addConstr(x[0] >= 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) -> 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] >= 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>
|
|
@ -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("Hello world")
|
|
||||||
assert sys.stdout == original_stdout
|
|
||||||
assert io.getvalue() == "Hello world\n"
|
|
||||||
|
|
||||||
|
|
||||||
def test_internal_solver_warm_starts():
|
|
||||||
for solver_class in _get_internal_solvers():
|
|
||||||
logger.info("Solver: %s" % solver_class)
|
|
||||||
instance = _get_knapsack_instance(solver_class)
|
|
||||||
model = instance.to_model()
|
|
||||||
solver = solver_class()
|
|
||||||
solver.set_instance(instance, model)
|
|
||||||
solver.set_warm_start(
|
|
||||||
{
|
|
||||||
"x": {
|
|
||||||
0: 1.0,
|
|
||||||
1: 0.0,
|
|
||||||
2: 0.0,
|
|
||||||
3: 1.0,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
stats = solver.solve(tee=True)
|
|
||||||
if stats["Warm start value"] is not None:
|
|
||||||
assert stats["Warm start value"] == 725.0
|
|
||||||
else:
|
|
||||||
warn(f"{solver_class.__name__} should set warm start value")
|
|
||||||
|
|
||||||
solver.set_warm_start(
|
|
||||||
{
|
|
||||||
"x": {
|
|
||||||
0: 1.0,
|
|
||||||
1: 1.0,
|
|
||||||
2: 1.0,
|
|
||||||
3: 1.0,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
stats = solver.solve(tee=True)
|
|
||||||
assert stats["Warm start value"] is None
|
|
||||||
|
|
||||||
solver.fix(
|
|
||||||
{
|
|
||||||
"x": {
|
|
||||||
0: 1.0,
|
|
||||||
1: 0.0,
|
|
||||||
2: 0.0,
|
|
||||||
3: 1.0,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
stats = solver.solve(tee=True)
|
|
||||||
assert stats["Lower bound"] == 725.0
|
|
||||||
assert stats["Upper bound"] == 725.0
|
|
||||||
|
|
||||||
|
|
||||||
def test_internal_solver():
|
|
||||||
for solver_class in _get_internal_solvers():
|
|
||||||
logger.info("Solver: %s" % 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["Optimal value"], 3) == 1287.923
|
|
||||||
assert len(stats["Log"]) > 100
|
|
||||||
|
|
||||||
solution = solver.get_solution()
|
|
||||||
assert round(solution["x"][0], 3) == 1.000
|
|
||||||
assert round(solution["x"][1], 3) == 0.923
|
|
||||||
assert round(solution["x"][2], 3) == 1.000
|
|
||||||
assert round(solution["x"][3], 3) == 0.000
|
|
||||||
|
|
||||||
stats = solver.solve(tee=True)
|
|
||||||
assert not solver.is_infeasible()
|
|
||||||
assert len(stats["Log"]) > 100
|
|
||||||
assert stats["Lower bound"] == 1183.0
|
|
||||||
assert stats["Upper bound"] == 1183.0
|
|
||||||
assert stats["Sense"] == "max"
|
|
||||||
assert isinstance(stats["Wallclock time"], float)
|
|
||||||
|
|
||||||
solution = solver.get_solution()
|
|
||||||
assert solution["x"][0] == 1.0
|
|
||||||
assert solution["x"][1] == 0.0
|
|
||||||
assert solution["x"][2] == 1.0
|
|
||||||
assert solution["x"][3] == 1.0
|
|
||||||
|
|
||||||
# Add a brand new constraint
|
|
||||||
if isinstance(solver, BasePyomoSolver):
|
|
||||||
model.cut = pe.Constraint(expr=model.x[0] <= 0.0, name="cut")
|
|
||||||
solver.add_constraint(model.cut)
|
|
||||||
elif isinstance(solver, GurobiSolver):
|
|
||||||
x = model.getVarByName("x[0]")
|
|
||||||
solver.add_constraint(x <= 0.0, name="cut")
|
|
||||||
else:
|
|
||||||
raise Exception("Illegal state")
|
|
||||||
|
|
||||||
# New constraint should affect solution and should be listed in
|
|
||||||
# constraint ids
|
|
||||||
assert solver.get_constraint_ids() == ["eq_capacity", "cut"]
|
|
||||||
stats = solver.solve()
|
|
||||||
assert stats["Lower bound"] == 1030.0
|
|
||||||
|
|
||||||
assert solver.get_sense() == "max"
|
|
||||||
assert solver.get_constraint_sense("cut") == "<"
|
|
||||||
assert solver.get_constraint_sense("eq_capacity") == "<"
|
|
||||||
|
|
||||||
# Verify slacks
|
|
||||||
assert solver.get_inequality_slacks() == {
|
|
||||||
"cut": 0.0,
|
|
||||||
"eq_capacity": 3.0,
|
|
||||||
}
|
|
||||||
|
|
||||||
if isinstance(solver, GurobiSolver):
|
|
||||||
# Extract the new constraint
|
|
||||||
cobj = solver.extract_constraint("cut")
|
|
||||||
|
|
||||||
# New constraint should no longer affect solution and should no longer
|
|
||||||
# be listed in constraint ids
|
|
||||||
assert solver.get_constraint_ids() == ["eq_capacity"]
|
|
||||||
stats = solver.solve()
|
|
||||||
assert stats["Lower bound"] == 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() == ["eq_capacity", "cut"]
|
|
||||||
stats = solver.solve()
|
|
||||||
assert stats["Lower bound"] == 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("cut", "=")
|
|
||||||
stats = solver.solve()
|
|
||||||
assert round(stats["Lower bound"]) == 1030.0
|
|
||||||
assert round(solver.get_dual("eq_capacity")) == 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["Lower bound"]) == 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["Upper bound"] is None
|
|
||||||
assert stats["Lower bound"] is None
|
|
||||||
|
|
||||||
stats = solver.solve_lp()
|
|
||||||
assert solver.get_solution() is None
|
|
||||||
assert stats["Optimal value"] is None
|
|
||||||
assert solver.get_value("x", 0) is None
|
|
||||||
|
|
||||||
|
|
||||||
def test_iteration_cb():
|
|
||||||
for solver_class in _get_internal_solvers():
|
|
||||||
logger.info("Solver: %s" % 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 < 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["Upper bound"] is None
|
|
||||||
assert stats["Lower bound"] is None
|
|
||||||
|
|
||||||
stats = solver.solve_lp()
|
|
||||||
assert solver.get_solution() is None
|
|
||||||
assert stats["Optimal value"] is None
|
|
||||||
assert solver.get_value("x", 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("Solver: %s" % 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["Optimal value"], 3) == 1287.923
|
|
||||||
assert len(stats["Log"]) > 100
|
|
||||||
|
|
||||||
solution = solver.get_solution()
|
|
||||||
assert round(solution["x"][0], 3) == 1.000
|
|
||||||
assert round(solution["x"][1], 3) == 0.923
|
|
||||||
assert round(solution["x"][2], 3) == 1.000
|
|
||||||
assert round(solution["x"][3], 3) == 0.000
|
|
||||||
|
|
||||||
stats = solver.solve(tee=True)
|
|
||||||
assert not solver.is_infeasible()
|
|
||||||
assert len(stats["Log"]) > 100
|
|
||||||
assert stats["Lower bound"] == 1183.0
|
|
||||||
assert stats["Upper bound"] == 1183.0
|
|
||||||
assert stats["Sense"] == "max"
|
|
||||||
assert isinstance(stats["Wallclock time"], float)
|
|
||||||
|
|
||||||
solution = solver.get_solution()
|
|
||||||
assert solution["x"][0] == 1.0
|
|
||||||
assert solution["x"][1] == 0.0
|
|
||||||
assert solution["x"][2] == 1.0
|
|
||||||
assert solution["x"][3] == 1.0
|
|
||||||
|
|
||||||
# Add a brand new constraint
|
|
||||||
if isinstance(solver, BasePyomoSolver):
|
|
||||||
model.cut = pe.Constraint(expr=model.x[0] <= 0.0, name="cut")
|
|
||||||
solver.add_constraint(model.cut)
|
|
||||||
elif isinstance(solver, GurobiSolver):
|
|
||||||
x = model.getVarByName("x[0]")
|
|
||||||
solver.add_constraint(x <= 0.0, name="cut")
|
|
||||||
else:
|
|
||||||
raise Exception("Illegal state")
|
|
||||||
|
|
||||||
# New constraint should affect solution and should be listed in
|
|
||||||
# constraint ids
|
|
||||||
assert solver.get_constraint_ids() == ["eq_capacity", "cut"]
|
|
||||||
stats = solver.solve()
|
|
||||||
assert stats["Lower bound"] == 1030.0
|
|
||||||
|
|
||||||
assert solver.get_sense() == "max"
|
|
||||||
assert solver.get_constraint_sense("cut") == "<"
|
|
||||||
assert solver.get_constraint_sense("eq_capacity") == "<"
|
|
||||||
|
|
||||||
# Verify slacks
|
|
||||||
assert solver.get_inequality_slacks() == {
|
|
||||||
"cut": 0.0,
|
|
||||||
"eq_capacity": 3.0,
|
|
||||||
}
|
|
||||||
|
|
||||||
if isinstance(solver, GurobiSolver):
|
|
||||||
# Extract the new constraint
|
|
||||||
cobj = solver.extract_constraint("cut")
|
|
||||||
|
|
||||||
# New constraint should no longer affect solution and should no longer
|
|
||||||
# be listed in constraint ids
|
|
||||||
assert solver.get_constraint_ids() == ["eq_capacity"]
|
|
||||||
stats = solver.solve()
|
|
||||||
assert stats["Lower bound"] == 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() == ["eq_capacity", "cut"]
|
|
||||||
stats = solver.solve()
|
|
||||||
assert stats["Lower bound"] == 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("cut", "=")
|
|
||||||
stats = solver.solve()
|
|
||||||
assert round(stats["Lower bound"]) == 1030.0
|
|
||||||
assert round(solver.get_dual("eq_capacity")) == 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("Solver: %s" % solver_class)
|
|
||||||
instance = _get_knapsack_instance(solver_class)
|
|
||||||
model = instance.to_model()
|
|
||||||
solver = solver_class()
|
|
||||||
solver.set_instance(instance, model)
|
|
||||||
solver.set_warm_start(
|
|
||||||
{
|
|
||||||
"x": {
|
|
||||||
0: 1.0,
|
|
||||||
1: 0.0,
|
|
||||||
2: 0.0,
|
|
||||||
3: 1.0,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
stats = solver.solve(tee=True)
|
|
||||||
if stats["Warm start value"] is not None:
|
|
||||||
assert stats["Warm start value"] == 725.0
|
|
||||||
else:
|
|
||||||
warn(f"{solver_class.__name__} should set warm start value")
|
|
||||||
|
|
||||||
solver.set_warm_start(
|
|
||||||
{
|
|
||||||
"x": {
|
|
||||||
0: 1.0,
|
|
||||||
1: 1.0,
|
|
||||||
2: 1.0,
|
|
||||||
3: 1.0,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
stats = solver.solve(tee=True)
|
|
||||||
assert stats["Warm start value"] is None
|
|
||||||
|
|
||||||
solver.fix(
|
|
||||||
{
|
|
||||||
"x": {
|
|
||||||
0: 1.0,
|
|
||||||
1: 0.0,
|
|
||||||
2: 0.0,
|
|
||||||
3: 1.0,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
stats = solver.solve(tee=True)
|
|
||||||
assert stats["Lower bound"] == 725.0
|
|
||||||
assert stats["Upper bound"] == 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("Solver: %s" % 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 < 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("Hello world")
|
|
||||||
assert sys.stdout == original_stdout
|
|
||||||
assert io.getvalue() == "Hello world\n"</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["Lower bound"]) == 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>
|
|
@ -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("x[0] = %.f" % cb_solver.get_value("x", 0))
|
|
||||||
cobj = (cb_model.getVarByName("x[0]") * 1.0, "<", 0.0, "cut")
|
|
||||||
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["x"][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("x[0] = %.f" % cb_solver.get_value("x", 0))
|
|
||||||
cobj = (cb_model.getVarByName("x[0]") * 1.0, "<", 0.0, "cut")
|
|
||||||
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["x"][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>
|
|
@ -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 ["exact", "heuristic"]:
|
|
||||||
for internal_solver in _get_internal_solvers():
|
|
||||||
logger.info("Solver: %s" % 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["Solution"]["x"][0] == 1.0
|
|
||||||
assert data["Solution"]["x"][1] == 0.0
|
|
||||||
assert data["Solution"]["x"][2] == 1.0
|
|
||||||
assert data["Solution"]["x"][3] == 1.0
|
|
||||||
assert data["Lower bound"] == 1183.0
|
|
||||||
assert data["Upper bound"] == 1183.0
|
|
||||||
assert round(data["LP solution"]["x"][0], 3) == 1.000
|
|
||||||
assert round(data["LP solution"]["x"][1], 3) == 0.923
|
|
||||||
assert round(data["LP solution"]["x"][2], 3) == 1.000
|
|
||||||
assert round(data["LP solution"]["x"][3], 3) == 0.000
|
|
||||||
assert round(data["LP value"], 3) == 1287.923
|
|
||||||
assert len(data["MIP log"]) > 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("Solver: %s" % 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["Solution"]["x"].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=".pkl", 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], "rb") as file:
|
|
||||||
instance = pickle.load(file)
|
|
||||||
assert len(instance.training_data) > 0
|
|
||||||
|
|
||||||
# Test: parallel_solve
|
|
||||||
solver.parallel_solve(filenames)
|
|
||||||
for filename in filenames:
|
|
||||||
with open(filename, "rb") as file:
|
|
||||||
instance = pickle.load(file)
|
|
||||||
assert len(instance.training_data) > 0
|
|
||||||
|
|
||||||
# Test: solve (with specified output)
|
|
||||||
output = [f + ".out" 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=".pkl", 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["Lower bound"] == stats["Predicted LB"]
|
|
||||||
|
|
||||||
|
|
||||||
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 ["exact", "heuristic"]:
|
|
||||||
for internal_solver in _get_internal_solvers():
|
|
||||||
logger.info("Solver: %s" % 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["Solution"]["x"][0] == 1.0
|
|
||||||
assert data["Solution"]["x"][1] == 0.0
|
|
||||||
assert data["Solution"]["x"][2] == 1.0
|
|
||||||
assert data["Solution"]["x"][3] == 1.0
|
|
||||||
assert data["Lower bound"] == 1183.0
|
|
||||||
assert data["Upper bound"] == 1183.0
|
|
||||||
assert round(data["LP solution"]["x"][0], 3) == 1.000
|
|
||||||
assert round(data["LP solution"]["x"][1], 3) == 0.923
|
|
||||||
assert round(data["LP solution"]["x"][2], 3) == 1.000
|
|
||||||
assert round(data["LP solution"]["x"][3], 3) == 0.000
|
|
||||||
assert round(data["LP value"], 3) == 1287.923
|
|
||||||
assert len(data["MIP log"]) > 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["Solution"]["x"].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=".pkl", 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["Lower bound"] == stats["Predicted LB"]</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=".pkl", 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], "rb") as file:
|
|
||||||
instance = pickle.load(file)
|
|
||||||
assert len(instance.training_data) > 0
|
|
||||||
|
|
||||||
# Test: parallel_solve
|
|
||||||
solver.parallel_solve(filenames)
|
|
||||||
for filename in filenames:
|
|
||||||
with open(filename, "rb") as file:
|
|
||||||
instance = pickle.load(file)
|
|
||||||
assert len(instance.training_data) > 0
|
|
||||||
|
|
||||||
# Test: solve (with specified output)
|
|
||||||
output = [f + ".out" 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("Solver: %s" % 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>
|
|
@ -1,138 +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.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.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 miplearn.problems.knapsack import KnapsackInstance
|
|
||||||
from miplearn.solvers.learning import LearningSolver
|
|
||||||
|
|
||||||
|
|
||||||
def get_test_pyomo_instances():
|
|
||||||
instances = [
|
|
||||||
KnapsackInstance(
|
|
||||||
weights=[23.0, 26.0, 20.0, 18.0],
|
|
||||||
prices=[505.0, 352.0, 458.0, 220.0],
|
|
||||||
capacity=67.0,
|
|
||||||
),
|
|
||||||
KnapsackInstance(
|
|
||||||
weights=[25.0, 30.0, 22.0, 18.0],
|
|
||||||
prices=[500.0, 365.0, 420.0, 150.0],
|
|
||||||
capacity=70.0,
|
|
||||||
),
|
|
||||||
]
|
|
||||||
models = [instance.to_model() for instance in instances]
|
|
||||||
solver = LearningSolver()
|
|
||||||
for i in range(len(instances)):
|
|
||||||
solver.solve(instances[i], models[i])
|
|
||||||
return instances, models</code></pre>
|
|
||||||
</details>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
<h2 class="section-title" id="header-submodules">Sub-modules</h2>
|
|
||||||
<dl>
|
|
||||||
<dt><code class="name"><a title="miplearn.tests.test_benchmark" href="test_benchmark.html">miplearn.tests.test_benchmark</a></code></dt>
|
|
||||||
<dd>
|
|
||||||
<section class="desc"></section>
|
|
||||||
</dd>
|
|
||||||
<dt><code class="name"><a title="miplearn.tests.test_extractors" href="test_extractors.html">miplearn.tests.test_extractors</a></code></dt>
|
|
||||||
<dd>
|
|
||||||
<section class="desc"></section>
|
|
||||||
</dd>
|
|
||||||
</dl>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
<h2 class="section-title" id="header-functions">Functions</h2>
|
|
||||||
<dl>
|
|
||||||
<dt id="miplearn.tests.get_test_pyomo_instances"><code class="name flex">
|
|
||||||
<span>def <span class="ident">get_test_pyomo_instances</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 get_test_pyomo_instances():
|
|
||||||
instances = [
|
|
||||||
KnapsackInstance(
|
|
||||||
weights=[23.0, 26.0, 20.0, 18.0],
|
|
||||||
prices=[505.0, 352.0, 458.0, 220.0],
|
|
||||||
capacity=67.0,
|
|
||||||
),
|
|
||||||
KnapsackInstance(
|
|
||||||
weights=[25.0, 30.0, 22.0, 18.0],
|
|
||||||
prices=[500.0, 365.0, 420.0, 150.0],
|
|
||||||
capacity=70.0,
|
|
||||||
),
|
|
||||||
]
|
|
||||||
models = [instance.to_model() for instance in instances]
|
|
||||||
solver = LearningSolver()
|
|
||||||
for i in range(len(instances)):
|
|
||||||
solver.solve(instances[i], models[i])
|
|
||||||
return instances, models</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" href="../index.html">miplearn</a></code></li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
<li><h3><a href="#header-submodules">Sub-modules</a></h3>
|
|
||||||
<ul>
|
|
||||||
<li><code><a title="miplearn.tests.test_benchmark" href="test_benchmark.html">miplearn.tests.test_benchmark</a></code></li>
|
|
||||||
<li><code><a title="miplearn.tests.test_extractors" href="test_extractors.html">miplearn.tests.test_extractors</a></code></li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
<li><h3><a href="#header-functions">Functions</a></h3>
|
|
||||||
<ul class="">
|
|
||||||
<li><code><a title="miplearn.tests.get_test_pyomo_instances" href="#miplearn.tests.get_test_pyomo_instances">get_test_pyomo_instances</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>
|
|
@ -1,134 +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.tests.test_benchmark 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.tests.test_benchmark</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 os.path
|
|
||||||
|
|
||||||
from miplearn.benchmark import BenchmarkRunner
|
|
||||||
from miplearn.problems.stab import MaxWeightStableSetGenerator
|
|
||||||
from scipy.stats import randint
|
|
||||||
|
|
||||||
from miplearn.solvers.learning import LearningSolver
|
|
||||||
|
|
||||||
|
|
||||||
def test_benchmark():
|
|
||||||
# Generate training and test instances
|
|
||||||
generator = MaxWeightStableSetGenerator(n=randint(low=25, high=26))
|
|
||||||
train_instances = generator.generate(5)
|
|
||||||
test_instances = generator.generate(3)
|
|
||||||
|
|
||||||
# Training phase...
|
|
||||||
training_solver = LearningSolver()
|
|
||||||
training_solver.parallel_solve(train_instances, n_jobs=10)
|
|
||||||
|
|
||||||
# Test phase...
|
|
||||||
test_solvers = {
|
|
||||||
"Strategy A": LearningSolver(),
|
|
||||||
"Strategy B": LearningSolver(),
|
|
||||||
}
|
|
||||||
benchmark = BenchmarkRunner(test_solvers)
|
|
||||||
benchmark.fit(train_instances)
|
|
||||||
benchmark.parallel_solve(test_instances, n_jobs=2, n_trials=2)
|
|
||||||
assert benchmark.results.values.shape == (12, 14)
|
|
||||||
|
|
||||||
benchmark.write_csv("/tmp/benchmark.csv")
|
|
||||||
assert os.path.isfile("/tmp/benchmark.csv")</code></pre>
|
|
||||||
</details>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
<h2 class="section-title" id="header-functions">Functions</h2>
|
|
||||||
<dl>
|
|
||||||
<dt id="miplearn.tests.test_benchmark.test_benchmark"><code class="name flex">
|
|
||||||
<span>def <span class="ident">test_benchmark</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_benchmark():
|
|
||||||
# Generate training and test instances
|
|
||||||
generator = MaxWeightStableSetGenerator(n=randint(low=25, high=26))
|
|
||||||
train_instances = generator.generate(5)
|
|
||||||
test_instances = generator.generate(3)
|
|
||||||
|
|
||||||
# Training phase...
|
|
||||||
training_solver = LearningSolver()
|
|
||||||
training_solver.parallel_solve(train_instances, n_jobs=10)
|
|
||||||
|
|
||||||
# Test phase...
|
|
||||||
test_solvers = {
|
|
||||||
"Strategy A": LearningSolver(),
|
|
||||||
"Strategy B": LearningSolver(),
|
|
||||||
}
|
|
||||||
benchmark = BenchmarkRunner(test_solvers)
|
|
||||||
benchmark.fit(train_instances)
|
|
||||||
benchmark.parallel_solve(test_instances, n_jobs=2, n_trials=2)
|
|
||||||
assert benchmark.results.values.shape == (12, 14)
|
|
||||||
|
|
||||||
benchmark.write_csv("/tmp/benchmark.csv")
|
|
||||||
assert os.path.isfile("/tmp/benchmark.csv")</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.tests" href="index.html">miplearn.tests</a></code></li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
<li><h3><a href="#header-functions">Functions</a></h3>
|
|
||||||
<ul class="">
|
|
||||||
<li><code><a title="miplearn.tests.test_benchmark.test_benchmark" href="#miplearn.tests.test_benchmark.test_benchmark">test_benchmark</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>
|
|
@ -1,201 +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.tests.test_extractors 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.tests.test_extractors</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 numpy as np
|
|
||||||
|
|
||||||
from miplearn.extractors import (
|
|
||||||
SolutionExtractor,
|
|
||||||
InstanceFeaturesExtractor,
|
|
||||||
VariableFeaturesExtractor,
|
|
||||||
)
|
|
||||||
from miplearn.problems.knapsack import KnapsackInstance
|
|
||||||
from miplearn.solvers.learning import LearningSolver
|
|
||||||
|
|
||||||
|
|
||||||
def _get_instances():
|
|
||||||
instances = [
|
|
||||||
KnapsackInstance(
|
|
||||||
weights=[1.0, 2.0, 3.0],
|
|
||||||
prices=[10.0, 20.0, 30.0],
|
|
||||||
capacity=2.5,
|
|
||||||
),
|
|
||||||
KnapsackInstance(
|
|
||||||
weights=[3.0, 4.0, 5.0],
|
|
||||||
prices=[20.0, 30.0, 40.0],
|
|
||||||
capacity=4.5,
|
|
||||||
),
|
|
||||||
]
|
|
||||||
models = [instance.to_model() for instance in instances]
|
|
||||||
solver = LearningSolver()
|
|
||||||
for (i, instance) in enumerate(instances):
|
|
||||||
solver.solve(instances[i], models[i])
|
|
||||||
return instances, models
|
|
||||||
|
|
||||||
|
|
||||||
def test_solution_extractor():
|
|
||||||
instances, models = _get_instances()
|
|
||||||
features = SolutionExtractor().extract(instances)
|
|
||||||
assert isinstance(features, dict)
|
|
||||||
assert "default" in features.keys()
|
|
||||||
assert isinstance(features["default"], np.ndarray)
|
|
||||||
assert features["default"].shape == (6, 2)
|
|
||||||
assert features["default"].ravel().tolist() == [
|
|
||||||
1.0,
|
|
||||||
0.0,
|
|
||||||
0.0,
|
|
||||||
1.0,
|
|
||||||
1.0,
|
|
||||||
0.0,
|
|
||||||
1.0,
|
|
||||||
0.0,
|
|
||||||
0.0,
|
|
||||||
1.0,
|
|
||||||
1.0,
|
|
||||||
0.0,
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
def test_instance_features_extractor():
|
|
||||||
instances, models = _get_instances()
|
|
||||||
features = InstanceFeaturesExtractor().extract(instances)
|
|
||||||
assert features.shape == (2, 3)
|
|
||||||
|
|
||||||
|
|
||||||
def test_variable_features_extractor():
|
|
||||||
instances, models = _get_instances()
|
|
||||||
features = VariableFeaturesExtractor().extract(instances)
|
|
||||||
assert isinstance(features, dict)
|
|
||||||
assert "default" in features
|
|
||||||
assert features["default"].shape == (6, 5)</code></pre>
|
|
||||||
</details>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
<h2 class="section-title" id="header-functions">Functions</h2>
|
|
||||||
<dl>
|
|
||||||
<dt id="miplearn.tests.test_extractors.test_instance_features_extractor"><code class="name flex">
|
|
||||||
<span>def <span class="ident">test_instance_features_extractor</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_instance_features_extractor():
|
|
||||||
instances, models = _get_instances()
|
|
||||||
features = InstanceFeaturesExtractor().extract(instances)
|
|
||||||
assert features.shape == (2, 3)</code></pre>
|
|
||||||
</details>
|
|
||||||
</dd>
|
|
||||||
<dt id="miplearn.tests.test_extractors.test_solution_extractor"><code class="name flex">
|
|
||||||
<span>def <span class="ident">test_solution_extractor</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_solution_extractor():
|
|
||||||
instances, models = _get_instances()
|
|
||||||
features = SolutionExtractor().extract(instances)
|
|
||||||
assert isinstance(features, dict)
|
|
||||||
assert "default" in features.keys()
|
|
||||||
assert isinstance(features["default"], np.ndarray)
|
|
||||||
assert features["default"].shape == (6, 2)
|
|
||||||
assert features["default"].ravel().tolist() == [
|
|
||||||
1.0,
|
|
||||||
0.0,
|
|
||||||
0.0,
|
|
||||||
1.0,
|
|
||||||
1.0,
|
|
||||||
0.0,
|
|
||||||
1.0,
|
|
||||||
0.0,
|
|
||||||
0.0,
|
|
||||||
1.0,
|
|
||||||
1.0,
|
|
||||||
0.0,
|
|
||||||
]</code></pre>
|
|
||||||
</details>
|
|
||||||
</dd>
|
|
||||||
<dt id="miplearn.tests.test_extractors.test_variable_features_extractor"><code class="name flex">
|
|
||||||
<span>def <span class="ident">test_variable_features_extractor</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_variable_features_extractor():
|
|
||||||
instances, models = _get_instances()
|
|
||||||
features = VariableFeaturesExtractor().extract(instances)
|
|
||||||
assert isinstance(features, dict)
|
|
||||||
assert "default" in features
|
|
||||||
assert features["default"].shape == (6, 5)</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.tests" href="index.html">miplearn.tests</a></code></li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
<li><h3><a href="#header-functions">Functions</a></h3>
|
|
||||||
<ul class="">
|
|
||||||
<li><code><a title="miplearn.tests.test_extractors.test_instance_features_extractor" href="#miplearn.tests.test_extractors.test_instance_features_extractor">test_instance_features_extractor</a></code></li>
|
|
||||||
<li><code><a title="miplearn.tests.test_extractors.test_solution_extractor" href="#miplearn.tests.test_extractors.test_solution_extractor">test_solution_extractor</a></code></li>
|
|
||||||
<li><code><a title="miplearn.tests.test_extractors.test_variable_features_extractor" href="#miplearn.tests.test_extractors.test_variable_features_extractor">test_variable_features_extractor</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>
|
|
Binary file not shown.
Loading…
Reference in new issue