<ahref="cliques_8h.html">Go to the documentation of this file.</a><divclass="fragment"><divclass="line"><aname="l00001"></a><spanclass="lineno"> 1</span> <spanclass="comment">// Copyright 2010-2018 Google LLC</span></div>
<divclass="line"><aname="l00002"></a><spanclass="lineno"> 2</span> <spanclass="comment">// Licensed under the Apache License, Version 2.0 (the "License");</span></div>
<divclass="line"><aname="l00003"></a><spanclass="lineno"> 3</span> <spanclass="comment">// you may not use this file except in compliance with the License.</span></div>
<divclass="line"><aname="l00004"></a><spanclass="lineno"> 4</span> <spanclass="comment">// You may obtain a copy of the License at</span></div>
<divclass="line"><aname="l00008"></a><spanclass="lineno"> 8</span> <spanclass="comment">// Unless required by applicable law or agreed to in writing, software</span></div>
<divclass="line"><aname="l00009"></a><spanclass="lineno"> 9</span> <spanclass="comment">// distributed under the License is distributed on an "AS IS" BASIS,</span></div>
<divclass="line"><aname="l00010"></a><spanclass="lineno"> 10</span> <spanclass="comment">// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.</span></div>
<divclass="line"><aname="l00011"></a><spanclass="lineno"> 11</span> <spanclass="comment">// See the License for the specific language governing permissions and</span></div>
<divclass="line"><aname="l00012"></a><spanclass="lineno"> 12</span> <spanclass="comment">// limitations under the License.</span></div>
<divclass="line"><aname="l00015"></a><spanclass="lineno"> 15</span> <spanclass="comment">// Maximal clique algorithms, based on the Bron-Kerbosch algorithm.</span></div>
<divclass="line"><aname="l00016"></a><spanclass="lineno"> 16</span> <spanclass="comment">// See http://en.wikipedia.org/wiki/Bron-Kerbosch_algorithm</span></div>
<divclass="line"><aname="l00018"></a><spanclass="lineno"> 18</span> <spanclass="comment">// C. Bron and J. Kerbosch, Joep, "Algorithm 457: finding all cliques of an</span></div>
<divclass="line"><aname="l00039"></a><spanclass="lineno"> 39</span> <spanclass="comment">// Finds all maximal cliques, even of size 1, in the</span></div>
<divclass="line"><aname="l00040"></a><spanclass="lineno"> 40</span> <spanclass="comment">// graph described by the graph callback. graph->Run(i, j) indicates</span></div>
<divclass="line"><aname="l00041"></a><spanclass="lineno"> 41</span> <spanclass="comment">// if there is an arc between i and j.</span></div>
<divclass="line"><aname="l00042"></a><spanclass="lineno"> 42</span> <spanclass="comment">// This function takes ownership of 'callback' and deletes it after it has run.</span></div>
<divclass="line"><aname="l00043"></a><spanclass="lineno"> 43</span> <spanclass="comment">// If 'callback' returns true, then the search for cliques stops.</span></div>
<divclass="line"><aname="l00047"></a><spanclass="lineno"> 47</span> <spanclass="comment">// Covers the maximum number of arcs of the graph with cliques. The graph</span></div>
<divclass="line"><aname="l00048"></a><spanclass="lineno"> 48</span> <spanclass="comment">// is described by the graph callback. graph->Run(i, j) indicates if</span></div>
<divclass="line"><aname="l00049"></a><spanclass="lineno"> 49</span> <spanclass="comment">// there is an arc between i and j.</span></div>
<divclass="line"><aname="l00050"></a><spanclass="lineno"> 50</span> <spanclass="comment">// This function takes ownership of 'callback' and deletes it after it has run.</span></div>
<divclass="line"><aname="l00051"></a><spanclass="lineno"> 51</span> <spanclass="comment">// It calls 'callback' upon each clique.</span></div>
<divclass="line"><aname="l00052"></a><spanclass="lineno"> 52</span> <spanclass="comment">// It ignores cliques of size 1.</span></div>
<divclass="line"><aname="l00056"></a><spanclass="lineno"> 56</span> <spanclass="comment">// Possible return values of the callback for reporting cliques. The returned</span></div>
<divclass="line"><aname="l00057"></a><spanclass="lineno"> 57</span> <spanclass="comment">// value determines whether the algorithm will continue the search.</span></div>
<divclass="line"><aname="l00059"></a><spanclass="lineno"> 59</span> <spanclass="comment">// The algorithm will continue searching for other maximal cliques.</span></div>
<divclass="line"><aname="l00061"></a><spanclass="lineno"> 61</span> <spanclass="comment">// The algorithm will stop the search immediately. The search can be resumed</span></div>
<divclass="line"><aname="l00062"></a><spanclass="lineno"> 62</span> <spanclass="comment">// by calling BronKerboschAlgorithm::Run (resp. RunIterations) again.</span></div>
<divclass="line"><aname="l00066"></a><spanclass="lineno"> 66</span> <spanclass="comment">// The status value returned by BronKerboschAlgorithm::Run and</span></div>
<divclass="line"><aname="l00069"></a><spanclass="lineno"> 69</span> <spanclass="comment">// The algorithm has enumerated all maximal cliques.</span></div>
<divclass="line"><aname="l00071"></a><spanclass="lineno"> 71</span> <spanclass="comment">// The search algorithm was interrupted either because it reached the</span></div>
<divclass="line"><aname="l00072"></a><spanclass="lineno"> 72</span> <spanclass="comment">// iteration limit or because the clique callback returned</span></div>
<divclass="line"><aname="l00077"></a><spanclass="lineno"> 77</span> <spanclass="comment">// Implements the Bron-Kerbosch algorithm for finding maximal cliques.</span></div>
<divclass="line"><aname="l00078"></a><spanclass="lineno"> 78</span> <spanclass="comment">// The graph is represented as a callback that gets two nodes as its arguments</span></div>
<divclass="line"><aname="l00079"></a><spanclass="lineno"> 79</span> <spanclass="comment">// and it returns true if and only if there is an arc between the two nodes. The</span></div>
<divclass="line"><aname="l00080"></a><spanclass="lineno"> 80</span> <spanclass="comment">// cliques are reported back to the user using a second callback.</span></div>
<divclass="line"><aname="l00096"></a><spanclass="lineno"> 96</span> <spanclass="comment">// This is a non-recursive implementation of the Bron-Kerbosch algorithm with</span></div>
<divclass="line"><aname="l00097"></a><spanclass="lineno"> 97</span> <spanclass="comment">// pivots as described in the paper by Bron and Kerbosch (1973) (the version 2</span></div>
<divclass="line"><aname="l00098"></a><spanclass="lineno"> 98</span> <spanclass="comment">// algorithm in the paper).</span></div>
<divclass="line"><aname="l00099"></a><spanclass="lineno"> 99</span> <spanclass="comment">// The basic idea of the algorithm is to incrementally build the cliques using</span></div>
<divclass="line"><aname="l00100"></a><spanclass="lineno"> 100</span> <spanclass="comment">// depth-first search. During the search, the algorithm maintains two sets of</span></div>
<divclass="line"><aname="l00101"></a><spanclass="lineno"> 101</span> <spanclass="comment">// candidates (nodes that are connected to all nodes in the current clique):</span></div>
<divclass="line"><aname="l00102"></a><spanclass="lineno"> 102</span> <spanclass="comment">// - the "not" set - these are candidates that were already visited by the</span></div>
<divclass="line"><aname="l00103"></a><spanclass="lineno"> 103</span> <spanclass="comment">// search and all the maximal cliques that contain them as a part of the</span></div>
<divclass="line"><aname="l00104"></a><spanclass="lineno"> 104</span> <spanclass="comment">// current clique were already reported.</span></div>
<divclass="line"><aname="l00105"></a><spanclass="lineno"> 105</span> <spanclass="comment">// - the actual candidates - these are candidates that were not visited yet, and</span></div>
<divclass="line"><aname="l00106"></a><spanclass="lineno"> 106</span> <spanclass="comment">// they can be added to the clique.</span></div>
<divclass="line"><aname="l00107"></a><spanclass="lineno"> 107</span> <spanclass="comment">// In each iteration, the algorithm does the first of the following actions that</span></div>
<divclass="line"><aname="l00109"></a><spanclass="lineno"> 109</span> <spanclass="comment">// A. If there are no actual candidates and there are candidates in the "not"</span></div>
<divclass="line"><aname="l00110"></a><spanclass="lineno"> 110</span> <spanclass="comment">// set, or if all actual candidates are connected to the same node in the</span></div>
<divclass="line"><aname="l00111"></a><spanclass="lineno"> 111</span> <spanclass="comment">// "not" set, the current clique can't be extended to a maximal clique that</span></div>
<divclass="line"><aname="l00112"></a><spanclass="lineno"> 112</span> <spanclass="comment">// was not already reported. Return from the recursive call and move the</span></div>
<divclass="line"><aname="l00113"></a><spanclass="lineno"> 113</span> <spanclass="comment">// selected candidate to the set "not".</span></div>
<divclass="line"><aname="l00114"></a><spanclass="lineno"> 114</span> <spanclass="comment">// B. If there are no candidates at all, it means that the current clique can't</span></div>
<divclass="line"><aname="l00115"></a><spanclass="lineno"> 115</span> <spanclass="comment">// be extended and that it is in fact a maximal clique. Report it to the user</span></div>
<divclass="line"><aname="l00116"></a><spanclass="lineno"> 116</span> <spanclass="comment">// and return from the recursive call. Move the selected candidate to the set</span></div>
<divclass="line"><aname="l00118"></a><spanclass="lineno"> 118</span> <spanclass="comment">// C. Otherwise, there are actual candidates, extend the current clique with one</span></div>
<divclass="line"><aname="l00119"></a><spanclass="lineno"> 119</span> <spanclass="comment">// of these candidates and process it recursively.</span></div>
<divclass="line"><aname="l00121"></a><spanclass="lineno"> 121</span> <spanclass="comment">// To avoid unnecessary steps, the algorithm selects a pivot at each level of</span></div>
<divclass="line"><aname="l00122"></a><spanclass="lineno"> 122</span> <spanclass="comment">// the recursion to guide the selection of candidates added to the current</span></div>
<divclass="line"><aname="l00123"></a><spanclass="lineno"> 123</span> <spanclass="comment">// clique. The pivot can be either in the "not" set and among the actual</span></div>
<divclass="line"><aname="l00124"></a><spanclass="lineno"> 124</span> <spanclass="comment">// candidates. The algorithm tries to move the pivot and all actual candidates</span></div>
<divclass="line"><aname="l00125"></a><spanclass="lineno"> 125</span> <spanclass="comment">// connected to it to the set "not" as quickly as possible. This will fulfill</span></div>
<divclass="line"><aname="l00126"></a><spanclass="lineno"> 126</span> <spanclass="comment">// the conditions of step A, and the search algorithm will be able to leave the</span></div>
<divclass="line"><aname="l00127"></a><spanclass="lineno"> 127</span> <spanclass="comment">// current branch. Selecting a pivot that has the lowest number of disconnected</span></div>
<divclass="line"><aname="l00128"></a><spanclass="lineno"> 128</span> <spanclass="comment">// nodes among the candidates can reduce the running time significantly.</span></div>
<divclass="line"><aname="l00130"></a><spanclass="lineno"> 130</span> <spanclass="comment">// The worst-case maximal depth of the recursion is equal to the number of nodes</span></div>
<divclass="line"><aname="l00131"></a><spanclass="lineno"> 131</span> <spanclass="comment">// in the graph, which makes the natural recursive implementation impractical</span></div>
<divclass="line"><aname="l00132"></a><spanclass="lineno"> 132</span> <spanclass="comment">// for nodes with more than a few thousands of nodes. To avoid the limitation,</span></div>
<divclass="line"><aname="l00133"></a><spanclass="lineno"> 133</span> <spanclass="comment">// this class simulates the recursion by maintaining a stack with the state at</span></div>
<divclass="line"><aname="l00134"></a><spanclass="lineno"> 134</span> <spanclass="comment">// each level of the recursion. The algorithm then runs in a loop. In each</span></div>
<divclass="line"><aname="l00135"></a><spanclass="lineno"> 135</span> <spanclass="comment">// iteration, the algorithm can do one or both of:</span></div>
<divclass="line"><aname="l00136"></a><spanclass="lineno"> 136</span> <spanclass="comment">// 1. Return to the previous recursion level (step A or B of the algorithm) by</span></div>
<divclass="line"><aname="l00137"></a><spanclass="lineno"> 137</span> <spanclass="comment">// removing the top state from the stack.</span></div>
<divclass="line"><aname="l00138"></a><spanclass="lineno"> 138</span> <spanclass="comment">// 2. Select the next candidate and enter the next recursion level (step C of</span></div>
<divclass="line"><aname="l00139"></a><spanclass="lineno"> 139</span> <spanclass="comment">// the algorithm) by adding a new state to the stack.</span></div>
<divclass="line"><aname="l00141"></a><spanclass="lineno"> 141</span> <spanclass="comment">// The worst-case time complexity of the algorithm is O(3^(N/3)), and the memory</span></div>
<divclass="line"><aname="l00142"></a><spanclass="lineno"> 142</span> <spanclass="comment">// complexity is O(N^2), where N is the number of nodes in the graph.</span></div>
<divclass="line"><aname="l00146"></a><spanclass="lineno"> 146</span> <spanclass="comment">// A callback called by the algorithm to test if there is an arc between a</span></div>
<divclass="line"><aname="l00147"></a><spanclass="lineno"> 147</span> <spanclass="comment">// pair of nodes. The callback must return true if and only if there is an</span></div>
<divclass="line"><aname="l00148"></a><spanclass="lineno"> 148</span> <spanclass="comment">// arc. Note that to function properly, the function must be symmetrical</span></div>
<divclass="line"><aname="l00149"></a><spanclass="lineno"> 149</span> <spanclass="comment">// (represent an undirected graph).</span></div>
<divclass="line"><aname="l00151"></a><spanclass="lineno"> 151</span> <spanclass="comment">// A callback called by the algorithm to report a maximal clique to the user.</span></div>
<divclass="line"><aname="l00152"></a><spanclass="lineno"> 152</span> <spanclass="comment">// The clique is returned as a list of nodes in the clique, in no particular</span></div>
<divclass="line"><aname="l00153"></a><spanclass="lineno"> 153</span> <spanclass="comment">// order. The caller must make a copy of the vector if they want to keep the</span></div>
<divclass="line"><aname="l00156"></a><spanclass="lineno"> 156</span> <spanclass="comment">// The return value of the callback controls how the algorithm continues after</span></div>
<divclass="line"><aname="l00157"></a><spanclass="lineno"> 157</span> <spanclass="comment">// this clique. See the description of the values of 'CliqueResponse' for more</span></div>
<divclass="line"><aname="l00162"></a><spanclass="lineno"> 162</span> <spanclass="comment">// Initializes the Bron-Kerbosch algorithm for the given graph and clique</span></div>
<divclass="line"><aname="l00170"></a><spanclass="lineno"> 170</span> <spanclass="comment">// Runs the Bron-Kerbosch algorithm for kint64max iterations. In practice,</span></div>
<divclass="line"><aname="l00171"></a><spanclass="lineno"> 171</span> <spanclass="comment">// this is equivalent to running until completion or until the clique callback</span></div>
<divclass="line"><aname="l00172"></a><spanclass="lineno"> 172</span> <spanclass="comment">// returns BronKerboschAlgorithmStatus::STOP. If the method returned because</span></div>
<divclass="line"><aname="l00173"></a><spanclass="lineno"> 173</span> <spanclass="comment">// the search is finished, it will return COMPLETED; otherwise, it will return</span></div>
<divclass="line"><aname="l00174"></a><spanclass="lineno"> 174</span> <spanclass="comment">// INTERRUPTED and it can be resumed by calling this method again.</span></div>
<divclass="line"><aname="l00177"></a><spanclass="lineno"> 177</span> <spanclass="comment">// Runs at most 'max_num_iterations' iterations of the Bron-Kerbosch</span></div>
<divclass="line"><aname="l00178"></a><spanclass="lineno"> 178</span> <spanclass="comment">// algorithm. When this function returns INTERRUPTED, there is still work to</span></div>
<divclass="line"><aname="l00179"></a><spanclass="lineno"> 179</span> <spanclass="comment">// be done to process all the cliques in the graph. In such case the method</span></div>
<divclass="line"><aname="l00180"></a><spanclass="lineno"> 180</span> <spanclass="comment">// can be called again and it will resume the work where the previous call had</span></div>
<divclass="line"><aname="l00181"></a><spanclass="lineno"> 181</span> <spanclass="comment">// stopped. When it returns COMPLETED any subsequent call to the method will</span></div>
<divclass="line"><aname="l00182"></a><spanclass="lineno"> 182</span> <spanclass="comment">// resume the search from the beginning.</span></div>
<divclass="line"><aname="l00185"></a><spanclass="lineno"> 185</span> <spanclass="comment">// Runs at most 'max_num_iterations' iterations of the Bron-Kerbosch</span></div>
<divclass="line"><aname="l00186"></a><spanclass="lineno"> 186</span> <spanclass="comment">// algorithm, until the time limit is exceeded or until all cliques are</span></div>
<divclass="line"><aname="l00187"></a><spanclass="lineno"> 187</span> <spanclass="comment">// enumerated. When this function returns INTERRUPTED, there is still work to</span></div>
<divclass="line"><aname="l00188"></a><spanclass="lineno"> 188</span> <spanclass="comment">// be done to process all the cliques in the graph. In such case the method</span></div>
<divclass="line"><aname="l00189"></a><spanclass="lineno"> 189</span> <spanclass="comment">// can be called again and it will resume the work where the previous call had</span></div>
<divclass="line"><aname="l00190"></a><spanclass="lineno"> 190</span> <spanclass="comment">// stopped. When it returns COMPLETED any subsequent call to the method will</span></div>
<divclass="line"><aname="l00191"></a><spanclass="lineno"> 191</span> <spanclass="comment">// resume the search from the beginning.</span></div>
<divclass="line"><aname="l00195"></a><spanclass="lineno"> 195</span> <spanclass="comment">// Runs the Bron-Kerbosch algorithm for at most kint64max iterations, until</span></div>
<divclass="line"><aname="l00196"></a><spanclass="lineno"> 196</span> <spanclass="comment">// the time limit is excceded or until all cliques are enumerated. In</span></div>
<divclass="line"><aname="l00197"></a><spanclass="lineno"> 197</span> <spanclass="comment">// practice, running the algorithm for kint64max iterations is equivalent to</span></div>
<divclass="line"><aname="l00198"></a><spanclass="lineno"> 198</span> <spanclass="comment">// running until completion or until the other stopping conditions apply. When</span></div>
<divclass="line"><aname="l00199"></a><spanclass="lineno"> 199</span> <spanclass="comment">// this function returns INTERRUPTED, there is still work to be done to</span></div>
<divclass="line"><aname="l00200"></a><spanclass="lineno"> 200</span> <spanclass="comment">// process all the cliques in the graph. In such case the method can be called</span></div>
<divclass="line"><aname="l00201"></a><spanclass="lineno"> 201</span> <spanclass="comment">// again and it will resume the work where the previous call had stopped. When</span></div>
<divclass="line"><aname="l00202"></a><spanclass="lineno"> 202</span> <spanclass="comment">// it returns COMPLETED any subsequent call to the method will resume the</span></div>
<divclass="line"><aname="l00203"></a><spanclass="lineno"> 203</span> <spanclass="comment">// search from the beginning.</span></div>
<divclass="line"><aname="l00211"></a><spanclass="lineno"> 211</span> <spanclass="comment">// A data structure that maintains the variables of one "iteration" of the</span></div>
<divclass="line"><aname="l00212"></a><spanclass="lineno"> 212</span> <spanclass="comment">// search algorithm. These are the variables that would normally be allocated</span></div>
<divclass="line"><aname="l00213"></a><spanclass="lineno"> 213</span> <spanclass="comment">// on the stack in the recursive implementation.</span></div>
<divclass="line"><aname="l00215"></a><spanclass="lineno"> 215</span> <spanclass="comment">// Note that most of the variables in the structure are explicitly left</span></div>
<divclass="line"><aname="l00216"></a><spanclass="lineno"> 216</span> <spanclass="comment">// uninitialized by the constructor to avoid wasting resources on values that</span></div>
<divclass="line"><aname="l00217"></a><spanclass="lineno"> 217</span> <spanclass="comment">// will be overwritten anyway. Most of the initialization is done in</span></div>
<divclass="line"><aname="l00237"></a><spanclass="lineno"> 237</span> <spanclass="comment">// Moves the first candidate in the state to the "not" set. Assumes that the</span></div>
<divclass="line"><aname="l00238"></a><spanclass="lineno"> 238</span> <spanclass="comment">// first candidate is also the pivot or a candidate disconnected from the</span></div>
<divclass="line"><aname="l00239"></a><spanclass="lineno"> 239</span> <spanclass="comment">// pivot (as done by RunIteration).</span></div>
<divclass="line"><aname="l00245"></a><spanclass="lineno"> 245</span> <spanclass="comment">// Creates a human-readable representation of the current state.</span></div>
<divclass="line"><aname="l00261"></a><spanclass="lineno"> 261</span> <spanclass="comment">// The pivot node selected for the given level of the recursion.</span></div>
<divclass="line"><aname="l00263"></a><spanclass="lineno"> 263</span> <spanclass="comment">// The number of remaining candidates to be explored at the given level of</span></div>
<divclass="line"><aname="l00264"></a><spanclass="lineno"> 264</span> <spanclass="comment">// the recursion; the number is computed as num_disconnected_nodes +</span></div>
<divclass="line"><aname="l00265"></a><spanclass="lineno"> 265</span> <spanclass="comment">// pre_increment in the original algorithm.</span></div>
<divclass="line"><aname="l00267"></a><spanclass="lineno"> 267</span> <spanclass="comment">// The list of nodes that are candidates for extending the current clique.</span></div>
<divclass="line"><aname="l00268"></a><spanclass="lineno"> 268</span> <spanclass="comment">// This vector has the format proposed in the paper by Bron-Kerbosch; the</span></div>
<divclass="line"><aname="l00269"></a><spanclass="lineno"> 269</span> <spanclass="comment">// first 'first_candidate_index' elements of the vector represent the</span></div>
<divclass="line"><aname="l00270"></a><spanclass="lineno"> 270</span> <spanclass="comment">// "not" set of nodes that were already visited by the algorithm. The</span></div>
<divclass="line"><aname="l00271"></a><spanclass="lineno"> 271</span> <spanclass="comment">// remaining elements are the actual candidates for extending the current</span></div>
<divclass="line"><aname="l00273"></a><spanclass="lineno"> 273</span> <spanclass="comment">// NOTE(user): We could store the delta between the iterations; however,</span></div>
<divclass="line"><aname="l00274"></a><spanclass="lineno"> 274</span> <spanclass="comment">// we need to evaluate the impact this would have on the performance.</span></div>
<divclass="line"><aname="l00276"></a><spanclass="lineno"> 276</span> <spanclass="comment">// The index of the first actual candidate in 'candidates'. This number is</span></div>
<divclass="line"><aname="l00277"></a><spanclass="lineno"> 277</span> <spanclass="comment">// also the number of elements of the "not" set stored at the beginning of</span></div>
<divclass="line"><aname="l00281"></a><spanclass="lineno"> 281</span> <spanclass="comment">// The current position in candidates when looking for the pivot and/or the</span></div>
<divclass="line"><aname="l00282"></a><spanclass="lineno"> 282</span> <spanclass="comment">// next candidate disconnected from the pivot.</span></div>
<divclass="line"><aname="l00286"></a><spanclass="lineno"> 286</span> <spanclass="comment">// The deterministic time coefficients for the push and pop operations of the</span></div>
<divclass="line"><aname="l00287"></a><spanclass="lineno"> 287</span> <spanclass="comment">// Bron-Kerbosch algorithm. The coefficients are set to match approximately</span></div>
<divclass="line"><aname="l00288"></a><spanclass="lineno"> 288</span> <spanclass="comment">// the running time in seconds on a recent workstation on the random graph</span></div>
<divclass="line"><aname="l00290"></a><spanclass="lineno"> 290</span> <spanclass="comment">// NOTE(user): PushState is not the only source of complexity in the</span></div>
<divclass="line"><aname="l00291"></a><spanclass="lineno"> 291</span> <spanclass="comment">// algorithm, but non-negative linear least squares produced zero coefficients</span></div>
<divclass="line"><aname="l00292"></a><spanclass="lineno"> 292</span> <spanclass="comment">// for all other deterministic counters tested during the benchmarking. When</span></div>
<divclass="line"><aname="l00293"></a><spanclass="lineno"> 293</span> <spanclass="comment">// we optimize the algorithm, we might need to add deterministic time to the</span></div>
<divclass="line"><aname="l00294"></a><spanclass="lineno"> 294</span> <spanclass="comment">// other places that may produce complexity, namely InitializeState, PopState</span></div>
<divclass="line"><aname="l00295"></a><spanclass="lineno"> 295</span> <spanclass="comment">// and SelectCandidateIndexForRecursion.</span></div>
<divclass="line"><aname="l00298"></a><spanclass="lineno"> 298</span> <spanclass="comment">// Initializes the root state of the algorithm.</span></div>
<divclass="line"><aname="l00301"></a><spanclass="lineno"> 301</span> <spanclass="comment">// Removes the top state from the state stack. This is equivalent to returning</span></div>
<divclass="line"><aname="l00302"></a><spanclass="lineno"> 302</span> <spanclass="comment">// in the recursive implementation of the algorithm.</span></div>
<divclass="line"><aname="l00305"></a><spanclass="lineno"> 305</span> <spanclass="comment">// Adds a new state to the top of the stack, adding the node 'selected' to the</span></div>
<divclass="line"><aname="l00306"></a><spanclass="lineno"> 306</span> <spanclass="comment">// current clique. This is equivalent to making a recurisve call in the</span></div>
<divclass="line"><aname="l00307"></a><spanclass="lineno"> 307</span> <spanclass="comment">// recursive implementation of the algorithm.</span></div>
<divclass="line"><aname="l00310"></a><spanclass="lineno"> 310</span> <spanclass="comment">// Initializes the given state. Runs the pivot selection algorithm in the</span></div>
<divclass="line"><aname="l00314"></a><spanclass="lineno"> 314</span> <spanclass="comment">// Returns true if (node1, node2) is an arc in the graph or if node1 == node2.</span></div>
<divclass="line"><aname="l00319"></a><spanclass="lineno"> 319</span> <spanclass="comment">// Selects the next node for recursion. The selected node is either the pivot</span></div>
<divclass="line"><aname="l00320"></a><spanclass="lineno"> 320</span> <spanclass="comment">// (if it is not in the set "not") or a node that is disconnected from the</span></div>
<divclass="line"><aname="l00324"></a><spanclass="lineno"> 324</span> <spanclass="comment">// Returns a human-readable string representation of the clique.</span></div>
<divclass="line"><aname="l00327"></a><spanclass="lineno"> 327</span> <spanclass="comment">// The callback called when the algorithm needs to determine if (node1, node2)</span></div>
<divclass="line"><aname="l00328"></a><spanclass="lineno"> 328</span> <spanclass="comment">// is an arc in the graph.</span></div>
<divclass="line"><aname="l00331"></a><spanclass="lineno"> 331</span> <spanclass="comment">// The callback called when the algorithm discovers a maximal clique. The</span></div>
<divclass="line"><aname="l00332"></a><spanclass="lineno"> 332</span> <spanclass="comment">// return value of the callback controls how the algorithm proceeds with the</span></div>
<divclass="line"><aname="l00339"></a><spanclass="lineno"> 339</span> <spanclass="comment">// Contains the state of the aglorithm. The vector serves as an external stack</span></div>
<divclass="line"><aname="l00340"></a><spanclass="lineno"> 340</span> <spanclass="comment">// for the recursive part of the algorithm - instead of using the C++ stack</span></div>
<divclass="line"><aname="l00341"></a><spanclass="lineno"> 341</span> <spanclass="comment">// and natural recursion, it is implemented as a loop and new states are added</span></div>
<divclass="line"><aname="l00342"></a><spanclass="lineno"> 342</span> <spanclass="comment">// to the top of the stack. The algorithm ends when the stack is empty.</span></div>
<divclass="line"><aname="l00345"></a><spanclass="lineno"> 345</span> <spanclass="comment">// A vector that receives the current clique found by the algorithm.</span></div>
<divclass="line"><aname="l00348"></a><spanclass="lineno"> 348</span> <spanclass="comment">// Set to true if the algorithm is active (it was not stopped by an the clique</span></div>
<divclass="line"><aname="l00352"></a><spanclass="lineno"> 352</span> <spanclass="comment">// The current time limit used by the solver. The time limit is assigned by</span></div>
<divclass="line"><aname="l00353"></a><spanclass="lineno"> 353</span> <spanclass="comment">// the Run methods and it can be different for each call to run.</span></div>
<divclass="line"><aname="l00459"></a><spanclass="lineno"> 459</span> <spanclass="comment">// Add all candidates from previous_state->candidates that are connected to</span></div>
<divclass="line"><aname="l00460"></a><spanclass="lineno"> 460</span> <spanclass="comment">// 'selected' in the graph to the vector 'new_candidates', skipping the node</span></div>
<divclass="line"><aname="l00461"></a><spanclass="lineno"> 461</span> <spanclass="comment">// 'selected'; this node is always at the position</span></div>
<divclass="line"><aname="l00462"></a><spanclass="lineno"> 462</span> <spanclass="comment">// 'previous_state->first_candidate_index', so we can skip it by skipping the</span></div>
<divclass="line"><aname="l00463"></a><spanclass="lineno"> 463</span> <spanclass="comment">// element at this particular index.</span></div>
<divclass="line"><aname="l00482"></a><spanclass="lineno"> 482</span> <spanclass="comment">// We've found a clique. Report it to the user, but do not push the state</span></div>
<divclass="line"><aname="l00483"></a><spanclass="lineno"> 483</span> <spanclass="comment">// because it would be popped immediately anyway.</span></div>
<divclass="line"><aname="l00487"></a><spanclass="lineno"> 487</span> <spanclass="comment">// The number of remaining iterations will be decremented at the end of</span></div>
<divclass="line"><aname="l00488"></a><spanclass="lineno"> 488</span> <spanclass="comment">// the loop in RunIterations; setting it to 0 here would make it -1 at</span></div>
<divclass="line"><aname="l00489"></a><spanclass="lineno"> 489</span> <spanclass="comment">// the end of the main loop.</span></div>
<divclass="line"><aname="l00497"></a><spanclass="lineno"> 497</span> <spanclass="comment">// NOTE(user): The following line may invalidate previous_state (if the</span></div>
<divclass="line"><aname="l00498"></a><spanclass="lineno"> 498</span> <spanclass="comment">// vector data was re-allocated in the process). We must avoid using</span></div>
<divclass="line"><aname="l00535"></a><spanclass="lineno"> 535</span> <aclass="code"href="namespaceoperations__research.html#a272bcc4d6ee0e87a7fc430a5cb13c582">NodeIndex</a>& f = state->candidates[state->first_candidate_index];</div>
<divclass="line"><aname="l00536"></a><spanclass="lineno"> 536</span> <aclass="code"href="namespaceoperations__research.html#a272bcc4d6ee0e87a7fc430a5cb13c582">NodeIndex</a>& s = state->candidates[selected_index];</div>