<ahref="strongly__connected__components_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="l00014"></a><spanclass="lineno"> 14</span> <spanclass="comment">// This code computes the strongly connected components of a directed graph,</span></div>
<divclass="line"><aname="l00015"></a><spanclass="lineno"> 15</span> <spanclass="comment">// and presents them sorted by reverse topological order.</span></div>
<divclass="line"><aname="l00017"></a><spanclass="lineno"> 17</span> <spanclass="comment">// It implements an efficient version of Tarjan's strongly connected components</span></div>
<divclass="line"><aname="l00018"></a><spanclass="lineno"> 18</span> <spanclass="comment">// algorithm published in: Tarjan, R. E. (1972), "Depth-first search and linear</span></div>
<divclass="line"><aname="l00019"></a><spanclass="lineno"> 19</span> <spanclass="comment">// graph algorithms", SIAM Journal on Computing.</span></div>
<divclass="line"><aname="l00026"></a><spanclass="lineno"> 26</span> <spanclass="comment">// Fill a vector<vector<int>> graph; representing your graph adjacency lists.</span></div>
<divclass="line"><aname="l00027"></a><spanclass="lineno"> 27</span> <spanclass="comment">// That is, graph[i] contains the nodes adjacent to node #i. The nodes must be</span></div>
<divclass="line"><aname="l00028"></a><spanclass="lineno"> 28</span> <spanclass="comment">// integers in [0, num_nodes). Then just do:</span></div>
<divclass="line"><aname="l00034"></a><spanclass="lineno"> 34</span> <spanclass="comment">// The nodes of each strongly connected components will be listed in each</span></div>
<divclass="line"><aname="l00035"></a><spanclass="lineno"> 35</span> <spanclass="comment">// subvector of components. The components appear in reverse topological order:</span></div>
<divclass="line"><aname="l00036"></a><spanclass="lineno"> 36</span> <spanclass="comment">// outgoing arcs from a component will only be towards earlier components.</span></div>
<divclass="line"><aname="l00038"></a><spanclass="lineno"> 38</span> <spanclass="comment">// IMPORTANT: num_nodes will be the number of nodes of the graph. Its type</span></div>
<divclass="line"><aname="l00039"></a><spanclass="lineno"> 39</span> <spanclass="comment">// is the type used internally by the algorithm. It is why it is better to</span></div>
<divclass="line"><aname="l00040"></a><spanclass="lineno"> 40</span> <spanclass="comment">// convert it to int or even int32 rather than using size_t which takes 64 bits.</span></div>
<divclass="line"><aname="l00051"></a><spanclass="lineno"> 51</span> <spanclass="comment">// Finds the strongly connected components of a directed graph. It is templated</span></div>
<divclass="line"><aname="l00052"></a><spanclass="lineno"> 52</span> <spanclass="comment">// so it can be used in many contexts. See the simple example above for the</span></div>
<divclass="line"><aname="l00053"></a><spanclass="lineno"> 53</span> <spanclass="comment">// easiest use case.</span></div>
<divclass="line"><aname="l00055"></a><spanclass="lineno"> 55</span> <spanclass="comment">// The requirement of the different types are:</span></div>
<divclass="line"><aname="l00056"></a><spanclass="lineno"> 56</span> <spanclass="comment">// - The type NodeIndex must be an integer type representing a node of the</span></div>
<divclass="line"><aname="l00057"></a><spanclass="lineno"> 57</span> <spanclass="comment">// graph. The nodes must be in [0, num_nodes). It can be unsigned.</span></div>
<divclass="line"><aname="l00058"></a><spanclass="lineno"> 58</span> <spanclass="comment">// - The type Graph must provide a [] operator such that the following code</span></div>
<divclass="line"><aname="l00059"></a><spanclass="lineno"> 59</span> <spanclass="comment">// iterates over the adjacency list of the given node:</span></div>
<divclass="line"><aname="l00060"></a><spanclass="lineno"> 60</span> <spanclass="comment">// for (const NodeIndex head : graph[node]) {}</span></div>
<divclass="line"><aname="l00061"></a><spanclass="lineno"> 61</span> <spanclass="comment">// - The type SccOutput must implement the function:</span></div>
<divclass="line"><aname="l00063"></a><spanclass="lineno"> 63</span> <spanclass="comment">// It will be called with the connected components of the given graph as they</span></div>
<divclass="line"><aname="l00064"></a><spanclass="lineno"> 64</span> <spanclass="comment">// are found (In the reverse topological order).</span></div>
<divclass="line"><aname="l00066"></a><spanclass="lineno"> 66</span> <spanclass="comment">// More practical details on the algorithm:</span></div>
<divclass="line"><aname="l00067"></a><spanclass="lineno"> 67</span> <spanclass="comment">// - It deals properly with self-loop and duplicate nodes.</span></div>
<divclass="line"><aname="l00068"></a><spanclass="lineno"> 68</span> <spanclass="comment">// - It is really fast! and work in O(nodes + edges).</span></div>
<divclass="line"><aname="l00069"></a><spanclass="lineno"> 69</span> <spanclass="comment">// - Its memory usage is also bounded by O(nodes + edges) but in practice it</span></div>
<divclass="line"><aname="l00070"></a><spanclass="lineno"> 70</span> <spanclass="comment">// uses less than the input graph.</span></div>
<divclass="line"><aname="l00075"></a><spanclass="lineno"> 75</span> <spanclass="comment">// A simple custom output class that just counts the number of SCC. Not</span></div>
<divclass="line"><aname="l00076"></a><spanclass="lineno"> 76</span> <spanclass="comment">// allocating many vectors can save both space and speed if your graph is large.</span></div>
<divclass="line"><aname="l00078"></a><spanclass="lineno"> 78</span> <spanclass="comment">// Note: If this matters, you probably don't want to use vector<vector<int>> as</span></div>
<divclass="line"><aname="l00079"></a><spanclass="lineno"> 79</span> <spanclass="comment">// an input either. See StaticGraph in ortools/graph/graph.h</span></div>
<divclass="line"><aname="l00080"></a><spanclass="lineno"> 80</span> <spanclass="comment">// for an efficient graph data structure compatible with this algorithm.</span></div>
<divclass="line"><aname="l00087"></a><spanclass="lineno"> 87</span> <spanclass="comment">// This is just here so this class can transparently replace a code that</span></div>
<divclass="line"><aname="l00088"></a><spanclass="lineno"> 88</span> <spanclass="comment">// use vector<vector<int>> as an SccOutput, and get its size with size().</span></div>
<divclass="line"><aname="l00092"></a><spanclass="lineno"> 92</span> <spanclass="comment">// This implementation is slightly different than a classical iterative version</span></div>
<divclass="line"><aname="l00093"></a><spanclass="lineno"> 93</span> <spanclass="comment">// of Tarjan's strongly connected components algorithm. But basically it is</span></div>
<divclass="line"><aname="l00094"></a><spanclass="lineno"> 94</span> <spanclass="comment">// still an iterative DFS. We use a class so memory can be reused if one needs</span></div>
<divclass="line"><aname="l00095"></a><spanclass="lineno"> 95</span> <spanclass="comment">// to compute many SCC in a row. It also allows more complex behavior in the</span></div>
<divclass="line"><aname="l00096"></a><spanclass="lineno"> 96</span> <spanclass="comment">// Graph or SccOutput class that might inspect the current state of the</span></div>
<divclass="line"><aname="l00099"></a><spanclass="lineno"> 99</span> <spanclass="comment">// TODO(user): Possible optimizations:</span></div>
<divclass="line"><aname="l00100"></a><spanclass="lineno"> 100</span> <spanclass="comment">// - Try to reserve the vectors which sizes are bounded by num_nodes.</span></div>
<divclass="line"><aname="l00101"></a><spanclass="lineno"> 101</span> <spanclass="comment">// - Use an index rather than doing push_back(), pop_back() on them.</span></div>
<divclass="line"><aname="l00114"></a><spanclass="lineno"> 114</span> <spanclass="comment">// Optimization. This will always be equal to scc_start_index_.back() except</span></div>
<divclass="line"><aname="l00115"></a><spanclass="lineno"> 115</span> <spanclass="comment">// when scc_stack_ is empty, in which case its value does not matter.</span></div>
<divclass="line"><aname="l00118"></a><spanclass="lineno"> 118</span> <spanclass="comment">// Loop over all the nodes not yet settled and start a DFS from each of</span></div>
<divclass="line"><aname="l00126"></a><spanclass="lineno"> 126</span> <spanclass="keyword">const</span><aclass="code"href="namespaceoperations__research.html#a272bcc4d6ee0e87a7fc430a5cb13c582">NodeIndex</a> index = node_index_[node];</div>
<divclass="line"><aname="l00128"></a><spanclass="lineno"> 128</span> <spanclass="comment">// We continue the dfs from this node and set its 1-based index.</span></div>
<divclass="line"><aname="l00141"></a><spanclass="lineno"> 141</span> <spanclass="comment">// Note that if head_index == kSettledIndex, nothing happens.</span></div>
<divclass="line"><aname="l00146"></a><spanclass="lineno"> 146</span> <spanclass="comment">// Update the start of this strongly connected component.</span></div>
<divclass="line"><aname="l00147"></a><spanclass="lineno"> 147</span> <spanclass="comment">// Note that scc_start_index_ can never be empty since it first</span></div>
<divclass="line"><aname="l00148"></a><spanclass="lineno"> 148</span> <spanclass="comment">// element is 1 and by definition min_head_index is 1-based and can't</span></div>
<divclass="line"><aname="l00149"></a><spanclass="lineno"> 149</span> <spanclass="comment">// be 0.</span></div>
<divclass="line"><aname="l00157"></a><spanclass="lineno"> 157</span> <spanclass="comment">// We found a strongly connected component.</span></div>
<divclass="line"><aname="l00173"></a><spanclass="lineno"> 173</span> <spanclass="comment">// Advanced usage. This can be used in either the Graph or SccOutput template</span></div>
<divclass="line"><aname="l00174"></a><spanclass="lineno"> 174</span> <spanclass="comment">// class to query the current state of the algorithm. It allows to build more</span></div>
<divclass="line"><aname="l00175"></a><spanclass="lineno"> 175</span> <spanclass="comment">// complex variant based on the core DFS algo.</span></div>
<divclass="line"><aname="l00184"></a><spanclass="lineno"> 184</span> <spanclass="comment">// Each node expanded by the DFS will be pushed on this stack. A node is only</span></div>
<divclass="line"><aname="l00185"></a><spanclass="lineno"> 185</span> <spanclass="comment">// popped back when its strongly connected component has been explored and</span></div>
<divclass="line"><aname="l00189"></a><spanclass="lineno"> 189</span> <spanclass="comment">// This is equivalent to the "low link" of a node in Tarjan's algorithm.</span></div>
<divclass="line"><aname="l00190"></a><spanclass="lineno"> 190</span> <spanclass="comment">// Basically, scc_start_index_.back() represent the 1-based index in</span></div>
<divclass="line"><aname="l00191"></a><spanclass="lineno"> 191</span> <spanclass="comment">// scc_stack_ of the beginning of the current strongly connected component.</span></div>
<divclass="line"><aname="l00192"></a><spanclass="lineno"> 192</span> <spanclass="comment">// All the nodes after this index will be on the same component.</span></div>
<divclass="line"><aname="l00195"></a><spanclass="lineno"> 195</span> <spanclass="comment">// Each node is assigned an index which changes 2 times in the algorithm:</span></div>
<divclass="line"><aname="l00196"></a><spanclass="lineno"> 196</span> <spanclass="comment">// - Everyone starts with an index of 0 which means unexplored.</span></div>
<divclass="line"><aname="l00197"></a><spanclass="lineno"> 197</span> <spanclass="comment">// - The first time they are explored by the DFS and pushed on scc_stack_,</span></div>
<divclass="line"><aname="l00198"></a><spanclass="lineno"> 198</span> <spanclass="comment">// they get their 1-based index on this stack.</span></div>
<divclass="line"><aname="l00199"></a><spanclass="lineno"> 199</span> <spanclass="comment">// - Once they have been processed and outputted to components, they are said</span></div>
<divclass="line"><aname="l00200"></a><spanclass="lineno"> 200</span> <spanclass="comment">// to be settled, and their index become kSettledIndex.</span></div>
<divclass="line"><aname="l00203"></a><spanclass="lineno"> 203</span> <spanclass="comment">// This is a well known way to do an efficient iterative DFS. Each time a node</span></div>
<divclass="line"><aname="l00204"></a><spanclass="lineno"> 204</span> <spanclass="comment">// is explored, all its adjacent nodes are pushed on this stack. The iterative</span></div>
<divclass="line"><aname="l00205"></a><spanclass="lineno"> 205</span> <spanclass="comment">// dfs processes the nodes one by one by popping them back from here.</span></div>