<ahref="cliques_8cc.html">Go to the documentation of this file.</a><divclass="fragment"><divclass="line"><aid="l00001"name="l00001"></a><spanclass="lineno"> 1</span><spanclass="comment">// Copyright 2010-2021 Google LLC</span></div>
<divclass="line"><aid="l00002"name="l00002"></a><spanclass="lineno"> 2</span><spanclass="comment">// Licensed under the Apache License, Version 2.0 (the "License");</span></div>
<divclass="line"><aid="l00003"name="l00003"></a><spanclass="lineno"> 3</span><spanclass="comment">// you may not use this file except in compliance with the License.</span></div>
<divclass="line"><aid="l00004"name="l00004"></a><spanclass="lineno"> 4</span><spanclass="comment">// You may obtain a copy of the License at</span></div>
<divclass="line"><aid="l00008"name="l00008"></a><spanclass="lineno"> 8</span><spanclass="comment">// Unless required by applicable law or agreed to in writing, software</span></div>
<divclass="line"><aid="l00009"name="l00009"></a><spanclass="lineno"> 9</span><spanclass="comment">// distributed under the License is distributed on an "AS IS" BASIS,</span></div>
<divclass="line"><aid="l00010"name="l00010"></a><spanclass="lineno"> 10</span><spanclass="comment">// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.</span></div>
<divclass="line"><aid="l00011"name="l00011"></a><spanclass="lineno"> 11</span><spanclass="comment">// See the License for the specific language governing permissions and</span></div>
<divclass="line"><aid="l00012"name="l00012"></a><spanclass="lineno"> 12</span><spanclass="comment">// limitations under the License.</span></div>
<divclass="line"><aid="l00026"name="l00026"></a><spanclass="lineno"> 26</span><spanclass="comment">// Encapsulates graph() to make all nodes self-connected.</span></div>
<divclass="line"><aid="l00027"name="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"><aid="l00028"name="l00028"></a><spanclass="lineno"> 28</span><spanclass="keywordflow">return</span> i == j || graph(i, j);</div>
<divclass="line"><aid="l00031"name="l00031"></a><spanclass="lineno"> 31</span><spanclass="comment">// Implements the recursive step of the Bron-Kerbosch algorithm with pivoting.</span></div>
<divclass="line"><aid="l00032"name="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"><aid="l00033"name="l00033"></a><spanclass="lineno"> 33</span><spanclass="comment">// arc between i and j.</span></div>
<divclass="line"><aid="l00034"name="l00034"></a><spanclass="lineno"> 34</span><spanclass="comment">// - callback is a callback called for all maximal cliques discovered by the</span></div>
<divclass="line"><aid="l00036"name="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"><aid="l00037"name="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"><aid="l00038"name="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"><aid="l00039"name="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"><aid="l00040"name="l00040"></a><spanclass="lineno"> 40</span><spanclass="comment">// paper), and nodes that are candidates for addition. The candidates from the</span></div>
<divclass="line"><aid="l00041"name="l00041"></a><spanclass="lineno"> 41</span><spanclass="comment">// "not" set are at the beginning of the array.</span></div>
<divclass="line"><aid="l00042"name="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"><aid="l00043"name="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"><aid="l00045"name="l00045"></a><spanclass="lineno"> 45</span><spanclass="comment">// - num_input_candidates is the number of elements in input_candidates,</span></div>
<divclass="line"><aid="l00046"name="l00046"></a><spanclass="lineno"> 46</span><spanclass="comment">// including both the "not" set and the actual candidates.</span></div>
<divclass="line"><aid="l00047"name="l00047"></a><spanclass="lineno"> 47</span><spanclass="comment">// - current_clique is the current clique discovered by the algorithm.</span></div>
<divclass="line"><aid="l00048"name="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"><aid="l00049"name="l00049"></a><spanclass="lineno"> 49</span><spanclass="comment">// is true, the algorithm stops further exploration and returns.</span></div>
<divclass="line"><aid="l00050"name="l00050"></a><spanclass="lineno"> 50</span><spanclass="comment">// TODO(user) : rewrite this algorithm without recursion.</span></div>
<divclass="line"><aid="l00056"name="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"><aid="l00057"name="l00057"></a><spanclass="lineno"> 57</span><spanclass="comment">// minimal number of nodes in the actual candidates (excluding the "not" set);</span></div>
<divclass="line"><aid="l00058"name="l00058"></a><spanclass="lineno"> 58</span><spanclass="comment">// the algorithm then selects only candidates that are disconnected from the</span></div>
<divclass="line"><aid="l00059"name="l00059"></a><spanclass="lineno"> 59</span><spanclass="comment">// pivot (and the pivot itself), to reach the termination condition as quickly</span></div>
<divclass="line"><aid="l00060"name="l00060"></a><spanclass="lineno"> 60</span><spanclass="comment">// as possible (see the original paper for more details).</span></div>
<divclass="line"><aid="l00063"name="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"><aid="l00064"name="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"><aid="l00068"name="l00068"></a><spanclass="lineno"> 68</span><spanclass="comment">// The number of candidates (that are not in "not") disconnected from the</span></div>
<divclass="line"><aid="l00069"name="l00069"></a><spanclass="lineno"> 69</span><spanclass="comment">// selected pivot. The value is computed during pivot selection. In the</span></div>
<divclass="line"><aid="l00070"name="l00070"></a><spanclass="lineno"> 70</span><spanclass="comment">// "recursive" phase, we only need to do explore num_disconnected_candidates</span></div>
<divclass="line"><aid="l00071"name="l00071"></a><spanclass="lineno"> 71</span><spanclass="comment">// nodes, because after this step, all remaining candidates will all be</span></div>
<divclass="line"><aid="l00072"name="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"><aid="l00076"name="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"><aid="l00077"name="l00077"></a><spanclass="lineno"> 77</span><spanclass="comment">// candidate (the pivot itself). pre_increment is added to</span></div>
<divclass="line"><aid="l00078"name="l00078"></a><spanclass="lineno"> 78</span><spanclass="comment">// num_disconnected_candidates to compensate for this fact.</span></div>
<divclass="line"><aid="l00086"name="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"><aid="l00087"name="l00087"></a><spanclass="lineno"> 87</span><spanclass="comment">// that are disconnected from the pivot candidate.</span></div>
<divclass="line"><aid="l00090"name="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"><aid="l00091"name="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"><aid="l00092"name="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"><aid="l00093"name="l00093"></a><spanclass="lineno"> 93</span><spanclass="comment">// disconnected from the pivot later in the iteration).</span></div>
<divclass="line"><aid="l00096"name="l00096"></a><spanclass="lineno"> 96</span><spanclass="comment">// Compute the number of candidate nodes that are disconnected from</span></div>
<divclass="line"><aid="l00097"name="l00097"></a><spanclass="lineno"> 97</span><spanclass="comment">// pivot_candidate. Note that this computation is the same for the "not"</span></div>
<divclass="line"><aid="l00098"name="l00098"></a><spanclass="lineno"> 98</span><spanclass="comment">// candidates and the normal candidates.</span></div>
<divclass="line"><aid="l00107"name="l00107"></a><spanclass="lineno"> 107</span><spanclass="comment">// Update the pivot candidate if we found a new minimum for</span></div>
<divclass="line"><aid="l00117"name="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"><aid="l00118"name="l00118"></a><spanclass="lineno"> 118</span><spanclass="comment">// the counter for the node to compensate for that.</span></div>
<divclass="line"><aid="l00128"name="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"><aid="l00129"name="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"><aid="l00130"name="l00130"></a><spanclass="lineno"> 130</span><spanclass="comment">// increasing the index of the first candidate that is not in "not".</span></div>
<divclass="line"><aid="l00135"name="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"><aid="l00150"name="l00150"></a><spanclass="lineno"> 150</span><spanclass="comment">// Add the selected candidate to the current clique.</span></div>
<divclass="line"><aid="l00153"name="l00153"></a><spanclass="lineno"> 153</span><spanclass="comment">// If there are no remaining candidates, we have found a maximal clique.</span></div>
<divclass="line"><aid="l00154"name="l00154"></a><spanclass="lineno"> 154</span><spanclass="comment">// Otherwise, do the recursive step.</span></div>
<divclass="line"><aid="l00168"name="l00168"></a><spanclass="lineno"> 168</span><spanclass="comment">// Remove the selected candidate from the current clique.</span></div>
<divclass="line"><aid="l00170"name="l00170"></a><spanclass="lineno"> 170</span><spanclass="comment">// Add the selected candidate to the set "not" - we've already processed</span></div>
<divclass="line"><aid="l00171"name="l00171"></a><spanclass="lineno"> 171</span><spanclass="comment">// all possible maximal cliques that use this node in 'current_clique'. The</span></div>
<divclass="line"><aid="l00172"name="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"><aid="l00173"name="l00173"></a><spanclass="lineno"> 173</span><spanclass="comment">// it to "not" simply by increasing first_candidate_index.</span></div>
<divclass="line"><aid="l00176"name="l00176"></a><spanclass="lineno"> 176</span><spanclass="comment">// Find the next candidate that is disconnected from the pivot.</span></div>
<divclass="line"><aid="l00224"name="l00224"></a><spanclass="lineno"> 224</span><spanclass="comment">// This method implements the 'version2' of the Bron-Kerbosch</span></div>
<divclass="line"><aid="l00225"name="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#l00262">id_map.h:262</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>
<divclass="ttc"id="anamespaceoperations__research_html_a5986867bcb6d1470fd6c27438d289fcd"><divclass="ttname"><ahref="namespaceoperations__research.html#a5986867bcb6d1470fd6c27438d289fcd">operations_research::CoverArcsByCliques</a></div><divclass="ttdeci">void CoverArcsByCliques(std::function< bool(int, int)> graph, int node_count, std::function< bool(const std::vector< int >&)> callback)</div><divclass="ttdef"><b>Definition:</b><ahref="cliques_8cc_source.html#l00240">cliques.cc:240</a></div></div>
<divclass="ttc"id="anamespaceoperations__research_html_af7f3504c258b748227551a4d7b7bf036"><divclass="ttname"><ahref="namespaceoperations__research.html#af7f3504c258b748227551a4d7b7bf036">operations_research::FindCliques</a></div><divclass="ttdeci">void FindCliques(std::function< bool(int, int)> graph, int node_count, std::function< bool(const std::vector< int >&)> callback)</div><divclass="ttdef"><b>Definition:</b><ahref="cliques_8cc_source.html#l00226">cliques.cc:226</a></div></div>