<ahref="cliques_8cc.html">Go to the documentation of this file.</a><divclass="fragment"><divclass="line"><aname="l00001"></a><spanclass="lineno"> 1</span> <spanclass="comment">// Copyright 2010-2021 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="l00026"></a><spanclass="lineno"> 26</span> <spanclass="comment">// Encapsulates graph() to make all nodes self-connected.</span></div>
<divclass="line"><aname="l00027"></a><spanclass="lineno"> 27</span> <spanclass="keyword">inline</span><spanclass="keywordtype">bool</span> Connects(std::function<<spanclass="keywordtype">bool</span>(<spanclass="keywordtype">int</span>, <spanclass="keywordtype">int</span>)> graph, <spanclass="keywordtype">int</span> i, <spanclass="keywordtype">int</span> j) {</div>
<divclass="line"><aname="l00028"></a><spanclass="lineno"> 28</span> <spanclass="keywordflow">return</span> i == j || graph(i, j);</div>
<divclass="line"><aname="l00031"></a><spanclass="lineno"> 31</span> <spanclass="comment">// Implements the recursive step of the Bron-Kerbosch algorithm with pivoting.</span></div>
<divclass="line"><aname="l00032"></a><spanclass="lineno"> 32</span> <spanclass="comment">// - graph is a callback such that graph->Run(i, j) returns true iff there is an</span></div>
<divclass="line"><aname="l00033"></a><spanclass="lineno"> 33</span> <spanclass="comment">// arc between i and j.</span></div>
<divclass="line"><aname="l00034"></a><spanclass="lineno"> 34</span> <spanclass="comment">// - callback is a callback called for all maximal cliques discovered by the</span></div>
<divclass="line"><aname="l00036"></a><spanclass="lineno"> 36</span> <spanclass="comment">// - input_candidates is an array that contains the list of nodes connected to</span></div>
<divclass="line"><aname="l00037"></a><spanclass="lineno"> 37</span> <spanclass="comment">// all nodes in the current clique. It is composed of two parts; the first</span></div>
<divclass="line"><aname="l00038"></a><spanclass="lineno"> 38</span> <spanclass="comment">// part contains the "not" set (nodes that were already processed and must not</span></div>
<divclass="line"><aname="l00039"></a><spanclass="lineno"> 39</span> <spanclass="comment">// be added to the clique - see the description of the algorithm in the</span></div>
<divclass="line"><aname="l00040"></a><spanclass="lineno"> 40</span> <spanclass="comment">// paper), and nodes that are candidates for addition. The candidates from the</span></div>
<divclass="line"><aname="l00041"></a><spanclass="lineno"> 41</span> <spanclass="comment">// "not" set are at the beginning of the array.</span></div>
<divclass="line"><aname="l00042"></a><spanclass="lineno"> 42</span> <spanclass="comment">// - first_candidate_index elements is the index of the first candidate that is</span></div>
<divclass="line"><aname="l00043"></a><spanclass="lineno"> 43</span> <spanclass="comment">// not in the "not" set (which is also the number of candidates in the "not"</span></div>
<divclass="line"><aname="l00045"></a><spanclass="lineno"> 45</span> <spanclass="comment">// - num_input_candidates is the number of elements in input_candidates,</span></div>
<divclass="line"><aname="l00046"></a><spanclass="lineno"> 46</span> <spanclass="comment">// including both the "not" set and the actual candidates.</span></div>
<divclass="line"><aname="l00047"></a><spanclass="lineno"> 47</span> <spanclass="comment">// - current_clique is the current clique discovered by the algorithm.</span></div>
<divclass="line"><aname="l00048"></a><spanclass="lineno"> 48</span> <spanclass="comment">// - stop is a stopping condition for the algorithm; if the value it points to</span></div>
<divclass="line"><aname="l00049"></a><spanclass="lineno"> 49</span> <spanclass="comment">// is true, the algorithm stops further exploration and returns.</span></div>
<divclass="line"><aname="l00050"></a><spanclass="lineno"> 50</span> <spanclass="comment">// TODO(user) : rewrite this algorithm without recursion.</span></div>
<divclass="line"><aname="l00056"></a><spanclass="lineno"> 56</span> <spanclass="comment">// The pivot is a node from input_candidates that is disconnected from the</span></div>
<divclass="line"><aname="l00057"></a><spanclass="lineno"> 57</span> <spanclass="comment">// minimal number of nodes in the actual candidates (excluding the "not" set);</span></div>
<divclass="line"><aname="l00058"></a><spanclass="lineno"> 58</span> <spanclass="comment">// the algorithm then selects only candidates that are disconnected from the</span></div>
<divclass="line"><aname="l00059"></a><spanclass="lineno"> 59</span> <spanclass="comment">// pivot (and the pivot itself), to reach the termination condition as quickly</span></div>
<divclass="line"><aname="l00060"></a><spanclass="lineno"> 60</span> <spanclass="comment">// as possible (see the original paper for more details).</span></div>
<divclass="line"><aname="l00063"></a><spanclass="lineno"> 63</span> <spanclass="comment">// A node that is disconnected from the selected pivot. This node is selected</span></div>
<divclass="line"><aname="l00064"></a><spanclass="lineno"> 64</span> <spanclass="comment">// during the pivot matching phase to speed up the first iteration of the</span></div>
<divclass="line"><aname="l00068"></a><spanclass="lineno"> 68</span> <spanclass="comment">// The number of candidates (that are not in "not") disconnected from the</span></div>
<divclass="line"><aname="l00069"></a><spanclass="lineno"> 69</span> <spanclass="comment">// selected pivot. The value is computed during pivot selection. In the</span></div>
<divclass="line"><aname="l00070"></a><spanclass="lineno"> 70</span> <spanclass="comment">// "recursive" phase, we only need to do explore num_disconnected_candidates</span></div>
<divclass="line"><aname="l00071"></a><spanclass="lineno"> 71</span> <spanclass="comment">// nodes, because after this step, all remaining candidates will all be</span></div>
<divclass="line"><aname="l00072"></a><spanclass="lineno"> 72</span> <spanclass="comment">// connected to the pivot node (which is in "not"), so they can't form a</span></div>
<divclass="line"><aname="l00076"></a><spanclass="lineno"> 76</span> <spanclass="comment">// If the selected pivot is not in "not", we need to process one more</span></div>
<divclass="line"><aname="l00077"></a><spanclass="lineno"> 77</span> <spanclass="comment">// candidate (the pivot itself). pre_increment is added to</span></div>
<divclass="line"><aname="l00078"></a><spanclass="lineno"> 78</span> <spanclass="comment">// num_disconnected_candidates to compensate for this fact.</span></div>
<divclass="line"><aname="l00086"></a><spanclass="lineno"> 86</span> <spanclass="comment">// Count is the number of candidates (not including nodes in the "not" set)</span></div>
<divclass="line"><aname="l00087"></a><spanclass="lineno"> 87</span> <spanclass="comment">// that are disconnected from the pivot candidate.</span></div>
<divclass="line"><aname="l00090"></a><spanclass="lineno"> 90</span> <spanclass="comment">// The index of a candidate node that is not connected to pivot_candidate.</span></div>
<divclass="line"><aname="l00091"></a><spanclass="lineno"> 91</span> <spanclass="comment">// This node will be used to quickly start the nested iteration (we keep</span></div>
<divclass="line"><aname="l00092"></a><spanclass="lineno"> 92</span> <spanclass="comment">// track of the index so that we don't have to find a node that is</span></div>
<divclass="line"><aname="l00093"></a><spanclass="lineno"> 93</span> <spanclass="comment">// disconnected from the pivot later in the iteration).</span></div>
<divclass="line"><aname="l00096"></a><spanclass="lineno"> 96</span> <spanclass="comment">// Compute the number of candidate nodes that are disconnected from</span></div>
<divclass="line"><aname="l00097"></a><spanclass="lineno"> 97</span> <spanclass="comment">// pivot_candidate. Note that this computation is the same for the "not"</span></div>
<divclass="line"><aname="l00098"></a><spanclass="lineno"> 98</span> <spanclass="comment">// candidates and the normal candidates.</span></div>
<divclass="line"><aname="l00107"></a><spanclass="lineno"> 107</span> <spanclass="comment">// Update the pivot candidate if we found a new minimum for</span></div>
<divclass="line"><aname="l00117"></a><spanclass="lineno"> 117</span> <spanclass="comment">// The pivot candidate is not in the "not" set. We need to pre-increment</span></div>
<divclass="line"><aname="l00118"></a><spanclass="lineno"> 118</span> <spanclass="comment">// the counter for the node to compensate for that.</span></div>
<divclass="line"><aname="l00128"></a><spanclass="lineno"> 128</span> <spanclass="comment">// Swap a node that is disconnected from the pivot (or the pivot itself)</span></div>
<divclass="line"><aname="l00129"></a><spanclass="lineno"> 129</span> <spanclass="comment">// with the first candidate, so that we can later move it to "not" simply by</span></div>
<divclass="line"><aname="l00130"></a><spanclass="lineno"> 130</span> <spanclass="comment">// increasing the index of the first candidate that is not in "not".</span></div>
<divclass="line"><aname="l00135"></a><spanclass="lineno"> 135</span> <spanclass="comment">// Fill the list of candidates and the "not" set for the recursive call:</span></div>
<divclass="line"><aname="l00150"></a><spanclass="lineno"> 150</span> <spanclass="comment">// Add the selected candidate to the current clique.</span></div>
<divclass="line"><aname="l00153"></a><spanclass="lineno"> 153</span> <spanclass="comment">// If there are no remaining candidates, we have found a maximal clique.</span></div>
<divclass="line"><aname="l00154"></a><spanclass="lineno"> 154</span> <spanclass="comment">// Otherwise, do the recursive step.</span></div>
<divclass="line"><aname="l00168"></a><spanclass="lineno"> 168</span> <spanclass="comment">// Remove the selected candidate from the current clique.</span></div>
<divclass="line"><aname="l00170"></a><spanclass="lineno"> 170</span> <spanclass="comment">// Add the selected candidate to the set "not" - we've already processed</span></div>
<divclass="line"><aname="l00171"></a><spanclass="lineno"> 171</span> <spanclass="comment">// all possible maximal cliques that use this node in 'current_clique'. The</span></div>
<divclass="line"><aname="l00172"></a><spanclass="lineno"> 172</span> <spanclass="comment">// current candidate is the element of the new candidate set, so we can move</span></div>
<divclass="line"><aname="l00173"></a><spanclass="lineno"> 173</span> <spanclass="comment">// it to "not" simply by increasing first_candidate_index.</span></div>
<divclass="line"><aname="l00176"></a><spanclass="lineno"> 176</span> <spanclass="comment">// Find the next candidate that is disconnected from the pivot.</span></div>
<divclass="line"><aname="l00224"></a><spanclass="lineno"> 224</span> <spanclass="comment">// This method implements the 'version2' of the Bron-Kerbosch</span></div>
<divclass="line"><aname="l00225"></a><spanclass="lineno"> 225</span> <spanclass="comment">// algorithm to find all maximal cliques in a undirected graph.</span></div>
<divclass="ttc"id="anamespaceoperations__research_1_1math__opt_html_a5de89a1f6e3f80a49a0d76136d8044e2"><divclass="ttname"><ahref="namespaceoperations__research_1_1math__opt.html#a5de89a1f6e3f80a49a0d76136d8044e2">operations_research::math_opt::swap</a></div><divclass="ttdeci">void swap(IdMap< K, V >&a, IdMap< K, V >&b)</div><divclass="ttdef"><b>Definition:</b><ahref="id__map_8h_source.html#l00263">id_map.h:263</a></div></div>
<divclass="ttc"id="anamespaceoperations__research_html"><divclass="ttname"><ahref="namespaceoperations__research.html">operations_research</a></div><divclass="ttdoc">Collection of objects used to extend the Constraint Solver library.</div><divclass="ttdef"><b>Definition:</b><ahref="dense__doubly__linked__list_8h_source.html#l00021">dense_doubly_linked_list.h:21</a></div></div>