Files
ortools-clone/docs/cpp/hamiltonian__path_8h_source.html
Laurent Perron a2ad6677e1 regenerate doc
2022-01-16 18:02:36 +01:00

206 lines
227 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!-- HTML header for doxygen 1.8.18-->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<meta name="generator" content="Doxygen 1.8.15"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>OR-Tools: hamiltonian_path.h Source File</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="navtree.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="resize.js"></script>
<script type="text/javascript" src="navtreedata.js"></script>
<script type="text/javascript" src="navtree.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
$(document).ready(initResizable);
/* @license-end */</script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/searchdata.js"></script>
<script type="text/javascript" src="search/search.js"></script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
<link href="styleSheet.tmp.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr style="height: 56px;">
<td id="projectlogo"><img alt="Logo" src="orLogo.png"/></td>
<td id="projectalign" style="padding-left: 0.5em;">
<div id="projectname">OR-Tools
&#160;<span id="projectnumber">9.2</span>
</div>
</td>
</tr>
</tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.8.15 -->
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
var searchBox = new SearchBox("searchBox", "search",false,'Search');
/* @license-end */
</script>
<script type="text/javascript" src="menudata.js"></script>
<script type="text/javascript" src="menu.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
$(function() {
initMenu('',true,false,'search.php','Search');
$(document).ready(function() { init_search(); });
});
/* @license-end */</script>
<div id="main-nav"></div>
</div><!-- top -->
<div id="side-nav" class="ui-resizable side-nav-resizable">
<div id="nav-tree">
<div id="nav-tree-contents">
<div id="nav-sync" class="sync"></div>
</div>
</div>
<div id="splitbar" style="-moz-user-select:none;"
class="ui-resizable-handle">
</div>
</div>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
$(document).ready(function(){initNavTree('hamiltonian__path_8h_source.html','');});
/* @license-end */
</script>
<div id="doc-content">
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
onmouseover="return searchBox.OnSearchSelectShow()"
onmouseout="return searchBox.OnSearchSelectHide()"
onkeydown="return searchBox.OnSearchSelectKey(event)">
</div>
<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<iframe src="javascript:void(0)" frameborder="0"
name="MSearchResults" id="MSearchResults">
</iframe>
</div>
<div class="header">
<div class="headertitle">
<div class="title">hamiltonian_path.h</div> </div>
</div><!--header-->
<div class="contents">
<a href="hamiltonian__path_8h.html">Go to the documentation of this file.</a><div class="fragment"><div class="line"><a name="l00001"></a><span class="lineno"> 1</span>&#160;<span class="comment">// Copyright 2010-2021 Google LLC</span></div><div class="line"><a name="l00002"></a><span class="lineno"> 2</span>&#160;<span class="comment">// Licensed under the Apache License, Version 2.0 (the &quot;License&quot;);</span></div><div class="line"><a name="l00003"></a><span class="lineno"> 3</span>&#160;<span class="comment">// you may not use this file except in compliance with the License.</span></div><div class="line"><a name="l00004"></a><span class="lineno"> 4</span>&#160;<span class="comment">// You may obtain a copy of the License at</span></div><div class="line"><a name="l00005"></a><span class="lineno"> 5</span>&#160;<span class="comment">//</span></div><div class="line"><a name="l00006"></a><span class="lineno"> 6</span>&#160;<span class="comment">// http://www.apache.org/licenses/LICENSE-2.0</span></div><div class="line"><a name="l00007"></a><span class="lineno"> 7</span>&#160;<span class="comment">//</span></div><div class="line"><a name="l00008"></a><span class="lineno"> 8</span>&#160;<span class="comment">// Unless required by applicable law or agreed to in writing, software</span></div><div class="line"><a name="l00009"></a><span class="lineno"> 9</span>&#160;<span class="comment">// distributed under the License is distributed on an &quot;AS IS&quot; BASIS,</span></div><div class="line"><a name="l00010"></a><span class="lineno"> 10</span>&#160;<span class="comment">// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.</span></div><div class="line"><a name="l00011"></a><span class="lineno"> 11</span>&#160;<span class="comment">// See the License for the specific language governing permissions and</span></div><div class="line"><a name="l00012"></a><span class="lineno"> 12</span>&#160;<span class="comment">// limitations under the License.</span></div><div class="line"><a name="l00013"></a><span class="lineno"> 13</span>&#160;</div><div class="line"><a name="l00014"></a><span class="lineno"> 14</span>&#160;<span class="preprocessor">#ifndef OR_TOOLS_GRAPH_HAMILTONIAN_PATH_H_</span></div><div class="line"><a name="l00015"></a><span class="lineno"> 15</span>&#160;<span class="preprocessor">#define OR_TOOLS_GRAPH_HAMILTONIAN_PATH_H_</span></div><div class="line"><a name="l00016"></a><span class="lineno"> 16</span>&#160;</div><div class="line"><a name="l00017"></a><span class="lineno"> 17</span>&#160;<span class="comment">// Solves the Shortest Hamiltonian Path Problem using a complete algorithm.</span></div><div class="line"><a name="l00018"></a><span class="lineno"> 18</span>&#160;<span class="comment">// The algorithm was first described in</span></div><div class="line"><a name="l00019"></a><span class="lineno"> 19</span>&#160;<span class="comment">// M. Held, R.M. Karp, A dynamic programming approach to sequencing problems,</span></div><div class="line"><a name="l00020"></a><span class="lineno"> 20</span>&#160;<span class="comment">// J. SIAM 10 (1962) 196-210</span></div><div class="line"><a name="l00021"></a><span class="lineno"> 21</span>&#160;<span class="comment">//</span></div><div class="line"><a name="l00022"></a><span class="lineno"> 22</span>&#160;<span class="comment">// The Shortest Hamiltonian Path Problem (SHPP) is similar to the Traveling</span></div><div class="line"><a name="l00023"></a><span class="lineno"> 23</span>&#160;<span class="comment">// Salesperson Problem (TSP).</span></div><div class="line"><a name="l00024"></a><span class="lineno"> 24</span>&#160;<span class="comment">// You have to visit all the cities, starting from a given one and you</span></div><div class="line"><a name="l00025"></a><span class="lineno"> 25</span>&#160;<span class="comment">// do not need to return to your starting point. With the TSP, you can start</span></div><div class="line"><a name="l00026"></a><span class="lineno"> 26</span>&#160;<span class="comment">// anywhere, but you have to return to your start location.</span></div><div class="line"><a name="l00027"></a><span class="lineno"> 27</span>&#160;<span class="comment">//</span></div><div class="line"><a name="l00028"></a><span class="lineno"> 28</span>&#160;<span class="comment">// By complete we mean that the algorithm guarantees to compute the optimal</span></div><div class="line"><a name="l00029"></a><span class="lineno"> 29</span>&#160;<span class="comment">// solution. The algorithm uses dynamic programming. Its time complexity is</span></div><div class="line"><a name="l00030"></a><span class="lineno"> 30</span>&#160;<span class="comment">// O(n^2 * 2^(n-1)), where n is the number of nodes to be visited, and &#39;^&#39;</span></div><div class="line"><a name="l00031"></a><span class="lineno"> 31</span>&#160;<span class="comment">// denotes exponentiation. Its space complexity is O(n * 2 ^ (n - 1)).</span></div><div class="line"><a name="l00032"></a><span class="lineno"> 32</span>&#160;<span class="comment">//</span></div><div class="line"><a name="l00033"></a><span class="lineno"> 33</span>&#160;<span class="comment">// Note that the naive implementation of the SHPP</span></div><div class="line"><a name="l00034"></a><span class="lineno"> 34</span>&#160;<span class="comment">// exploring all permutations without memorizing intermediate results would</span></div><div class="line"><a name="l00035"></a><span class="lineno"> 35</span>&#160;<span class="comment">// have a complexity of (n - 1)! (factorial of (n - 1) ), which is much higher</span></div><div class="line"><a name="l00036"></a><span class="lineno"> 36</span>&#160;<span class="comment">// than n^2 * 2^(n-1). To convince oneself of this, just use Stirling&#39;s</span></div><div class="line"><a name="l00037"></a><span class="lineno"> 37</span>&#160;<span class="comment">// formula: n! ~ sqrt(2 * pi * n)*( n / exp(1)) ^ n.</span></div><div class="line"><a name="l00038"></a><span class="lineno"> 38</span>&#160;<span class="comment">// Because of these complexity figures, the algorithm is not practical for</span></div><div class="line"><a name="l00039"></a><span class="lineno"> 39</span>&#160;<span class="comment">// problems with more than 20 nodes.</span></div><div class="line"><a name="l00040"></a><span class="lineno"> 40</span>&#160;<span class="comment">//</span></div><div class="line"><a name="l00041"></a><span class="lineno"> 41</span>&#160;<span class="comment">// Here is how the algorithm works:</span></div><div class="line"><a name="l00042"></a><span class="lineno"> 42</span>&#160;<span class="comment">// Let us denote the nodes to be visited by their indices 0 .. n - 1</span></div><div class="line"><a name="l00043"></a><span class="lineno"> 43</span>&#160;<span class="comment">// Let us pick 0 as the starting node.</span></div><div class="line"><a name="l00044"></a><span class="lineno"> 44</span>&#160;<span class="comment">// Let d(i,j) denote the distance (or cost) from i to j.</span></div><div class="line"><a name="l00045"></a><span class="lineno"> 45</span>&#160;<span class="comment">// f(S, j) where S is a set of nodes and j is a node in S is defined as follows:</span></div><div class="line"><a name="l00046"></a><span class="lineno"> 46</span>&#160;<span class="comment">// f(S, j) = min (i in S \ {j}, f(S \ {j}, i) + cost(i, j))</span></div><div class="line"><a name="l00047"></a><span class="lineno"> 47</span>&#160;<span class="comment">// (j is an element of S)</span></div><div class="line"><a name="l00048"></a><span class="lineno"> 48</span>&#160;<span class="comment">// Note that this formulation, from the original Held-Karp paper is a bit</span></div><div class="line"><a name="l00049"></a><span class="lineno"> 49</span>&#160;<span class="comment">// different, but equivalent to the one used in Caseau and Laburthe, Solving</span></div><div class="line"><a name="l00050"></a><span class="lineno"> 50</span>&#160;<span class="comment">// Small TSPs with Constraints, 1997, ICLP</span></div><div class="line"><a name="l00051"></a><span class="lineno"> 51</span>&#160;<span class="comment">// f(S, j) = min (i in S, f(S \ {i}, i) + cost(i, j))</span></div><div class="line"><a name="l00052"></a><span class="lineno"> 52</span>&#160;<span class="comment">// (j is not an element of S)</span></div><div class="line"><a name="l00053"></a><span class="lineno"> 53</span>&#160;<span class="comment">//</span></div><div class="line"><a name="l00054"></a><span class="lineno"> 54</span>&#160;<span class="comment">// The advantage of the Held and Karp formulation is that it enables:</span></div><div class="line"><a name="l00055"></a><span class="lineno"> 55</span>&#160;<span class="comment">// - to build the dynamic programming lattice layer by layer starting from the</span></div><div class="line"><a name="l00056"></a><span class="lineno"> 56</span>&#160;<span class="comment">// subsets with cardinality 1, and increasing the cardinality.</span></div><div class="line"><a name="l00057"></a><span class="lineno"> 57</span>&#160;<span class="comment">// - to traverse the dynamic programming lattice using sequential memory</span></div><div class="line"><a name="l00058"></a><span class="lineno"> 58</span>&#160;<span class="comment">// accesses, making the algorithm cache-friendly, and faster, despite the large</span></div><div class="line"><a name="l00059"></a><span class="lineno"> 59</span>&#160;<span class="comment">// amount of computation needed to get the position when f(S, j) is stored.</span></div><div class="line"><a name="l00060"></a><span class="lineno"> 60</span>&#160;<span class="comment">// - TODO(user): implement pruning procedures on top of the Held-Karp algorithm.</span></div><div class="line"><a name="l00061"></a><span class="lineno"> 61</span>&#160;<span class="comment">//</span></div><div class="line"><a name="l00062"></a><span class="lineno"> 62</span>&#160;<span class="comment">// The set S can be represented by an integer where bit i corresponds to</span></div><div class="line"><a name="l00063"></a><span class="lineno"> 63</span>&#160;<span class="comment">// element i in the set. In the following S denotes the integer corresponding</span></div><div class="line"><a name="l00064"></a><span class="lineno"> 64</span>&#160;<span class="comment">// to set S.</span></div><div class="line"><a name="l00065"></a><span class="lineno"> 65</span>&#160;<span class="comment">//</span></div><div class="line"><a name="l00066"></a><span class="lineno"> 66</span>&#160;<span class="comment">// The dynamic programming iteration is implemented in the method Solve.</span></div><div class="line"><a name="l00067"></a><span class="lineno"> 67</span>&#160;<span class="comment">// The optimal value of the Hamiltonian path starting at 0 is given by</span></div><div class="line"><a name="l00068"></a><span class="lineno"> 68</span>&#160;<span class="comment">// min (i in S, f(2 ^ n - 1, i))</span></div><div class="line"><a name="l00069"></a><span class="lineno"> 69</span>&#160;<span class="comment">// The optimal value of the Traveling Salesman tour is given by f(2 ^ n, 0).</span></div><div class="line"><a name="l00070"></a><span class="lineno"> 70</span>&#160;<span class="comment">// (There is actually no need to duplicate the first node, as all the paths</span></div><div class="line"><a name="l00071"></a><span class="lineno"> 71</span>&#160;<span class="comment">// are computed from node 0.)</span></div><div class="line"><a name="l00072"></a><span class="lineno"> 72</span>&#160;<span class="comment">//</span></div><div class="line"><a name="l00073"></a><span class="lineno"> 73</span>&#160;<span class="comment">// To implement dynamic programming, we store the preceding results of</span></div><div class="line"><a name="l00074"></a><span class="lineno"> 74</span>&#160;<span class="comment">// computing f(S,j) in an array M[Offset(S,j)]. See the comments about</span></div><div class="line"><a name="l00075"></a><span class="lineno"> 75</span>&#160;<span class="comment">// LatticeMemoryManager::BaseOffset() to see how this is computed.</span></div><div class="line"><a name="l00076"></a><span class="lineno"> 76</span>&#160;<span class="comment">//</span></div><div class="line"><a name="l00077"></a><span class="lineno"> 77</span>&#160;<span class="comment">// Keywords: Traveling Salesman, Hamiltonian Path, Dynamic Programming,</span></div><div class="line"><a name="l00078"></a><span class="lineno"> 78</span>&#160;<span class="comment">// Held, Karp.</span></div><div class="line"><a name="l00079"></a><span class="lineno"> 79</span>&#160;</div><div class="line"><a name="l00080"></a><span class="lineno"> 80</span>&#160;<span class="preprocessor">#include &lt;math.h&gt;</span></div><div class="line"><a name="l00081"></a><span class="lineno"> 81</span>&#160;<span class="preprocessor">#include &lt;stddef.h&gt;</span></div><div class="line"><a name="l00082"></a><span class="lineno"> 82</span>&#160;</div><div class="line"><a name="l00083"></a><span class="lineno"> 83</span>&#160;<span class="preprocessor">#include &lt;algorithm&gt;</span></div><div class="line"><a name="l00084"></a><span class="lineno"> 84</span>&#160;<span class="preprocessor">#include &lt;cmath&gt;</span></div><div class="line"><a name="l00085"></a><span class="lineno"> 85</span>&#160;<span class="preprocessor">#include &lt;cstdint&gt;</span></div><div class="line"><a name="l00086"></a><span class="lineno"> 86</span>&#160;<span class="preprocessor">#include &lt;limits&gt;</span></div><div class="line"><a name="l00087"></a><span class="lineno"> 87</span>&#160;<span class="preprocessor">#include &lt;memory&gt;</span></div><div class="line"><a name="l00088"></a><span class="lineno"> 88</span>&#160;<span class="preprocessor">#include &lt;stack&gt;</span></div><div class="line"><a name="l00089"></a><span class="lineno"> 89</span>&#160;<span class="preprocessor">#include &lt;type_traits&gt;</span></div><div class="line"><a name="l00090"></a><span class="lineno"> 90</span>&#160;<span class="preprocessor">#include &lt;utility&gt;</span></div><div class="line"><a name="l00091"></a><span class="lineno"> 91</span>&#160;<span class="preprocessor">#include &lt;vector&gt;</span></div><div class="line"><a name="l00092"></a><span class="lineno"> 92</span>&#160;</div><div class="line"><a name="l00093"></a><span class="lineno"> 93</span>&#160;<span class="preprocessor">#include &quot;<a class="code" href="integral__types_8h.html">ortools/base/integral_types.h</a>&quot;</span></div><div class="line"><a name="l00094"></a><span class="lineno"> 94</span>&#160;<span class="preprocessor">#include &quot;<a class="code" href="base_2logging_8h.html">ortools/base/logging.h</a>&quot;</span></div><div class="line"><a name="l00095"></a><span class="lineno"> 95</span>&#160;<span class="preprocessor">#include &quot;<a class="code" href="bitset_8h.html">ortools/util/bitset.h</a>&quot;</span></div><div class="line"><a name="l00096"></a><span class="lineno"> 96</span>&#160;<span class="preprocessor">#include &quot;<a class="code" href="saturated__arithmetic_8h.html">ortools/util/saturated_arithmetic.h</a>&quot;</span></div><div class="line"><a name="l00097"></a><span class="lineno"> 97</span>&#160;<span class="preprocessor">#include &quot;<a class="code" href="vector__or__function_8h.html">ortools/util/vector_or_function.h</a>&quot;</span></div><div class="line"><a name="l00098"></a><span class="lineno"> 98</span>&#160;</div><div class="line"><a name="l00099"></a><span class="lineno"> 99</span>&#160;<span class="keyword">namespace </span><a class="code" href="namespaceoperations__research.html">operations_research</a> {</div><div class="line"><a name="l00100"></a><span class="lineno"> 100</span>&#160;</div><div class="line"><a name="l00101"></a><span class="lineno"> 101</span>&#160;<span class="comment">// TODO(user): Move the Set-related classbelow to util/bitset.h</span></div><div class="line"><a name="l00102"></a><span class="lineno"> 102</span>&#160;<span class="comment">// Iterates over the elements of a set represented as an unsigned integer,</span></div><div class="line"><a name="l00103"></a><span class="lineno"> 103</span>&#160;<span class="comment">// starting from the smallest element. (See the class Set&lt;Integer&gt; below.)</span></div><div class="line"><a name="l00104"></a><span class="lineno"> 104</span>&#160;<span class="keyword">template</span> &lt;<span class="keyword">typename</span> Set&gt;</div><div class="line"><a name="l00105"></a><span class="lineno"><a class="line" href="classoperations__research_1_1_element_iterator.html"> 105</a></span>&#160;<span class="keyword">class </span><a class="code" href="classoperations__research_1_1_element_iterator.html">ElementIterator</a> {</div><div class="line"><a name="l00106"></a><span class="lineno"> 106</span>&#160; <span class="keyword">public</span>:</div><div class="line"><a name="l00107"></a><span class="lineno"><a class="line" href="classoperations__research_1_1_element_iterator.html#a0a290cf047b502171a3d1770cd194c52"> 107</a></span>&#160; <span class="keyword">explicit</span> <a class="code" href="classoperations__research_1_1_element_iterator.html#a0a290cf047b502171a3d1770cd194c52">ElementIterator</a>(<a class="code" href="classoperations__research_1_1_set.html">Set</a> set) : current_set_(set) {}</div><div class="line"><a name="l00108"></a><span class="lineno"><a class="line" href="classoperations__research_1_1_element_iterator.html#aefcf46820145a241c215f2e82b69d5f5"> 108</a></span>&#160; <span class="keywordtype">bool</span> <a class="code" href="classoperations__research_1_1_element_iterator.html#aefcf46820145a241c215f2e82b69d5f5">operator!=</a>(<span class="keyword">const</span> <a class="code" href="classoperations__research_1_1_element_iterator.html">ElementIterator</a>&amp; other)<span class="keyword"> const </span>{</div><div class="line"><a name="l00109"></a><span class="lineno"> 109</span>&#160; <span class="keywordflow">return</span> current_set_ != other.current_set_;</div><div class="line"><a name="l00110"></a><span class="lineno"> 110</span>&#160; }</div><div class="line"><a name="l00111"></a><span class="lineno"> 111</span>&#160;</div><div class="line"><a name="l00112"></a><span class="lineno"> 112</span>&#160; <span class="comment">// Returns the smallest element in the current_set_.</span></div><div class="line"><a name="l00113"></a><span class="lineno"><a class="line" href="classoperations__research_1_1_element_iterator.html#a9cf56c599b564897633c67574e2e460b"> 113</a></span>&#160; <span class="keywordtype">int</span> <a class="code" href="classoperations__research_1_1_element_iterator.html#a9cf56c599b564897633c67574e2e460b">operator*</a>()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> current_set_.<a class="code" href="classoperations__research_1_1_set.html#abb2b3831b27fd81d60fb39ad01e108a3">SmallestElement</a>(); }</div><div class="line"><a name="l00114"></a><span class="lineno"> 114</span>&#160;</div><div class="line"><a name="l00115"></a><span class="lineno"> 115</span>&#160; <span class="comment">// Advances the iterator by removing its smallest element.</span></div><div class="line"><a name="l00116"></a><span class="lineno"><a class="line" href="classoperations__research_1_1_element_iterator.html#a6eb44ef439441ada8ffaaf6ee33a9c40"> 116</a></span>&#160; <span class="keyword">const</span> <a class="code" href="classoperations__research_1_1_element_iterator.html">ElementIterator</a>&amp; <a class="code" href="classoperations__research_1_1_element_iterator.html#a6eb44ef439441ada8ffaaf6ee33a9c40">operator++</a>() {</div><div class="line"><a name="l00117"></a><span class="lineno"> 117</span>&#160; current_set_ = current_set_.<a class="code" href="classoperations__research_1_1_set.html#a5865d6398576a8e71b0f346e79c583e7">RemoveSmallestElement</a>();</div><div class="line"><a name="l00118"></a><span class="lineno"> 118</span>&#160; <span class="keywordflow">return</span> *<span class="keyword">this</span>;</div><div class="line"><a name="l00119"></a><span class="lineno"> 119</span>&#160; }</div><div class="line"><a name="l00120"></a><span class="lineno"> 120</span>&#160;</div><div class="line"><a name="l00121"></a><span class="lineno"> 121</span>&#160; <span class="keyword">private</span>:</div><div class="line"><a name="l00122"></a><span class="lineno"> 122</span>&#160; <span class="comment">// The current position of the iterator. Stores the set consisting of the</span></div><div class="line"><a name="l00123"></a><span class="lineno"> 123</span>&#160; <span class="comment">// not-yet iterated elements.</span></div><div class="line"><a name="l00124"></a><span class="lineno"> 124</span>&#160; <a class="code" href="classoperations__research_1_1_set.html">Set</a> current_set_;</div><div class="line"><a name="l00125"></a><span class="lineno"> 125</span>&#160;};</div><div class="line"><a name="l00126"></a><span class="lineno"> 126</span>&#160;</div><div class="line"><a name="l00127"></a><span class="lineno"> 127</span>&#160;<span class="keyword">template</span> &lt;<span class="keyword">typename</span> Integer&gt;</div><div class="line"><a name="l00128"></a><span class="lineno"><a class="line" href="classoperations__research_1_1_set.html"> 128</a></span>&#160;<span class="keyword">class </span><a class="code" href="classoperations__research_1_1_set.html">Set</a> {</div><div class="line"><a name="l00129"></a><span class="lineno"> 129</span>&#160; <span class="keyword">public</span>:</div><div class="line"><a name="l00130"></a><span class="lineno"> 130</span>&#160; <span class="comment">// Make this visible to classes using this class.</span></div><div class="line"><a name="l00131"></a><span class="lineno"><a class="line" href="classoperations__research_1_1_set.html#aabbec0d4f2a126cbdd6c1bce67b7cc8b"> 131</a></span>&#160; <span class="keyword">typedef</span> Integer <a class="code" href="classoperations__research_1_1_set.html#aabbec0d4f2a126cbdd6c1bce67b7cc8b">IntegerType</a>;</div><div class="line"><a name="l00132"></a><span class="lineno"> 132</span>&#160;</div><div class="line"><a name="l00133"></a><span class="lineno"> 133</span>&#160; <span class="comment">// Useful constants.</span></div><div class="line"><a name="l00134"></a><span class="lineno"><a class="line" href="classoperations__research_1_1_set.html#a7f72b10501772e497164805b53e2ec80"> 134</a></span>&#160; <span class="keyword">static</span> constexpr Integer <a class="code" href="classoperations__research_1_1_set.html#a7f72b10501772e497164805b53e2ec80">One</a> = static_cast&lt;Integer&gt;(1);</div><div class="line"><a name="l00135"></a><span class="lineno"><a class="line" href="classoperations__research_1_1_set.html#ac2fa078fad730b08d36dc600a24e21a1"> 135</a></span>&#160; <span class="keyword">static</span> constexpr Integer <a class="code" href="classoperations__research_1_1_set.html#ac2fa078fad730b08d36dc600a24e21a1">Zero</a> = static_cast&lt;Integer&gt;(0);</div><div class="line"><a name="l00136"></a><span class="lineno"><a class="line" href="classoperations__research_1_1_set.html#a062c0acf17a051b885ad211acad31079"> 136</a></span>&#160; <span class="keyword">static</span> <span class="keyword">const</span> <span class="keywordtype">int</span> <a class="code" href="classoperations__research_1_1_set.html#a062c0acf17a051b885ad211acad31079">MaxCardinality</a> = 8 * <span class="keyword">sizeof</span>(Integer); <span class="comment">// NOLINT</span></div><div class="line"><a name="l00137"></a><span class="lineno"> 137</span>&#160;</div><div class="line"><a name="l00138"></a><span class="lineno"> 138</span>&#160; <span class="comment">// Construct a set from an Integer.</span></div><div class="line"><a name="l00139"></a><span class="lineno"><a class="line" href="classoperations__research_1_1_set.html#a450e5cf964a0b2c866641c8f4e4b3361"> 139</a></span>&#160; <span class="keyword">explicit</span> <a class="code" href="classoperations__research_1_1_set.html#a450e5cf964a0b2c866641c8f4e4b3361">Set</a>(Integer n) : value_(n) {</div><div class="line"><a name="l00140"></a><span class="lineno"> 140</span>&#160; static_assert(<a class="code" href="demon__profiler_8cc.html#ac072af30c4ffbc834bb4c681f6ecb514">std::is_integral&lt;Integer&gt;::value</a>, <span class="stringliteral">&quot;Integral type required&quot;</span>);</div><div class="line"><a name="l00141"></a><span class="lineno"> 141</span>&#160; static_assert(<a class="code" href="demon__profiler_8cc.html#ac072af30c4ffbc834bb4c681f6ecb514">std::is_unsigned&lt;Integer&gt;::value</a>, <span class="stringliteral">&quot;Unsigned type required&quot;</span>);</div><div class="line"><a name="l00142"></a><span class="lineno"> 142</span>&#160; }</div><div class="line"><a name="l00143"></a><span class="lineno"> 143</span>&#160;</div><div class="line"><a name="l00144"></a><span class="lineno"> 144</span>&#160; <span class="comment">// Returns the integer corresponding to the set.</span></div><div class="line"><a name="l00145"></a><span class="lineno"><a class="line" href="classoperations__research_1_1_set.html#a983cf4555b2577512febcc3aa327a3c8"> 145</a></span>&#160; Integer <a class="code" href="classoperations__research_1_1_set.html#a983cf4555b2577512febcc3aa327a3c8">value</a>()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> value_; }</div><div class="line"><a name="l00146"></a><span class="lineno"> 146</span>&#160;</div><div class="line"><a name="l00147"></a><span class="lineno"><a class="line" href="classoperations__research_1_1_set.html#ae7cd733dab92b86a3aaac89c4d49503f"> 147</a></span>&#160; <span class="keyword">static</span> <a class="code" href="classoperations__research_1_1_set.html">Set</a> <a class="code" href="classoperations__research_1_1_set.html#ae7cd733dab92b86a3aaac89c4d49503f">FullSet</a>(Integer card) {</div><div class="line"><a name="l00148"></a><span class="lineno"> 148</span>&#160; <span class="keywordflow">return</span> card == 0 ? <a class="code" href="classoperations__research_1_1_set.html#a450e5cf964a0b2c866641c8f4e4b3361">Set</a>(0) : <a class="code" href="classoperations__research_1_1_set.html#a450e5cf964a0b2c866641c8f4e4b3361">Set</a>(~<a class="code" href="classoperations__research_1_1_set.html#ac2fa078fad730b08d36dc600a24e21a1">Zero</a> &gt;&gt; (<a class="code" href="classoperations__research_1_1_set.html#a062c0acf17a051b885ad211acad31079">MaxCardinality</a> - card));</div><div class="line"><a name="l00149"></a><span class="lineno"> 149</span>&#160; }</div><div class="line"><a name="l00150"></a><span class="lineno"> 150</span>&#160;</div><div class="line"><a name="l00151"></a><span class="lineno"> 151</span>&#160; <span class="comment">// Returns the singleton set with &#39;n&#39; as its only element.</span></div><div class="line"><a name="l00152"></a><span class="lineno"><a class="line" href="classoperations__research_1_1_set.html#abbfaa99a45c4a90475cb2f5138f9a162"> 152</a></span>&#160; <span class="keyword">static</span> <a class="code" href="classoperations__research_1_1_set.html">Set</a> <a class="code" href="classoperations__research_1_1_set.html#abbfaa99a45c4a90475cb2f5138f9a162">Singleton</a>(Integer n) { <span class="keywordflow">return</span> <a class="code" href="classoperations__research_1_1_set.html#a450e5cf964a0b2c866641c8f4e4b3361">Set</a>(<a class="code" href="classoperations__research_1_1_set.html#a7f72b10501772e497164805b53e2ec80">One</a> &lt;&lt; n); }</div><div class="line"><a name="l00153"></a><span class="lineno"> 153</span>&#160;</div><div class="line"><a name="l00154"></a><span class="lineno"> 154</span>&#160; <span class="comment">// Returns a set equal to the calling object, with element n added.</span></div><div class="line"><a name="l00155"></a><span class="lineno"> 155</span>&#160; <span class="comment">// If n is already in the set, no operation occurs.</span></div><div class="line"><a name="l00156"></a><span class="lineno"><a class="line" href="classoperations__research_1_1_set.html#afe05ca596cfc024da65cf61a79812a2f"> 156</a></span>&#160; <a class="code" href="classoperations__research_1_1_set.html">Set</a> <a class="code" href="classoperations__research_1_1_set.html#afe05ca596cfc024da65cf61a79812a2f">AddElement</a>(<span class="keywordtype">int</span> n)<span class="keyword"> const </span>{ <span class="keywordflow">return</span> <a class="code" href="classoperations__research_1_1_set.html#a450e5cf964a0b2c866641c8f4e4b3361">Set</a>(value_ | (<a class="code" href="classoperations__research_1_1_set.html#a7f72b10501772e497164805b53e2ec80">One</a> &lt;&lt; n)); }</div><div class="line"><a name="l00157"></a><span class="lineno"> 157</span>&#160;</div><div class="line"><a name="l00158"></a><span class="lineno"> 158</span>&#160; <span class="comment">// Returns a set equal to the calling object, with element n removed.</span></div><div class="line"><a name="l00159"></a><span class="lineno"> 159</span>&#160; <span class="comment">// If n is not in the set, no operation occurs.</span></div><div class="line"><a name="l00160"></a><span class="lineno"><a class="line" href="classoperations__research_1_1_set.html#a190d6e916c3a1a06e2eff670e8b52da8"> 160</a></span>&#160; <a class="code" href="classoperations__research_1_1_set.html">Set</a> <a class="code" href="classoperations__research_1_1_set.html#a190d6e916c3a1a06e2eff670e8b52da8">RemoveElement</a>(<span class="keywordtype">int</span> n)<span class="keyword"> const </span>{ <span class="keywordflow">return</span> <a class="code" href="classoperations__research_1_1_set.html#a450e5cf964a0b2c866641c8f4e4b3361">Set</a>(value_ &amp; ~(<a class="code" href="classoperations__research_1_1_set.html#a7f72b10501772e497164805b53e2ec80">One</a> &lt;&lt; n)); }</div><div class="line"><a name="l00161"></a><span class="lineno"> 161</span>&#160;</div><div class="line"><a name="l00162"></a><span class="lineno"> 162</span>&#160; <span class="comment">// Returns true if the calling set contains element n.</span></div><div class="line"><a name="l00163"></a><span class="lineno"><a class="line" href="classoperations__research_1_1_set.html#a0faec65dbf29460ec59dfa75d0536efb"> 163</a></span>&#160; <span class="keywordtype">bool</span> <a class="code" href="classoperations__research_1_1_set.html#a0faec65dbf29460ec59dfa75d0536efb">Contains</a>(<span class="keywordtype">int</span> n)<span class="keyword"> const </span>{ <span class="keywordflow">return</span> ((<a class="code" href="classoperations__research_1_1_set.html#a7f72b10501772e497164805b53e2ec80">One</a> &lt;&lt; n) &amp; value_) != 0; }</div><div class="line"><a name="l00164"></a><span class="lineno"> 164</span>&#160;</div><div class="line"><a name="l00165"></a><span class="lineno"> 165</span>&#160; <span class="comment">// Returns true if &#39;other&#39; is included in the calling set.</span></div><div class="line"><a name="l00166"></a><span class="lineno"><a class="line" href="classoperations__research_1_1_set.html#a9c628cec54eb559f322c284c096f1837"> 166</a></span>&#160; <span class="keywordtype">bool</span> <a class="code" href="classoperations__research_1_1_set.html#a9c628cec54eb559f322c284c096f1837">Includes</a>(<a class="code" href="classoperations__research_1_1_set.html">Set</a> other)<span class="keyword"> const </span>{</div><div class="line"><a name="l00167"></a><span class="lineno"> 167</span>&#160; <span class="keywordflow">return</span> (value_ &amp; other.value_) == other.value_;</div><div class="line"><a name="l00168"></a><span class="lineno"> 168</span>&#160; }</div><div class="line"><a name="l00169"></a><span class="lineno"> 169</span>&#160;</div><div class="line"><a name="l00170"></a><span class="lineno"> 170</span>&#160; <span class="comment">// Returns the number of elements in the set. Uses the 32-bit version for</span></div><div class="line"><a name="l00171"></a><span class="lineno"> 171</span>&#160; <span class="comment">// types that have 32-bits or less. Specialized for uint64_t.</span></div><div class="line"><a name="l00172"></a><span class="lineno"><a class="line" href="classoperations__research_1_1_set.html#a879ebf910431019a01f98d0865749c8d"> 172</a></span>&#160; <span class="keywordtype">int</span> <a class="code" href="classoperations__research_1_1_set.html#a879ebf910431019a01f98d0865749c8d">Cardinality</a>()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> <a class="code" href="namespaceoperations__research.html#a4841d3c6b072a22ba2b2fe43d6c03298">BitCount32</a>(value_); }</div><div class="line"><a name="l00173"></a><span class="lineno"> 173</span>&#160;</div><div class="line"><a name="l00174"></a><span class="lineno"> 174</span>&#160; <span class="comment">// Returns the index of the smallest element in the set. Uses the 32-bit</span></div><div class="line"><a name="l00175"></a><span class="lineno"> 175</span>&#160; <span class="comment">// version for types that have 32-bits or less. Specialized for uint64_t.</span></div><div class="line"><a name="l00176"></a><span class="lineno"><a class="line" href="classoperations__research_1_1_set.html#abb2b3831b27fd81d60fb39ad01e108a3"> 176</a></span>&#160; <span class="keywordtype">int</span> <a class="code" href="classoperations__research_1_1_set.html#abb2b3831b27fd81d60fb39ad01e108a3">SmallestElement</a>()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> <a class="code" href="namespaceoperations__research.html#aeaca21c840bf285f12127938231369b9">LeastSignificantBitPosition32</a>(value_); }</div><div class="line"><a name="l00177"></a><span class="lineno"> 177</span>&#160;</div><div class="line"><a name="l00178"></a><span class="lineno"> 178</span>&#160; <span class="comment">// Returns a set equal to the calling object, with its smallest</span></div><div class="line"><a name="l00179"></a><span class="lineno"> 179</span>&#160; <span class="comment">// element removed.</span></div><div class="line"><a name="l00180"></a><span class="lineno"><a class="line" href="classoperations__research_1_1_set.html#a5865d6398576a8e71b0f346e79c583e7"> 180</a></span>&#160; <a class="code" href="classoperations__research_1_1_set.html">Set</a> <a class="code" href="classoperations__research_1_1_set.html#a5865d6398576a8e71b0f346e79c583e7">RemoveSmallestElement</a>()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> <a class="code" href="classoperations__research_1_1_set.html#a450e5cf964a0b2c866641c8f4e4b3361">Set</a>(value_ &amp; (value_ - 1)); }</div><div class="line"><a name="l00181"></a><span class="lineno"> 181</span>&#160;</div><div class="line"><a name="l00182"></a><span class="lineno"> 182</span>&#160; <span class="comment">// Returns the rank of an element in a set. For the set 11100, ElementRank(4)</span></div><div class="line"><a name="l00183"></a><span class="lineno"> 183</span>&#160; <span class="comment">// would return 2. (Ranks start at zero).</span></div><div class="line"><a name="l00184"></a><span class="lineno"><a class="line" href="classoperations__research_1_1_set.html#a33392f61ea41062250f3664a055cd3bf"> 184</a></span>&#160; <span class="keywordtype">int</span> <a class="code" href="classoperations__research_1_1_set.html#a33392f61ea41062250f3664a055cd3bf">ElementRank</a>(<span class="keywordtype">int</span> n)<span class="keyword"> const </span>{</div><div class="line"><a name="l00185"></a><span class="lineno"> 185</span>&#160; <a class="code" href="base_2logging_8h.html#ae17f8119c108cf3070bad3449c7e0006">DCHECK</a>(<a class="code" href="classoperations__research_1_1_set.html#a0faec65dbf29460ec59dfa75d0536efb">Contains</a>(n)) &lt;&lt; <span class="stringliteral">&quot;n = &quot;</span> &lt;&lt; n &lt;&lt; <span class="stringliteral">&quot;, value_ = &quot;</span> &lt;&lt; value_;</div><div class="line"><a name="l00186"></a><span class="lineno"> 186</span>&#160; <span class="keywordflow">return</span> <a class="code" href="classoperations__research_1_1_set.html#a31dd4f4c450a217b20db6d8389d71a4e">SingletonRank</a>(<a class="code" href="classoperations__research_1_1_set.html#abbfaa99a45c4a90475cb2f5138f9a162">Singleton</a>(n));</div><div class="line"><a name="l00187"></a><span class="lineno"> 187</span>&#160; }</div><div class="line"><a name="l00188"></a><span class="lineno"> 188</span>&#160;</div><div class="line"><a name="l00189"></a><span class="lineno"> 189</span>&#160; <span class="comment">// Returns the set consisting of the smallest element of the calling object.</span></div><div class="line"><a name="l00190"></a><span class="lineno"><a class="line" href="classoperations__research_1_1_set.html#a64f741970505f1dea6a662c3b1776c74"> 190</a></span>&#160; <a class="code" href="classoperations__research_1_1_set.html">Set</a> <a class="code" href="classoperations__research_1_1_set.html#a64f741970505f1dea6a662c3b1776c74">SmallestSingleton</a>()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> <a class="code" href="classoperations__research_1_1_set.html#a450e5cf964a0b2c866641c8f4e4b3361">Set</a>(value_ &amp; -value_); }</div><div class="line"><a name="l00191"></a><span class="lineno"> 191</span>&#160;</div><div class="line"><a name="l00192"></a><span class="lineno"> 192</span>&#160; <span class="comment">// Returns the rank of the singleton&#39;s element in the calling Set.</span></div><div class="line"><a name="l00193"></a><span class="lineno"><a class="line" href="classoperations__research_1_1_set.html#a31dd4f4c450a217b20db6d8389d71a4e"> 193</a></span>&#160; <span class="keywordtype">int</span> <a class="code" href="classoperations__research_1_1_set.html#a31dd4f4c450a217b20db6d8389d71a4e">SingletonRank</a>(<a class="code" href="classoperations__research_1_1_set.html">Set</a> singleton)<span class="keyword"> const </span>{</div><div class="line"><a name="l00194"></a><span class="lineno"> 194</span>&#160; <a class="code" href="base_2logging_8h.html#ae89df3243bbb8341130c7b3f44145ea0">DCHECK_EQ</a>(singleton.<a class="code" href="classoperations__research_1_1_set.html#a983cf4555b2577512febcc3aa327a3c8">value</a>(), singleton.<a class="code" href="classoperations__research_1_1_set.html#a64f741970505f1dea6a662c3b1776c74">SmallestSingleton</a>().<a class="code" href="classoperations__research_1_1_set.html#a983cf4555b2577512febcc3aa327a3c8">value</a>());</div><div class="line"><a name="l00195"></a><span class="lineno"> 195</span>&#160; <span class="keywordflow">return</span> <a class="code" href="classoperations__research_1_1_set.html#a450e5cf964a0b2c866641c8f4e4b3361">Set</a>(value_ &amp; (singleton.value_ - 1)).Cardinality();</div><div class="line"><a name="l00196"></a><span class="lineno"> 196</span>&#160; }</div><div class="line"><a name="l00197"></a><span class="lineno"> 197</span>&#160;</div><div class="line"><a name="l00198"></a><span class="lineno"> 198</span>&#160; <span class="comment">// STL iterator-related member functions.</span></div><div class="line"><a name="l00199"></a><span class="lineno"><a class="line" href="classoperations__research_1_1_set.html#a191fa6bb5261ddd97d311ccc1d90fe7c"> 199</a></span>&#160; <a class="code" href="classoperations__research_1_1_element_iterator.html">ElementIterator&lt;Set&gt;</a> <a class="code" href="classoperations__research_1_1_set.html#a191fa6bb5261ddd97d311ccc1d90fe7c">begin</a>()<span class="keyword"> const </span>{</div><div class="line"><a name="l00200"></a><span class="lineno"> 200</span>&#160; <span class="keywordflow">return</span> <a class="code" href="classoperations__research_1_1_element_iterator.html">ElementIterator&lt;Set&gt;</a>(<a class="code" href="classoperations__research_1_1_set.html#a450e5cf964a0b2c866641c8f4e4b3361">Set</a>(value_));</div><div class="line"><a name="l00201"></a><span class="lineno"> 201</span>&#160; }</div><div class="line"><a name="l00202"></a><span class="lineno"><a class="line" href="classoperations__research_1_1_set.html#a67d03a6e5178376e21bdfa720680e447"> 202</a></span>&#160; <a class="code" href="classoperations__research_1_1_element_iterator.html">ElementIterator&lt;Set&gt;</a> <a class="code" href="classoperations__research_1_1_set.html#a67d03a6e5178376e21bdfa720680e447">end</a>()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> <a class="code" href="classoperations__research_1_1_element_iterator.html">ElementIterator&lt;Set&gt;</a>(<a class="code" href="classoperations__research_1_1_set.html#a450e5cf964a0b2c866641c8f4e4b3361">Set</a>(0)); }</div><div class="line"><a name="l00203"></a><span class="lineno"><a class="line" href="classoperations__research_1_1_set.html#a3382ddf3a1f05b9ded21ddb7b0013f78"> 203</a></span>&#160; <span class="keywordtype">bool</span> <a class="code" href="classoperations__research_1_1_set.html#a3382ddf3a1f05b9ded21ddb7b0013f78">operator!=</a>(<span class="keyword">const</span> <a class="code" href="classoperations__research_1_1_set.html">Set</a>&amp; other)<span class="keyword"> const </span>{ <span class="keywordflow">return</span> value_ != other.value_; }</div><div class="line"><a name="l00204"></a><span class="lineno"> 204</span>&#160;</div><div class="line"><a name="l00205"></a><span class="lineno"> 205</span>&#160; <span class="keyword">private</span>:</div><div class="line"><a name="l00206"></a><span class="lineno"> 206</span>&#160; <span class="comment">// The Integer representing the set.</span></div><div class="line"><a name="l00207"></a><span class="lineno"> 207</span>&#160; Integer value_;</div><div class="line"><a name="l00208"></a><span class="lineno"> 208</span>&#160;};</div><div class="line"><a name="l00209"></a><span class="lineno"> 209</span>&#160;</div><div class="line"><a name="l00210"></a><span class="lineno"> 210</span>&#160;<span class="keyword">template</span> &lt;&gt;</div><div class="line"><a name="l00211"></a><span class="lineno"><a class="line" href="classoperations__research_1_1_set.html#ab1a611fb9b161c503e676197ce82dcc1"> 211</a></span>&#160;<span class="keyword">inline</span> <span class="keywordtype">int</span> <a class="code" href="classoperations__research_1_1_set.html#abb2b3831b27fd81d60fb39ad01e108a3">Set&lt;uint64_t&gt;::SmallestElement</a>()<span class="keyword"> const </span>{</div><div class="line"><a name="l00212"></a><span class="lineno"> 212</span>&#160; <span class="keywordflow">return</span> <a class="code" href="namespaceoperations__research.html#ae13fcb4162a4180395806f43237c44b2">LeastSignificantBitPosition64</a>(value_);</div><div class="line"><a name="l00213"></a><span class="lineno"> 213</span>&#160;}</div><div class="line"><a name="l00214"></a><span class="lineno"> 214</span>&#160;</div><div class="line"><a name="l00215"></a><span class="lineno"> 215</span>&#160;<span class="keyword">template</span> &lt;&gt;</div><div class="line"><a name="l00216"></a><span class="lineno"><a class="line" href="classoperations__research_1_1_set.html#a4549c2beac5748836f490f1a9691aad2"> 216</a></span>&#160;<span class="keyword">inline</span> <span class="keywordtype">int</span> <a class="code" href="classoperations__research_1_1_set.html#a879ebf910431019a01f98d0865749c8d">Set&lt;uint64_t&gt;::Cardinality</a>()<span class="keyword"> const </span>{</div><div class="line"><a name="l00217"></a><span class="lineno"> 217</span>&#160; <span class="keywordflow">return</span> <a class="code" href="namespaceoperations__research.html#abc979832d72da1ae793ba6d28ae46672">BitCount64</a>(value_);</div><div class="line"><a name="l00218"></a><span class="lineno"> 218</span>&#160;}</div><div class="line"><a name="l00219"></a><span class="lineno"> 219</span>&#160;</div><div class="line"><a name="l00220"></a><span class="lineno"> 220</span>&#160;<span class="comment">// An iterator for sets of increasing corresponding values that have the same</span></div><div class="line"><a name="l00221"></a><span class="lineno"> 221</span>&#160;<span class="comment">// cardinality. For example, the sets with cardinality 3 will be listed as</span></div><div class="line"><a name="l00222"></a><span class="lineno"> 222</span>&#160;<span class="comment">// ...00111, ...01011, ...01101, ...1110, etc...</span></div><div class="line"><a name="l00223"></a><span class="lineno"> 223</span>&#160;<span class="keyword">template</span> &lt;<span class="keyword">typename</span> SetRange&gt;</div><div class="line"><a name="l00224"></a><span class="lineno"><a class="line" href="classoperations__research_1_1_set_range_iterator.html"> 224</a></span>&#160;<span class="keyword">class </span><a class="code" href="classoperations__research_1_1_set_range_iterator.html">SetRangeIterator</a> {</div><div class="line"><a name="l00225"></a><span class="lineno"> 225</span>&#160; <span class="keyword">public</span>:</div><div class="line"><a name="l00226"></a><span class="lineno"> 226</span>&#160; <span class="comment">// Make the parameter types visible to SetRangeWithCardinality.</span></div><div class="line"><a name="l00227"></a><span class="lineno"><a class="line" href="classoperations__research_1_1_set_range_iterator.html#a0e4b89b4bb1b1a5bb3c799938380aeb0"> 227</a></span>&#160; <span class="keyword">typedef</span> <span class="keyword">typename</span> SetRange::SetType <a class="code" href="classoperations__research_1_1_set_range_iterator.html#a0e4b89b4bb1b1a5bb3c799938380aeb0">SetType</a>;</div><div class="line"><a name="l00228"></a><span class="lineno"><a class="line" href="classoperations__research_1_1_set_range_iterator.html#a4ee741618ffbec86b3a2a280c61ca3f0"> 228</a></span>&#160; <span class="keyword">typedef</span> <span class="keyword">typename</span> SetType::IntegerType <a class="code" href="classoperations__research_1_1_set_range_iterator.html#a4ee741618ffbec86b3a2a280c61ca3f0">IntegerType</a>;</div><div class="line"><a name="l00229"></a><span class="lineno"> 229</span>&#160;</div><div class="line"><a name="l00230"></a><span class="lineno"><a class="line" href="classoperations__research_1_1_set_range_iterator.html#ad82623d8471ab5eb30f4e19bc89796b9"> 230</a></span>&#160; <span class="keyword">explicit</span> <a class="code" href="classoperations__research_1_1_set_range_iterator.html#ad82623d8471ab5eb30f4e19bc89796b9">SetRangeIterator</a>(<span class="keyword">const</span> <a class="code" href="classoperations__research_1_1_set_range_iterator.html#a0e4b89b4bb1b1a5bb3c799938380aeb0">SetType</a> set) : current_set_(set) {}</div><div class="line"><a name="l00231"></a><span class="lineno"> 231</span>&#160;</div><div class="line"><a name="l00232"></a><span class="lineno"> 232</span>&#160; <span class="comment">// STL iterator-related methods.</span></div><div class="line"><a name="l00233"></a><span class="lineno"><a class="line" href="classoperations__research_1_1_set_range_iterator.html#a8f6ae547a7aba92b9e4fe92a8713085a"> 233</a></span>&#160; <a class="code" href="classoperations__research_1_1_set_range_iterator.html#a0e4b89b4bb1b1a5bb3c799938380aeb0">SetType</a> <a class="code" href="classoperations__research_1_1_set_range_iterator.html#a8f6ae547a7aba92b9e4fe92a8713085a">operator*</a>()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> current_set_; }</div><div class="line"><a name="l00234"></a><span class="lineno"><a class="line" href="classoperations__research_1_1_set_range_iterator.html#a9a69c0a346336b270178d60cd6da6404"> 234</a></span>&#160; <span class="keywordtype">bool</span> <a class="code" href="classoperations__research_1_1_set_range_iterator.html#a9a69c0a346336b270178d60cd6da6404">operator!=</a>(<span class="keyword">const</span> <a class="code" href="classoperations__research_1_1_set_range_iterator.html">SetRangeIterator</a>&amp; other)<span class="keyword"> const </span>{</div><div class="line"><a name="l00235"></a><span class="lineno"> 235</span>&#160; <span class="keywordflow">return</span> current_set_ != other.current_set_;</div><div class="line"><a name="l00236"></a><span class="lineno"> 236</span>&#160; }</div><div class="line"><a name="l00237"></a><span class="lineno"> 237</span>&#160;</div><div class="line"><a name="l00238"></a><span class="lineno"> 238</span>&#160; <span class="comment">// Computes the next set with the same cardinality using Gosper&#39;s hack.</span></div><div class="line"><a name="l00239"></a><span class="lineno"> 239</span>&#160; <span class="comment">// ftp://publications.ai.mit.edu/ai-publications/pdf/AIM-239.pdf ITEM 175</span></div><div class="line"><a name="l00240"></a><span class="lineno"> 240</span>&#160; <span class="comment">// Also translated in C https://www.cl.cam.ac.uk/~am21/hakmemc.html</span></div><div class="line"><a name="l00241"></a><span class="lineno"><a class="line" href="classoperations__research_1_1_set_range_iterator.html#ab199aaba95428b8647f6bfdd83ecb68c"> 241</a></span>&#160; <span class="keyword">const</span> <a class="code" href="classoperations__research_1_1_set_range_iterator.html">SetRangeIterator</a>&amp; <a class="code" href="classoperations__research_1_1_set_range_iterator.html#ab199aaba95428b8647f6bfdd83ecb68c">operator++</a>() {</div><div class="line"><a name="l00242"></a><span class="lineno"> 242</span>&#160; <span class="keyword">const</span> <a class="code" href="classoperations__research_1_1_set_range_iterator.html#a4ee741618ffbec86b3a2a280c61ca3f0">IntegerType</a> c = current_set_.SmallestSingleton().value();</div><div class="line"><a name="l00243"></a><span class="lineno"> 243</span>&#160; <span class="keyword">const</span> <a class="code" href="classoperations__research_1_1_set_range_iterator.html#a4ee741618ffbec86b3a2a280c61ca3f0">IntegerType</a> <a class="code" href="constraint__solver_2table_8cc.html#acb18315d548212835cd8ed4287e6c0b6">a</a> = current_set_.value();</div><div class="line"><a name="l00244"></a><span class="lineno"> 244</span>&#160; <span class="keyword">const</span> <a class="code" href="classoperations__research_1_1_set_range_iterator.html#a4ee741618ffbec86b3a2a280c61ca3f0">IntegerType</a> r = c + current_set_.value();</div><div class="line"><a name="l00245"></a><span class="lineno"> 245</span>&#160; <span class="comment">// Dividing by c as in HAKMEMC can be avoided by taking into account</span></div><div class="line"><a name="l00246"></a><span class="lineno"> 246</span>&#160; <span class="comment">// that c is the smallest singleton of current_set_, and using a shift.</span></div><div class="line"><a name="l00247"></a><span class="lineno"> 247</span>&#160; <span class="keyword">const</span> <a class="code" href="classoperations__research_1_1_set_range_iterator.html#a4ee741618ffbec86b3a2a280c61ca3f0">IntegerType</a> shift = current_set_.SmallestElement();</div><div class="line"><a name="l00248"></a><span class="lineno"> 248</span>&#160; current_set_ = r == 0 ? <a class="code" href="classoperations__research_1_1_set_range_iterator.html#a0e4b89b4bb1b1a5bb3c799938380aeb0">SetType</a>(0) : <a class="code" href="classoperations__research_1_1_set_range_iterator.html#a0e4b89b4bb1b1a5bb3c799938380aeb0">SetType</a>(((r ^ <a class="code" href="constraint__solver_2table_8cc.html#acb18315d548212835cd8ed4287e6c0b6">a</a>) &gt;&gt; (shift + 2)) | r);</div><div class="line"><a name="l00249"></a><span class="lineno"> 249</span>&#160; <span class="keywordflow">return</span> *<span class="keyword">this</span>;</div><div class="line"><a name="l00250"></a><span class="lineno"> 250</span>&#160; }</div><div class="line"><a name="l00251"></a><span class="lineno"> 251</span>&#160;</div><div class="line"><a name="l00252"></a><span class="lineno"> 252</span>&#160; <span class="keyword">private</span>:</div><div class="line"><a name="l00253"></a><span class="lineno"> 253</span>&#160; <span class="comment">// The current set of iterator.</span></div><div class="line"><a name="l00254"></a><span class="lineno"> 254</span>&#160; <a class="code" href="classoperations__research_1_1_set_range_iterator.html#a0e4b89b4bb1b1a5bb3c799938380aeb0">SetType</a> current_set_;</div><div class="line"><a name="l00255"></a><span class="lineno"> 255</span>&#160;};</div><div class="line"><a name="l00256"></a><span class="lineno"> 256</span>&#160;</div><div class="line"><a name="l00257"></a><span class="lineno"> 257</span>&#160;<span class="keyword">template</span> &lt;<span class="keyword">typename</span> Set&gt;</div><div class="line"><a name="l00258"></a><span class="lineno"><a class="line" href="classoperations__research_1_1_set_range_with_cardinality.html"> 258</a></span>&#160;<span class="keyword">class </span><a class="code" href="classoperations__research_1_1_set_range_with_cardinality.html">SetRangeWithCardinality</a> {</div><div class="line"><a name="l00259"></a><span class="lineno"> 259</span>&#160; <span class="keyword">public</span>:</div><div class="line"><a name="l00260"></a><span class="lineno"><a class="line" href="classoperations__research_1_1_set_range_with_cardinality.html#ac04647d141301b9671da400a7add8e37"> 260</a></span>&#160; <span class="keyword">typedef</span> <a class="code" href="classoperations__research_1_1_set.html">Set</a> <a class="code" href="classoperations__research_1_1_set_range_with_cardinality.html#ac04647d141301b9671da400a7add8e37">SetType</a>;</div><div class="line"><a name="l00261"></a><span class="lineno"> 261</span>&#160; <span class="comment">// The end_ set is the first set with cardinality card, that does not fit</span></div><div class="line"><a name="l00262"></a><span class="lineno"> 262</span>&#160; <span class="comment">// in max_card bits. Thus, its bit at position max_card is set, and the</span></div><div class="line"><a name="l00263"></a><span class="lineno"> 263</span>&#160; <span class="comment">// rightmost (card - 1) bits are set.</span></div><div class="line"><a name="l00264"></a><span class="lineno"><a class="line" href="classoperations__research_1_1_set_range_with_cardinality.html#ac227945449c4f8144b6c92afd6ae2156"> 264</a></span>&#160; <a class="code" href="classoperations__research_1_1_set_range_with_cardinality.html#ac227945449c4f8144b6c92afd6ae2156">SetRangeWithCardinality</a>(<span class="keywordtype">int</span> card, <span class="keywordtype">int</span> max_card)</div><div class="line"><a name="l00265"></a><span class="lineno"> 265</span>&#160; : begin_(<a class="code" href="classoperations__research_1_1_set.html">Set</a>::FullSet(card)),</div><div class="line"><a name="l00266"></a><span class="lineno"> 266</span>&#160; end_(<a class="code" href="classoperations__research_1_1_set.html">Set</a>::FullSet(card - 1).AddElement(max_card)) {</div><div class="line"><a name="l00267"></a><span class="lineno"> 267</span>&#160; <a class="code" href="base_2logging_8h.html#ab62f5ed8f2d48e29802be0cbbcd1359a">DCHECK_LT</a>(0, card);</div><div class="line"><a name="l00268"></a><span class="lineno"> 268</span>&#160; <a class="code" href="base_2logging_8h.html#ab62f5ed8f2d48e29802be0cbbcd1359a">DCHECK_LT</a>(0, max_card);</div><div class="line"><a name="l00269"></a><span class="lineno"> 269</span>&#160; <a class="code" href="base_2logging_8h.html#ae89df3243bbb8341130c7b3f44145ea0">DCHECK_EQ</a>(card, begin_.<a class="code" href="classoperations__research_1_1_set.html#a879ebf910431019a01f98d0865749c8d">Cardinality</a>());</div><div class="line"><a name="l00270"></a><span class="lineno"> 270</span>&#160; <a class="code" href="base_2logging_8h.html#ae89df3243bbb8341130c7b3f44145ea0">DCHECK_EQ</a>(card, end_.<a class="code" href="classoperations__research_1_1_set.html#a879ebf910431019a01f98d0865749c8d">Cardinality</a>());</div><div class="line"><a name="l00271"></a><span class="lineno"> 271</span>&#160; }</div><div class="line"><a name="l00272"></a><span class="lineno"> 272</span>&#160;</div><div class="line"><a name="l00273"></a><span class="lineno"> 273</span>&#160; <span class="comment">// STL iterator-related methods.</span></div><div class="line"><a name="l00274"></a><span class="lineno"><a class="line" href="classoperations__research_1_1_set_range_with_cardinality.html#a24d9704faf4d419fdabbde6a716e181d"> 274</a></span>&#160; <a class="code" href="classoperations__research_1_1_set_range_iterator.html">SetRangeIterator&lt;SetRangeWithCardinality&gt;</a> <a class="code" href="classoperations__research_1_1_set_range_with_cardinality.html#a24d9704faf4d419fdabbde6a716e181d">begin</a>()<span class="keyword"> const </span>{</div><div class="line"><a name="l00275"></a><span class="lineno"> 275</span>&#160; <span class="keywordflow">return</span> <a class="code" href="classoperations__research_1_1_set_range_iterator.html">SetRangeIterator&lt;SetRangeWithCardinality&gt;</a>(begin_);</div><div class="line"><a name="l00276"></a><span class="lineno"> 276</span>&#160; }</div><div class="line"><a name="l00277"></a><span class="lineno"><a class="line" href="classoperations__research_1_1_set_range_with_cardinality.html#af7124add76feb58bf035c3375fe140f9"> 277</a></span>&#160; <a class="code" href="classoperations__research_1_1_set_range_iterator.html">SetRangeIterator&lt;SetRangeWithCardinality&gt;</a> <a class="code" href="classoperations__research_1_1_set_range_with_cardinality.html#af7124add76feb58bf035c3375fe140f9">end</a>()<span class="keyword"> const </span>{</div><div class="line"><a name="l00278"></a><span class="lineno"> 278</span>&#160; <span class="keywordflow">return</span> <a class="code" href="classoperations__research_1_1_set_range_iterator.html">SetRangeIterator&lt;SetRangeWithCardinality&gt;</a>(end_);</div><div class="line"><a name="l00279"></a><span class="lineno"> 279</span>&#160; }</div><div class="line"><a name="l00280"></a><span class="lineno"> 280</span>&#160;</div><div class="line"><a name="l00281"></a><span class="lineno"> 281</span>&#160; <span class="keyword">private</span>:</div><div class="line"><a name="l00282"></a><span class="lineno"> 282</span>&#160; <span class="comment">// Keep the beginning and end of the iterator.</span></div><div class="line"><a name="l00283"></a><span class="lineno"> 283</span>&#160; <a class="code" href="classoperations__research_1_1_set_range_with_cardinality.html#ac04647d141301b9671da400a7add8e37">SetType</a> begin_;</div><div class="line"><a name="l00284"></a><span class="lineno"> 284</span>&#160; <a class="code" href="classoperations__research_1_1_set_range_with_cardinality.html#ac04647d141301b9671da400a7add8e37">SetType</a> end_;</div><div class="line"><a name="l00285"></a><span class="lineno"> 285</span>&#160;};</div><div class="line"><a name="l00286"></a><span class="lineno"> 286</span>&#160;</div><div class="line"><a name="l00287"></a><span class="lineno"> 287</span>&#160;<span class="comment">// The Dynamic Programming (DP) algorithm memorizes the values f(set, node) for</span></div><div class="line"><a name="l00288"></a><span class="lineno"> 288</span>&#160;<span class="comment">// node in set, for all the subsets of cardinality &lt;= max_card_.</span></div><div class="line"><a name="l00289"></a><span class="lineno"> 289</span>&#160;<span class="comment">// LatticeMemoryManager manages the storage of f(set, node) so that the</span></div><div class="line"><a name="l00290"></a><span class="lineno"> 290</span>&#160;<span class="comment">// DP iteration access memory in increasing addresses.</span></div><div class="line"><a name="l00291"></a><span class="lineno"> 291</span>&#160;<span class="keyword">template</span> &lt;<span class="keyword">typename</span> Set, <span class="keyword">typename</span> CostType&gt;</div><div class="line"><a name="l00292"></a><span class="lineno"><a class="line" href="classoperations__research_1_1_lattice_memory_manager.html"> 292</a></span>&#160;<span class="keyword">class </span><a class="code" href="classoperations__research_1_1_lattice_memory_manager.html">LatticeMemoryManager</a> {</div><div class="line"><a name="l00293"></a><span class="lineno"> 293</span>&#160; <span class="keyword">public</span>:</div><div class="line"><a name="l00294"></a><span class="lineno"><a class="line" href="classoperations__research_1_1_lattice_memory_manager.html#a03b88bdfd0b2fcc7e14106cbd425629a"> 294</a></span>&#160; <a class="code" href="classoperations__research_1_1_lattice_memory_manager.html#a03b88bdfd0b2fcc7e14106cbd425629a">LatticeMemoryManager</a>() : max_card_(0) {}</div><div class="line"><a name="l00295"></a><span class="lineno"> 295</span>&#160;</div><div class="line"><a name="l00296"></a><span class="lineno"> 296</span>&#160; <span class="comment">// Reserves memory and fills in the data necessary to access memory.</span></div><div class="line"><a name="l00297"></a><span class="lineno"> 297</span>&#160; <span class="keywordtype">void</span> <a class="code" href="classoperations__research_1_1_lattice_memory_manager.html#a9614dfea1a66f5d18799a058adc57a95">Init</a>(<span class="keywordtype">int</span> max_card);</div><div class="line"><a name="l00298"></a><span class="lineno"> 298</span>&#160;</div><div class="line"><a name="l00299"></a><span class="lineno"> 299</span>&#160; <span class="comment">// Returns the offset in memory for f(s, node), with node contained in s.</span></div><div class="line"><a name="l00300"></a><span class="lineno"> 300</span>&#160; uint64_t <a class="code" href="classoperations__research_1_1_lattice_memory_manager.html#a1958048f654b22c744e32dfbcdbeb416">Offset</a>(<a class="code" href="classoperations__research_1_1_set.html">Set</a> s, <span class="keywordtype">int</span> node) <span class="keyword">const</span>;</div><div class="line"><a name="l00301"></a><span class="lineno"> 301</span>&#160;</div><div class="line"><a name="l00302"></a><span class="lineno"> 302</span>&#160; <span class="comment">// Returns the base offset in memory for f(s, node), with node contained in s.</span></div><div class="line"><a name="l00303"></a><span class="lineno"> 303</span>&#160; <span class="comment">// This is useful in the Dynamic Programming iterations.</span></div><div class="line"><a name="l00304"></a><span class="lineno"> 304</span>&#160; <span class="comment">// Note(user): inlining this function gains about 5%.</span></div><div class="line"><a name="l00305"></a><span class="lineno"> 305</span>&#160; <span class="comment">// TODO(user): Investigate how to compute BaseOffset(card - 1, s \ { n })</span></div><div class="line"><a name="l00306"></a><span class="lineno"> 306</span>&#160; <span class="comment">// from BaseOffset(card, n) to speed up the DP iteration.</span></div><div class="line"><a name="l00307"></a><span class="lineno"> 307</span>&#160; <span class="keyword">inline</span> uint64_t <a class="code" href="classoperations__research_1_1_lattice_memory_manager.html#af4a801d214f8a294a6abf462ac12e80a">BaseOffset</a>(<span class="keywordtype">int</span> card, <a class="code" href="classoperations__research_1_1_set.html">Set</a> s) <span class="keyword">const</span>;</div><div class="line"><a name="l00308"></a><span class="lineno"> 308</span>&#160;</div><div class="line"><a name="l00309"></a><span class="lineno"> 309</span>&#160; <span class="comment">// Returns the offset delta for a set of cardinality &#39;card&#39;, to which</span></div><div class="line"><a name="l00310"></a><span class="lineno"> 310</span>&#160; <span class="comment">// node &#39;removed_node&#39; is replaced by &#39;added_node&#39; at &#39;rank&#39;</span></div><div class="line"><a name="l00311"></a><span class="lineno"><a class="line" href="classoperations__research_1_1_lattice_memory_manager.html#a6789c7b14fc935d7e3d03e1376cb79d8"> 311</a></span>&#160; uint64_t <a class="code" href="classoperations__research_1_1_lattice_memory_manager.html#a6789c7b14fc935d7e3d03e1376cb79d8">OffsetDelta</a>(<span class="keywordtype">int</span> card, <span class="keywordtype">int</span> added_node, <span class="keywordtype">int</span> removed_node,</div><div class="line"><a name="l00312"></a><span class="lineno"> 312</span>&#160; <span class="keywordtype">int</span> rank)<span class="keyword"> const </span>{</div><div class="line"><a name="l00313"></a><span class="lineno"> 313</span>&#160; <span class="keywordflow">return</span> card *</div><div class="line"><a name="l00314"></a><span class="lineno"> 314</span>&#160; (binomial_coefficients_[added_node][rank] - <span class="comment">// delta for added_node</span></div><div class="line"><a name="l00315"></a><span class="lineno"> 315</span>&#160; binomial_coefficients_[removed_node][rank]); <span class="comment">// for removed_node.</span></div><div class="line"><a name="l00316"></a><span class="lineno"> 316</span>&#160; }</div><div class="line"><a name="l00317"></a><span class="lineno"> 317</span>&#160;</div><div class="line"><a name="l00318"></a><span class="lineno"> 318</span>&#160; <span class="comment">// Memorizes the value = f(s, node) at the correct offset.</span></div><div class="line"><a name="l00319"></a><span class="lineno"> 319</span>&#160; <span class="comment">// This is favored in all other uses than the Dynamic Programming iterations.</span></div><div class="line"><a name="l00320"></a><span class="lineno"> 320</span>&#160; <span class="keywordtype">void</span> <a class="code" href="classoperations__research_1_1_lattice_memory_manager.html#a4c59c8afdecf1f9d139609ffe9f172ca">SetValue</a>(<a class="code" href="classoperations__research_1_1_set.html">Set</a> s, <span class="keywordtype">int</span> node, CostType <a class="code" href="demon__profiler_8cc.html#ac072af30c4ffbc834bb4c681f6ecb514">value</a>);</div><div class="line"><a name="l00321"></a><span class="lineno"> 321</span>&#160;</div><div class="line"><a name="l00322"></a><span class="lineno"> 322</span>&#160; <span class="comment">// Memorizes &#39;value&#39; at &#39;offset&#39;. This is useful in the Dynamic Programming</span></div><div class="line"><a name="l00323"></a><span class="lineno"> 323</span>&#160; <span class="comment">// iterations where we want to avoid compute the offset of a pair (set, node).</span></div><div class="line"><a name="l00324"></a><span class="lineno"><a class="line" href="classoperations__research_1_1_lattice_memory_manager.html#a91814684a688a3264fc8f29972969d61"> 324</a></span>&#160; <span class="keywordtype">void</span> <a class="code" href="classoperations__research_1_1_lattice_memory_manager.html#a91814684a688a3264fc8f29972969d61">SetValueAtOffset</a>(uint64_t offset, CostType <a class="code" href="demon__profiler_8cc.html#ac072af30c4ffbc834bb4c681f6ecb514">value</a>) {</div><div class="line"><a name="l00325"></a><span class="lineno"> 325</span>&#160; memory_[offset] = <a class="code" href="demon__profiler_8cc.html#ac072af30c4ffbc834bb4c681f6ecb514">value</a>;</div><div class="line"><a name="l00326"></a><span class="lineno"> 326</span>&#160; }</div><div class="line"><a name="l00327"></a><span class="lineno"> 327</span>&#160;</div><div class="line"><a name="l00328"></a><span class="lineno"> 328</span>&#160; <span class="comment">// Returns the memorized value f(s, node) with node in s.</span></div><div class="line"><a name="l00329"></a><span class="lineno"> 329</span>&#160; <span class="comment">// This is favored in all other uses than the Dynamic Programming iterations.</span></div><div class="line"><a name="l00330"></a><span class="lineno"> 330</span>&#160; CostType <a class="code" href="classoperations__research_1_1_lattice_memory_manager.html#aab77eae51a0b3e7781df913213ff4372">Value</a>(<a class="code" href="classoperations__research_1_1_set.html">Set</a> s, <span class="keywordtype">int</span> node) <span class="keyword">const</span>;</div><div class="line"><a name="l00331"></a><span class="lineno"> 331</span>&#160;</div><div class="line"><a name="l00332"></a><span class="lineno"> 332</span>&#160; <span class="comment">// Returns the memorized value at &#39;offset&#39;.</span></div><div class="line"><a name="l00333"></a><span class="lineno"> 333</span>&#160; <span class="comment">// This is useful in the Dynamic Programming iterations.</span></div><div class="line"><a name="l00334"></a><span class="lineno"><a class="line" href="classoperations__research_1_1_lattice_memory_manager.html#afc715a6711310680640765eb66822f8b"> 334</a></span>&#160; CostType <a class="code" href="classoperations__research_1_1_lattice_memory_manager.html#afc715a6711310680640765eb66822f8b">ValueAtOffset</a>(uint64_t offset)<span class="keyword"> const </span>{ <span class="keywordflow">return</span> memory_[offset]; }</div><div class="line"><a name="l00335"></a><span class="lineno"> 335</span>&#160;</div><div class="line"><a name="l00336"></a><span class="lineno"> 336</span>&#160; <span class="keyword">private</span>:</div><div class="line"><a name="l00337"></a><span class="lineno"> 337</span>&#160; <span class="comment">// Returns true if the values used to manage memory are set correctly.</span></div><div class="line"><a name="l00338"></a><span class="lineno"> 338</span>&#160; <span class="comment">// This is intended to only be used in a DCHECK.</span></div><div class="line"><a name="l00339"></a><span class="lineno"> 339</span>&#160; <span class="keywordtype">bool</span> CheckConsistency() <span class="keyword">const</span>;</div><div class="line"><a name="l00340"></a><span class="lineno"> 340</span>&#160;</div><div class="line"><a name="l00341"></a><span class="lineno"> 341</span>&#160; <span class="comment">// The maximum cardinality of the set on which the lattice is going to be</span></div><div class="line"><a name="l00342"></a><span class="lineno"> 342</span>&#160; <span class="comment">// used. This is equal to the number of nodes in the TSP.</span></div><div class="line"><a name="l00343"></a><span class="lineno"> 343</span>&#160; <span class="keywordtype">int</span> max_card_;</div><div class="line"><a name="l00344"></a><span class="lineno"> 344</span>&#160;</div><div class="line"><a name="l00345"></a><span class="lineno"> 345</span>&#160; <span class="comment">// binomial_coefficients_[n][k] contains (n choose k).</span></div><div class="line"><a name="l00346"></a><span class="lineno"> 346</span>&#160; std::vector&lt;std::vector&lt;uint64_t&gt;&gt; binomial_coefficients_;</div><div class="line"><a name="l00347"></a><span class="lineno"> 347</span>&#160;</div><div class="line"><a name="l00348"></a><span class="lineno"> 348</span>&#160; <span class="comment">// base_offset_[card] contains the base offset for all f(set, node) with</span></div><div class="line"><a name="l00349"></a><span class="lineno"> 349</span>&#160; <span class="comment">// card(set) == card.</span></div><div class="line"><a name="l00350"></a><span class="lineno"> 350</span>&#160; std::vector&lt;int64_t&gt; base_offset_;</div><div class="line"><a name="l00351"></a><span class="lineno"> 351</span>&#160;</div><div class="line"><a name="l00352"></a><span class="lineno"> 352</span>&#160; <span class="comment">// memory_[Offset(set, node)] contains the costs of the partial path</span></div><div class="line"><a name="l00353"></a><span class="lineno"> 353</span>&#160; <span class="comment">// f(set, node).</span></div><div class="line"><a name="l00354"></a><span class="lineno"> 354</span>&#160; std::vector&lt;CostType&gt; memory_;</div><div class="line"><a name="l00355"></a><span class="lineno"> 355</span>&#160;};</div><div class="line"><a name="l00356"></a><span class="lineno"> 356</span>&#160;</div><div class="line"><a name="l00357"></a><span class="lineno"> 357</span>&#160;<span class="keyword">template</span> &lt;<span class="keyword">typename</span> Set, <span class="keyword">typename</span> CostType&gt;</div><div class="line"><a name="l00358"></a><span class="lineno"><a class="line" href="classoperations__research_1_1_lattice_memory_manager.html#a9614dfea1a66f5d18799a058adc57a95"> 358</a></span>&#160;<span class="keywordtype">void</span> <a class="code" href="classoperations__research_1_1_lattice_memory_manager.html#a9614dfea1a66f5d18799a058adc57a95">LatticeMemoryManager&lt;Set, CostType&gt;::Init</a>(<span class="keywordtype">int</span> max_card) {</div><div class="line"><a name="l00359"></a><span class="lineno"> 359</span>&#160; <a class="code" href="base_2logging_8h.html#ab62f5ed8f2d48e29802be0cbbcd1359a">DCHECK_LT</a>(0, max_card);</div><div class="line"><a name="l00360"></a><span class="lineno"> 360</span>&#160; <a class="code" href="base_2logging_8h.html#aae2dc65d9ea248d54bf39daa986dd295">DCHECK_GE</a>(<a class="code" href="classoperations__research_1_1_set.html#a062c0acf17a051b885ad211acad31079">Set::MaxCardinality</a>, max_card);</div><div class="line"><a name="l00361"></a><span class="lineno"> 361</span>&#160; <span class="keywordflow">if</span> (max_card &lt;= max_card_) <span class="keywordflow">return</span>;</div><div class="line"><a name="l00362"></a><span class="lineno"> 362</span>&#160; max_card_ = max_card;</div><div class="line"><a name="l00363"></a><span class="lineno"> 363</span>&#160; binomial_coefficients_.resize(max_card_ + 1);</div><div class="line"><a name="l00364"></a><span class="lineno"> 364</span>&#160;</div><div class="line"><a name="l00365"></a><span class="lineno"> 365</span>&#160; <span class="comment">// Initialize binomial_coefficients_ using Pascal&#39;s triangle recursion.</span></div><div class="line"><a name="l00366"></a><span class="lineno"> 366</span>&#160; <span class="keywordflow">for</span> (<span class="keywordtype">int</span> n = 0; n &lt;= max_card_; ++n) {</div><div class="line"><a name="l00367"></a><span class="lineno"> 367</span>&#160; binomial_coefficients_[n].resize(n + 2);</div><div class="line"><a name="l00368"></a><span class="lineno"> 368</span>&#160; binomial_coefficients_[n][0] = 1;</div><div class="line"><a name="l00369"></a><span class="lineno"> 369</span>&#160; <span class="keywordflow">for</span> (<span class="keywordtype">int</span> k = 1; k &lt;= n; ++k) {</div><div class="line"><a name="l00370"></a><span class="lineno"> 370</span>&#160; binomial_coefficients_[n][k] = binomial_coefficients_[n - 1][k - 1] +</div><div class="line"><a name="l00371"></a><span class="lineno"> 371</span>&#160; binomial_coefficients_[n - 1][k];</div><div class="line"><a name="l00372"></a><span class="lineno"> 372</span>&#160; }</div><div class="line"><a name="l00373"></a><span class="lineno"> 373</span>&#160; <span class="comment">// Extend to (n, n + 1) to minimize branchings in LatticeMemoryManager().</span></div><div class="line"><a name="l00374"></a><span class="lineno"> 374</span>&#160; <span class="comment">// This also makes the recurrence above work for k = n.</span></div><div class="line"><a name="l00375"></a><span class="lineno"> 375</span>&#160; binomial_coefficients_[n][n + 1] = 0;</div><div class="line"><a name="l00376"></a><span class="lineno"> 376</span>&#160; }</div><div class="line"><a name="l00377"></a><span class="lineno"> 377</span>&#160; base_offset_.resize(max_card_ + 1);</div><div class="line"><a name="l00378"></a><span class="lineno"> 378</span>&#160; base_offset_[0] = 0;</div><div class="line"><a name="l00379"></a><span class="lineno"> 379</span>&#160; <span class="comment">// There are k * binomial_coefficients_[max_card_][k] f(S,j) values to store</span></div><div class="line"><a name="l00380"></a><span class="lineno"> 380</span>&#160; <span class="comment">// for each group of f(S,j), with card(S) = k. Update base_offset[k]</span></div><div class="line"><a name="l00381"></a><span class="lineno"> 381</span>&#160; <span class="comment">// accordingly.</span></div><div class="line"><a name="l00382"></a><span class="lineno"> 382</span>&#160; <span class="keywordflow">for</span> (<span class="keywordtype">int</span> k = 0; k &lt; max_card_; ++k) {</div><div class="line"><a name="l00383"></a><span class="lineno"> 383</span>&#160; base_offset_[k + 1] =</div><div class="line"><a name="l00384"></a><span class="lineno"> 384</span>&#160; base_offset_[k] + k * binomial_coefficients_[max_card_][k];</div><div class="line"><a name="l00385"></a><span class="lineno"> 385</span>&#160; }</div><div class="line"><a name="l00386"></a><span class="lineno"> 386</span>&#160; memory_.resize(0);</div><div class="line"><a name="l00387"></a><span class="lineno"> 387</span>&#160; memory_.shrink_to_fit();</div><div class="line"><a name="l00388"></a><span class="lineno"> 388</span>&#160; memory_.resize(max_card_ * (1 &lt;&lt; (max_card_ - 1)));</div><div class="line"><a name="l00389"></a><span class="lineno"> 389</span>&#160; <a class="code" href="base_2logging_8h.html#ae17f8119c108cf3070bad3449c7e0006">DCHECK</a>(CheckConsistency());</div><div class="line"><a name="l00390"></a><span class="lineno"> 390</span>&#160;}</div><div class="line"><a name="l00391"></a><span class="lineno"> 391</span>&#160;</div><div class="line"><a name="l00392"></a><span class="lineno"> 392</span>&#160;<span class="keyword">template</span> &lt;<span class="keyword">typename</span> Set, <span class="keyword">typename</span> CostType&gt;</div><div class="line"><a name="l00393"></a><span class="lineno"> 393</span>&#160;<span class="keywordtype">bool</span> <a class="code" href="classoperations__research_1_1_lattice_memory_manager.html">LatticeMemoryManager&lt;Set, CostType&gt;::CheckConsistency</a>()<span class="keyword"> const </span>{</div><div class="line"><a name="l00394"></a><span class="lineno"> 394</span>&#160; <span class="keywordflow">for</span> (<span class="keywordtype">int</span> n = 0; n &lt;= max_card_; ++n) {</div><div class="line"><a name="l00395"></a><span class="lineno"> 395</span>&#160; int64_t sum = 0;</div><div class="line"><a name="l00396"></a><span class="lineno"> 396</span>&#160; <span class="keywordflow">for</span> (<span class="keywordtype">int</span> k = 0; k &lt;= n; ++k) {</div><div class="line"><a name="l00397"></a><span class="lineno"> 397</span>&#160; sum += binomial_coefficients_[n][k];</div><div class="line"><a name="l00398"></a><span class="lineno"> 398</span>&#160; }</div><div class="line"><a name="l00399"></a><span class="lineno"> 399</span>&#160; <a class="code" href="base_2logging_8h.html#ae89df3243bbb8341130c7b3f44145ea0">DCHECK_EQ</a>(1 &lt;&lt; n, sum);</div><div class="line"><a name="l00400"></a><span class="lineno"> 400</span>&#160; }</div><div class="line"><a name="l00401"></a><span class="lineno"> 401</span>&#160; <a class="code" href="base_2logging_8h.html#ae89df3243bbb8341130c7b3f44145ea0">DCHECK_EQ</a>(0, base_offset_[1]);</div><div class="line"><a name="l00402"></a><span class="lineno"> 402</span>&#160; <a class="code" href="base_2logging_8h.html#ae89df3243bbb8341130c7b3f44145ea0">DCHECK_EQ</a>(max_card_ * (1 &lt;&lt; (max_card_ - 1)),</div><div class="line"><a name="l00403"></a><span class="lineno"> 403</span>&#160; base_offset_[max_card_] + max_card_);</div><div class="line"><a name="l00404"></a><span class="lineno"> 404</span>&#160; <span class="keywordflow">return</span> <span class="keyword">true</span>;</div><div class="line"><a name="l00405"></a><span class="lineno"> 405</span>&#160;}</div><div class="line"><a name="l00406"></a><span class="lineno"> 406</span>&#160;</div><div class="line"><a name="l00407"></a><span class="lineno"> 407</span>&#160;<span class="keyword">template</span> &lt;<span class="keyword">typename</span> Set, <span class="keyword">typename</span> CostType&gt;</div><div class="line"><a name="l00408"></a><span class="lineno"><a class="line" href="classoperations__research_1_1_lattice_memory_manager.html#af4a801d214f8a294a6abf462ac12e80a"> 408</a></span>&#160;uint64_t <a class="code" href="classoperations__research_1_1_lattice_memory_manager.html#af4a801d214f8a294a6abf462ac12e80a">LatticeMemoryManager&lt;Set, CostType&gt;::BaseOffset</a>(<span class="keywordtype">int</span> card,</div><div class="line"><a name="l00409"></a><span class="lineno"> 409</span>&#160; <a class="code" href="classoperations__research_1_1_set.html">Set</a> set)<span class="keyword"> const </span>{</div><div class="line"><a name="l00410"></a><span class="lineno"> 410</span>&#160; <a class="code" href="base_2logging_8h.html#ab62f5ed8f2d48e29802be0cbbcd1359a">DCHECK_LT</a>(0, card);</div><div class="line"><a name="l00411"></a><span class="lineno"> 411</span>&#160; <a class="code" href="base_2logging_8h.html#ae89df3243bbb8341130c7b3f44145ea0">DCHECK_EQ</a>(set.<a class="code" href="classoperations__research_1_1_set.html#a879ebf910431019a01f98d0865749c8d">Cardinality</a>(), card);</div><div class="line"><a name="l00412"></a><span class="lineno"> 412</span>&#160; uint64_t local_offset = 0;</div><div class="line"><a name="l00413"></a><span class="lineno"> 413</span>&#160; <span class="keywordtype">int</span> node_rank = 0;</div><div class="line"><a name="l00414"></a><span class="lineno"> 414</span>&#160; <span class="keywordflow">for</span> (<span class="keywordtype">int</span> node : set) {</div><div class="line"><a name="l00415"></a><span class="lineno"> 415</span>&#160; <span class="comment">// There are binomial_coefficients_[node][node_rank + 1] sets which have</span></div><div class="line"><a name="l00416"></a><span class="lineno"> 416</span>&#160; <span class="comment">// node at node_rank.</span></div><div class="line"><a name="l00417"></a><span class="lineno"> 417</span>&#160; local_offset += binomial_coefficients_[node][node_rank + 1];</div><div class="line"><a name="l00418"></a><span class="lineno"> 418</span>&#160; ++node_rank;</div><div class="line"><a name="l00419"></a><span class="lineno"> 419</span>&#160; }</div><div class="line"><a name="l00420"></a><span class="lineno"> 420</span>&#160; <a class="code" href="base_2logging_8h.html#ae89df3243bbb8341130c7b3f44145ea0">DCHECK_EQ</a>(card, node_rank);</div><div class="line"><a name="l00421"></a><span class="lineno"> 421</span>&#160; <span class="comment">// Note(user): It is possible to get rid of base_offset_[card] by using a 2-D</span></div><div class="line"><a name="l00422"></a><span class="lineno"> 422</span>&#160; <span class="comment">// array. It would also make it possible to free all the memory but the layer</span></div><div class="line"><a name="l00423"></a><span class="lineno"> 423</span>&#160; <span class="comment">// being constructed and the preceding one, if another lattice of paths is</span></div><div class="line"><a name="l00424"></a><span class="lineno"> 424</span>&#160; <span class="comment">// constructed.</span></div><div class="line"><a name="l00425"></a><span class="lineno"> 425</span>&#160; <span class="comment">// TODO(user): Evaluate the interest of the above.</span></div><div class="line"><a name="l00426"></a><span class="lineno"> 426</span>&#160; <span class="comment">// There are &#39;card&#39; f(set, j) to store. That is why we need to multiply</span></div><div class="line"><a name="l00427"></a><span class="lineno"> 427</span>&#160; <span class="comment">// local_offset by card before adding it to the corresponding base_offset_.</span></div><div class="line"><a name="l00428"></a><span class="lineno"> 428</span>&#160; <span class="keywordflow">return</span> base_offset_[card] + card * local_offset;</div><div class="line"><a name="l00429"></a><span class="lineno"> 429</span>&#160;}</div><div class="line"><a name="l00430"></a><span class="lineno"> 430</span>&#160;</div><div class="line"><a name="l00431"></a><span class="lineno"> 431</span>&#160;<span class="keyword">template</span> &lt;<span class="keyword">typename</span> Set, <span class="keyword">typename</span> CostType&gt;</div><div class="line"><a name="l00432"></a><span class="lineno"><a class="line" href="classoperations__research_1_1_lattice_memory_manager.html#a1958048f654b22c744e32dfbcdbeb416"> 432</a></span>&#160;uint64_t <a class="code" href="classoperations__research_1_1_lattice_memory_manager.html#a1958048f654b22c744e32dfbcdbeb416">LatticeMemoryManager&lt;Set, CostType&gt;::Offset</a>(<a class="code" href="classoperations__research_1_1_set.html">Set</a> set, <span class="keywordtype">int</span> node)<span class="keyword"> const </span>{</div><div class="line"><a name="l00433"></a><span class="lineno"> 433</span>&#160; <a class="code" href="base_2logging_8h.html#ae17f8119c108cf3070bad3449c7e0006">DCHECK</a>(set.<a class="code" href="classoperations__research_1_1_set.html#a0faec65dbf29460ec59dfa75d0536efb">Contains</a>(node));</div><div class="line"><a name="l00434"></a><span class="lineno"> 434</span>&#160; <span class="keywordflow">return</span> BaseOffset(set.<a class="code" href="classoperations__research_1_1_set.html#a879ebf910431019a01f98d0865749c8d">Cardinality</a>(), set) + set.<a class="code" href="classoperations__research_1_1_set.html#a33392f61ea41062250f3664a055cd3bf">ElementRank</a>(node);</div><div class="line"><a name="l00435"></a><span class="lineno"> 435</span>&#160;}</div><div class="line"><a name="l00436"></a><span class="lineno"> 436</span>&#160;</div><div class="line"><a name="l00437"></a><span class="lineno"> 437</span>&#160;<span class="keyword">template</span> &lt;<span class="keyword">typename</span> Set, <span class="keyword">typename</span> CostType&gt;</div><div class="line"><a name="l00438"></a><span class="lineno"><a class="line" href="classoperations__research_1_1_lattice_memory_manager.html#aab77eae51a0b3e7781df913213ff4372"> 438</a></span>&#160;CostType <a class="code" href="classoperations__research_1_1_lattice_memory_manager.html#aab77eae51a0b3e7781df913213ff4372">LatticeMemoryManager&lt;Set, CostType&gt;::Value</a>(<a class="code" href="classoperations__research_1_1_set.html">Set</a> set, <span class="keywordtype">int</span> node)<span class="keyword"> const </span>{</div><div class="line"><a name="l00439"></a><span class="lineno"> 439</span>&#160; <a class="code" href="base_2logging_8h.html#ae17f8119c108cf3070bad3449c7e0006">DCHECK</a>(set.<a class="code" href="classoperations__research_1_1_set.html#a0faec65dbf29460ec59dfa75d0536efb">Contains</a>(node));</div><div class="line"><a name="l00440"></a><span class="lineno"> 440</span>&#160; <span class="keywordflow">return</span> ValueAtOffset(Offset(set, node));</div><div class="line"><a name="l00441"></a><span class="lineno"> 441</span>&#160;}</div><div class="line"><a name="l00442"></a><span class="lineno"> 442</span>&#160;</div><div class="line"><a name="l00443"></a><span class="lineno"> 443</span>&#160;<span class="keyword">template</span> &lt;<span class="keyword">typename</span> Set, <span class="keyword">typename</span> CostType&gt;</div><div class="line"><a name="l00444"></a><span class="lineno"><a class="line" href="classoperations__research_1_1_lattice_memory_manager.html#a4c59c8afdecf1f9d139609ffe9f172ca"> 444</a></span>&#160;<span class="keywordtype">void</span> <a class="code" href="classoperations__research_1_1_lattice_memory_manager.html#a4c59c8afdecf1f9d139609ffe9f172ca">LatticeMemoryManager&lt;Set, CostType&gt;::SetValue</a>(<a class="code" href="classoperations__research_1_1_set.html">Set</a> set, <span class="keywordtype">int</span> node,</div><div class="line"><a name="l00445"></a><span class="lineno"> 445</span>&#160; CostType <a class="code" href="demon__profiler_8cc.html#ac072af30c4ffbc834bb4c681f6ecb514">value</a>) {</div><div class="line"><a name="l00446"></a><span class="lineno"> 446</span>&#160; <a class="code" href="base_2logging_8h.html#ae17f8119c108cf3070bad3449c7e0006">DCHECK</a>(set.<a class="code" href="classoperations__research_1_1_set.html#a0faec65dbf29460ec59dfa75d0536efb">Contains</a>(node));</div><div class="line"><a name="l00447"></a><span class="lineno"> 447</span>&#160; SetValueAtOffset(Offset(set, node), <a class="code" href="demon__profiler_8cc.html#ac072af30c4ffbc834bb4c681f6ecb514">value</a>);</div><div class="line"><a name="l00448"></a><span class="lineno"> 448</span>&#160;}</div><div class="line"><a name="l00449"></a><span class="lineno"> 449</span>&#160;</div><div class="line"><a name="l00450"></a><span class="lineno"> 450</span>&#160;<span class="comment">// Deprecated type.</span></div><div class="line"><a name="l00451"></a><span class="lineno"><a class="line" href="namespaceoperations__research.html#ae8625c5e71962a0f99954d34dab9f92d"> 451</a></span>&#160;<span class="keyword">typedef</span> <span class="keywordtype">int</span> <a class="code" href="namespaceoperations__research.html#ae8625c5e71962a0f99954d34dab9f92d">PathNodeIndex</a>;</div><div class="line"><a name="l00452"></a><span class="lineno"> 452</span>&#160;</div><div class="line"><a name="l00453"></a><span class="lineno"> 453</span>&#160;<span class="keyword">template</span> &lt;<span class="keyword">typename</span> CostType, <span class="keyword">typename</span> CostFunction&gt;</div><div class="line"><a name="l00454"></a><span class="lineno"><a class="line" href="classoperations__research_1_1_hamiltonian_path_solver.html"> 454</a></span>&#160;<span class="keyword">class </span><a class="code" href="classoperations__research_1_1_hamiltonian_path_solver.html">HamiltonianPathSolver</a> {</div><div class="line"><a name="l00455"></a><span class="lineno"> 455</span>&#160; <span class="comment">// HamiltonianPathSolver computes a minimum Hamiltonian path starting at node</span></div><div class="line"><a name="l00456"></a><span class="lineno"> 456</span>&#160; <span class="comment">// 0 over a graph defined by a cost matrix. The cost function need not be</span></div><div class="line"><a name="l00457"></a><span class="lineno"> 457</span>&#160; <span class="comment">// symmetric.</span></div><div class="line"><a name="l00458"></a><span class="lineno"> 458</span>&#160; <span class="comment">// When the Hamiltonian path is closed, it&#39;s a Hamiltonian cycle,</span></div><div class="line"><a name="l00459"></a><span class="lineno"> 459</span>&#160; <span class="comment">// i.e. the algorithm solves the Traveling Salesman Problem.</span></div><div class="line"><a name="l00460"></a><span class="lineno"> 460</span>&#160; <span class="comment">// Example:</span></div><div class="line"><a name="l00461"></a><span class="lineno"> 461</span>&#160;</div><div class="line"><a name="l00462"></a><span class="lineno"> 462</span>&#160; <span class="comment">// std::vector&lt;std::vector&lt;int&gt;&gt; cost_mat;</span></div><div class="line"><a name="l00463"></a><span class="lineno"> 463</span>&#160; <span class="comment">// ... fill in cost matrix</span></div><div class="line"><a name="l00464"></a><span class="lineno"> 464</span>&#160; <span class="comment">// HamiltonianPathSolver&lt;int, std::vector&lt;std::vector&lt;int&gt;&gt;&gt;</span></div><div class="line"><a name="l00465"></a><span class="lineno"> 465</span>&#160; <span class="comment">// mhp(cost_mat); // no computation done</span></div><div class="line"><a name="l00466"></a><span class="lineno"> 466</span>&#160; <span class="comment">// printf(&quot;%d\n&quot;, mhp.TravelingSalesmanCost()); // computation done and</span></div><div class="line"><a name="l00467"></a><span class="lineno"> 467</span>&#160; <span class="comment">// stored</span></div><div class="line"><a name="l00468"></a><span class="lineno"> 468</span>&#160; <span class="keyword">public</span>:</div><div class="line"><a name="l00469"></a><span class="lineno"> 469</span>&#160; <span class="comment">// In 2010, 26 was the maximum solvable with 24 Gigs of RAM, and it took</span></div><div class="line"><a name="l00470"></a><span class="lineno"> 470</span>&#160; <span class="comment">// several minutes. With this 2014 version of the code, one may go a little</span></div><div class="line"><a name="l00471"></a><span class="lineno"> 471</span>&#160; <span class="comment">// higher, but considering the complexity of the algorithm (n*2^n), and that</span></div><div class="line"><a name="l00472"></a><span class="lineno"> 472</span>&#160; <span class="comment">// there are very good ways to solve TSP with more than 32 cities,</span></div><div class="line"><a name="l00473"></a><span class="lineno"> 473</span>&#160; <span class="comment">// we limit ourselves to 32 cites.</span></div><div class="line"><a name="l00474"></a><span class="lineno"> 474</span>&#160; <span class="comment">// This is why we define the type NodeSet to be 32-bit wide.</span></div><div class="line"><a name="l00475"></a><span class="lineno"> 475</span>&#160; <span class="comment">// TODO(user): remove this limitation by using pruning techniques.</span></div><div class="line"><a name="l00476"></a><span class="lineno"><a class="line" href="classoperations__research_1_1_hamiltonian_path_solver.html#a346635bd62f6d557d98e490ff2f3f306"> 476</a></span>&#160; <span class="keyword">typedef</span> uint32_t <a class="code" href="classoperations__research_1_1_hamiltonian_path_solver.html#a346635bd62f6d557d98e490ff2f3f306">Integer</a>;</div><div class="line"><a name="l00477"></a><span class="lineno"><a class="line" href="classoperations__research_1_1_hamiltonian_path_solver.html#a03106785fd757b213975f94d4b780709"> 477</a></span>&#160; <span class="keyword">typedef</span> <a class="code" href="classoperations__research_1_1_set.html">Set&lt;Integer&gt;</a> <a class="code" href="classoperations__research_1_1_hamiltonian_path_solver.html#a03106785fd757b213975f94d4b780709">NodeSet</a>;</div><div class="line"><a name="l00478"></a><span class="lineno"> 478</span>&#160;</div><div class="line"><a name="l00479"></a><span class="lineno"> 479</span>&#160; <span class="keyword">explicit</span> <a class="code" href="classoperations__research_1_1_hamiltonian_path_solver.html#a9c8cdf78154ae6a73f4a272cb8d1ac4a">HamiltonianPathSolver</a>(CostFunction <a class="code" href="routing__flow_8cc.html#a75d7b5e4cab1e156cc7a2c5eba1e16f1">cost</a>);</div><div class="line"><a name="l00480"></a><span class="lineno"> 480</span>&#160; <a class="code" href="classoperations__research_1_1_hamiltonian_path_solver.html#a9c8cdf78154ae6a73f4a272cb8d1ac4a">HamiltonianPathSolver</a>(<span class="keywordtype">int</span> num_nodes, CostFunction <a class="code" href="routing__flow_8cc.html#a75d7b5e4cab1e156cc7a2c5eba1e16f1">cost</a>);</div><div class="line"><a name="l00481"></a><span class="lineno"> 481</span>&#160;</div><div class="line"><a name="l00482"></a><span class="lineno"> 482</span>&#160; <span class="comment">// Replaces the cost matrix while avoiding re-allocating memory.</span></div><div class="line"><a name="l00483"></a><span class="lineno"> 483</span>&#160; <span class="keywordtype">void</span> <a class="code" href="classoperations__research_1_1_hamiltonian_path_solver.html#a19edb994fca04e71736cf3a8d62d7a73">ChangeCostMatrix</a>(CostFunction <a class="code" href="routing__flow_8cc.html#a75d7b5e4cab1e156cc7a2c5eba1e16f1">cost</a>);</div><div class="line"><a name="l00484"></a><span class="lineno"> 484</span>&#160; <span class="keywordtype">void</span> <a class="code" href="classoperations__research_1_1_hamiltonian_path_solver.html#a19edb994fca04e71736cf3a8d62d7a73">ChangeCostMatrix</a>(<span class="keywordtype">int</span> num_nodes, CostFunction <a class="code" href="routing__flow_8cc.html#a75d7b5e4cab1e156cc7a2c5eba1e16f1">cost</a>);</div><div class="line"><a name="l00485"></a><span class="lineno"> 485</span>&#160;</div><div class="line"><a name="l00486"></a><span class="lineno"> 486</span>&#160; <span class="comment">// Returns the cost of the Hamiltonian path from 0 to end_node.</span></div><div class="line"><a name="l00487"></a><span class="lineno"> 487</span>&#160; CostType <a class="code" href="classoperations__research_1_1_hamiltonian_path_solver.html#a0b31a8637cf8c0fb125444577e6ad92b">HamiltonianCost</a>(<span class="keywordtype">int</span> end_node);</div><div class="line"><a name="l00488"></a><span class="lineno"> 488</span>&#160;</div><div class="line"><a name="l00489"></a><span class="lineno"> 489</span>&#160; <span class="comment">// Returns the shortest Hamiltonian path from 0 to end_node.</span></div><div class="line"><a name="l00490"></a><span class="lineno"> 490</span>&#160; std::vector&lt;int&gt; <a class="code" href="classoperations__research_1_1_hamiltonian_path_solver.html#a8acc60c87190fac89379315aa08ce7a5">HamiltonianPath</a>(<span class="keywordtype">int</span> end_node);</div><div class="line"><a name="l00491"></a><span class="lineno"> 491</span>&#160;</div><div class="line"><a name="l00492"></a><span class="lineno"> 492</span>&#160; <span class="comment">// Returns the end-node that yields the shortest Hamiltonian path of</span></div><div class="line"><a name="l00493"></a><span class="lineno"> 493</span>&#160; <span class="comment">// all shortest Hamiltonian path from 0 to end-node (end-node != 0).</span></div><div class="line"><a name="l00494"></a><span class="lineno"> 494</span>&#160; <span class="keywordtype">int</span> <a class="code" href="classoperations__research_1_1_hamiltonian_path_solver.html#ad20cbbfc6081d40231920c3c9543f97e">BestHamiltonianPathEndNode</a>();</div><div class="line"><a name="l00495"></a><span class="lineno"> 495</span>&#160;</div><div class="line"><a name="l00496"></a><span class="lineno"> 496</span>&#160; <span class="comment">// Deprecated API. Stores HamiltonianPath(BestHamiltonianPathEndNode()) into</span></div><div class="line"><a name="l00497"></a><span class="lineno"> 497</span>&#160; <span class="comment">// *path.</span></div><div class="line"><a name="l00498"></a><span class="lineno"> 498</span>&#160; <span class="keywordtype">void</span> <a class="code" href="classoperations__research_1_1_hamiltonian_path_solver.html#a8acc60c87190fac89379315aa08ce7a5">HamiltonianPath</a>(std::vector&lt;PathNodeIndex&gt;* path);</div><div class="line"><a name="l00499"></a><span class="lineno"> 499</span>&#160;</div><div class="line"><a name="l00500"></a><span class="lineno"> 500</span>&#160; <span class="comment">// Returns the cost of the TSP tour.</span></div><div class="line"><a name="l00501"></a><span class="lineno"> 501</span>&#160; CostType <a class="code" href="classoperations__research_1_1_hamiltonian_path_solver.html#ab558649a26fef3a74f0909ef5af45e90">TravelingSalesmanCost</a>();</div><div class="line"><a name="l00502"></a><span class="lineno"> 502</span>&#160;</div><div class="line"><a name="l00503"></a><span class="lineno"> 503</span>&#160; <span class="comment">// Returns the TSP tour in the vector pointed to by the argument.</span></div><div class="line"><a name="l00504"></a><span class="lineno"> 504</span>&#160; std::vector&lt;int&gt; <a class="code" href="classoperations__research_1_1_hamiltonian_path_solver.html#a326a998ed18bedda49bd2cab5cbd4079">TravelingSalesmanPath</a>();</div><div class="line"><a name="l00505"></a><span class="lineno"> 505</span>&#160;</div><div class="line"><a name="l00506"></a><span class="lineno"> 506</span>&#160; <span class="comment">// Deprecated API.</span></div><div class="line"><a name="l00507"></a><span class="lineno"> 507</span>&#160; <span class="keywordtype">void</span> <a class="code" href="classoperations__research_1_1_hamiltonian_path_solver.html#a326a998ed18bedda49bd2cab5cbd4079">TravelingSalesmanPath</a>(std::vector&lt;PathNodeIndex&gt;* path);</div><div class="line"><a name="l00508"></a><span class="lineno"> 508</span>&#160;</div><div class="line"><a name="l00509"></a><span class="lineno"> 509</span>&#160; <span class="comment">// Returns true if there won&#39;t be precision issues.</span></div><div class="line"><a name="l00510"></a><span class="lineno"> 510</span>&#160; <span class="comment">// This is always true for integers, but not for floating-point types.</span></div><div class="line"><a name="l00511"></a><span class="lineno"> 511</span>&#160; <span class="keywordtype">bool</span> <a class="code" href="classoperations__research_1_1_hamiltonian_path_solver.html#a5daed8b7f3c98c693f32dff60adeb4cc">IsRobust</a>();</div><div class="line"><a name="l00512"></a><span class="lineno"> 512</span>&#160;</div><div class="line"><a name="l00513"></a><span class="lineno"> 513</span>&#160; <span class="comment">// Returns true if the cost matrix verifies the triangle inequality.</span></div><div class="line"><a name="l00514"></a><span class="lineno"> 514</span>&#160; <span class="keywordtype">bool</span> <a class="code" href="classoperations__research_1_1_hamiltonian_path_solver.html#a44af6c2df0188e77ceeec78a190ecf3f">VerifiesTriangleInequality</a>();</div><div class="line"><a name="l00515"></a><span class="lineno"> 515</span>&#160;</div><div class="line"><a name="l00516"></a><span class="lineno"> 516</span>&#160; <span class="keyword">private</span>:</div><div class="line"><a name="l00517"></a><span class="lineno"> 517</span>&#160; <span class="comment">// Saturated arithmetic helper class.</span></div><div class="line"><a name="l00518"></a><span class="lineno"> 518</span>&#160; <span class="keyword">template</span> &lt;<span class="keyword">typename</span> T,</div><div class="line"><a name="l00519"></a><span class="lineno"> 519</span>&#160; <span class="keywordtype">bool</span> = <span class="keyword">true</span> <span class="comment">/* Dummy parameter to allow specialization */</span>&gt;</div><div class="line"><a name="l00520"></a><span class="lineno"> 520</span>&#160; <span class="comment">// Returns the saturated addition of a and b. It is specialized below for</span></div><div class="line"><a name="l00521"></a><span class="lineno"> 521</span>&#160; <span class="comment">// int32_t and int64_t.</span></div><div class="line"><a name="l00522"></a><span class="lineno"> 522</span>&#160; <span class="keyword">struct </span>SaturatedArithmetic {</div><div class="line"><a name="l00523"></a><span class="lineno"> 523</span>&#160; <span class="keyword">static</span> T Add(T <a class="code" href="constraint__solver_2table_8cc.html#acb18315d548212835cd8ed4287e6c0b6">a</a>, T <a class="code" href="constraint__solver_2table_8cc.html#a9293e4d29cac928301645070dd307683">b</a>) { <span class="keywordflow">return</span> <a class="code" href="constraint__solver_2table_8cc.html#acb18315d548212835cd8ed4287e6c0b6">a</a> + <a class="code" href="constraint__solver_2table_8cc.html#a9293e4d29cac928301645070dd307683">b</a>; }</div><div class="line"><a name="l00524"></a><span class="lineno"> 524</span>&#160; <span class="keyword">static</span> T Sub(T <a class="code" href="constraint__solver_2table_8cc.html#acb18315d548212835cd8ed4287e6c0b6">a</a>, T <a class="code" href="constraint__solver_2table_8cc.html#a9293e4d29cac928301645070dd307683">b</a>) { <span class="keywordflow">return</span> <a class="code" href="constraint__solver_2table_8cc.html#acb18315d548212835cd8ed4287e6c0b6">a</a> - <a class="code" href="constraint__solver_2table_8cc.html#a9293e4d29cac928301645070dd307683">b</a>; }</div><div class="line"><a name="l00525"></a><span class="lineno"> 525</span>&#160; };</div><div class="line"><a name="l00526"></a><span class="lineno"> 526</span>&#160; <span class="keyword">template</span> &lt;<span class="keywordtype">bool</span> Dummy&gt;</div><div class="line"><a name="l00527"></a><span class="lineno"> 527</span>&#160; <span class="keyword">struct </span>SaturatedArithmetic&lt;int64_t, Dummy&gt; {</div><div class="line"><a name="l00528"></a><span class="lineno"> 528</span>&#160; <span class="keyword">static</span> int64_t Add(int64_t <a class="code" href="constraint__solver_2table_8cc.html#acb18315d548212835cd8ed4287e6c0b6">a</a>, int64_t <a class="code" href="constraint__solver_2table_8cc.html#a9293e4d29cac928301645070dd307683">b</a>) { <span class="keywordflow">return</span> <a class="code" href="namespaceoperations__research.html#a111f44b9b9cf67a8e8d83794ac9f5291">CapAdd</a>(<a class="code" href="constraint__solver_2table_8cc.html#acb18315d548212835cd8ed4287e6c0b6">a</a>, <a class="code" href="constraint__solver_2table_8cc.html#a9293e4d29cac928301645070dd307683">b</a>); }</div><div class="line"><a name="l00529"></a><span class="lineno"> 529</span>&#160; <span class="keyword">static</span> int64_t Sub(int64_t <a class="code" href="constraint__solver_2table_8cc.html#acb18315d548212835cd8ed4287e6c0b6">a</a>, int64_t <a class="code" href="constraint__solver_2table_8cc.html#a9293e4d29cac928301645070dd307683">b</a>) { <span class="keywordflow">return</span> <a class="code" href="namespaceoperations__research.html#a4a43d435871f16c321861fa5de32df82">CapSub</a>(<a class="code" href="constraint__solver_2table_8cc.html#acb18315d548212835cd8ed4287e6c0b6">a</a>, <a class="code" href="constraint__solver_2table_8cc.html#a9293e4d29cac928301645070dd307683">b</a>); }</div><div class="line"><a name="l00530"></a><span class="lineno"> 530</span>&#160; };</div><div class="line"><a name="l00531"></a><span class="lineno"> 531</span>&#160; <span class="comment">// TODO(user): implement this natively in saturated_arithmetic.h</span></div><div class="line"><a name="l00532"></a><span class="lineno"> 532</span>&#160; <span class="keyword">template</span> &lt;<span class="keywordtype">bool</span> Dummy&gt;</div><div class="line"><a name="l00533"></a><span class="lineno"> 533</span>&#160; <span class="keyword">struct </span>SaturatedArithmetic&lt;int32_t, Dummy&gt; {</div><div class="line"><a name="l00534"></a><span class="lineno"> 534</span>&#160; <span class="keyword">static</span> int32_t Add(int32_t <a class="code" href="constraint__solver_2table_8cc.html#acb18315d548212835cd8ed4287e6c0b6">a</a>, int32_t <a class="code" href="constraint__solver_2table_8cc.html#a9293e4d29cac928301645070dd307683">b</a>) {</div><div class="line"><a name="l00535"></a><span class="lineno"> 535</span>&#160; <span class="keyword">const</span> int64_t a64 = <a class="code" href="constraint__solver_2table_8cc.html#acb18315d548212835cd8ed4287e6c0b6">a</a>;</div><div class="line"><a name="l00536"></a><span class="lineno"> 536</span>&#160; <span class="keyword">const</span> int64_t b64 = <a class="code" href="constraint__solver_2table_8cc.html#a9293e4d29cac928301645070dd307683">b</a>;</div><div class="line"><a name="l00537"></a><span class="lineno"> 537</span>&#160; <span class="keyword">const</span> int64_t min_int32 = <a class="code" href="alldiff__cst_8cc.html#ad10edae0a852d72fb76afb1c77735045">std::numeric_limits&lt;int32_t&gt;::min</a>();</div><div class="line"><a name="l00538"></a><span class="lineno"> 538</span>&#160; <span class="keyword">const</span> int64_t max_int32 = <a class="code" href="alldiff__cst_8cc.html#a26e6db9bcc64b584051ecc28171ed11f">std::numeric_limits&lt;int32_t&gt;::max</a>();</div><div class="line"><a name="l00539"></a><span class="lineno"> 539</span>&#160; <span class="keywordflow">return</span> static_cast&lt;int32_t&gt;(</div><div class="line"><a name="l00540"></a><span class="lineno"> 540</span>&#160; <a class="code" href="alldiff__cst_8cc.html#a26e6db9bcc64b584051ecc28171ed11f">std::max</a>(min_int32, <a class="code" href="alldiff__cst_8cc.html#ad10edae0a852d72fb76afb1c77735045">std::min</a>(max_int32, a64 + b64)));</div><div class="line"><a name="l00541"></a><span class="lineno"> 541</span>&#160; }</div><div class="line"><a name="l00542"></a><span class="lineno"> 542</span>&#160; <span class="keyword">static</span> int32_t Sub(int32_t <a class="code" href="constraint__solver_2table_8cc.html#acb18315d548212835cd8ed4287e6c0b6">a</a>, int32_t <a class="code" href="constraint__solver_2table_8cc.html#a9293e4d29cac928301645070dd307683">b</a>) {</div><div class="line"><a name="l00543"></a><span class="lineno"> 543</span>&#160; <span class="keyword">const</span> int64_t a64 = <a class="code" href="constraint__solver_2table_8cc.html#acb18315d548212835cd8ed4287e6c0b6">a</a>;</div><div class="line"><a name="l00544"></a><span class="lineno"> 544</span>&#160; <span class="keyword">const</span> int64_t b64 = <a class="code" href="constraint__solver_2table_8cc.html#a9293e4d29cac928301645070dd307683">b</a>;</div><div class="line"><a name="l00545"></a><span class="lineno"> 545</span>&#160; <span class="keyword">const</span> int64_t min_int32 = <a class="code" href="alldiff__cst_8cc.html#ad10edae0a852d72fb76afb1c77735045">std::numeric_limits&lt;int32_t&gt;::min</a>();</div><div class="line"><a name="l00546"></a><span class="lineno"> 546</span>&#160; <span class="keyword">const</span> int64_t max_int32 = <a class="code" href="alldiff__cst_8cc.html#a26e6db9bcc64b584051ecc28171ed11f">std::numeric_limits&lt;int32_t&gt;::max</a>();</div><div class="line"><a name="l00547"></a><span class="lineno"> 547</span>&#160; <span class="keywordflow">return</span> static_cast&lt;int32_t&gt;(</div><div class="line"><a name="l00548"></a><span class="lineno"> 548</span>&#160; <a class="code" href="alldiff__cst_8cc.html#a26e6db9bcc64b584051ecc28171ed11f">std::max</a>(min_int32, <a class="code" href="alldiff__cst_8cc.html#ad10edae0a852d72fb76afb1c77735045">std::min</a>(max_int32, a64 - b64)));</div><div class="line"><a name="l00549"></a><span class="lineno"> 549</span>&#160; }</div><div class="line"><a name="l00550"></a><span class="lineno"> 550</span>&#160; };</div><div class="line"><a name="l00551"></a><span class="lineno"> 551</span>&#160;</div><div class="line"><a name="l00552"></a><span class="lineno"> 552</span>&#160; <span class="keyword">template</span> &lt;<span class="keyword">typename</span> T&gt;</div><div class="line"><a name="l00553"></a><span class="lineno"> 553</span>&#160; <span class="keyword">using</span> Saturated = SaturatedArithmetic&lt;T&gt;;</div><div class="line"><a name="l00554"></a><span class="lineno"> 554</span>&#160;</div><div class="line"><a name="l00555"></a><span class="lineno"> 555</span>&#160; <span class="comment">// Returns the cost value between two nodes.</span></div><div class="line"><a name="l00556"></a><span class="lineno"> 556</span>&#160; CostType Cost(<span class="keywordtype">int</span> i, <span class="keywordtype">int</span> j) { <span class="keywordflow">return</span> cost_(i, j); }</div><div class="line"><a name="l00557"></a><span class="lineno"> 557</span>&#160;</div><div class="line"><a name="l00558"></a><span class="lineno"> 558</span>&#160; <span class="comment">// Does all the Dynamic Progamming iterations.</span></div><div class="line"><a name="l00559"></a><span class="lineno"> 559</span>&#160; <span class="keywordtype">void</span> Solve();</div><div class="line"><a name="l00560"></a><span class="lineno"> 560</span>&#160;</div><div class="line"><a name="l00561"></a><span class="lineno"> 561</span>&#160; <span class="comment">// Computes a path by looking at the information in mem_.</span></div><div class="line"><a name="l00562"></a><span class="lineno"> 562</span>&#160; std::vector&lt;int&gt; ComputePath(CostType <a class="code" href="routing__flow_8cc.html#a75d7b5e4cab1e156cc7a2c5eba1e16f1">cost</a>, <a class="code" href="classoperations__research_1_1_hamiltonian_path_solver.html#a03106785fd757b213975f94d4b780709">NodeSet</a> set, <span class="keywordtype">int</span> end);</div><div class="line"><a name="l00563"></a><span class="lineno"> 563</span>&#160;</div><div class="line"><a name="l00564"></a><span class="lineno"> 564</span>&#160; <span class="comment">// Returns true if the path covers all nodes, and its cost is equal to cost.</span></div><div class="line"><a name="l00565"></a><span class="lineno"> 565</span>&#160; <span class="keywordtype">bool</span> PathIsValid(<span class="keyword">const</span> std::vector&lt;int&gt;&amp; path, CostType <a class="code" href="routing__flow_8cc.html#a75d7b5e4cab1e156cc7a2c5eba1e16f1">cost</a>);</div><div class="line"><a name="l00566"></a><span class="lineno"> 566</span>&#160;</div><div class="line"><a name="l00567"></a><span class="lineno"> 567</span>&#160; <span class="comment">// Cost function used to build Hamiltonian paths.</span></div><div class="line"><a name="l00568"></a><span class="lineno"> 568</span>&#160; MatrixOrFunction&lt;CostType, CostFunction, true&gt; cost_;</div><div class="line"><a name="l00569"></a><span class="lineno"> 569</span>&#160;</div><div class="line"><a name="l00570"></a><span class="lineno"> 570</span>&#160; <span class="comment">// The number of nodes in the problem.</span></div><div class="line"><a name="l00571"></a><span class="lineno"> 571</span>&#160; <span class="keywordtype">int</span> num_nodes_;</div><div class="line"><a name="l00572"></a><span class="lineno"> 572</span>&#160;</div><div class="line"><a name="l00573"></a><span class="lineno"> 573</span>&#160; <span class="comment">// The cost of the computed TSP path.</span></div><div class="line"><a name="l00574"></a><span class="lineno"> 574</span>&#160; CostType tsp_cost_;</div><div class="line"><a name="l00575"></a><span class="lineno"> 575</span>&#160;</div><div class="line"><a name="l00576"></a><span class="lineno"> 576</span>&#160; <span class="comment">// The cost of the computed Hamiltonian path.</span></div><div class="line"><a name="l00577"></a><span class="lineno"> 577</span>&#160; std::vector&lt;CostType&gt; hamiltonian_costs_;</div><div class="line"><a name="l00578"></a><span class="lineno"> 578</span>&#160;</div><div class="line"><a name="l00579"></a><span class="lineno"> 579</span>&#160; <span class="keywordtype">bool</span> robust_;</div><div class="line"><a name="l00580"></a><span class="lineno"> 580</span>&#160; <span class="keywordtype">bool</span> triangle_inequality_ok_;</div><div class="line"><a name="l00581"></a><span class="lineno"> 581</span>&#160; <span class="keywordtype">bool</span> robustness_checked_;</div><div class="line"><a name="l00582"></a><span class="lineno"> 582</span>&#160; <span class="keywordtype">bool</span> triangle_inequality_checked_;</div><div class="line"><a name="l00583"></a><span class="lineno"> 583</span>&#160; <span class="keywordtype">bool</span> solved_;</div><div class="line"><a name="l00584"></a><span class="lineno"> 584</span>&#160; std::vector&lt;int&gt; tsp_path_;</div><div class="line"><a name="l00585"></a><span class="lineno"> 585</span>&#160;</div><div class="line"><a name="l00586"></a><span class="lineno"> 586</span>&#160; <span class="comment">// The vector of smallest Hamiltonian paths starting at 0, indexed by their</span></div><div class="line"><a name="l00587"></a><span class="lineno"> 587</span>&#160; <span class="comment">// end nodes.</span></div><div class="line"><a name="l00588"></a><span class="lineno"> 588</span>&#160; std::vector&lt;std::vector&lt;int&gt;&gt; hamiltonian_paths_;</div><div class="line"><a name="l00589"></a><span class="lineno"> 589</span>&#160;</div><div class="line"><a name="l00590"></a><span class="lineno"> 590</span>&#160; <span class="comment">// The end node that gives the smallest Hamiltonian path. The smallest</span></div><div class="line"><a name="l00591"></a><span class="lineno"> 591</span>&#160; <span class="comment">// Hamiltonian path starting at 0 of all</span></div><div class="line"><a name="l00592"></a><span class="lineno"> 592</span>&#160; <span class="comment">// is hamiltonian_paths_[best_hamiltonian_path_end_node_].</span></div><div class="line"><a name="l00593"></a><span class="lineno"> 593</span>&#160; <span class="keywordtype">int</span> best_hamiltonian_path_end_node_;</div><div class="line"><a name="l00594"></a><span class="lineno"> 594</span>&#160;</div><div class="line"><a name="l00595"></a><span class="lineno"> 595</span>&#160; LatticeMemoryManager&lt;NodeSet, CostType&gt; mem_;</div><div class="line"><a name="l00596"></a><span class="lineno"> 596</span>&#160;};</div><div class="line"><a name="l00597"></a><span class="lineno"> 597</span>&#160;</div><div class="line"><a name="l00598"></a><span class="lineno"> 598</span>&#160;<span class="comment">// Utility function to simplify building a HamiltonianPathSolver from a functor.</span></div><div class="line"><a name="l00599"></a><span class="lineno"> 599</span>&#160;<span class="keyword">template</span> &lt;<span class="keyword">typename</span> CostType, <span class="keyword">typename</span> CostFunction&gt;</div><div class="line"><a name="l00600"></a><span class="lineno"><a class="line" href="namespaceoperations__research.html#a715b0dbb9f0903ab629b8c6da1b35b45"> 600</a></span>&#160;<a class="code" href="classoperations__research_1_1_hamiltonian_path_solver.html">HamiltonianPathSolver&lt;CostType, CostFunction&gt;</a> <a class="code" href="namespaceoperations__research.html#a715b0dbb9f0903ab629b8c6da1b35b45">MakeHamiltonianPathSolver</a>(</div><div class="line"><a name="l00601"></a><span class="lineno"> 601</span>&#160; <span class="keywordtype">int</span> num_nodes, CostFunction <a class="code" href="routing__flow_8cc.html#a75d7b5e4cab1e156cc7a2c5eba1e16f1">cost</a>) {</div><div class="line"><a name="l00602"></a><span class="lineno"> 602</span>&#160; <span class="keywordflow">return</span> <a class="code" href="classoperations__research_1_1_hamiltonian_path_solver.html">HamiltonianPathSolver&lt;CostType, CostFunction&gt;</a>(num_nodes,</div><div class="line"><a name="l00603"></a><span class="lineno"> 603</span>&#160; std::move(<a class="code" href="routing__flow_8cc.html#a75d7b5e4cab1e156cc7a2c5eba1e16f1">cost</a>));</div><div class="line"><a name="l00604"></a><span class="lineno"> 604</span>&#160;}</div><div class="line"><a name="l00605"></a><span class="lineno"> 605</span>&#160;</div><div class="line"><a name="l00606"></a><span class="lineno"> 606</span>&#160;<span class="keyword">template</span> &lt;<span class="keyword">typename</span> CostType, <span class="keyword">typename</span> CostFunction&gt;</div><div class="line"><a name="l00607"></a><span class="lineno"><a class="line" href="classoperations__research_1_1_hamiltonian_path_solver.html#a9c8cdf78154ae6a73f4a272cb8d1ac4a"> 607</a></span>&#160;<a class="code" href="classoperations__research_1_1_hamiltonian_path_solver.html#a9c8cdf78154ae6a73f4a272cb8d1ac4a">HamiltonianPathSolver&lt;CostType, CostFunction&gt;::HamiltonianPathSolver</a>(</div><div class="line"><a name="l00608"></a><span class="lineno"> 608</span>&#160; CostFunction <a class="code" href="routing__flow_8cc.html#a75d7b5e4cab1e156cc7a2c5eba1e16f1">cost</a>)</div><div class="line"><a name="l00609"></a><span class="lineno"> 609</span>&#160; : <a class="code" href="classoperations__research_1_1_hamiltonian_path_solver.html">HamiltonianPathSolver</a>&lt;CostType, CostFunction&gt;(<a class="code" href="routing__flow_8cc.html#a75d7b5e4cab1e156cc7a2c5eba1e16f1">cost</a>.size(), <a class="code" href="routing__flow_8cc.html#a75d7b5e4cab1e156cc7a2c5eba1e16f1">cost</a>) {}</div><div class="line"><a name="l00610"></a><span class="lineno"> 610</span>&#160;</div><div class="line"><a name="l00611"></a><span class="lineno"> 611</span>&#160;<span class="keyword">template</span> &lt;<span class="keyword">typename</span> CostType, <span class="keyword">typename</span> CostFunction&gt;</div><div class="line"><a name="l00612"></a><span class="lineno"><a class="line" href="classoperations__research_1_1_hamiltonian_path_solver.html#acc36ec0dcfa554cf72acb4ddb64c066c"> 612</a></span>&#160;<a class="code" href="classoperations__research_1_1_hamiltonian_path_solver.html">HamiltonianPathSolver&lt;CostType, CostFunction&gt;::HamiltonianPathSolver</a>(</div><div class="line"><a name="l00613"></a><span class="lineno"> 613</span>&#160; <span class="keywordtype">int</span> num_nodes, CostFunction <a class="code" href="routing__flow_8cc.html#a75d7b5e4cab1e156cc7a2c5eba1e16f1">cost</a>)</div><div class="line"><a name="l00614"></a><span class="lineno"> 614</span>&#160; : cost_(std::move(<a class="code" href="routing__flow_8cc.html#a75d7b5e4cab1e156cc7a2c5eba1e16f1">cost</a>)),</div><div class="line"><a name="l00615"></a><span class="lineno"> 615</span>&#160; num_nodes_(num_nodes),</div><div class="line"><a name="l00616"></a><span class="lineno"> 616</span>&#160; tsp_cost_(0),</div><div class="line"><a name="l00617"></a><span class="lineno"> 617</span>&#160; hamiltonian_costs_(0),</div><div class="line"><a name="l00618"></a><span class="lineno"> 618</span>&#160; robust_(true),</div><div class="line"><a name="l00619"></a><span class="lineno"> 619</span>&#160; triangle_inequality_ok_(true),</div><div class="line"><a name="l00620"></a><span class="lineno"> 620</span>&#160; robustness_checked_(false),</div><div class="line"><a name="l00621"></a><span class="lineno"> 621</span>&#160; triangle_inequality_checked_(false),</div><div class="line"><a name="l00622"></a><span class="lineno"> 622</span>&#160; solved_(false) {</div><div class="line"><a name="l00623"></a><span class="lineno"> 623</span>&#160; <a class="code" href="base_2logging_8h.html#a7cc25402ecd7591b4c39934dd656b1f9">CHECK_GE</a>(NodeSet::MaxCardinality, num_nodes_);</div><div class="line"><a name="l00624"></a><span class="lineno"> 624</span>&#160; <a class="code" href="base_2logging_8h.html#a3e1cfef60e774a81f30eaddf26a3a274">CHECK</a>(cost_.Check());</div><div class="line"><a name="l00625"></a><span class="lineno"> 625</span>&#160;}</div><div class="line"><a name="l00626"></a><span class="lineno"> 626</span>&#160;</div><div class="line"><a name="l00627"></a><span class="lineno"> 627</span>&#160;<span class="keyword">template</span> &lt;<span class="keyword">typename</span> CostType, <span class="keyword">typename</span> CostFunction&gt;</div><div class="line"><a name="l00628"></a><span class="lineno"><a class="line" href="classoperations__research_1_1_hamiltonian_path_solver.html#a19edb994fca04e71736cf3a8d62d7a73"> 628</a></span>&#160;<span class="keywordtype">void</span> <a class="code" href="classoperations__research_1_1_hamiltonian_path_solver.html">HamiltonianPathSolver&lt;CostType, CostFunction&gt;::ChangeCostMatrix</a>(</div><div class="line"><a name="l00629"></a><span class="lineno"> 629</span>&#160; CostFunction <a class="code" href="routing__flow_8cc.html#a75d7b5e4cab1e156cc7a2c5eba1e16f1">cost</a>) {</div><div class="line"><a name="l00630"></a><span class="lineno"> 630</span>&#160; ChangeCostMatrix(<a class="code" href="routing__flow_8cc.html#a75d7b5e4cab1e156cc7a2c5eba1e16f1">cost</a>.size(), <a class="code" href="routing__flow_8cc.html#a75d7b5e4cab1e156cc7a2c5eba1e16f1">cost</a>);</div><div class="line"><a name="l00631"></a><span class="lineno"> 631</span>&#160;}</div><div class="line"><a name="l00632"></a><span class="lineno"> 632</span>&#160;</div><div class="line"><a name="l00633"></a><span class="lineno"> 633</span>&#160;<span class="keyword">template</span> &lt;<span class="keyword">typename</span> CostType, <span class="keyword">typename</span> CostFunction&gt;</div><div class="line"><a name="l00634"></a><span class="lineno"><a class="line" href="classoperations__research_1_1_hamiltonian_path_solver.html#a25f9e15b1f7c966c06f9a3e308d93436"> 634</a></span>&#160;<span class="keywordtype">void</span> <a class="code" href="classoperations__research_1_1_hamiltonian_path_solver.html">HamiltonianPathSolver&lt;CostType, CostFunction&gt;::ChangeCostMatrix</a>(</div><div class="line"><a name="l00635"></a><span class="lineno"> 635</span>&#160; <span class="keywordtype">int</span> num_nodes, CostFunction <a class="code" href="routing__flow_8cc.html#a75d7b5e4cab1e156cc7a2c5eba1e16f1">cost</a>) {</div><div class="line"><a name="l00636"></a><span class="lineno"> 636</span>&#160; robustness_checked_ = <span class="keyword">false</span>;</div><div class="line"><a name="l00637"></a><span class="lineno"> 637</span>&#160; triangle_inequality_checked_ = <span class="keyword">false</span>;</div><div class="line"><a name="l00638"></a><span class="lineno"> 638</span>&#160; solved_ = <span class="keyword">false</span>;</div><div class="line"><a name="l00639"></a><span class="lineno"> 639</span>&#160; cost_.Reset(<a class="code" href="routing__flow_8cc.html#a75d7b5e4cab1e156cc7a2c5eba1e16f1">cost</a>);</div><div class="line"><a name="l00640"></a><span class="lineno"> 640</span>&#160; num_nodes_ = num_nodes;</div><div class="line"><a name="l00641"></a><span class="lineno"> 641</span>&#160; <a class="code" href="base_2logging_8h.html#a7cc25402ecd7591b4c39934dd656b1f9">CHECK_GE</a>(NodeSet::MaxCardinality, num_nodes_);</div><div class="line"><a name="l00642"></a><span class="lineno"> 642</span>&#160; <a class="code" href="base_2logging_8h.html#a3e1cfef60e774a81f30eaddf26a3a274">CHECK</a>(cost_.Check());</div><div class="line"><a name="l00643"></a><span class="lineno"> 643</span>&#160;}</div><div class="line"><a name="l00644"></a><span class="lineno"> 644</span>&#160;</div><div class="line"><a name="l00645"></a><span class="lineno"> 645</span>&#160;<span class="keyword">template</span> &lt;<span class="keyword">typename</span> CostType, <span class="keyword">typename</span> CostFunction&gt;</div><div class="line"><a name="l00646"></a><span class="lineno"> 646</span>&#160;<span class="keywordtype">void</span> <a class="code" href="namespaceoperations__research_1_1sat.html#af904018d9a1c9983624b1ce0331f2bf5">HamiltonianPathSolver&lt;CostType, CostFunction&gt;::Solve</a>() {</div><div class="line"><a name="l00647"></a><span class="lineno"> 647</span>&#160; <span class="keywordflow">if</span> (solved_) <span class="keywordflow">return</span>;</div><div class="line"><a name="l00648"></a><span class="lineno"> 648</span>&#160; <span class="keywordflow">if</span> (num_nodes_ == 0) {</div><div class="line"><a name="l00649"></a><span class="lineno"> 649</span>&#160; tsp_cost_ = 0;</div><div class="line"><a name="l00650"></a><span class="lineno"> 650</span>&#160; tsp_path_ = {0};</div><div class="line"><a name="l00651"></a><span class="lineno"> 651</span>&#160; hamiltonian_paths_.resize(1);</div><div class="line"><a name="l00652"></a><span class="lineno"> 652</span>&#160; hamiltonian_costs_.resize(1);</div><div class="line"><a name="l00653"></a><span class="lineno"> 653</span>&#160; best_hamiltonian_path_end_node_ = 0;</div><div class="line"><a name="l00654"></a><span class="lineno"> 654</span>&#160; hamiltonian_costs_[0] = 0;</div><div class="line"><a name="l00655"></a><span class="lineno"> 655</span>&#160; hamiltonian_paths_[0] = {0};</div><div class="line"><a name="l00656"></a><span class="lineno"> 656</span>&#160; <span class="keywordflow">return</span>;</div><div class="line"><a name="l00657"></a><span class="lineno"> 657</span>&#160; }</div><div class="line"><a name="l00658"></a><span class="lineno"> 658</span>&#160; mem_.Init(num_nodes_);</div><div class="line"><a name="l00659"></a><span class="lineno"> 659</span>&#160; <span class="comment">// Initialize the first layer of the search lattice, taking into account</span></div><div class="line"><a name="l00660"></a><span class="lineno"> 660</span>&#160; <span class="comment">// that base_offset_[1] == 0. (This is what the DCHECK_EQ is for).</span></div><div class="line"><a name="l00661"></a><span class="lineno"> 661</span>&#160; <span class="keywordflow">for</span> (<span class="keywordtype">int</span> dest = 0; dest &lt; num_nodes_; ++dest) {</div><div class="line"><a name="l00662"></a><span class="lineno"> 662</span>&#160; <a class="code" href="base_2logging_8h.html#ae89df3243bbb8341130c7b3f44145ea0">DCHECK_EQ</a>(dest, mem_.BaseOffset(1, NodeSet::Singleton(dest)));</div><div class="line"><a name="l00663"></a><span class="lineno"> 663</span>&#160; mem_.SetValueAtOffset(dest, Cost(0, dest));</div><div class="line"><a name="l00664"></a><span class="lineno"> 664</span>&#160; }</div><div class="line"><a name="l00665"></a><span class="lineno"> 665</span>&#160;</div><div class="line"><a name="l00666"></a><span class="lineno"> 666</span>&#160; <span class="comment">// Populate the dynamic programming lattice layer by layer, by iterating</span></div><div class="line"><a name="l00667"></a><span class="lineno"> 667</span>&#160; <span class="comment">// on cardinality.</span></div><div class="line"><a name="l00668"></a><span class="lineno"> 668</span>&#160; <span class="keywordflow">for</span> (<span class="keywordtype">int</span> card = 2; card &lt;= num_nodes_; ++card) {</div><div class="line"><a name="l00669"></a><span class="lineno"> 669</span>&#160; <span class="comment">// Iterate on sets of same cardinality.</span></div><div class="line"><a name="l00670"></a><span class="lineno"> 670</span>&#160; <span class="keywordflow">for</span> (NodeSet set :</div><div class="line"><a name="l00671"></a><span class="lineno"> 671</span>&#160; SetRangeWithCardinality&lt;Set&lt;uint32_t&gt;&gt;(card, num_nodes_)) {</div><div class="line"><a name="l00672"></a><span class="lineno"> 672</span>&#160; <span class="comment">// Using BaseOffset and maintaining the node ranks, to reduce the</span></div><div class="line"><a name="l00673"></a><span class="lineno"> 673</span>&#160; <span class="comment">// computational effort for accessing the data.</span></div><div class="line"><a name="l00674"></a><span class="lineno"> 674</span>&#160; <span class="keyword">const</span> uint64_t set_offset = mem_.BaseOffset(card, set);</div><div class="line"><a name="l00675"></a><span class="lineno"> 675</span>&#160; <span class="comment">// The first subset on which we&#39;ll iterate is set.RemoveSmallestElement().</span></div><div class="line"><a name="l00676"></a><span class="lineno"> 676</span>&#160; <span class="comment">// Compute its offset. It will be updated incrementaly. This saves about</span></div><div class="line"><a name="l00677"></a><span class="lineno"> 677</span>&#160; <span class="comment">// 30-35% of computation time.</span></div><div class="line"><a name="l00678"></a><span class="lineno"> 678</span>&#160; uint64_t subset_offset =</div><div class="line"><a name="l00679"></a><span class="lineno"> 679</span>&#160; mem_.BaseOffset(card - 1, set.RemoveSmallestElement());</div><div class="line"><a name="l00680"></a><span class="lineno"> 680</span>&#160; <span class="keywordtype">int</span> prev_dest = set.SmallestElement();</div><div class="line"><a name="l00681"></a><span class="lineno"> 681</span>&#160; <span class="keywordtype">int</span> dest_rank = 0;</div><div class="line"><a name="l00682"></a><span class="lineno"> 682</span>&#160; <span class="keywordflow">for</span> (<span class="keywordtype">int</span> dest : set) {</div><div class="line"><a name="l00683"></a><span class="lineno"> 683</span>&#160; CostType min_cost = <a class="code" href="alldiff__cst_8cc.html#a26e6db9bcc64b584051ecc28171ed11f">std::numeric_limits&lt;CostType&gt;::max</a>();</div><div class="line"><a name="l00684"></a><span class="lineno"> 684</span>&#160; <span class="keyword">const</span> NodeSet subset = set.RemoveElement(dest);</div><div class="line"><a name="l00685"></a><span class="lineno"> 685</span>&#160; <span class="comment">// We compute the offset for subset from the preceding iteration</span></div><div class="line"><a name="l00686"></a><span class="lineno"> 686</span>&#160; <span class="comment">// by taking into account that prev_dest is now in subset, and</span></div><div class="line"><a name="l00687"></a><span class="lineno"> 687</span>&#160; <span class="comment">// that dest is now removed from subset.</span></div><div class="line"><a name="l00688"></a><span class="lineno"> 688</span>&#160; subset_offset += mem_.OffsetDelta(card - 1, prev_dest, dest, dest_rank);</div><div class="line"><a name="l00689"></a><span class="lineno"> 689</span>&#160; <span class="keywordtype">int</span> src_rank = 0;</div><div class="line"><a name="l00690"></a><span class="lineno"> 690</span>&#160; <span class="keywordflow">for</span> (<span class="keywordtype">int</span> src : subset) {</div><div class="line"><a name="l00691"></a><span class="lineno"> 691</span>&#160; min_cost = <a class="code" href="alldiff__cst_8cc.html#ad10edae0a852d72fb76afb1c77735045">std::min</a>(</div><div class="line"><a name="l00692"></a><span class="lineno"> 692</span>&#160; min_cost, Saturated&lt;CostType&gt;::Add(</div><div class="line"><a name="l00693"></a><span class="lineno"> 693</span>&#160; Cost(src, dest),</div><div class="line"><a name="l00694"></a><span class="lineno"> 694</span>&#160; mem_.ValueAtOffset(subset_offset + src_rank)));</div><div class="line"><a name="l00695"></a><span class="lineno"> 695</span>&#160; ++src_rank;</div><div class="line"><a name="l00696"></a><span class="lineno"> 696</span>&#160; }</div><div class="line"><a name="l00697"></a><span class="lineno"> 697</span>&#160; prev_dest = dest;</div><div class="line"><a name="l00698"></a><span class="lineno"> 698</span>&#160; mem_.SetValueAtOffset(set_offset + dest_rank, min_cost);</div><div class="line"><a name="l00699"></a><span class="lineno"> 699</span>&#160; ++dest_rank;</div><div class="line"><a name="l00700"></a><span class="lineno"> 700</span>&#160; }</div><div class="line"><a name="l00701"></a><span class="lineno"> 701</span>&#160; }</div><div class="line"><a name="l00702"></a><span class="lineno"> 702</span>&#160; }</div><div class="line"><a name="l00703"></a><span class="lineno"> 703</span>&#160;</div><div class="line"><a name="l00704"></a><span class="lineno"> 704</span>&#160; <span class="keyword">const</span> NodeSet full_set = NodeSet::FullSet(num_nodes_);</div><div class="line"><a name="l00705"></a><span class="lineno"> 705</span>&#160;</div><div class="line"><a name="l00706"></a><span class="lineno"> 706</span>&#160; <span class="comment">// Get the cost of the tsp from node 0. It is the path that leaves 0 and goes</span></div><div class="line"><a name="l00707"></a><span class="lineno"> 707</span>&#160; <span class="comment">// through all other nodes, and returns at 0, with minimal cost.</span></div><div class="line"><a name="l00708"></a><span class="lineno"> 708</span>&#160; tsp_cost_ = mem_.Value(full_set, 0);</div><div class="line"><a name="l00709"></a><span class="lineno"> 709</span>&#160; tsp_path_ = ComputePath(tsp_cost_, full_set, 0);</div><div class="line"><a name="l00710"></a><span class="lineno"> 710</span>&#160;</div><div class="line"><a name="l00711"></a><span class="lineno"> 711</span>&#160; hamiltonian_paths_.resize(num_nodes_);</div><div class="line"><a name="l00712"></a><span class="lineno"> 712</span>&#160; hamiltonian_costs_.resize(num_nodes_);</div><div class="line"><a name="l00713"></a><span class="lineno"> 713</span>&#160; <span class="comment">// Compute the cost of the Hamiltonian paths starting from node 0, going</span></div><div class="line"><a name="l00714"></a><span class="lineno"> 714</span>&#160; <span class="comment">// through all the other nodes, and ending at end_node. Compute the minimum</span></div><div class="line"><a name="l00715"></a><span class="lineno"> 715</span>&#160; <span class="comment">// one along the way.</span></div><div class="line"><a name="l00716"></a><span class="lineno"> 716</span>&#160; CostType min_hamiltonian_cost = <a class="code" href="alldiff__cst_8cc.html#a26e6db9bcc64b584051ecc28171ed11f">std::numeric_limits&lt;CostType&gt;::max</a>();</div><div class="line"><a name="l00717"></a><span class="lineno"> 717</span>&#160; <span class="keyword">const</span> NodeSet hamiltonian_set = full_set.RemoveElement(0);</div><div class="line"><a name="l00718"></a><span class="lineno"> 718</span>&#160; <span class="keywordflow">for</span> (<span class="keywordtype">int</span> end_node : hamiltonian_set) {</div><div class="line"><a name="l00719"></a><span class="lineno"> 719</span>&#160; <span class="keyword">const</span> CostType <a class="code" href="routing__flow_8cc.html#a75d7b5e4cab1e156cc7a2c5eba1e16f1">cost</a> = mem_.Value(hamiltonian_set, end_node);</div><div class="line"><a name="l00720"></a><span class="lineno"> 720</span>&#160; hamiltonian_costs_[end_node] = <a class="code" href="routing__flow_8cc.html#a75d7b5e4cab1e156cc7a2c5eba1e16f1">cost</a>;</div><div class="line"><a name="l00721"></a><span class="lineno"> 721</span>&#160; <span class="keywordflow">if</span> (<a class="code" href="routing__flow_8cc.html#a75d7b5e4cab1e156cc7a2c5eba1e16f1">cost</a> &lt;= min_hamiltonian_cost) {</div><div class="line"><a name="l00722"></a><span class="lineno"> 722</span>&#160; min_hamiltonian_cost = <a class="code" href="routing__flow_8cc.html#a75d7b5e4cab1e156cc7a2c5eba1e16f1">cost</a>;</div><div class="line"><a name="l00723"></a><span class="lineno"> 723</span>&#160; best_hamiltonian_path_end_node_ = end_node;</div><div class="line"><a name="l00724"></a><span class="lineno"> 724</span>&#160; }</div><div class="line"><a name="l00725"></a><span class="lineno"> 725</span>&#160; <a class="code" href="base_2logging_8h.html#a4395e95bab44e222cb2e77251017a0e2">DCHECK_LE</a>(tsp_cost_, Saturated&lt;CostType&gt;::Add(<a class="code" href="routing__flow_8cc.html#a75d7b5e4cab1e156cc7a2c5eba1e16f1">cost</a>, Cost(end_node, 0)));</div><div class="line"><a name="l00726"></a><span class="lineno"> 726</span>&#160; <span class="comment">// Get the Hamiltonian paths.</span></div><div class="line"><a name="l00727"></a><span class="lineno"> 727</span>&#160; hamiltonian_paths_[end_node] =</div><div class="line"><a name="l00728"></a><span class="lineno"> 728</span>&#160; ComputePath(hamiltonian_costs_[end_node], hamiltonian_set, end_node);</div><div class="line"><a name="l00729"></a><span class="lineno"> 729</span>&#160; }</div><div class="line"><a name="l00730"></a><span class="lineno"> 730</span>&#160;</div><div class="line"><a name="l00731"></a><span class="lineno"> 731</span>&#160; solved_ = <span class="keyword">true</span>;</div><div class="line"><a name="l00732"></a><span class="lineno"> 732</span>&#160;}</div><div class="line"><a name="l00733"></a><span class="lineno"> 733</span>&#160;</div><div class="line"><a name="l00734"></a><span class="lineno"> 734</span>&#160;<span class="keyword">template</span> &lt;<span class="keyword">typename</span> CostType, <span class="keyword">typename</span> CostFunction&gt;</div><div class="line"><a name="l00735"></a><span class="lineno"> 735</span>&#160;std::vector&lt;int&gt; HamiltonianPathSolver&lt;CostType, CostFunction&gt;::ComputePath(</div><div class="line"><a name="l00736"></a><span class="lineno"> 736</span>&#160; CostType <a class="code" href="routing__flow_8cc.html#a75d7b5e4cab1e156cc7a2c5eba1e16f1">cost</a>, NodeSet set, <span class="keywordtype">int</span> end_node) {</div><div class="line"><a name="l00737"></a><span class="lineno"> 737</span>&#160; <a class="code" href="base_2logging_8h.html#ae17f8119c108cf3070bad3449c7e0006">DCHECK</a>(set.Contains(end_node));</div><div class="line"><a name="l00738"></a><span class="lineno"> 738</span>&#160; <span class="keyword">const</span> <span class="keywordtype">int</span> path_size = set.Cardinality() + 1;</div><div class="line"><a name="l00739"></a><span class="lineno"> 739</span>&#160; std::vector&lt;int&gt; path(path_size, 0);</div><div class="line"><a name="l00740"></a><span class="lineno"> 740</span>&#160; NodeSet subset = set.RemoveElement(end_node);</div><div class="line"><a name="l00741"></a><span class="lineno"> 741</span>&#160; path[path_size - 1] = end_node;</div><div class="line"><a name="l00742"></a><span class="lineno"> 742</span>&#160; <span class="keywordtype">int</span> dest = end_node;</div><div class="line"><a name="l00743"></a><span class="lineno"> 743</span>&#160; CostType current_cost = <a class="code" href="routing__flow_8cc.html#a75d7b5e4cab1e156cc7a2c5eba1e16f1">cost</a>;</div><div class="line"><a name="l00744"></a><span class="lineno"> 744</span>&#160; <span class="keywordflow">for</span> (<span class="keywordtype">int</span> rank = path_size - 2; rank &gt;= 0; --rank) {</div><div class="line"><a name="l00745"></a><span class="lineno"> 745</span>&#160; <span class="keywordflow">for</span> (<span class="keywordtype">int</span> src : subset) {</div><div class="line"><a name="l00746"></a><span class="lineno"> 746</span>&#160; <span class="keyword">const</span> CostType partial_cost = mem_.Value(subset, src);</div><div class="line"><a name="l00747"></a><span class="lineno"> 747</span>&#160; <span class="keyword">const</span> CostType incumbent_cost =</div><div class="line"><a name="l00748"></a><span class="lineno"> 748</span>&#160; Saturated&lt;CostType&gt;::Add(partial_cost, Cost(src, dest));</div><div class="line"><a name="l00749"></a><span class="lineno"> 749</span>&#160; <span class="comment">// Take precision into account when CosttType is float or double.</span></div><div class="line"><a name="l00750"></a><span class="lineno"> 750</span>&#160; <span class="comment">// There is no visible penalty in the case CostType is an integer type.</span></div><div class="line"><a name="l00751"></a><span class="lineno"> 751</span>&#160; <span class="keywordflow">if</span> (std::abs(Saturated&lt;CostType&gt;::Sub(current_cost, incumbent_cost)) &lt;=</div><div class="line"><a name="l00752"></a><span class="lineno"> 752</span>&#160; std::numeric_limits&lt;CostType&gt;::epsilon() * current_cost) {</div><div class="line"><a name="l00753"></a><span class="lineno"> 753</span>&#160; subset = subset.RemoveElement(src);</div><div class="line"><a name="l00754"></a><span class="lineno"> 754</span>&#160; current_cost = partial_cost;</div><div class="line"><a name="l00755"></a><span class="lineno"> 755</span>&#160; path[rank] = src;</div><div class="line"><a name="l00756"></a><span class="lineno"> 756</span>&#160; dest = src;</div><div class="line"><a name="l00757"></a><span class="lineno"> 757</span>&#160; <span class="keywordflow">break</span>;</div><div class="line"><a name="l00758"></a><span class="lineno"> 758</span>&#160; }</div><div class="line"><a name="l00759"></a><span class="lineno"> 759</span>&#160; }</div><div class="line"><a name="l00760"></a><span class="lineno"> 760</span>&#160; }</div><div class="line"><a name="l00761"></a><span class="lineno"> 761</span>&#160; <a class="code" href="base_2logging_8h.html#ae89df3243bbb8341130c7b3f44145ea0">DCHECK_EQ</a>(0, subset.value());</div><div class="line"><a name="l00762"></a><span class="lineno"> 762</span>&#160; <a class="code" href="base_2logging_8h.html#ae17f8119c108cf3070bad3449c7e0006">DCHECK</a>(PathIsValid(path, <a class="code" href="routing__flow_8cc.html#a75d7b5e4cab1e156cc7a2c5eba1e16f1">cost</a>));</div><div class="line"><a name="l00763"></a><span class="lineno"> 763</span>&#160; <span class="keywordflow">return</span> path;</div><div class="line"><a name="l00764"></a><span class="lineno"> 764</span>&#160;}</div><div class="line"><a name="l00765"></a><span class="lineno"> 765</span>&#160;</div><div class="line"><a name="l00766"></a><span class="lineno"> 766</span>&#160;<span class="keyword">template</span> &lt;<span class="keyword">typename</span> CostType, <span class="keyword">typename</span> CostFunction&gt;</div><div class="line"><a name="l00767"></a><span class="lineno"> 767</span>&#160;<span class="keywordtype">bool</span> HamiltonianPathSolver&lt;CostType, CostFunction&gt;::PathIsValid(</div><div class="line"><a name="l00768"></a><span class="lineno"> 768</span>&#160; <span class="keyword">const</span> std::vector&lt;int&gt;&amp; path, CostType <a class="code" href="routing__flow_8cc.html#a75d7b5e4cab1e156cc7a2c5eba1e16f1">cost</a>) {</div><div class="line"><a name="l00769"></a><span class="lineno"> 769</span>&#160; NodeSet coverage(0);</div><div class="line"><a name="l00770"></a><span class="lineno"> 770</span>&#160; <span class="keywordflow">for</span> (<span class="keywordtype">int</span> node : path) {</div><div class="line"><a name="l00771"></a><span class="lineno"> 771</span>&#160; coverage = coverage.AddElement(node);</div><div class="line"><a name="l00772"></a><span class="lineno"> 772</span>&#160; }</div><div class="line"><a name="l00773"></a><span class="lineno"> 773</span>&#160; <a class="code" href="base_2logging_8h.html#ae89df3243bbb8341130c7b3f44145ea0">DCHECK_EQ</a>(NodeSet::FullSet(num_nodes_).<a class="code" href="demon__profiler_8cc.html#ac072af30c4ffbc834bb4c681f6ecb514">value</a>(), coverage.value());</div><div class="line"><a name="l00774"></a><span class="lineno"> 774</span>&#160; CostType check_cost = 0;</div><div class="line"><a name="l00775"></a><span class="lineno"> 775</span>&#160; <span class="keywordflow">for</span> (<span class="keywordtype">int</span> i = 0; i &lt; path.size() - 1; ++i) {</div><div class="line"><a name="l00776"></a><span class="lineno"> 776</span>&#160; check_cost =</div><div class="line"><a name="l00777"></a><span class="lineno"> 777</span>&#160; Saturated&lt;CostType&gt;::Add(check_cost, Cost(path[i], path[i + 1]));</div><div class="line"><a name="l00778"></a><span class="lineno"> 778</span>&#160; }</div><div class="line"><a name="l00779"></a><span class="lineno"> 779</span>&#160; <a class="code" href="base_2logging_8h.html#a4395e95bab44e222cb2e77251017a0e2">DCHECK_LE</a>(std::abs(Saturated&lt;CostType&gt;::Sub(<a class="code" href="routing__flow_8cc.html#a75d7b5e4cab1e156cc7a2c5eba1e16f1">cost</a>, check_cost)),</div><div class="line"><a name="l00780"></a><span class="lineno"> 780</span>&#160; std::numeric_limits&lt;CostType&gt;::epsilon() * <a class="code" href="routing__flow_8cc.html#a75d7b5e4cab1e156cc7a2c5eba1e16f1">cost</a>)</div><div class="line"><a name="l00781"></a><span class="lineno"> 781</span>&#160; &lt;&lt; <span class="stringliteral">&quot;cost = &quot;</span> &lt;&lt; <a class="code" href="routing__flow_8cc.html#a75d7b5e4cab1e156cc7a2c5eba1e16f1">cost</a> &lt;&lt; <span class="stringliteral">&quot; check_cost = &quot;</span> &lt;&lt; check_cost;</div><div class="line"><a name="l00782"></a><span class="lineno"> 782</span>&#160; <span class="keywordflow">return</span> <span class="keyword">true</span>;</div><div class="line"><a name="l00783"></a><span class="lineno"> 783</span>&#160;}</div><div class="line"><a name="l00784"></a><span class="lineno"> 784</span>&#160;</div><div class="line"><a name="l00785"></a><span class="lineno"> 785</span>&#160;<span class="keyword">template</span> &lt;<span class="keyword">typename</span> CostType, <span class="keyword">typename</span> CostFunction&gt;</div><div class="line"><a name="l00786"></a><span class="lineno"><a class="line" href="classoperations__research_1_1_hamiltonian_path_solver.html#a5daed8b7f3c98c693f32dff60adeb4cc"> 786</a></span>&#160;<span class="keywordtype">bool</span> <a class="code" href="classoperations__research_1_1_hamiltonian_path_solver.html">HamiltonianPathSolver&lt;CostType, CostFunction&gt;::IsRobust</a>() {</div><div class="line"><a name="l00787"></a><span class="lineno"> 787</span>&#160; <span class="keywordflow">if</span> (std::numeric_limits&lt;CostType&gt;::is_integer) <span class="keywordflow">return</span> <span class="keyword">true</span>;</div><div class="line"><a name="l00788"></a><span class="lineno"> 788</span>&#160; <span class="keywordflow">if</span> (robustness_checked_) <span class="keywordflow">return</span> robust_;</div><div class="line"><a name="l00789"></a><span class="lineno"> 789</span>&#160; CostType min_cost = <a class="code" href="alldiff__cst_8cc.html#a26e6db9bcc64b584051ecc28171ed11f">std::numeric_limits&lt;CostType&gt;::max</a>();</div><div class="line"><a name="l00790"></a><span class="lineno"> 790</span>&#160; CostType max_cost = <a class="code" href="alldiff__cst_8cc.html#ad10edae0a852d72fb76afb1c77735045">std::numeric_limits&lt;CostType&gt;::min</a>();</div><div class="line"><a name="l00791"></a><span class="lineno"> 791</span>&#160;</div><div class="line"><a name="l00792"></a><span class="lineno"> 792</span>&#160; <span class="comment">// We compute the min and max for the cost matrix.</span></div><div class="line"><a name="l00793"></a><span class="lineno"> 793</span>&#160; <span class="keywordflow">for</span> (<span class="keywordtype">int</span> i = 0; i &lt; num_nodes_; ++i) {</div><div class="line"><a name="l00794"></a><span class="lineno"> 794</span>&#160; <span class="keywordflow">for</span> (<span class="keywordtype">int</span> j = 0; j &lt; num_nodes_; ++j) {</div><div class="line"><a name="l00795"></a><span class="lineno"> 795</span>&#160; <span class="keywordflow">if</span> (i == j) <span class="keywordflow">continue</span>;</div><div class="line"><a name="l00796"></a><span class="lineno"> 796</span>&#160; min_cost = <a class="code" href="alldiff__cst_8cc.html#ad10edae0a852d72fb76afb1c77735045">std::min</a>(min_cost, Cost(i, j));</div><div class="line"><a name="l00797"></a><span class="lineno"> 797</span>&#160; max_cost = <a class="code" href="alldiff__cst_8cc.html#a26e6db9bcc64b584051ecc28171ed11f">std::max</a>(max_cost, Cost(i, j));</div><div class="line"><a name="l00798"></a><span class="lineno"> 798</span>&#160; }</div><div class="line"><a name="l00799"></a><span class="lineno"> 799</span>&#160; }</div><div class="line"><a name="l00800"></a><span class="lineno"> 800</span>&#160; <span class="comment">// We determine if the range of the cost matrix is going to</span></div><div class="line"><a name="l00801"></a><span class="lineno"> 801</span>&#160; <span class="comment">// make the algorithm not robust because of precision issues.</span></div><div class="line"><a name="l00802"></a><span class="lineno"> 802</span>&#160; robust_ =</div><div class="line"><a name="l00803"></a><span class="lineno"> 803</span>&#160; min_cost &gt;= 0 &amp;&amp; min_cost &gt; num_nodes_ * max_cost *</div><div class="line"><a name="l00804"></a><span class="lineno"> 804</span>&#160; std::numeric_limits&lt;CostType&gt;::epsilon();</div><div class="line"><a name="l00805"></a><span class="lineno"> 805</span>&#160; robustness_checked_ = <span class="keyword">true</span>;</div><div class="line"><a name="l00806"></a><span class="lineno"> 806</span>&#160; <span class="keywordflow">return</span> robust_;</div><div class="line"><a name="l00807"></a><span class="lineno"> 807</span>&#160;}</div><div class="line"><a name="l00808"></a><span class="lineno"> 808</span>&#160;</div><div class="line"><a name="l00809"></a><span class="lineno"> 809</span>&#160;<span class="keyword">template</span> &lt;<span class="keyword">typename</span> CostType, <span class="keyword">typename</span> CostFunction&gt;</div><div class="line"><a name="l00810"></a><span class="lineno"> 810</span>&#160;<span class="keywordtype">bool</span> <a class="code" href="classoperations__research_1_1_hamiltonian_path_solver.html">HamiltonianPathSolver</a>&lt;CostType,</div><div class="line"><a name="l00811"></a><span class="lineno"><a class="line" href="classoperations__research_1_1_hamiltonian_path_solver.html#a44af6c2df0188e77ceeec78a190ecf3f"> 811</a></span>&#160; CostFunction&gt;::VerifiesTriangleInequality() {</div><div class="line"><a name="l00812"></a><span class="lineno"> 812</span>&#160; <span class="keywordflow">if</span> (triangle_inequality_checked_) <span class="keywordflow">return</span> triangle_inequality_ok_;</div><div class="line"><a name="l00813"></a><span class="lineno"> 813</span>&#160; triangle_inequality_ok_ = <span class="keyword">true</span>;</div><div class="line"><a name="l00814"></a><span class="lineno"> 814</span>&#160; triangle_inequality_checked_ = <span class="keyword">true</span>;</div><div class="line"><a name="l00815"></a><span class="lineno"> 815</span>&#160; <span class="keywordflow">for</span> (<span class="keywordtype">int</span> k = 0; k &lt; num_nodes_; ++k) {</div><div class="line"><a name="l00816"></a><span class="lineno"> 816</span>&#160; <span class="keywordflow">for</span> (<span class="keywordtype">int</span> i = 0; i &lt; num_nodes_; ++i) {</div><div class="line"><a name="l00817"></a><span class="lineno"> 817</span>&#160; <span class="keywordflow">for</span> (<span class="keywordtype">int</span> j = 0; j &lt; num_nodes_; ++j) {</div><div class="line"><a name="l00818"></a><span class="lineno"> 818</span>&#160; <span class="keyword">const</span> CostType detour_cost =</div><div class="line"><a name="l00819"></a><span class="lineno"> 819</span>&#160; Saturated&lt;CostType&gt;::Add(Cost(i, k), Cost(k, j));</div><div class="line"><a name="l00820"></a><span class="lineno"> 820</span>&#160; <span class="keywordflow">if</span> (detour_cost &lt; Cost(i, j)) {</div><div class="line"><a name="l00821"></a><span class="lineno"> 821</span>&#160; triangle_inequality_ok_ = <span class="keyword">false</span>;</div><div class="line"><a name="l00822"></a><span class="lineno"> 822</span>&#160; <span class="keywordflow">return</span> triangle_inequality_ok_;</div><div class="line"><a name="l00823"></a><span class="lineno"> 823</span>&#160; }</div><div class="line"><a name="l00824"></a><span class="lineno"> 824</span>&#160; }</div><div class="line"><a name="l00825"></a><span class="lineno"> 825</span>&#160; }</div><div class="line"><a name="l00826"></a><span class="lineno"> 826</span>&#160; }</div><div class="line"><a name="l00827"></a><span class="lineno"> 827</span>&#160; <span class="keywordflow">return</span> triangle_inequality_ok_;</div><div class="line"><a name="l00828"></a><span class="lineno"> 828</span>&#160;}</div><div class="line"><a name="l00829"></a><span class="lineno"> 829</span>&#160;</div><div class="line"><a name="l00830"></a><span class="lineno"> 830</span>&#160;<span class="keyword">template</span> &lt;<span class="keyword">typename</span> CostType, <span class="keyword">typename</span> CostFunction&gt;</div><div class="line"><a name="l00831"></a><span class="lineno"> 831</span>&#160;<span class="keywordtype">int</span> <a class="code" href="classoperations__research_1_1_hamiltonian_path_solver.html">HamiltonianPathSolver</a>&lt;CostType,</div><div class="line"><a name="l00832"></a><span class="lineno"><a class="line" href="classoperations__research_1_1_hamiltonian_path_solver.html#ad20cbbfc6081d40231920c3c9543f97e"> 832</a></span>&#160; CostFunction&gt;::BestHamiltonianPathEndNode() {</div><div class="line"><a name="l00833"></a><span class="lineno"> 833</span>&#160; <a class="code" href="namespaceoperations__research_1_1sat.html#af904018d9a1c9983624b1ce0331f2bf5">Solve</a>();</div><div class="line"><a name="l00834"></a><span class="lineno"> 834</span>&#160; <span class="keywordflow">return</span> best_hamiltonian_path_end_node_;</div><div class="line"><a name="l00835"></a><span class="lineno"> 835</span>&#160;}</div><div class="line"><a name="l00836"></a><span class="lineno"> 836</span>&#160;</div><div class="line"><a name="l00837"></a><span class="lineno"> 837</span>&#160;<span class="keyword">template</span> &lt;<span class="keyword">typename</span> CostType, <span class="keyword">typename</span> CostFunction&gt;</div><div class="line"><a name="l00838"></a><span class="lineno"><a class="line" href="classoperations__research_1_1_hamiltonian_path_solver.html#a0b31a8637cf8c0fb125444577e6ad92b"> 838</a></span>&#160;CostType <a class="code" href="classoperations__research_1_1_hamiltonian_path_solver.html">HamiltonianPathSolver&lt;CostType, CostFunction&gt;::HamiltonianCost</a>(</div><div class="line"><a name="l00839"></a><span class="lineno"> 839</span>&#160; <span class="keywordtype">int</span> end_node) {</div><div class="line"><a name="l00840"></a><span class="lineno"> 840</span>&#160; <a class="code" href="namespaceoperations__research_1_1sat.html#af904018d9a1c9983624b1ce0331f2bf5">Solve</a>();</div><div class="line"><a name="l00841"></a><span class="lineno"> 841</span>&#160; <span class="keywordflow">return</span> hamiltonian_costs_[end_node];</div><div class="line"><a name="l00842"></a><span class="lineno"> 842</span>&#160;}</div><div class="line"><a name="l00843"></a><span class="lineno"> 843</span>&#160;</div><div class="line"><a name="l00844"></a><span class="lineno"> 844</span>&#160;<span class="keyword">template</span> &lt;<span class="keyword">typename</span> CostType, <span class="keyword">typename</span> CostFunction&gt;</div><div class="line"><a name="l00845"></a><span class="lineno"><a class="line" href="classoperations__research_1_1_hamiltonian_path_solver.html#a8acc60c87190fac89379315aa08ce7a5"> 845</a></span>&#160;std::vector&lt;int&gt; <a class="code" href="classoperations__research_1_1_hamiltonian_path_solver.html">HamiltonianPathSolver&lt;CostType, CostFunction&gt;::HamiltonianPath</a>(</div><div class="line"><a name="l00846"></a><span class="lineno"> 846</span>&#160; <span class="keywordtype">int</span> end_node) {</div><div class="line"><a name="l00847"></a><span class="lineno"> 847</span>&#160; <a class="code" href="namespaceoperations__research_1_1sat.html#af904018d9a1c9983624b1ce0331f2bf5">Solve</a>();</div><div class="line"><a name="l00848"></a><span class="lineno"> 848</span>&#160; <span class="keywordflow">return</span> hamiltonian_paths_[end_node];</div><div class="line"><a name="l00849"></a><span class="lineno"> 849</span>&#160;}</div><div class="line"><a name="l00850"></a><span class="lineno"> 850</span>&#160;</div><div class="line"><a name="l00851"></a><span class="lineno"> 851</span>&#160;<span class="keyword">template</span> &lt;<span class="keyword">typename</span> CostType, <span class="keyword">typename</span> CostFunction&gt;</div><div class="line"><a name="l00852"></a><span class="lineno"><a class="line" href="classoperations__research_1_1_hamiltonian_path_solver.html#a971732356f9acd6f4806e12ef8bddfb0"> 852</a></span>&#160;<span class="keywordtype">void</span> <a class="code" href="classoperations__research_1_1_hamiltonian_path_solver.html">HamiltonianPathSolver&lt;CostType, CostFunction&gt;::HamiltonianPath</a>(</div><div class="line"><a name="l00853"></a><span class="lineno"> 853</span>&#160; std::vector&lt;PathNodeIndex&gt;* path) {</div><div class="line"><a name="l00854"></a><span class="lineno"> 854</span>&#160; *path = HamiltonianPath(best_hamiltonian_path_end_node_);</div><div class="line"><a name="l00855"></a><span class="lineno"> 855</span>&#160;}</div><div class="line"><a name="l00856"></a><span class="lineno"> 856</span>&#160;</div><div class="line"><a name="l00857"></a><span class="lineno"> 857</span>&#160;<span class="keyword">template</span> &lt;<span class="keyword">typename</span> CostType, <span class="keyword">typename</span> CostFunction&gt;</div><div class="line"><a name="l00858"></a><span class="lineno"> 858</span>&#160;CostType</div><div class="line"><a name="l00859"></a><span class="lineno"><a class="line" href="classoperations__research_1_1_hamiltonian_path_solver.html#ab558649a26fef3a74f0909ef5af45e90"> 859</a></span>&#160;<a class="code" href="classoperations__research_1_1_hamiltonian_path_solver.html">HamiltonianPathSolver&lt;CostType, CostFunction&gt;::TravelingSalesmanCost</a>() {</div><div class="line"><a name="l00860"></a><span class="lineno"> 860</span>&#160; <a class="code" href="namespaceoperations__research_1_1sat.html#af904018d9a1c9983624b1ce0331f2bf5">Solve</a>();</div><div class="line"><a name="l00861"></a><span class="lineno"> 861</span>&#160; <span class="keywordflow">return</span> tsp_cost_;</div><div class="line"><a name="l00862"></a><span class="lineno"> 862</span>&#160;}</div><div class="line"><a name="l00863"></a><span class="lineno"> 863</span>&#160;</div><div class="line"><a name="l00864"></a><span class="lineno"> 864</span>&#160;<span class="keyword">template</span> &lt;<span class="keyword">typename</span> CostType, <span class="keyword">typename</span> CostFunction&gt;</div><div class="line"><a name="l00865"></a><span class="lineno"> 865</span>&#160;std::vector&lt;int&gt;</div><div class="line"><a name="l00866"></a><span class="lineno"><a class="line" href="classoperations__research_1_1_hamiltonian_path_solver.html#a326a998ed18bedda49bd2cab5cbd4079"> 866</a></span>&#160;<a class="code" href="classoperations__research_1_1_hamiltonian_path_solver.html">HamiltonianPathSolver&lt;CostType, CostFunction&gt;::TravelingSalesmanPath</a>() {</div><div class="line"><a name="l00867"></a><span class="lineno"> 867</span>&#160; <a class="code" href="namespaceoperations__research_1_1sat.html#af904018d9a1c9983624b1ce0331f2bf5">Solve</a>();</div><div class="line"><a name="l00868"></a><span class="lineno"> 868</span>&#160; <span class="keywordflow">return</span> tsp_path_;</div><div class="line"><a name="l00869"></a><span class="lineno"> 869</span>&#160;}</div><div class="line"><a name="l00870"></a><span class="lineno"> 870</span>&#160;</div><div class="line"><a name="l00871"></a><span class="lineno"> 871</span>&#160;<span class="keyword">template</span> &lt;<span class="keyword">typename</span> CostType, <span class="keyword">typename</span> CostFunction&gt;</div><div class="line"><a name="l00872"></a><span class="lineno"><a class="line" href="classoperations__research_1_1_hamiltonian_path_solver.html#a30e8f070c957fed7c7bf2ebcc5c338b8"> 872</a></span>&#160;<span class="keywordtype">void</span> <a class="code" href="classoperations__research_1_1_hamiltonian_path_solver.html">HamiltonianPathSolver&lt;CostType, CostFunction&gt;::TravelingSalesmanPath</a>(</div><div class="line"><a name="l00873"></a><span class="lineno"> 873</span>&#160; std::vector&lt;PathNodeIndex&gt;* path) {</div><div class="line"><a name="l00874"></a><span class="lineno"> 874</span>&#160; *path = TravelingSalesmanPath();</div><div class="line"><a name="l00875"></a><span class="lineno"> 875</span>&#160;}</div><div class="line"><a name="l00876"></a><span class="lineno"> 876</span>&#160;</div><div class="line"><a name="l00877"></a><span class="lineno"> 877</span>&#160;<span class="keyword">template</span> &lt;<span class="keyword">typename</span> CostType, <span class="keyword">typename</span> CostFunction&gt;</div><div class="line"><a name="l00878"></a><span class="lineno"><a class="line" href="classoperations__research_1_1_pruning_hamiltonian_solver.html"> 878</a></span>&#160;<span class="keyword">class </span><a class="code" href="classoperations__research_1_1_pruning_hamiltonian_solver.html">PruningHamiltonianSolver</a> {</div><div class="line"><a name="l00879"></a><span class="lineno"> 879</span>&#160; <span class="comment">// PruningHamiltonianSolver computes a minimum Hamiltonian path from node 0</span></div><div class="line"><a name="l00880"></a><span class="lineno"> 880</span>&#160; <span class="comment">// over a graph defined by a cost matrix, with pruning. For each search state,</span></div><div class="line"><a name="l00881"></a><span class="lineno"> 881</span>&#160; <span class="comment">// PruningHamiltonianSolver computes the lower bound for the future overall</span></div><div class="line"><a name="l00882"></a><span class="lineno"> 882</span>&#160; <span class="comment">// TSP cost, and stops further search if it exceeds the current best solution.</span></div><div class="line"><a name="l00883"></a><span class="lineno"> 883</span>&#160;</div><div class="line"><a name="l00884"></a><span class="lineno"> 884</span>&#160; <span class="comment">// For the heuristics to determine future lower bound over visited nodeset S</span></div><div class="line"><a name="l00885"></a><span class="lineno"> 885</span>&#160; <span class="comment">// and last visited node k, the cost of minimum spanning tree of (V \ S) {k}</span></div><div class="line"><a name="l00886"></a><span class="lineno"> 886</span>&#160; <span class="comment">// is calculated and added to the current cost(S). The cost of MST is</span></div><div class="line"><a name="l00887"></a><span class="lineno"> 887</span>&#160; <span class="comment">// guaranteed to be smaller than or equal to the cost of Hamiltonian path,</span></div><div class="line"><a name="l00888"></a><span class="lineno"> 888</span>&#160; <span class="comment">// because Hamiltonian path is a spanning tree itself.</span></div><div class="line"><a name="l00889"></a><span class="lineno"> 889</span>&#160;</div><div class="line"><a name="l00890"></a><span class="lineno"> 890</span>&#160; <span class="comment">// TODO(user): Use generic map-based cache instead of lattice-based one.</span></div><div class="line"><a name="l00891"></a><span class="lineno"> 891</span>&#160; <span class="comment">// TODO(user): Use SaturatedArithmetic for better precision.</span></div><div class="line"><a name="l00892"></a><span class="lineno"> 892</span>&#160;</div><div class="line"><a name="l00893"></a><span class="lineno"> 893</span>&#160; <span class="keyword">public</span>:</div><div class="line"><a name="l00894"></a><span class="lineno"><a class="line" href="classoperations__research_1_1_pruning_hamiltonian_solver.html#a346635bd62f6d557d98e490ff2f3f306"> 894</a></span>&#160; <span class="keyword">typedef</span> uint32_t <a class="code" href="classoperations__research_1_1_pruning_hamiltonian_solver.html#a346635bd62f6d557d98e490ff2f3f306">Integer</a>;</div><div class="line"><a name="l00895"></a><span class="lineno"><a class="line" href="classoperations__research_1_1_pruning_hamiltonian_solver.html#a03106785fd757b213975f94d4b780709"> 895</a></span>&#160; <span class="keyword">typedef</span> <a class="code" href="classoperations__research_1_1_set.html">Set&lt;Integer&gt;</a> <a class="code" href="classoperations__research_1_1_pruning_hamiltonian_solver.html#a03106785fd757b213975f94d4b780709">NodeSet</a>;</div><div class="line"><a name="l00896"></a><span class="lineno"> 896</span>&#160;</div><div class="line"><a name="l00897"></a><span class="lineno"> 897</span>&#160; <span class="keyword">explicit</span> <a class="code" href="classoperations__research_1_1_pruning_hamiltonian_solver.html">PruningHamiltonianSolver</a>(CostFunction <a class="code" href="routing__flow_8cc.html#a75d7b5e4cab1e156cc7a2c5eba1e16f1">cost</a>);</div><div class="line"><a name="l00898"></a><span class="lineno"> 898</span>&#160; <a class="code" href="classoperations__research_1_1_pruning_hamiltonian_solver.html">PruningHamiltonianSolver</a>(<span class="keywordtype">int</span> num_nodes, CostFunction <a class="code" href="routing__flow_8cc.html#a75d7b5e4cab1e156cc7a2c5eba1e16f1">cost</a>);</div><div class="line"><a name="l00899"></a><span class="lineno"> 899</span>&#160;</div><div class="line"><a name="l00900"></a><span class="lineno"> 900</span>&#160; <span class="comment">// Returns the cost of the Hamiltonian path from 0 to end_node.</span></div><div class="line"><a name="l00901"></a><span class="lineno"> 901</span>&#160; CostType HamiltonianCost(<span class="keywordtype">int</span> end_node);</div><div class="line"><a name="l00902"></a><span class="lineno"> 902</span>&#160;</div><div class="line"><a name="l00903"></a><span class="lineno"> 903</span>&#160; <span class="comment">// TODO(user): Add function to return an actual path.</span></div><div class="line"><a name="l00904"></a><span class="lineno"> 904</span>&#160; <span class="comment">// TODO(user): Add functions for Hamiltonian cycle.</span></div><div class="line"><a name="l00905"></a><span class="lineno"> 905</span>&#160;</div><div class="line"><a name="l00906"></a><span class="lineno"> 906</span>&#160; <span class="keyword">private</span>:</div><div class="line"><a name="l00907"></a><span class="lineno"> 907</span>&#160; <span class="comment">// Returns the cost value between two nodes.</span></div><div class="line"><a name="l00908"></a><span class="lineno"> 908</span>&#160; CostType Cost(<span class="keywordtype">int</span> i, <span class="keywordtype">int</span> j) { <span class="keywordflow">return</span> cost_(i, j); }</div><div class="line"><a name="l00909"></a><span class="lineno"> 909</span>&#160;</div><div class="line"><a name="l00910"></a><span class="lineno"> 910</span>&#160; <span class="comment">// Solve and get TSP cost.</span></div><div class="line"><a name="l00911"></a><span class="lineno"> 911</span>&#160; <span class="keywordtype">void</span> <a class="code" href="namespaceoperations__research_1_1sat.html#af904018d9a1c9983624b1ce0331f2bf5">Solve</a>(<span class="keywordtype">int</span> end_node);</div><div class="line"><a name="l00912"></a><span class="lineno"> 912</span>&#160;</div><div class="line"><a name="l00913"></a><span class="lineno"> 913</span>&#160; <span class="comment">// Compute lower bound for remaining subgraph.</span></div><div class="line"><a name="l00914"></a><span class="lineno"> 914</span>&#160; CostType ComputeFutureLowerBound(NodeSet current_set, <span class="keywordtype">int</span> last_visited);</div><div class="line"><a name="l00915"></a><span class="lineno"> 915</span>&#160;</div><div class="line"><a name="l00916"></a><span class="lineno"> 916</span>&#160; <span class="comment">// Cost function used to build Hamiltonian paths.</span></div><div class="line"><a name="l00917"></a><span class="lineno"> 917</span>&#160; <a class="code" href="classoperations__research_1_1_matrix_or_function.html">MatrixOrFunction&lt;CostType, CostFunction, true&gt;</a> cost_;</div><div class="line"><a name="l00918"></a><span class="lineno"> 918</span>&#160;</div><div class="line"><a name="l00919"></a><span class="lineno"> 919</span>&#160; <span class="comment">// The number of nodes in the problem.</span></div><div class="line"><a name="l00920"></a><span class="lineno"> 920</span>&#160; <span class="keywordtype">int</span> num_nodes_;</div><div class="line"><a name="l00921"></a><span class="lineno"> 921</span>&#160;</div><div class="line"><a name="l00922"></a><span class="lineno"> 922</span>&#160; <span class="comment">// The cost of the computed TSP path.</span></div><div class="line"><a name="l00923"></a><span class="lineno"> 923</span>&#160; CostType tsp_cost_;</div><div class="line"><a name="l00924"></a><span class="lineno"> 924</span>&#160;</div><div class="line"><a name="l00925"></a><span class="lineno"> 925</span>&#160; <span class="comment">// If already solved.</span></div><div class="line"><a name="l00926"></a><span class="lineno"> 926</span>&#160; <span class="keywordtype">bool</span> solved_;</div><div class="line"><a name="l00927"></a><span class="lineno"> 927</span>&#160;</div><div class="line"><a name="l00928"></a><span class="lineno"> 928</span>&#160; <span class="comment">// Memoize for dynamic programming.</span></div><div class="line"><a name="l00929"></a><span class="lineno"> 929</span>&#160; <a class="code" href="classoperations__research_1_1_lattice_memory_manager.html">LatticeMemoryManager&lt;NodeSet, CostType&gt;</a> mem_;</div><div class="line"><a name="l00930"></a><span class="lineno"> 930</span>&#160;};</div><div class="line"><a name="l00931"></a><span class="lineno"> 931</span>&#160;</div><div class="line"><a name="l00932"></a><span class="lineno"> 932</span>&#160;<span class="keyword">template</span> &lt;<span class="keyword">typename</span> CostType, <span class="keyword">typename</span> CostFunction&gt;</div><div class="line"><a name="l00933"></a><span class="lineno"><a class="line" href="classoperations__research_1_1_pruning_hamiltonian_solver.html#a4772bfe5f78a696373e531ba983bc695"> 933</a></span>&#160;<a class="code" href="classoperations__research_1_1_pruning_hamiltonian_solver.html">PruningHamiltonianSolver&lt;CostType, CostFunction&gt;::PruningHamiltonianSolver</a>(</div><div class="line"><a name="l00934"></a><span class="lineno"> 934</span>&#160; CostFunction <a class="code" href="routing__flow_8cc.html#a75d7b5e4cab1e156cc7a2c5eba1e16f1">cost</a>)</div><div class="line"><a name="l00935"></a><span class="lineno"> 935</span>&#160; : <a class="code" href="classoperations__research_1_1_pruning_hamiltonian_solver.html">PruningHamiltonianSolver</a>&lt;CostType, CostFunction&gt;(<a class="code" href="routing__flow_8cc.html#a75d7b5e4cab1e156cc7a2c5eba1e16f1">cost</a>.size(), <a class="code" href="routing__flow_8cc.html#a75d7b5e4cab1e156cc7a2c5eba1e16f1">cost</a>) {}</div><div class="line"><a name="l00936"></a><span class="lineno"> 936</span>&#160;</div><div class="line"><a name="l00937"></a><span class="lineno"> 937</span>&#160;<span class="keyword">template</span> &lt;<span class="keyword">typename</span> CostType, <span class="keyword">typename</span> CostFunction&gt;</div><div class="line"><a name="l00938"></a><span class="lineno"><a class="line" href="classoperations__research_1_1_pruning_hamiltonian_solver.html#a5834452c9889879749638cdb31869678"> 938</a></span>&#160;<a class="code" href="classoperations__research_1_1_pruning_hamiltonian_solver.html#a4772bfe5f78a696373e531ba983bc695">PruningHamiltonianSolver&lt;CostType, CostFunction&gt;::PruningHamiltonianSolver</a>(</div><div class="line"><a name="l00939"></a><span class="lineno"> 939</span>&#160; <span class="keywordtype">int</span> num_nodes, CostFunction <a class="code" href="routing__flow_8cc.html#a75d7b5e4cab1e156cc7a2c5eba1e16f1">cost</a>)</div><div class="line"><a name="l00940"></a><span class="lineno"> 940</span>&#160; : cost_(std::move(<a class="code" href="routing__flow_8cc.html#a75d7b5e4cab1e156cc7a2c5eba1e16f1">cost</a>)),</div><div class="line"><a name="l00941"></a><span class="lineno"> 941</span>&#160; num_nodes_(num_nodes),</div><div class="line"><a name="l00942"></a><span class="lineno"> 942</span>&#160; tsp_cost_(0),</div><div class="line"><a name="l00943"></a><span class="lineno"> 943</span>&#160; solved_(false) {}</div><div class="line"><a name="l00944"></a><span class="lineno"> 944</span>&#160;</div><div class="line"><a name="l00945"></a><span class="lineno"> 945</span>&#160;<span class="keyword">template</span> &lt;<span class="keyword">typename</span> CostType, <span class="keyword">typename</span> CostFunction&gt;</div><div class="line"><a name="l00946"></a><span class="lineno"> 946</span>&#160;<span class="keywordtype">void</span> <a class="code" href="classoperations__research_1_1_pruning_hamiltonian_solver.html">PruningHamiltonianSolver&lt;CostType, CostFunction&gt;::Solve</a>(<span class="keywordtype">int</span> end_node) {</div><div class="line"><a name="l00947"></a><span class="lineno"> 947</span>&#160; <span class="keywordflow">if</span> (solved_ || num_nodes_ == 0) <span class="keywordflow">return</span>;</div><div class="line"><a name="l00948"></a><span class="lineno"> 948</span>&#160; <span class="comment">// TODO(user): Use an approximate solution as a base target before solving.</span></div><div class="line"><a name="l00949"></a><span class="lineno"> 949</span>&#160;</div><div class="line"><a name="l00950"></a><span class="lineno"> 950</span>&#160; <span class="comment">// TODO(user): Instead of pure DFS, find out the order of sets to compute</span></div><div class="line"><a name="l00951"></a><span class="lineno"> 951</span>&#160; <span class="comment">// to utilize cache as possible.</span></div><div class="line"><a name="l00952"></a><span class="lineno"> 952</span>&#160;</div><div class="line"><a name="l00953"></a><span class="lineno"> 953</span>&#160; mem_.Init(num_nodes_);</div><div class="line"><a name="l00954"></a><span class="lineno"> 954</span>&#160; NodeSet start_set = NodeSet::Singleton(0);</div><div class="line"><a name="l00955"></a><span class="lineno"> 955</span>&#160; std::stack&lt;std::pair&lt;NodeSet, int&gt;&gt; state_stack;</div><div class="line"><a name="l00956"></a><span class="lineno"> 956</span>&#160; state_stack.push(std::make_pair(start_set, 0));</div><div class="line"><a name="l00957"></a><span class="lineno"> 957</span>&#160;</div><div class="line"><a name="l00958"></a><span class="lineno"> 958</span>&#160; <span class="keywordflow">while</span> (!state_stack.empty()) {</div><div class="line"><a name="l00959"></a><span class="lineno"> 959</span>&#160; <span class="keyword">const</span> std::pair&lt;NodeSet, int&gt; current = state_stack.top();</div><div class="line"><a name="l00960"></a><span class="lineno"> 960</span>&#160; state_stack.pop();</div><div class="line"><a name="l00961"></a><span class="lineno"> 961</span>&#160;</div><div class="line"><a name="l00962"></a><span class="lineno"> 962</span>&#160; <span class="keyword">const</span> NodeSet current_set = current.first;</div><div class="line"><a name="l00963"></a><span class="lineno"> 963</span>&#160; <span class="keyword">const</span> <span class="keywordtype">int</span> last_visited = current.second;</div><div class="line"><a name="l00964"></a><span class="lineno"> 964</span>&#160; <span class="keyword">const</span> CostType current_cost = mem_.Value(current_set, last_visited);</div><div class="line"><a name="l00965"></a><span class="lineno"> 965</span>&#160;</div><div class="line"><a name="l00966"></a><span class="lineno"> 966</span>&#160; <span class="comment">// TODO(user): Optimize iterating unvisited nodes.</span></div><div class="line"><a name="l00967"></a><span class="lineno"> 967</span>&#160; <span class="keywordflow">for</span> (<span class="keywordtype">int</span> next_to_visit = 0; next_to_visit &lt; num_nodes_; next_to_visit++) {</div><div class="line"><a name="l00968"></a><span class="lineno"> 968</span>&#160; <span class="comment">// Let&#39;s to as much check possible before adding to stack.</span></div><div class="line"><a name="l00969"></a><span class="lineno"> 969</span>&#160;</div><div class="line"><a name="l00970"></a><span class="lineno"> 970</span>&#160; <span class="comment">// Skip if this node is already visited.</span></div><div class="line"><a name="l00971"></a><span class="lineno"> 971</span>&#160; <span class="keywordflow">if</span> (current_set.Contains(next_to_visit)) <span class="keywordflow">continue</span>;</div><div class="line"><a name="l00972"></a><span class="lineno"> 972</span>&#160;</div><div class="line"><a name="l00973"></a><span class="lineno"> 973</span>&#160; <span class="comment">// Skip if the end node is prematurely visited.</span></div><div class="line"><a name="l00974"></a><span class="lineno"> 974</span>&#160; <span class="keyword">const</span> <span class="keywordtype">int</span> next_cardinality = current_set.Cardinality() + 1;</div><div class="line"><a name="l00975"></a><span class="lineno"> 975</span>&#160; <span class="keywordflow">if</span> (next_to_visit == end_node &amp;&amp; next_cardinality != num_nodes_) <span class="keywordflow">continue</span>;</div><div class="line"><a name="l00976"></a><span class="lineno"> 976</span>&#160;</div><div class="line"><a name="l00977"></a><span class="lineno"> 977</span>&#160; <span class="keyword">const</span> NodeSet next_set = current_set.AddElement(next_to_visit);</div><div class="line"><a name="l00978"></a><span class="lineno"> 978</span>&#160; <span class="keyword">const</span> CostType next_cost =</div><div class="line"><a name="l00979"></a><span class="lineno"> 979</span>&#160; current_cost + Cost(last_visited, next_to_visit);</div><div class="line"><a name="l00980"></a><span class="lineno"> 980</span>&#160;</div><div class="line"><a name="l00981"></a><span class="lineno"> 981</span>&#160; <span class="comment">// Compare with the best cost found so far, and skip if that is better.</span></div><div class="line"><a name="l00982"></a><span class="lineno"> 982</span>&#160; <span class="keyword">const</span> CostType previous_best = mem_.Value(next_set, next_to_visit);</div><div class="line"><a name="l00983"></a><span class="lineno"> 983</span>&#160; <span class="keywordflow">if</span> (previous_best != 0 &amp;&amp; next_cost &gt;= previous_best) <span class="keywordflow">continue</span>;</div><div class="line"><a name="l00984"></a><span class="lineno"> 984</span>&#160;</div><div class="line"><a name="l00985"></a><span class="lineno"> 985</span>&#160; <span class="comment">// Compute lower bound of Hamiltonian cost, and skip if this is greater</span></div><div class="line"><a name="l00986"></a><span class="lineno"> 986</span>&#160; <span class="comment">// than the best Hamiltonian cost found so far.</span></div><div class="line"><a name="l00987"></a><span class="lineno"> 987</span>&#160; <span class="keyword">const</span> CostType <a class="code" href="gscip__solver_8cc.html#a1e2f9a2352c1d9a6cada9544898fceec">lower_bound</a> =</div><div class="line"><a name="l00988"></a><span class="lineno"> 988</span>&#160; ComputeFutureLowerBound(next_set, next_to_visit);</div><div class="line"><a name="l00989"></a><span class="lineno"> 989</span>&#160; <span class="keywordflow">if</span> (tsp_cost_ != 0 &amp;&amp; next_cost + <a class="code" href="gscip__solver_8cc.html#a1e2f9a2352c1d9a6cada9544898fceec">lower_bound</a> &gt;= tsp_cost_) <span class="keywordflow">continue</span>;</div><div class="line"><a name="l00990"></a><span class="lineno"> 990</span>&#160;</div><div class="line"><a name="l00991"></a><span class="lineno"> 991</span>&#160; <span class="comment">// If next is the last node to visit, update tsp_cost_ and skip.</span></div><div class="line"><a name="l00992"></a><span class="lineno"> 992</span>&#160; <span class="keywordflow">if</span> (next_cardinality == num_nodes_) {</div><div class="line"><a name="l00993"></a><span class="lineno"> 993</span>&#160; tsp_cost_ = next_cost;</div><div class="line"><a name="l00994"></a><span class="lineno"> 994</span>&#160; <span class="keywordflow">continue</span>;</div><div class="line"><a name="l00995"></a><span class="lineno"> 995</span>&#160; }</div><div class="line"><a name="l00996"></a><span class="lineno"> 996</span>&#160;</div><div class="line"><a name="l00997"></a><span class="lineno"> 997</span>&#160; <span class="comment">// Add to the stack, finally.</span></div><div class="line"><a name="l00998"></a><span class="lineno"> 998</span>&#160; mem_.SetValue(next_set, next_to_visit, next_cost);</div><div class="line"><a name="l00999"></a><span class="lineno"> 999</span>&#160; state_stack.push(std::make_pair(next_set, next_to_visit));</div><div class="line"><a name="l01000"></a><span class="lineno"> 1000</span>&#160; }</div><div class="line"><a name="l01001"></a><span class="lineno"> 1001</span>&#160; }</div><div class="line"><a name="l01002"></a><span class="lineno"> 1002</span>&#160;</div><div class="line"><a name="l01003"></a><span class="lineno"> 1003</span>&#160; solved_ = <span class="keyword">true</span>;</div><div class="line"><a name="l01004"></a><span class="lineno"> 1004</span>&#160;}</div><div class="line"><a name="l01005"></a><span class="lineno"> 1005</span>&#160;</div><div class="line"><a name="l01006"></a><span class="lineno"> 1006</span>&#160;<span class="keyword">template</span> &lt;<span class="keyword">typename</span> CostType, <span class="keyword">typename</span> CostFunction&gt;</div><div class="line"><a name="l01007"></a><span class="lineno"><a class="line" href="classoperations__research_1_1_pruning_hamiltonian_solver.html#a0b31a8637cf8c0fb125444577e6ad92b"> 1007</a></span>&#160;CostType <a class="code" href="classoperations__research_1_1_pruning_hamiltonian_solver.html#a0b31a8637cf8c0fb125444577e6ad92b">PruningHamiltonianSolver&lt;CostType, CostFunction&gt;::HamiltonianCost</a>(</div><div class="line"><a name="l01008"></a><span class="lineno"> 1008</span>&#160; <span class="keywordtype">int</span> end_node) {</div><div class="line"><a name="l01009"></a><span class="lineno"> 1009</span>&#160; <a class="code" href="namespaceoperations__research_1_1sat.html#af904018d9a1c9983624b1ce0331f2bf5">Solve</a>(end_node);</div><div class="line"><a name="l01010"></a><span class="lineno"> 1010</span>&#160; <span class="keywordflow">return</span> tsp_cost_;</div><div class="line"><a name="l01011"></a><span class="lineno"> 1011</span>&#160;}</div><div class="line"><a name="l01012"></a><span class="lineno"> 1012</span>&#160;</div><div class="line"><a name="l01013"></a><span class="lineno"> 1013</span>&#160;<span class="keyword">template</span> &lt;<span class="keyword">typename</span> CostType, <span class="keyword">typename</span> CostFunction&gt;</div><div class="line"><a name="l01014"></a><span class="lineno"> 1014</span>&#160;CostType</div><div class="line"><a name="l01015"></a><span class="lineno"> 1015</span>&#160;<a class="code" href="classoperations__research_1_1_pruning_hamiltonian_solver.html">PruningHamiltonianSolver&lt;CostType, CostFunction&gt;::ComputeFutureLowerBound</a>(</div><div class="line"><a name="l01016"></a><span class="lineno"> 1016</span>&#160; NodeSet current_set, <span class="keywordtype">int</span> last_visited) {</div><div class="line"><a name="l01017"></a><span class="lineno"> 1017</span>&#160; <span class="comment">// TODO(user): Compute MST.</span></div><div class="line"><a name="l01018"></a><span class="lineno"> 1018</span>&#160; <span class="keywordflow">return</span> 0; <span class="comment">// For now, return 0 as future lower bound.</span></div><div class="line"><a name="l01019"></a><span class="lineno"> 1019</span>&#160;}</div><div class="line"><a name="l01020"></a><span class="lineno"> 1020</span>&#160;} <span class="comment">// namespace operations_research</span></div><div class="line"><a name="l01021"></a><span class="lineno"> 1021</span>&#160;</div><div class="line"><a name="l01022"></a><span class="lineno"> 1022</span>&#160;<span class="preprocessor">#endif // OR_TOOLS_GRAPH_HAMILTONIAN_PATH_H_</span></div><div class="ttc" id="classoperations__research_1_1_hamiltonian_path_solver_html_a19edb994fca04e71736cf3a8d62d7a73"><div class="ttname"><a href="classoperations__research_1_1_hamiltonian_path_solver.html#a19edb994fca04e71736cf3a8d62d7a73">operations_research::HamiltonianPathSolver::ChangeCostMatrix</a></div><div class="ttdeci">void ChangeCostMatrix(CostFunction cost)</div><div class="ttdef"><b>Definition:</b> <a href="hamiltonian__path_8h_source.html#l00628">hamiltonian_path.h:628</a></div></div>
<div class="ttc" id="classoperations__research_1_1_lattice_memory_manager_html_a91814684a688a3264fc8f29972969d61"><div class="ttname"><a href="classoperations__research_1_1_lattice_memory_manager.html#a91814684a688a3264fc8f29972969d61">operations_research::LatticeMemoryManager::SetValueAtOffset</a></div><div class="ttdeci">void SetValueAtOffset(uint64_t offset, CostType value)</div><div class="ttdef"><b>Definition:</b> <a href="hamiltonian__path_8h_source.html#l00324">hamiltonian_path.h:324</a></div></div>
<div class="ttc" id="base_2logging_8h_html_a3e1cfef60e774a81f30eaddf26a3a274"><div class="ttname"><a href="base_2logging_8h.html#a3e1cfef60e774a81f30eaddf26a3a274">CHECK</a></div><div class="ttdeci">#define CHECK(condition)</div><div class="ttdef"><b>Definition:</b> <a href="base_2logging_8h_source.html#l00495">base/logging.h:495</a></div></div>
<div class="ttc" id="namespaceoperations__research_html_a4a43d435871f16c321861fa5de32df82"><div class="ttname"><a href="namespaceoperations__research.html#a4a43d435871f16c321861fa5de32df82">operations_research::CapSub</a></div><div class="ttdeci">int64_t CapSub(int64_t x, int64_t y)</div><div class="ttdef"><b>Definition:</b> <a href="saturated__arithmetic_8h_source.html#l00158">saturated_arithmetic.h:158</a></div></div>
<div class="ttc" id="alldiff__cst_8cc_html_ad10edae0a852d72fb76afb1c77735045"><div class="ttname"><a href="alldiff__cst_8cc.html#ad10edae0a852d72fb76afb1c77735045">min</a></div><div class="ttdeci">int64_t min</div><div class="ttdef"><b>Definition:</b> <a href="alldiff__cst_8cc_source.html#l00139">alldiff_cst.cc:139</a></div></div>
<div class="ttc" id="base_2logging_8h_html_a7cc25402ecd7591b4c39934dd656b1f9"><div class="ttname"><a href="base_2logging_8h.html#a7cc25402ecd7591b4c39934dd656b1f9">CHECK_GE</a></div><div class="ttdeci">#define CHECK_GE(val1, val2)</div><div class="ttdef"><b>Definition:</b> <a href="base_2logging_8h_source.html#l00706">base/logging.h:706</a></div></div>
<div class="ttc" id="classoperations__research_1_1_set_range_iterator_html_ad82623d8471ab5eb30f4e19bc89796b9"><div class="ttname"><a href="classoperations__research_1_1_set_range_iterator.html#ad82623d8471ab5eb30f4e19bc89796b9">operations_research::SetRangeIterator::SetRangeIterator</a></div><div class="ttdeci">SetRangeIterator(const SetType set)</div><div class="ttdef"><b>Definition:</b> <a href="hamiltonian__path_8h_source.html#l00230">hamiltonian_path.h:230</a></div></div>
<div class="ttc" id="classoperations__research_1_1_set_html_afe05ca596cfc024da65cf61a79812a2f"><div class="ttname"><a href="classoperations__research_1_1_set.html#afe05ca596cfc024da65cf61a79812a2f">operations_research::Set::AddElement</a></div><div class="ttdeci">Set AddElement(int n) const</div><div class="ttdef"><b>Definition:</b> <a href="hamiltonian__path_8h_source.html#l00156">hamiltonian_path.h:156</a></div></div>
<div class="ttc" id="classoperations__research_1_1_hamiltonian_path_solver_html_a0b31a8637cf8c0fb125444577e6ad92b"><div class="ttname"><a href="classoperations__research_1_1_hamiltonian_path_solver.html#a0b31a8637cf8c0fb125444577e6ad92b">operations_research::HamiltonianPathSolver::HamiltonianCost</a></div><div class="ttdeci">CostType HamiltonianCost(int end_node)</div><div class="ttdef"><b>Definition:</b> <a href="hamiltonian__path_8h_source.html#l00838">hamiltonian_path.h:838</a></div></div>
<div class="ttc" id="classoperations__research_1_1_lattice_memory_manager_html_afc715a6711310680640765eb66822f8b"><div class="ttname"><a href="classoperations__research_1_1_lattice_memory_manager.html#afc715a6711310680640765eb66822f8b">operations_research::LatticeMemoryManager::ValueAtOffset</a></div><div class="ttdeci">CostType ValueAtOffset(uint64_t offset) const</div><div class="ttdef"><b>Definition:</b> <a href="hamiltonian__path_8h_source.html#l00334">hamiltonian_path.h:334</a></div></div>
<div class="ttc" id="classoperations__research_1_1_set_html_abb2b3831b27fd81d60fb39ad01e108a3"><div class="ttname"><a href="classoperations__research_1_1_set.html#abb2b3831b27fd81d60fb39ad01e108a3">operations_research::Set::SmallestElement</a></div><div class="ttdeci">int SmallestElement() const</div><div class="ttdef"><b>Definition:</b> <a href="hamiltonian__path_8h_source.html#l00176">hamiltonian_path.h:176</a></div></div>
<div class="ttc" id="classoperations__research_1_1_hamiltonian_path_solver_html_ad20cbbfc6081d40231920c3c9543f97e"><div class="ttname"><a href="classoperations__research_1_1_hamiltonian_path_solver.html#ad20cbbfc6081d40231920c3c9543f97e">operations_research::HamiltonianPathSolver::BestHamiltonianPathEndNode</a></div><div class="ttdeci">int BestHamiltonianPathEndNode()</div><div class="ttdef"><b>Definition:</b> <a href="hamiltonian__path_8h_source.html#l00832">hamiltonian_path.h:832</a></div></div>
<div class="ttc" id="namespaceoperations__research_html_a715b0dbb9f0903ab629b8c6da1b35b45"><div class="ttname"><a href="namespaceoperations__research.html#a715b0dbb9f0903ab629b8c6da1b35b45">operations_research::MakeHamiltonianPathSolver</a></div><div class="ttdeci">HamiltonianPathSolver&lt; CostType, CostFunction &gt; MakeHamiltonianPathSolver(int num_nodes, CostFunction cost)</div><div class="ttdef"><b>Definition:</b> <a href="hamiltonian__path_8h_source.html#l00600">hamiltonian_path.h:600</a></div></div>
<div class="ttc" id="classoperations__research_1_1_hamiltonian_path_solver_html"><div class="ttname"><a href="classoperations__research_1_1_hamiltonian_path_solver.html">operations_research::HamiltonianPathSolver</a></div><div class="ttdef"><b>Definition:</b> <a href="hamiltonian__path_8h_source.html#l00454">hamiltonian_path.h:454</a></div></div>
<div class="ttc" id="classoperations__research_1_1_set_html_a67d03a6e5178376e21bdfa720680e447"><div class="ttname"><a href="classoperations__research_1_1_set.html#a67d03a6e5178376e21bdfa720680e447">operations_research::Set::end</a></div><div class="ttdeci">ElementIterator&lt; Set &gt; end() const</div><div class="ttdef"><b>Definition:</b> <a href="hamiltonian__path_8h_source.html#l00202">hamiltonian_path.h:202</a></div></div>
<div class="ttc" id="classoperations__research_1_1_set_range_iterator_html_a0e4b89b4bb1b1a5bb3c799938380aeb0"><div class="ttname"><a href="classoperations__research_1_1_set_range_iterator.html#a0e4b89b4bb1b1a5bb3c799938380aeb0">operations_research::SetRangeIterator::SetType</a></div><div class="ttdeci">SetRange::SetType SetType</div><div class="ttdef"><b>Definition:</b> <a href="hamiltonian__path_8h_source.html#l00227">hamiltonian_path.h:227</a></div></div>
<div class="ttc" id="classoperations__research_1_1_pruning_hamiltonian_solver_html_a4772bfe5f78a696373e531ba983bc695"><div class="ttname"><a href="classoperations__research_1_1_pruning_hamiltonian_solver.html#a4772bfe5f78a696373e531ba983bc695">operations_research::PruningHamiltonianSolver::PruningHamiltonianSolver</a></div><div class="ttdeci">PruningHamiltonianSolver(CostFunction cost)</div><div class="ttdef"><b>Definition:</b> <a href="hamiltonian__path_8h_source.html#l00933">hamiltonian_path.h:933</a></div></div>
<div class="ttc" id="classoperations__research_1_1_lattice_memory_manager_html_a1958048f654b22c744e32dfbcdbeb416"><div class="ttname"><a href="classoperations__research_1_1_lattice_memory_manager.html#a1958048f654b22c744e32dfbcdbeb416">operations_research::LatticeMemoryManager::Offset</a></div><div class="ttdeci">uint64_t Offset(Set s, int node) const</div><div class="ttdef"><b>Definition:</b> <a href="hamiltonian__path_8h_source.html#l00432">hamiltonian_path.h:432</a></div></div>
<div class="ttc" id="classoperations__research_1_1_lattice_memory_manager_html_aab77eae51a0b3e7781df913213ff4372"><div class="ttname"><a href="classoperations__research_1_1_lattice_memory_manager.html#aab77eae51a0b3e7781df913213ff4372">operations_research::LatticeMemoryManager::Value</a></div><div class="ttdeci">CostType Value(Set s, int node) const</div><div class="ttdef"><b>Definition:</b> <a href="hamiltonian__path_8h_source.html#l00438">hamiltonian_path.h:438</a></div></div>
<div class="ttc" id="namespaceoperations__research_1_1sat_html_af904018d9a1c9983624b1ce0331f2bf5"><div class="ttname"><a href="namespaceoperations__research_1_1sat.html#af904018d9a1c9983624b1ce0331f2bf5">operations_research::sat::Solve</a></div><div class="ttdeci">CpSolverResponse Solve(const CpModelProto &amp;model_proto)</div><div class="ttdoc">Solves the given CpModelProto and returns an instance of CpSolverResponse.</div><div class="ttdef"><b>Definition:</b> <a href="cp__model__solver_8cc_source.html#l03470">cp_model_solver.cc:3470</a></div></div>
<div class="ttc" id="classoperations__research_1_1_hamiltonian_path_solver_html_a346635bd62f6d557d98e490ff2f3f306"><div class="ttname"><a href="classoperations__research_1_1_hamiltonian_path_solver.html#a346635bd62f6d557d98e490ff2f3f306">operations_research::HamiltonianPathSolver::Integer</a></div><div class="ttdeci">uint32_t Integer</div><div class="ttdef"><b>Definition:</b> <a href="hamiltonian__path_8h_source.html#l00476">hamiltonian_path.h:476</a></div></div>
<div class="ttc" id="classoperations__research_1_1_element_iterator_html_a6eb44ef439441ada8ffaaf6ee33a9c40"><div class="ttname"><a href="classoperations__research_1_1_element_iterator.html#a6eb44ef439441ada8ffaaf6ee33a9c40">operations_research::ElementIterator::operator++</a></div><div class="ttdeci">const ElementIterator &amp; operator++()</div><div class="ttdef"><b>Definition:</b> <a href="hamiltonian__path_8h_source.html#l00116">hamiltonian_path.h:116</a></div></div>
<div class="ttc" id="classoperations__research_1_1_set_html_a450e5cf964a0b2c866641c8f4e4b3361"><div class="ttname"><a href="classoperations__research_1_1_set.html#a450e5cf964a0b2c866641c8f4e4b3361">operations_research::Set::Set</a></div><div class="ttdeci">Set(Integer n)</div><div class="ttdef"><b>Definition:</b> <a href="hamiltonian__path_8h_source.html#l00139">hamiltonian_path.h:139</a></div></div>
<div class="ttc" id="classoperations__research_1_1_lattice_memory_manager_html"><div class="ttname"><a href="classoperations__research_1_1_lattice_memory_manager.html">operations_research::LatticeMemoryManager</a></div><div class="ttdef"><b>Definition:</b> <a href="hamiltonian__path_8h_source.html#l00292">hamiltonian_path.h:292</a></div></div>
<div class="ttc" id="classoperations__research_1_1_set_html_a879ebf910431019a01f98d0865749c8d"><div class="ttname"><a href="classoperations__research_1_1_set.html#a879ebf910431019a01f98d0865749c8d">operations_research::Set::Cardinality</a></div><div class="ttdeci">int Cardinality() const</div><div class="ttdef"><b>Definition:</b> <a href="hamiltonian__path_8h_source.html#l00172">hamiltonian_path.h:172</a></div></div>
<div class="ttc" id="classoperations__research_1_1_set_html_a983cf4555b2577512febcc3aa327a3c8"><div class="ttname"><a href="classoperations__research_1_1_set.html#a983cf4555b2577512febcc3aa327a3c8">operations_research::Set::value</a></div><div class="ttdeci">Integer value() const</div><div class="ttdef"><b>Definition:</b> <a href="hamiltonian__path_8h_source.html#l00145">hamiltonian_path.h:145</a></div></div>
<div class="ttc" id="classoperations__research_1_1_pruning_hamiltonian_solver_html_a0b31a8637cf8c0fb125444577e6ad92b"><div class="ttname"><a href="classoperations__research_1_1_pruning_hamiltonian_solver.html#a0b31a8637cf8c0fb125444577e6ad92b">operations_research::PruningHamiltonianSolver::HamiltonianCost</a></div><div class="ttdeci">CostType HamiltonianCost(int end_node)</div><div class="ttdef"><b>Definition:</b> <a href="hamiltonian__path_8h_source.html#l01007">hamiltonian_path.h:1007</a></div></div>
<div class="ttc" id="classoperations__research_1_1_lattice_memory_manager_html_af4a801d214f8a294a6abf462ac12e80a"><div class="ttname"><a href="classoperations__research_1_1_lattice_memory_manager.html#af4a801d214f8a294a6abf462ac12e80a">operations_research::LatticeMemoryManager::BaseOffset</a></div><div class="ttdeci">uint64_t BaseOffset(int card, Set s) const</div><div class="ttdef"><b>Definition:</b> <a href="hamiltonian__path_8h_source.html#l00408">hamiltonian_path.h:408</a></div></div>
<div class="ttc" id="classoperations__research_1_1_set_html_a33392f61ea41062250f3664a055cd3bf"><div class="ttname"><a href="classoperations__research_1_1_set.html#a33392f61ea41062250f3664a055cd3bf">operations_research::Set::ElementRank</a></div><div class="ttdeci">int ElementRank(int n) const</div><div class="ttdef"><b>Definition:</b> <a href="hamiltonian__path_8h_source.html#l00184">hamiltonian_path.h:184</a></div></div>
<div class="ttc" id="constraint__solver_2table_8cc_html_a9293e4d29cac928301645070dd307683"><div class="ttname"><a href="constraint__solver_2table_8cc.html#a9293e4d29cac928301645070dd307683">b</a></div><div class="ttdeci">int64_t b</div><div class="ttdef"><b>Definition:</b> <a href="constraint__solver_2table_8cc_source.html#l00047">constraint_solver/table.cc:47</a></div></div>
<div class="ttc" id="classoperations__research_1_1_set_html_a9c628cec54eb559f322c284c096f1837"><div class="ttname"><a href="classoperations__research_1_1_set.html#a9c628cec54eb559f322c284c096f1837">operations_research::Set::Includes</a></div><div class="ttdeci">bool Includes(Set other) const</div><div class="ttdef"><b>Definition:</b> <a href="hamiltonian__path_8h_source.html#l00166">hamiltonian_path.h:166</a></div></div>
<div class="ttc" id="integral__types_8h_html"><div class="ttname"><a href="integral__types_8h.html">integral_types.h</a></div></div>
<div class="ttc" id="classoperations__research_1_1_set_html_abbfaa99a45c4a90475cb2f5138f9a162"><div class="ttname"><a href="classoperations__research_1_1_set.html#abbfaa99a45c4a90475cb2f5138f9a162">operations_research::Set::Singleton</a></div><div class="ttdeci">static Set Singleton(Integer n)</div><div class="ttdef"><b>Definition:</b> <a href="hamiltonian__path_8h_source.html#l00152">hamiltonian_path.h:152</a></div></div>
<div class="ttc" id="classoperations__research_1_1_set_range_iterator_html_a9a69c0a346336b270178d60cd6da6404"><div class="ttname"><a href="classoperations__research_1_1_set_range_iterator.html#a9a69c0a346336b270178d60cd6da6404">operations_research::SetRangeIterator::operator!=</a></div><div class="ttdeci">bool operator!=(const SetRangeIterator &amp;other) const</div><div class="ttdef"><b>Definition:</b> <a href="hamiltonian__path_8h_source.html#l00234">hamiltonian_path.h:234</a></div></div>
<div class="ttc" id="classoperations__research_1_1_element_iterator_html_a9cf56c599b564897633c67574e2e460b"><div class="ttname"><a href="classoperations__research_1_1_element_iterator.html#a9cf56c599b564897633c67574e2e460b">operations_research::ElementIterator::operator *</a></div><div class="ttdeci">int operator *() const</div><div class="ttdef"><b>Definition:</b> <a href="hamiltonian__path_8h_source.html#l00113">hamiltonian_path.h:113</a></div></div>
<div class="ttc" id="classoperations__research_1_1_set_html_aabbec0d4f2a126cbdd6c1bce67b7cc8b"><div class="ttname"><a href="classoperations__research_1_1_set.html#aabbec0d4f2a126cbdd6c1bce67b7cc8b">operations_research::Set::IntegerType</a></div><div class="ttdeci">Integer IntegerType</div><div class="ttdef"><b>Definition:</b> <a href="hamiltonian__path_8h_source.html#l00131">hamiltonian_path.h:131</a></div></div>
<div class="ttc" id="namespaceoperations__research_html_a4841d3c6b072a22ba2b2fe43d6c03298"><div class="ttname"><a href="namespaceoperations__research.html#a4841d3c6b072a22ba2b2fe43d6c03298">operations_research::BitCount32</a></div><div class="ttdeci">uint32_t BitCount32(uint32_t n)</div><div class="ttdef"><b>Definition:</b> <a href="bitset_8h_source.html#l00053">bitset.h:53</a></div></div>
<div class="ttc" id="classoperations__research_1_1_set_html_a31dd4f4c450a217b20db6d8389d71a4e"><div class="ttname"><a href="classoperations__research_1_1_set.html#a31dd4f4c450a217b20db6d8389d71a4e">operations_research::Set::SingletonRank</a></div><div class="ttdeci">int SingletonRank(Set singleton) const</div><div class="ttdef"><b>Definition:</b> <a href="hamiltonian__path_8h_source.html#l00193">hamiltonian_path.h:193</a></div></div>
<div class="ttc" id="alldiff__cst_8cc_html_a26e6db9bcc64b584051ecc28171ed11f"><div class="ttname"><a href="alldiff__cst_8cc.html#a26e6db9bcc64b584051ecc28171ed11f">max</a></div><div class="ttdeci">int64_t max</div><div class="ttdef"><b>Definition:</b> <a href="alldiff__cst_8cc_source.html#l00140">alldiff_cst.cc:140</a></div></div>
<div class="ttc" id="classoperations__research_1_1_set_range_with_cardinality_html_af7124add76feb58bf035c3375fe140f9"><div class="ttname"><a href="classoperations__research_1_1_set_range_with_cardinality.html#af7124add76feb58bf035c3375fe140f9">operations_research::SetRangeWithCardinality::end</a></div><div class="ttdeci">SetRangeIterator&lt; SetRangeWithCardinality &gt; end() const</div><div class="ttdef"><b>Definition:</b> <a href="hamiltonian__path_8h_source.html#l00277">hamiltonian_path.h:277</a></div></div>
<div class="ttc" id="namespaceoperations__research_html_a111f44b9b9cf67a8e8d83794ac9f5291"><div class="ttname"><a href="namespaceoperations__research.html#a111f44b9b9cf67a8e8d83794ac9f5291">operations_research::CapAdd</a></div><div class="ttdeci">int64_t CapAdd(int64_t x, int64_t y)</div><div class="ttdef"><b>Definition:</b> <a href="saturated__arithmetic_8h_source.html#l00126">saturated_arithmetic.h:126</a></div></div>
<div class="ttc" id="gscip__solver_8cc_html_a1e2f9a2352c1d9a6cada9544898fceec"><div class="ttname"><a href="gscip__solver_8cc.html#a1e2f9a2352c1d9a6cada9544898fceec">lower_bound</a></div><div class="ttdeci">double lower_bound</div><div class="ttdef"><b>Definition:</b> <a href="gscip__solver_8cc_source.html#l00125">gscip_solver.cc:125</a></div></div>
<div class="ttc" id="vector__or__function_8h_html"><div class="ttname"><a href="vector__or__function_8h.html">vector_or_function.h</a></div></div>
<div class="ttc" id="classoperations__research_1_1_set_html_a0faec65dbf29460ec59dfa75d0536efb"><div class="ttname"><a href="classoperations__research_1_1_set.html#a0faec65dbf29460ec59dfa75d0536efb">operations_research::Set::Contains</a></div><div class="ttdeci">bool Contains(int n) const</div><div class="ttdef"><b>Definition:</b> <a href="hamiltonian__path_8h_source.html#l00163">hamiltonian_path.h:163</a></div></div>
<div class="ttc" id="classoperations__research_1_1_set_range_iterator_html_ab199aaba95428b8647f6bfdd83ecb68c"><div class="ttname"><a href="classoperations__research_1_1_set_range_iterator.html#ab199aaba95428b8647f6bfdd83ecb68c">operations_research::SetRangeIterator::operator++</a></div><div class="ttdeci">const SetRangeIterator &amp; operator++()</div><div class="ttdef"><b>Definition:</b> <a href="hamiltonian__path_8h_source.html#l00241">hamiltonian_path.h:241</a></div></div>
<div class="ttc" id="classoperations__research_1_1_set_range_iterator_html"><div class="ttname"><a href="classoperations__research_1_1_set_range_iterator.html">operations_research::SetRangeIterator</a></div><div class="ttdef"><b>Definition:</b> <a href="hamiltonian__path_8h_source.html#l00224">hamiltonian_path.h:224</a></div></div>
<div class="ttc" id="classoperations__research_1_1_set_html_a5865d6398576a8e71b0f346e79c583e7"><div class="ttname"><a href="classoperations__research_1_1_set.html#a5865d6398576a8e71b0f346e79c583e7">operations_research::Set::RemoveSmallestElement</a></div><div class="ttdeci">Set RemoveSmallestElement() const</div><div class="ttdef"><b>Definition:</b> <a href="hamiltonian__path_8h_source.html#l00180">hamiltonian_path.h:180</a></div></div>
<div class="ttc" id="classoperations__research_1_1_set_html_ae7cd733dab92b86a3aaac89c4d49503f"><div class="ttname"><a href="classoperations__research_1_1_set.html#ae7cd733dab92b86a3aaac89c4d49503f">operations_research::Set::FullSet</a></div><div class="ttdeci">static Set FullSet(Integer card)</div><div class="ttdef"><b>Definition:</b> <a href="hamiltonian__path_8h_source.html#l00147">hamiltonian_path.h:147</a></div></div>
<div class="ttc" id="classoperations__research_1_1_set_html_ac2fa078fad730b08d36dc600a24e21a1"><div class="ttname"><a href="classoperations__research_1_1_set.html#ac2fa078fad730b08d36dc600a24e21a1">operations_research::Set::Zero</a></div><div class="ttdeci">static constexpr Integer Zero</div><div class="ttdef"><b>Definition:</b> <a href="hamiltonian__path_8h_source.html#l00135">hamiltonian_path.h:135</a></div></div>
<div class="ttc" id="classoperations__research_1_1_hamiltonian_path_solver_html_ab558649a26fef3a74f0909ef5af45e90"><div class="ttname"><a href="classoperations__research_1_1_hamiltonian_path_solver.html#ab558649a26fef3a74f0909ef5af45e90">operations_research::HamiltonianPathSolver::TravelingSalesmanCost</a></div><div class="ttdeci">CostType TravelingSalesmanCost()</div><div class="ttdef"><b>Definition:</b> <a href="hamiltonian__path_8h_source.html#l00859">hamiltonian_path.h:859</a></div></div>
<div class="ttc" id="classoperations__research_1_1_set_html"><div class="ttname"><a href="classoperations__research_1_1_set.html">operations_research::Set</a></div><div class="ttdef"><b>Definition:</b> <a href="hamiltonian__path_8h_source.html#l00128">hamiltonian_path.h:128</a></div></div>
<div class="ttc" id="classoperations__research_1_1_element_iterator_html"><div class="ttname"><a href="classoperations__research_1_1_element_iterator.html">operations_research::ElementIterator</a></div><div class="ttdef"><b>Definition:</b> <a href="hamiltonian__path_8h_source.html#l00105">hamiltonian_path.h:105</a></div></div>
<div class="ttc" id="base_2logging_8h_html_aae2dc65d9ea248d54bf39daa986dd295"><div class="ttname"><a href="base_2logging_8h.html#aae2dc65d9ea248d54bf39daa986dd295">DCHECK_GE</a></div><div class="ttdeci">#define DCHECK_GE(val1, val2)</div><div class="ttdef"><b>Definition:</b> <a href="base_2logging_8h_source.html#l00894">base/logging.h:894</a></div></div>
<div class="ttc" id="saturated__arithmetic_8h_html"><div class="ttname"><a href="saturated__arithmetic_8h.html">saturated_arithmetic.h</a></div></div>
<div class="ttc" id="classoperations__research_1_1_element_iterator_html_a0a290cf047b502171a3d1770cd194c52"><div class="ttname"><a href="classoperations__research_1_1_element_iterator.html#a0a290cf047b502171a3d1770cd194c52">operations_research::ElementIterator::ElementIterator</a></div><div class="ttdeci">ElementIterator(Set set)</div><div class="ttdef"><b>Definition:</b> <a href="hamiltonian__path_8h_source.html#l00107">hamiltonian_path.h:107</a></div></div>
<div class="ttc" id="classoperations__research_1_1_lattice_memory_manager_html_a6789c7b14fc935d7e3d03e1376cb79d8"><div class="ttname"><a href="classoperations__research_1_1_lattice_memory_manager.html#a6789c7b14fc935d7e3d03e1376cb79d8">operations_research::LatticeMemoryManager::OffsetDelta</a></div><div class="ttdeci">uint64_t OffsetDelta(int card, int added_node, int removed_node, int rank) const</div><div class="ttdef"><b>Definition:</b> <a href="hamiltonian__path_8h_source.html#l00311">hamiltonian_path.h:311</a></div></div>
<div class="ttc" id="classoperations__research_1_1_set_html_a190d6e916c3a1a06e2eff670e8b52da8"><div class="ttname"><a href="classoperations__research_1_1_set.html#a190d6e916c3a1a06e2eff670e8b52da8">operations_research::Set::RemoveElement</a></div><div class="ttdeci">Set RemoveElement(int n) const</div><div class="ttdef"><b>Definition:</b> <a href="hamiltonian__path_8h_source.html#l00160">hamiltonian_path.h:160</a></div></div>
<div class="ttc" id="routing__flow_8cc_html_a75d7b5e4cab1e156cc7a2c5eba1e16f1"><div class="ttname"><a href="routing__flow_8cc.html#a75d7b5e4cab1e156cc7a2c5eba1e16f1">cost</a></div><div class="ttdeci">int64_t cost</div><div class="ttdef"><b>Definition:</b> <a href="routing__flow_8cc_source.html#l00152">routing_flow.cc:152</a></div></div>
<div class="ttc" id="base_2logging_8h_html"><div class="ttname"><a href="base_2logging_8h.html">logging.h</a></div></div>
<div class="ttc" id="classoperations__research_1_1_hamiltonian_path_solver_html_a9c8cdf78154ae6a73f4a272cb8d1ac4a"><div class="ttname"><a href="classoperations__research_1_1_hamiltonian_path_solver.html#a9c8cdf78154ae6a73f4a272cb8d1ac4a">operations_research::HamiltonianPathSolver::HamiltonianPathSolver</a></div><div class="ttdeci">HamiltonianPathSolver(CostFunction cost)</div><div class="ttdef"><b>Definition:</b> <a href="hamiltonian__path_8h_source.html#l00607">hamiltonian_path.h:607</a></div></div>
<div class="ttc" id="classoperations__research_1_1_set_range_with_cardinality_html_a24d9704faf4d419fdabbde6a716e181d"><div class="ttname"><a href="classoperations__research_1_1_set_range_with_cardinality.html#a24d9704faf4d419fdabbde6a716e181d">operations_research::SetRangeWithCardinality::begin</a></div><div class="ttdeci">SetRangeIterator&lt; SetRangeWithCardinality &gt; begin() const</div><div class="ttdef"><b>Definition:</b> <a href="hamiltonian__path_8h_source.html#l00274">hamiltonian_path.h:274</a></div></div>
<div class="ttc" id="base_2logging_8h_html_ae17f8119c108cf3070bad3449c7e0006"><div class="ttname"><a href="base_2logging_8h.html#ae17f8119c108cf3070bad3449c7e0006">DCHECK</a></div><div class="ttdeci">#define DCHECK(condition)</div><div class="ttdef"><b>Definition:</b> <a href="base_2logging_8h_source.html#l00889">base/logging.h:889</a></div></div>
<div class="ttc" id="classoperations__research_1_1_hamiltonian_path_solver_html_a326a998ed18bedda49bd2cab5cbd4079"><div class="ttname"><a href="classoperations__research_1_1_hamiltonian_path_solver.html#a326a998ed18bedda49bd2cab5cbd4079">operations_research::HamiltonianPathSolver::TravelingSalesmanPath</a></div><div class="ttdeci">std::vector&lt; int &gt; TravelingSalesmanPath()</div><div class="ttdef"><b>Definition:</b> <a href="hamiltonian__path_8h_source.html#l00866">hamiltonian_path.h:866</a></div></div>
<div class="ttc" id="classoperations__research_1_1_set_html_a191fa6bb5261ddd97d311ccc1d90fe7c"><div class="ttname"><a href="classoperations__research_1_1_set.html#a191fa6bb5261ddd97d311ccc1d90fe7c">operations_research::Set::begin</a></div><div class="ttdeci">ElementIterator&lt; Set &gt; begin() const</div><div class="ttdef"><b>Definition:</b> <a href="hamiltonian__path_8h_source.html#l00199">hamiltonian_path.h:199</a></div></div>
<div class="ttc" id="base_2logging_8h_html_ae89df3243bbb8341130c7b3f44145ea0"><div class="ttname"><a href="base_2logging_8h.html#ae89df3243bbb8341130c7b3f44145ea0">DCHECK_EQ</a></div><div class="ttdeci">#define DCHECK_EQ(val1, val2)</div><div class="ttdef"><b>Definition:</b> <a href="base_2logging_8h_source.html#l00890">base/logging.h:890</a></div></div>
<div class="ttc" id="classoperations__research_1_1_set_range_with_cardinality_html_ac04647d141301b9671da400a7add8e37"><div class="ttname"><a href="classoperations__research_1_1_set_range_with_cardinality.html#ac04647d141301b9671da400a7add8e37">operations_research::SetRangeWithCardinality::SetType</a></div><div class="ttdeci">Set SetType</div><div class="ttdef"><b>Definition:</b> <a href="hamiltonian__path_8h_source.html#l00260">hamiltonian_path.h:260</a></div></div>
<div class="ttc" id="classoperations__research_1_1_matrix_or_function_html"><div class="ttname"><a href="classoperations__research_1_1_matrix_or_function.html">operations_research::MatrixOrFunction&lt; CostType, CostFunction, true &gt;</a></div></div>
<div class="ttc" id="classoperations__research_1_1_pruning_hamiltonian_solver_html"><div class="ttname"><a href="classoperations__research_1_1_pruning_hamiltonian_solver.html">operations_research::PruningHamiltonianSolver</a></div><div class="ttdef"><b>Definition:</b> <a href="hamiltonian__path_8h_source.html#l00878">hamiltonian_path.h:878</a></div></div>
<div class="ttc" id="namespaceoperations__research_html_ae13fcb4162a4180395806f43237c44b2"><div class="ttname"><a href="namespaceoperations__research.html#ae13fcb4162a4180395806f43237c44b2">operations_research::LeastSignificantBitPosition64</a></div><div class="ttdeci">int LeastSignificantBitPosition64(uint64_t n)</div><div class="ttdef"><b>Definition:</b> <a href="bitset_8h_source.html#l00127">bitset.h:127</a></div></div>
<div class="ttc" id="classoperations__research_1_1_lattice_memory_manager_html_a9614dfea1a66f5d18799a058adc57a95"><div class="ttname"><a href="classoperations__research_1_1_lattice_memory_manager.html#a9614dfea1a66f5d18799a058adc57a95">operations_research::LatticeMemoryManager::Init</a></div><div class="ttdeci">void Init(int max_card)</div><div class="ttdef"><b>Definition:</b> <a href="hamiltonian__path_8h_source.html#l00358">hamiltonian_path.h:358</a></div></div>
<div class="ttc" id="namespaceoperations__research_html_abc979832d72da1ae793ba6d28ae46672"><div class="ttname"><a href="namespaceoperations__research.html#abc979832d72da1ae793ba6d28ae46672">operations_research::BitCount64</a></div><div class="ttdeci">uint64_t BitCount64(uint64_t n)</div><div class="ttdef"><b>Definition:</b> <a href="bitset_8h_source.html#l00042">bitset.h:42</a></div></div>
<div class="ttc" id="classoperations__research_1_1_hamiltonian_path_solver_html_a03106785fd757b213975f94d4b780709"><div class="ttname"><a href="classoperations__research_1_1_hamiltonian_path_solver.html#a03106785fd757b213975f94d4b780709">operations_research::HamiltonianPathSolver::NodeSet</a></div><div class="ttdeci">Set&lt; Integer &gt; NodeSet</div><div class="ttdef"><b>Definition:</b> <a href="hamiltonian__path_8h_source.html#l00477">hamiltonian_path.h:477</a></div></div>
<div class="ttc" id="classoperations__research_1_1_set_range_iterator_html_a8f6ae547a7aba92b9e4fe92a8713085a"><div class="ttname"><a href="classoperations__research_1_1_set_range_iterator.html#a8f6ae547a7aba92b9e4fe92a8713085a">operations_research::SetRangeIterator::operator *</a></div><div class="ttdeci">SetType operator *() const</div><div class="ttdef"><b>Definition:</b> <a href="hamiltonian__path_8h_source.html#l00233">hamiltonian_path.h:233</a></div></div>
<div class="ttc" id="classoperations__research_1_1_hamiltonian_path_solver_html_a5daed8b7f3c98c693f32dff60adeb4cc"><div class="ttname"><a href="classoperations__research_1_1_hamiltonian_path_solver.html#a5daed8b7f3c98c693f32dff60adeb4cc">operations_research::HamiltonianPathSolver::IsRobust</a></div><div class="ttdeci">bool IsRobust()</div><div class="ttdef"><b>Definition:</b> <a href="hamiltonian__path_8h_source.html#l00786">hamiltonian_path.h:786</a></div></div>
<div class="ttc" id="classoperations__research_1_1_set_range_iterator_html_a4ee741618ffbec86b3a2a280c61ca3f0"><div class="ttname"><a href="classoperations__research_1_1_set_range_iterator.html#a4ee741618ffbec86b3a2a280c61ca3f0">operations_research::SetRangeIterator::IntegerType</a></div><div class="ttdeci">SetType::IntegerType IntegerType</div><div class="ttdef"><b>Definition:</b> <a href="hamiltonian__path_8h_source.html#l00228">hamiltonian_path.h:228</a></div></div>
<div class="ttc" id="base_2logging_8h_html_a4395e95bab44e222cb2e77251017a0e2"><div class="ttname"><a href="base_2logging_8h.html#a4395e95bab44e222cb2e77251017a0e2">DCHECK_LE</a></div><div class="ttdeci">#define DCHECK_LE(val1, val2)</div><div class="ttdef"><b>Definition:</b> <a href="base_2logging_8h_source.html#l00892">base/logging.h:892</a></div></div>
<div class="ttc" id="namespaceoperations__research_html"><div class="ttname"><a href="namespaceoperations__research.html">operations_research</a></div><div class="ttdoc">Collection of objects used to extend the Constraint Solver library.</div><div class="ttdef"><b>Definition:</b> <a href="dense__doubly__linked__list_8h_source.html#l00021">dense_doubly_linked_list.h:21</a></div></div>
<div class="ttc" id="classoperations__research_1_1_set_html_a3382ddf3a1f05b9ded21ddb7b0013f78"><div class="ttname"><a href="classoperations__research_1_1_set.html#a3382ddf3a1f05b9ded21ddb7b0013f78">operations_research::Set::operator!=</a></div><div class="ttdeci">bool operator!=(const Set &amp;other) const</div><div class="ttdef"><b>Definition:</b> <a href="hamiltonian__path_8h_source.html#l00203">hamiltonian_path.h:203</a></div></div>
<div class="ttc" id="classoperations__research_1_1_hamiltonian_path_solver_html_a44af6c2df0188e77ceeec78a190ecf3f"><div class="ttname"><a href="classoperations__research_1_1_hamiltonian_path_solver.html#a44af6c2df0188e77ceeec78a190ecf3f">operations_research::HamiltonianPathSolver::VerifiesTriangleInequality</a></div><div class="ttdeci">bool VerifiesTriangleInequality()</div><div class="ttdef"><b>Definition:</b> <a href="hamiltonian__path_8h_source.html#l00811">hamiltonian_path.h:811</a></div></div>
<div class="ttc" id="classoperations__research_1_1_element_iterator_html_aefcf46820145a241c215f2e82b69d5f5"><div class="ttname"><a href="classoperations__research_1_1_element_iterator.html#aefcf46820145a241c215f2e82b69d5f5">operations_research::ElementIterator::operator!=</a></div><div class="ttdeci">bool operator!=(const ElementIterator &amp;other) const</div><div class="ttdef"><b>Definition:</b> <a href="hamiltonian__path_8h_source.html#l00108">hamiltonian_path.h:108</a></div></div>
<div class="ttc" id="namespaceoperations__research_html_aeaca21c840bf285f12127938231369b9"><div class="ttname"><a href="namespaceoperations__research.html#aeaca21c840bf285f12127938231369b9">operations_research::LeastSignificantBitPosition32</a></div><div class="ttdeci">int LeastSignificantBitPosition32(uint32_t n)</div><div class="ttdef"><b>Definition:</b> <a href="bitset_8h_source.html#l00182">bitset.h:182</a></div></div>
<div class="ttc" id="classoperations__research_1_1_set_range_with_cardinality_html"><div class="ttname"><a href="classoperations__research_1_1_set_range_with_cardinality.html">operations_research::SetRangeWithCardinality</a></div><div class="ttdef"><b>Definition:</b> <a href="hamiltonian__path_8h_source.html#l00258">hamiltonian_path.h:258</a></div></div>
<div class="ttc" id="classoperations__research_1_1_lattice_memory_manager_html_a03b88bdfd0b2fcc7e14106cbd425629a"><div class="ttname"><a href="classoperations__research_1_1_lattice_memory_manager.html#a03b88bdfd0b2fcc7e14106cbd425629a">operations_research::LatticeMemoryManager::LatticeMemoryManager</a></div><div class="ttdeci">LatticeMemoryManager()</div><div class="ttdef"><b>Definition:</b> <a href="hamiltonian__path_8h_source.html#l00294">hamiltonian_path.h:294</a></div></div>
<div class="ttc" id="bitset_8h_html"><div class="ttname"><a href="bitset_8h.html">bitset.h</a></div></div>
<div class="ttc" id="classoperations__research_1_1_lattice_memory_manager_html_a4c59c8afdecf1f9d139609ffe9f172ca"><div class="ttname"><a href="classoperations__research_1_1_lattice_memory_manager.html#a4c59c8afdecf1f9d139609ffe9f172ca">operations_research::LatticeMemoryManager::SetValue</a></div><div class="ttdeci">void SetValue(Set s, int node, CostType value)</div><div class="ttdef"><b>Definition:</b> <a href="hamiltonian__path_8h_source.html#l00444">hamiltonian_path.h:444</a></div></div>
<div class="ttc" id="classoperations__research_1_1_set_html_a64f741970505f1dea6a662c3b1776c74"><div class="ttname"><a href="classoperations__research_1_1_set.html#a64f741970505f1dea6a662c3b1776c74">operations_research::Set::SmallestSingleton</a></div><div class="ttdeci">Set SmallestSingleton() const</div><div class="ttdef"><b>Definition:</b> <a href="hamiltonian__path_8h_source.html#l00190">hamiltonian_path.h:190</a></div></div>
<div class="ttc" id="classoperations__research_1_1_pruning_hamiltonian_solver_html_a346635bd62f6d557d98e490ff2f3f306"><div class="ttname"><a href="classoperations__research_1_1_pruning_hamiltonian_solver.html#a346635bd62f6d557d98e490ff2f3f306">operations_research::PruningHamiltonianSolver::Integer</a></div><div class="ttdeci">uint32_t Integer</div><div class="ttdef"><b>Definition:</b> <a href="hamiltonian__path_8h_source.html#l00894">hamiltonian_path.h:894</a></div></div>
<div class="ttc" id="classoperations__research_1_1_set_range_with_cardinality_html_ac227945449c4f8144b6c92afd6ae2156"><div class="ttname"><a href="classoperations__research_1_1_set_range_with_cardinality.html#ac227945449c4f8144b6c92afd6ae2156">operations_research::SetRangeWithCardinality::SetRangeWithCardinality</a></div><div class="ttdeci">SetRangeWithCardinality(int card, int max_card)</div><div class="ttdef"><b>Definition:</b> <a href="hamiltonian__path_8h_source.html#l00264">hamiltonian_path.h:264</a></div></div>
<div class="ttc" id="classoperations__research_1_1_set_html_a062c0acf17a051b885ad211acad31079"><div class="ttname"><a href="classoperations__research_1_1_set.html#a062c0acf17a051b885ad211acad31079">operations_research::Set::MaxCardinality</a></div><div class="ttdeci">static const int MaxCardinality</div><div class="ttdef"><b>Definition:</b> <a href="hamiltonian__path_8h_source.html#l00136">hamiltonian_path.h:136</a></div></div>
<div class="ttc" id="classoperations__research_1_1_pruning_hamiltonian_solver_html_a03106785fd757b213975f94d4b780709"><div class="ttname"><a href="classoperations__research_1_1_pruning_hamiltonian_solver.html#a03106785fd757b213975f94d4b780709">operations_research::PruningHamiltonianSolver::NodeSet</a></div><div class="ttdeci">Set&lt; Integer &gt; NodeSet</div><div class="ttdef"><b>Definition:</b> <a href="hamiltonian__path_8h_source.html#l00895">hamiltonian_path.h:895</a></div></div>
<div class="ttc" id="demon__profiler_8cc_html_ac072af30c4ffbc834bb4c681f6ecb514"><div class="ttname"><a href="demon__profiler_8cc.html#ac072af30c4ffbc834bb4c681f6ecb514">value</a></div><div class="ttdeci">int64_t value</div><div class="ttdef"><b>Definition:</b> <a href="demon__profiler_8cc_source.html#l00044">demon_profiler.cc:44</a></div></div>
<div class="ttc" id="base_2logging_8h_html_ab62f5ed8f2d48e29802be0cbbcd1359a"><div class="ttname"><a href="base_2logging_8h.html#ab62f5ed8f2d48e29802be0cbbcd1359a">DCHECK_LT</a></div><div class="ttdeci">#define DCHECK_LT(val1, val2)</div><div class="ttdef"><b>Definition:</b> <a href="base_2logging_8h_source.html#l00893">base/logging.h:893</a></div></div>
<div class="ttc" id="classoperations__research_1_1_set_html_a7f72b10501772e497164805b53e2ec80"><div class="ttname"><a href="classoperations__research_1_1_set.html#a7f72b10501772e497164805b53e2ec80">operations_research::Set::One</a></div><div class="ttdeci">static constexpr Integer One</div><div class="ttdef"><b>Definition:</b> <a href="hamiltonian__path_8h_source.html#l00134">hamiltonian_path.h:134</a></div></div>
<div class="ttc" id="namespaceoperations__research_html_ae8625c5e71962a0f99954d34dab9f92d"><div class="ttname"><a href="namespaceoperations__research.html#ae8625c5e71962a0f99954d34dab9f92d">operations_research::PathNodeIndex</a></div><div class="ttdeci">int PathNodeIndex</div><div class="ttdef"><b>Definition:</b> <a href="hamiltonian__path_8h_source.html#l00451">hamiltonian_path.h:451</a></div></div>
<div class="ttc" id="constraint__solver_2table_8cc_html_acb18315d548212835cd8ed4287e6c0b6"><div class="ttname"><a href="constraint__solver_2table_8cc.html#acb18315d548212835cd8ed4287e6c0b6">a</a></div><div class="ttdeci">int64_t a</div><div class="ttdef"><b>Definition:</b> <a href="constraint__solver_2table_8cc_source.html#l00046">constraint_solver/table.cc:46</a></div></div>
<div class="ttc" id="classoperations__research_1_1_hamiltonian_path_solver_html_a8acc60c87190fac89379315aa08ce7a5"><div class="ttname"><a href="classoperations__research_1_1_hamiltonian_path_solver.html#a8acc60c87190fac89379315aa08ce7a5">operations_research::HamiltonianPathSolver::HamiltonianPath</a></div><div class="ttdeci">std::vector&lt; int &gt; HamiltonianPath(int end_node)</div><div class="ttdef"><b>Definition:</b> <a href="hamiltonian__path_8h_source.html#l00845">hamiltonian_path.h:845</a></div></div>
</div><!-- fragment --></div><!-- contents -->
</div><!-- doc-content -->
<!-- HTML footer for doxygen 1.8.18-->
<!-- start footer part -->
<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
<ul>
<li class="navelem"><a class="el" href="dir_a7cc1eeded8f693d0da6c729bc88c45a.html">ortools</a></li><li class="navelem"><a class="el" href="dir_725f3a5915051842f84e3ea508be2a62.html">graph</a></li><li class="navelem"><a class="el" href="hamiltonian__path_8h.html">hamiltonian_path.h</a></li>
<li class="footer">Generated by
<a href="http://www.doxygen.org/index.html">
<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.8.15 </li>
</ul>
</div>
</body>
</html>