<trclass="memdesc:"><tdclass="mdescLeft"> </td><tdclass="mdescRight">Base class of all Graphs implemented here. <ahref="classutil_1_1BaseGraph.html#details">More...</a><br/></td></tr>
<trclass="memdesc:"><tdclass="mdescLeft"> </td><tdclass="mdescRight"><aclass="el"href="classutil_1_1CompleteBipartiteGraph.html"title="CompleteBipartiteGraph implementation ------------------------------------— Nodes and arcs are implic...">CompleteBipartiteGraph</a> implementation ------------------------------------— Nodes and arcs are implicit and not stored. <ahref="classutil_1_1CompleteBipartiteGraph.html#details">More...</a><br/></td></tr>
<trclass="memdesc:"><tdclass="mdescLeft"> </td><tdclass="mdescRight"><aclass="el"href="classutil_1_1CompleteGraph.html"title="CompleteGraph implementation ---------------------------------------------— Nodes and arcs are implic...">CompleteGraph</a> implementation ---------------------------------------------— Nodes and arcs are implicit and not stored. <ahref="classutil_1_1CompleteGraph.html#details">More...</a><br/></td></tr>
<trclass="memdesc:"><tdclass="mdescLeft"> </td><tdclass="mdescRight">Extends the <aclass="el"href="classutil_1_1ListGraph.html"title="Basic graph implementation without reverse arc.">ListGraph</a> by also storing the reverse arcs. <ahref="classutil_1_1ReverseArcListGraph.html#details">More...</a><br/></td></tr>
<trclass="memdesc:"><tdclass="mdescLeft"> </td><tdclass="mdescRight">This graph is a mix between the <aclass="el"href="classutil_1_1ReverseArcListGraph.html"title="Extends the ListGraph by also storing the reverse arcs.">ReverseArcListGraph</a> and the <aclass="el"href="classutil_1_1ReverseArcStaticGraph.html"title="StaticGraph with reverse arc.">ReverseArcStaticGraph</a>. <ahref="classutil_1_1ReverseArcMixedGraph.html#details">More...</a><br/></td></tr>
<trclass="memdesc:"><tdclass="mdescLeft"> </td><tdclass="mdescRight"><aclass="el"href="classutil_1_1StaticGraph.html"title="Most efficient implementation of a graph without reverse arcs:">StaticGraph</a> with reverse arc. <ahref="classutil_1_1ReverseArcStaticGraph.html#details">More...</a><br/></td></tr>
<trclass="memdesc:"><tdclass="mdescLeft"> </td><tdclass="mdescRight">Most efficient implementation of a graph without reverse arcs: <ahref="classutil_1_1StaticGraph.html#details">More...</a><br/></td></tr>
<trclass="memdesc:"><tdclass="mdescLeft"> </td><tdclass="mdescRight">This can be used to view a directed graph (that supports reverse arcs) from <aclass="el"href="graph_8h.html">graph.h</a> as un undirected graph: operator[](node) returns a pseudo-container that iterates over all nodes adjacent to "node" (from outgoing or incoming arcs). <ahref="classutil_1_1UndirectedAdjacencyListsOfDirectedGraph.html#details">More...</a><br/></td></tr>
<trclass="memdesc:ae76339cb2dcd3bc05ad762146f91fdda"><tdclass="mdescLeft"> </td><tdclass="mdescRight">Defining the simplest Graph interface as Graph for convenience. <ahref="#ae76339cb2dcd3bc05ad762146f91fdda">More...</a><br/></td></tr>
<trclass="memdesc:ae705e1342dacc10a13fb3f11f91d0696"><tdclass="mdescLeft"> </td><tdclass="mdescRight">Returns a std::string representation of a graph. <ahref="namespaceutil.html#ae705e1342dacc10a13fb3f11f91d0696">More...</a><br/></td></tr>
<trclass="memitem:a13f0e8f7e15873600cf8e395958c71e1"><tdclass="memTemplItemLeft"align="right"valign="top">std::vector< int > </td><tdclass="memTemplItemRight"valign="bottom"><aclass="el"href="namespaceutil.html#a13f0e8f7e15873600cf8e395958c71e1">GetConnectedComponents</a> (int num_nodes, const UndirectedGraph &graph)</td></tr>
<trclass="memdesc:a13f0e8f7e15873600cf8e395958c71e1"><tdclass="mdescLeft"> </td><tdclass="mdescRight">Finds the connected components of the graph, using BFS internally. <ahref="#a13f0e8f7e15873600cf8e395958c71e1">More...</a><br/></td></tr>
<trclass="memitem:a9470623ca7db3c4a62ce3b326c6b07d8"><tdclass="memTemplParams"colspan="2">template<class IntVector , class Array , class ElementType ></td></tr>
<trclass="memdesc:a9470623ca7db3c4a62ce3b326c6b07d8"><tdclass="mdescLeft"> </td><tdclass="mdescRight">Permutes the elements of array_to_permute: element #i will be moved to position permutation[i]. <ahref="#a9470623ca7db3c4a62ce3b326c6b07d8">More...</a><br/></td></tr>
<trclass="memdesc:ac497881c4166bc694adc4bee62746118"><tdclass="mdescLeft"> </td><tdclass="mdescRight">We need a specialization for std::vector<bool>, because the default code uses (*array_to_permute)[0] as ElementType, which isn't 'bool' in that case. <ahref="#ac497881c4166bc694adc4bee62746118">More...</a><br/></td></tr>
<trclass="memdesc:af3c40fc068f645d9dcd15c332e44fc25"><tdclass="mdescLeft"> </td><tdclass="mdescRight"><aclass="el"href="classutil_1_1StaticGraph.html"title="Most efficient implementation of a graph without reverse arcs:">StaticGraph</a> implementation -----------------------------------------------—. <ahref="#af3c40fc068f645d9dcd15c332e44fc25">More...</a><br/></td></tr>
<trclass="memdesc:a3098e161a6aceeca482be78d2d221b3b"><tdclass="mdescLeft"> </td><tdclass="mdescRight"><aclass="el"href="classutil_1_1ReverseArcListGraph.html"title="Extends the ListGraph by also storing the reverse arcs.">ReverseArcListGraph</a> implementation ---------------------------------------—. <ahref="#a3098e161a6aceeca482be78d2d221b3b">More...</a><br/></td></tr>
<trclass="memdesc:ab3308688d13e59e2351bef038ce1fdb0"><tdclass="mdescLeft"> </td><tdclass="mdescRight"><aclass="el"href="classutil_1_1ReverseArcMixedGraph.html"title="This graph is a mix between the ReverseArcListGraph and the ReverseArcStaticGraph.">ReverseArcMixedGraph</a> implementation --------------------------------------—. <ahref="#ab3308688d13e59e2351bef038ce1fdb0">More...</a><br/></td></tr>
<trclass="memdesc:affed79554a202aaa8bda5b5e98c3a6b2"><tdclass="mdescLeft"> </td><tdclass="mdescRight">Implementations of the templated methods. <ahref="#affed79554a202aaa8bda5b5e98c3a6b2">More...</a><br/></td></tr>
<trclass="memdesc:a86199e4832dd5c1d61baa53bfecb7b6d"><tdclass="mdescLeft"> </td><tdclass="mdescRight">Read a graph file in the simple ".g" format: the file should be a text file containing only space-separated integers, whose first line is: <num nodes>=""><num edges>=""> [<num_colors><index of first node with color #1><index of first node with color #2> ...] and whose subsequent lines represent edges if "directed" is false, or arcs if "directed" is true: <node1><node2>. <ahref="#a86199e4832dd5c1d61baa53bfecb7b6d">More...</a><br/></td></tr>
<trclass="memdesc:a6600986f328a49c9485aa03fb6c82946"><tdclass="mdescLeft"> </td><tdclass="mdescRight">Writes a graph to the ".g" file format described above. <ahref="#a6600986f328a49c9485aa03fb6c82946">More...</a><br/></td></tr>
<trclass="memdesc:ac4af76993c891ee4ad507783edec2a1c"><tdclass="mdescLeft"> </td><tdclass="mdescRight">Here's a set of simple diagnosis tools. <ahref="#ac4af76993c891ee4ad507783edec2a1c">More...</a><br/></td></tr>
<trclass="memdesc:a0ed748741b17dad9e6cc485728bb0043"><tdclass="mdescLeft"> </td><tdclass="mdescRight">Returns a fresh copy of a given graph. <ahref="#a0ed748741b17dad9e6cc485728bb0043">More...</a><br/></td></tr>
<trclass="memitem:acfecdce43e9933bde2a94fd879f12f5f"><tdclass="memTemplItemLeft"align="right"valign="top">std::unique_ptr<<aclass="el"href="namespaceutil.html#ae76339cb2dcd3bc05ad762146f91fdda">Graph</a>> </td><tdclass="memTemplItemRight"valign="bottom"><aclass="el"href="namespaceutil.html#acfecdce43e9933bde2a94fd879f12f5f">RemapGraph</a> (const <aclass="el"href="namespaceutil.html#ae76339cb2dcd3bc05ad762146f91fdda">Graph</a>&graph, const std::vector< int >&new_node_index)</td></tr>
<trclass="memdesc:acfecdce43e9933bde2a94fd879f12f5f"><tdclass="mdescLeft"> </td><tdclass="mdescRight">Creates a remapped copy of graph "graph", where node i becomes node new_node_index[i]. <ahref="#acfecdce43e9933bde2a94fd879f12f5f">More...</a><br/></td></tr>
<trclass="memitem:ad1df170a504d335462a1104a942e6069"><tdclass="memTemplItemLeft"align="right"valign="top">std::unique_ptr<<aclass="el"href="namespaceutil.html#ae76339cb2dcd3bc05ad762146f91fdda">Graph</a>> </td><tdclass="memTemplItemRight"valign="bottom"><aclass="el"href="namespaceutil.html#ad1df170a504d335462a1104a942e6069">GetSubgraphOfNodes</a> (const <aclass="el"href="namespaceutil.html#ae76339cb2dcd3bc05ad762146f91fdda">Graph</a>&graph, const std::vector< int >&nodes)</td></tr>
<trclass="memdesc:ad1df170a504d335462a1104a942e6069"><tdclass="mdescLeft"> </td><tdclass="mdescRight">Gets the induced subgraph of "graph" restricted to the nodes in "nodes": the resulting graph will have exactly nodes.size() nodes, and its node #0 will be the former graph's node #nodes[0], etc. <ahref="#ad1df170a504d335462a1104a942e6069">More...</a><br/></td></tr>
<trclass="memitem:ab34783e729bb5fc99042893f6bfcbb2f"><tdclass="memTemplItemLeft"align="right"valign="top">std::vector< int > </td><tdclass="memTemplItemRight"valign="bottom"><aclass="el"href="namespaceutil.html#ab34783e729bb5fc99042893f6bfcbb2f">GetWeaklyConnectedComponents</a> (const <aclass="el"href="namespaceutil.html#ae76339cb2dcd3bc05ad762146f91fdda">Graph</a>&graph)</td></tr>
<trclass="memdesc:ab34783e729bb5fc99042893f6bfcbb2f"><tdclass="mdescLeft"> </td><tdclass="mdescRight">Computes the weakly connected components of a directed graph that provides the OutgoingOrOppositeIncomingArcs() API, and returns them as a mapping from node to component index. <ahref="#ab34783e729bb5fc99042893f6bfcbb2f">More...</a><br/></td></tr>
<trclass="memitem:aa9fb4c9a176acaf72053b11727436e9e"><tdclass="memItemLeft"align="right"valign="top">bool </td><tdclass="memItemRight"valign="bottom"><aclass="el"href="namespaceutil.html#aa9fb4c9a176acaf72053b11727436e9e">IsSubsetOf0N</a> (const std::vector< int >&v, int n)</td></tr>
<trclass="memdesc:aa9fb4c9a176acaf72053b11727436e9e"><tdclass="mdescLeft"> </td><tdclass="mdescRight">Returns true iff the given vector is a subset of [0..n-1], i.e. <ahref="#aa9fb4c9a176acaf72053b11727436e9e">More...</a><br/></td></tr>
<trclass="memitem:ad7986b01cf61a31c09a27b4a97db6a83"><tdclass="memItemLeft"align="right"valign="top">bool </td><tdclass="memItemRight"valign="bottom"><aclass="el"href="namespaceutil.html#ad7986b01cf61a31c09a27b4a97db6a83">IsValidPermutation</a> (const std::vector< int >&v)</td></tr>
<trclass="memdesc:ad7986b01cf61a31c09a27b4a97db6a83"><tdclass="mdescLeft"> </td><tdclass="mdescRight">Returns true iff the given vector is a permutation of [0..size()-1]. <ahref="#ad7986b01cf61a31c09a27b4a97db6a83">More...</a><br/></td></tr>
<trclass="memdesc:a8a06031908a024a50dbdddc394a22490"><tdclass="mdescLeft"> </td><tdclass="mdescRight">Returns a copy of "graph", without self-arcs and duplicate arcs. <ahref="#a8a06031908a024a50dbdddc394a22490">More...</a><br/></td></tr>
<trclass="memitem:a06fa201576c927d92657e090fa86bfdb"><tdclass="memTemplItemLeft"align="right"valign="top">void </td><tdclass="memTemplItemRight"valign="bottom"><aclass="el"href="namespaceutil.html#a06fa201576c927d92657e090fa86bfdb">RemoveCyclesFromPath</a> (const <aclass="el"href="namespaceutil.html#ae76339cb2dcd3bc05ad762146f91fdda">Graph</a>&graph, std::vector< int > *arc_path)</td></tr>
<trclass="memdesc:a06fa201576c927d92657e090fa86bfdb"><tdclass="mdescLeft"> </td><tdclass="mdescRight">Given an arc path, changes it to a sub-path with the same source and destination but without any cycle. <ahref="#a06fa201576c927d92657e090fa86bfdb">More...</a><br/></td></tr>
<trclass="memitem:adbb18bcb2f9d64cbbaeb57c328f57e7b"><tdclass="memTemplItemLeft"align="right"valign="top">bool </td><tdclass="memTemplItemRight"valign="bottom"><aclass="el"href="namespaceutil.html#adbb18bcb2f9d64cbbaeb57c328f57e7b">PathHasCycle</a> (const <aclass="el"href="namespaceutil.html#ae76339cb2dcd3bc05ad762146f91fdda">Graph</a>&graph, const std::vector< int >&arc_path)</td></tr>
<trclass="memdesc:adbb18bcb2f9d64cbbaeb57c328f57e7b"><tdclass="mdescLeft"> </td><tdclass="mdescRight">Returns true iff the given path contains a cycle. <ahref="#adbb18bcb2f9d64cbbaeb57c328f57e7b">More...</a><br/></td></tr>
<trclass="memitem:ae469c559688b92f36bae2788c2e6063e"><tdclass="memTemplItemLeft"align="right"valign="top">std::vector< int > </td><tdclass="memTemplItemRight"valign="bottom"><aclass="el"href="namespaceutil.html#ae469c559688b92f36bae2788c2e6063e">ComputeOnePossibleReverseArcMapping</a> (const <aclass="el"href="namespaceutil.html#ae76339cb2dcd3bc05ad762146f91fdda">Graph</a>&graph, bool die_if_not_symmetric)</td></tr>
<trclass="memdesc:ae469c559688b92f36bae2788c2e6063e"><tdclass="mdescLeft"> </td><tdclass="mdescRight">Returns a vector representing a mapping from arcs to arcs such that each arc is mapped to another arc with its (tail, head) flipped, if such an arc exists (otherwise it is mapped to -1). <ahref="#ae469c559688b92f36bae2788c2e6063e">More...</a><br/></td></tr>
<trclass="memdesc:a123e77d101e4aeb54a2b9e7d9612ad1b"><tdclass="mdescLeft"> </td><tdclass="mdescRight">< More complicated error handling. <ahref="#a123e77d101e4aeb54a2b9e7d9612ad1b">More...</a><br/></td></tr>
<trclass="memdesc:aadd7603ae6e78cc2490ca9710fbaf180"><tdclass="mdescLeft"> </td><tdclass="mdescRight">This is useful for wrapping iterators of a class that support many different iterations. <ahref="#aadd7603ae6e78cc2490ca9710fbaf180">More...</a><br/></td></tr>
<divclass="textblock"><p>Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. </p>
<p>Implementations of the method templates.</p>
<p>You may obtain a copy of the License at </p><divclass="fragment"><divclass="line">http:<spanclass="comment">//www.apache.org/licenses/LICENSE-2.0</span></div></div><!-- fragment --><p> Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at </p><divclass="fragment"><divclass="line">http:<spanclass="comment">//www.apache.org/licenses/LICENSE-2.0</span></div></div><!-- fragment --><p> Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Finds the connected components in an undirected graph: <ahref="https://en.wikipedia.org/wiki/Connected_component_(graph_theory)">https://en.wikipedia.org/wiki/Connected_component_(graph_theory)</a></p>
<p>If you have a fixed graph where the node are dense integers, use <aclass="el"href="namespaceutil.html#a13f0e8f7e15873600cf8e395958c71e1"title="Finds the connected components of the graph, using BFS internally.">GetConnectedComponents()</a>: it's very fast and uses little memory.</p>
<p>If you have a more dynamic scenario where you want to incrementally add nodes or edges and query the connectivity between them, use the [Dense]<aclass="el"href="classConnectedComponentsFinder.html"title="Usage: ConnectedComponentsFinder<MyNodeType> cc; cc.AddNode(node1); cc.AddNode(node2); cc....">ConnectedComponentsFinder</a> class, which uses the union-find algorithm aka disjoint sets: <ahref="https://en.wikipedia.org/wiki/Disjoint-set_data_structure">https://en.wikipedia.org/wiki/Disjoint-set_data_structure</a>.</p>
<p>You may obtain a copy of the License at </p><divclass="fragment"><divclass="line">http:<spanclass="comment">//www.apache.org/licenses/LICENSE-2.0</span></div></div><!-- fragment --><p> Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. This file defines a generic graph interface on which most algorithms can be built and provides a few efficient implementations with a fast construction time. Its design is based on the experience acquired by the Operations Research team in their various graph algorithm implementations.</p>
<p>The main ideas are:</p><ul>
<li>Graph nodes and arcs are represented by integers.</li>
<li>Node or arc annotations (weight, cost, ...) are not part of the graph class, they can be stored outside in one or more arrays and can be easily retrieved using a node or arc as an index.</li>
</ul>
<p>Terminology:</p><ul>
<li>An arc of a graph is directed and going from a tail node to a head node.</li>
<li>Some implementations also store 'reverse' arcs and can be used for undirected graph or flow-like algorithm.</li>
<li>A node or arc index is 'valid' if it represents a node or arc of the graph. The validity ranges are always [0, num_nodes()) for nodes and [0, num_arcs()) for forward arcs. Reverse arcs are elements of [-num_arcs(), 0) and are also considered valid by the implementations that store them.</li>
</ul>
<p>Provided implementations:</p><ul>
<li>ListGraph<> for the simplest api. Also aliased to <aclass="el"href="namespaceutil.html#ae76339cb2dcd3bc05ad762146f91fdda"title="Defining the simplest Graph interface as Graph for convenience.">util::Graph</a>.</li>
<li>StaticGraph<> for performance, but require calling Build(), see below</li>
<li>CompleteGraph<> if you need a fully connected graph</li>
<li>CompleteBipartiteGraph<> if you need a fully connected bipartite graph</li>
<li>ReverseArcListGraph<> to add reverse arcs to ListGraph<></li>
<li>ReverseArcStaticGraph<> to add reverse arcs to StaticGraph<></li>
<li>ReverseArcMixedGraph<> for a smaller memory footprint</li>
</ul>
<p>Utility classes & functions:</p><ul>
<li><aclass="el"href="namespaceutil.html#a8c227a057c1ce9d46b1185abf77ad91e">Permute()</a> to permute an array according to a given permutation.</li>
<li>SVector<> vector with index range [-size(), size()) for ReverseArcGraph.</li>
</ul>
<p>Basic usage: typedef ListGraph<> Graph; ///< Choose a graph implementation. Graph graph; for (...) { graph.AddArc(tail, head); } ... for (int node = 0; node < graph.num_nodes(); ++node) { for (const int arc : graph.OutgoingArcs(node)) { head = graph.Head(arc); tail = node; ///< or graph.Tail(arc) which is fast but not as much. } }</p>
<p>Iteration over the arcs touching a node:</p>
<ul>
<li>OutgoingArcs(node): All the forward arcs leaving the node.</li>
<li>IncomingArcs(node): All the forward arcs arriving at the node.</li>
</ul>
<p>And two more involved ones:</p>
<ul>
<li>OutgoingOrOppositeIncomingArcs(node): This returns both the forward arcs leaving the node (i.e. OutgoingArcs(node)) and the reverse arcs leaving the node (i.e. the opposite arcs of the ones returned by IncomingArcs(node)).</li>
<li>OppositeIncomingArcs(node): This returns the reverse arcs leaving the node.</li>
</ul>
<p>Note on iteration efficiency: When re-indexing the arcs it is not possible to have both the outgoing arcs and the incoming ones form a consecutive range.</p>
<p>It is however possible to do so for the outgoing arcs and the opposite incoming arcs. It is why the OutgoingOrOppositeIncomingArcs() and OutgoingArcs() iterations are more efficient than the IncomingArcs() one.</p>
<p>If you know the graph size in advance, this already set the number of nodes, reserve space for the arcs and check in DEBUG mode that you don't go over the bounds: Graph graph(num_nodes, arc_capacity);</p>
<p>Storing and using node annotations: std::vector<bool> is_visited(graph.num_nodes(), false); ... for (int node = 0; node < graph.num_nodes(); ++node) { if (!is_visited[node]) ... }</p>
<p>Storing and using arc annotations: std::vector<int> weights; for (...) { graph.AddArc(tail, head); weights.push_back(arc_weight); } ... for (const int arc : graph.OutgoingArcs(node)) { ... weights[arc] ...; }</p>
<p>More efficient version: typedef StaticGraph<> Graph; Graph graph(num_nodes, arc_capacity); ///< Optional, but help memory usage. std::vector<int> weights; weights.reserve(arc_capacity); ///< Optional, but help memory usage. for (...) { graph.AddArc(tail, head); weights.push_back(arc_weight); } ... std::vector<Graph::ArcIndex> permutation; graph.Build(&permutation); ///< A static graph must be Build() before usage. Permute(permutation, &weights); ///< Build() may permute the arc index. ...</p>
<p>Encoding an undirected graph: If you don't need arc annotation, then the best is to add two arcs for each edge (one in each direction) to a directed graph. Otherwise you can do the following.</p>
<p>typedef ReverseArc... Graph; Graph graph; for (...) { graph.AddArc(tail, head); ///< or graph.AddArc(head, tail) but not both. edge_annotations.push_back(value); } ... for (const <aclass="el"href="classutil_1_1BaseGraph.html#adb271cf4bcf2de5b5bbe300d7054af29"title="Typedef so you can use Graph::NodeIndex and Graph::ArcIndex to be generic but also to improve the rea...">Graph::NodeIndex</a> node : graph.AllNodes()) { for (const <aclass="el"href="classutil_1_1BaseGraph.html#a0eba6e5899924388644dfa2258ae8929">Graph::ArcIndex</a> arc : graph.OutgoingOrOppositeIncomingArcs(node)) { destination = graph.Head(arc); annotation = edge_annotations[arc < 0 ? graph.OppositeArc(arc) : arc]; } }</p>
<dlclass="section note"><dt>Note</dt><dd>The graphs are primarily designed to be constructed first and then used because it covers most of the use cases. It is possible to extend the interface with more dynamicity (like removing arcs), but this is not done at this point. Note that a "dynamic" implementation will break some assumptions we make on what node or arc are valid and also on the indices returned by AddArc(). Some arguments for simplifying the interface at the cost of dynamicity are:</dd></dl>
<ul>
<li>It is always possible to construct a static graph from a dynamic one before calling a complex algo.</li>
<li>If you really need a dynamic graph, maybe it is better to compute a graph property incrementally rather than calling an algorithm that starts from scratch each time.</li>
</ul>
<p>You may obtain a copy of the License at </p><divclass="fragment"><divclass="line">http:<spanclass="comment">//www.apache.org/licenses/LICENSE-2.0</span></div></div><!-- fragment --><p> Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. A collections of i/o utilities for the Graph classes in ./graph.h.</p>
<p>You may obtain a copy of the License at </p><divclass="fragment"><divclass="line">http:<spanclass="comment">//www.apache.org/licenses/LICENSE-2.0</span></div></div><!-- fragment --><p> Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Helper classes to make it easy to implement range-based for loops.</p>
<p>You may obtain a copy of the License at </p><divclass="fragment"><divclass="line">http:<spanclass="comment">//www.apache.org/licenses/LICENSE-2.0</span></div></div><!-- fragment --><p> Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. A collections of utilities for the Graph classes in ./graph.h. </p>
<p>Defining the simplest Graph interface as Graph for convenience. </p>
<pclass="definition">Definition at line <aclass="el"href="graph_8h_source.html#l02358">2358</a> of file <aclass="el"href="graph_8h_source.html">graph.h</a>.</p>
</div>
</div>
<h2class="groupheader">Enumeration Type Documentation</h2>
<p>Returns a std::string representation of a graph. </p>
<tableclass="fieldtable">
<tr><thcolspan="2">Enumerator</th></tr><tr><tdclass="fieldname"><aid="ae705e1342dacc10a13fb3f11f91d0696acac9245da1bf36d1d9382dc579e1a4fd"></a>PRINT_GRAPH_ARCS </td><tdclass="fielddoc"><p>One arc per line, eg. "3->1". </p>
</td></tr>
<tr><tdclass="fieldname"><aid="ae705e1342dacc10a13fb3f11f91d0696aaed5759e3b6e3a8592c9a21e0048b565"></a>PRINT_GRAPH_ADJACENCY_LISTS </td><tdclass="fielddoc"><p>One space-separated adjacency list per line, eg. </p>
<p>"3: 5 1 3 1". Nodes with no outgoing arc get an empty list. </p>
</td></tr>
<tr><tdclass="fieldname"><aid="ae705e1342dacc10a13fb3f11f91d0696a454bb1ede69e280a1e4959acb82748ef"></a>PRINT_GRAPH_ADJACENCY_LISTS_SORTED </td><tdclass="fielddoc"><p>Ditto, but the adjacency lists are sorted. </p>
</td></tr>
</table>
<pclass="definition">Definition at line <aclass="el"href="io_8h_source.html#l00038">38</a> of file <aclass="el"href="io_8h_source.html">io.h</a>.</p>
<p>Returns a vector representing a mapping from arcs to arcs such that each arc is mapped to another arc with its (tail, head) flipped, if such an arc exists (otherwise it is mapped to -1). </p>
<p>If the graph is symmetric, the returned mapping is bijective and reflexive, i.e. out[out[arc]] = arc for all "arc", where "out" is the returned vector. If "die_if_not_symmetric" is true, this function CHECKs() that the graph is symmetric.</p>
<p>Self-arcs are always mapped to themselves.</p>
<dlclass="section note"><dt>Note</dt><dd>since graphs may have multi-arcs, the mapping isn't necessarily unique, hence the function name. </dd></dl>
<p>Special case: directly map any self-arc to itself.</p>
<p>Lookup for the reverse arc of the current one...</p>
<p>Found a reverse arc! Store the mapping and remove the reverse arc from the map.</p>
<p>Reverse arc not in the map. Add the current arc to the map.</p>
<p>Algorithm check, for debugging.</p>
<p>Special case: directly map any self-arc to itself.</p>
<p>Lookup for the reverse arc of the current one...</p>
<p>Found a reverse arc! Store the mapping and remove the reverse arc from the map.</p>
<p>Reverse arc not in the map. Add the current arc to the map.</p>
<p>Algorithm check, for debugging. </p>
<pclass="definition">Definition at line <aclass="el"href="util_8h_source.html#l00382">382</a> of file <aclass="el"href="util_8h_source.html">util.h</a>.</p>
<pclass="definition">Definition at line <aclass="el"href="util_8h_source.html#l00258">258</a> of file <aclass="el"href="util_8h_source.html">util.h</a>.</p>
<p><aclass="el"href="classutil_1_1StaticGraph.html"title="Most efficient implementation of a graph without reverse arcs:">StaticGraph</a> implementation -----------------------------------------------—. </p>
<p><aclass="el"href="classutil_1_1ReverseArcListGraph.html"title="Extends the ListGraph by also storing the reverse arcs.">ReverseArcListGraph</a> implementation ---------------------------------------—. </p>
<p><aclass="el"href="classutil_1_1ReverseArcMixedGraph.html"title="This graph is a mix between the ReverseArcListGraph and the ReverseArcStaticGraph.">ReverseArcMixedGraph</a> implementation --------------------------------------—. </p>
<p>Finds the connected components of the graph, using BFS internally. </p>
<p>Works on any <em>undirected</em> graph class whose nodes are dense integers and that supports the [] operator for adjacency lists: graph[x] must be an integer container listing the nodes that are adjacent to node #x. Example: std::vector<std::vector<int>>.</p>
<p>"Undirected" means that for all y in graph[x], x is in graph[y].</p>
<p>Returns the mapping from node to component index. The component indices are deterministic: Component #0 will be the one that has node #0, component #1 the one that has the lowest-index node that isn't in component #0, and so on.</p>
<p>Example on the following 6-node graph: 5–3–0–1 2–4 std::vector<std::vector<int>> graph = {{1, 3}, {0}, {4}, {0, 5}, {2}, {3}}; GetConnectedComponents(graph); ///< returns [0, 0, 1, 0, 1, 0]. </p>
<pclass="definition">Definition at line <aclass="el"href="connected__components_8h_source.html#l00289">289</a> of file <aclass="el"href="connected__components_8h_source.html">connected_components.h</a>.</p>
<p>Gets the induced subgraph of "graph" restricted to the nodes in "nodes": the resulting graph will have exactly nodes.size() nodes, and its node #0 will be the former graph's node #nodes[0], etc. </p>
<p>See <ahref="https://en.wikipedia.org/wiki/Induced_subgraph">https://en.wikipedia.org/wiki/Induced_subgraph</a> . The "nodes" must be a valid subset (no repetitions) of [0..graph.num_nodes()-1], or the behavior is undefined (it may die). </p><dlclass="section note"><dt>Note</dt><dd>you can call <aclass="el"href="namespaceutil.html#aa9fb4c9a176acaf72053b11727436e9e"title="Returns true iff the given vector is a subset of [0..n-1], i.e.">IsSubsetOf0N()</a> to check it yourself.</dd></dl>
<p>Current complexity: O(num old nodes + num new arcs). It could easily be done in O(num new nodes + num new arcs) but with a higher constant. </p>
<p>Do a first pass to count the arcs, so that we don't allocate more memory than needed.</p>
<p>A second pass where we actually copy the subgraph. NOTE(user): there might seem to be a bit of duplication with <aclass="el"href="namespaceutil.html#acfecdce43e9933bde2a94fd879f12f5f"title="Creates a remapped copy of graph "graph", where node i becomes node new_node_index[i].">RemapGraph()</a>, but there is a key difference: the loop below only iterates on "nodes", which could be much smaller than all the graph's nodes.</p>
<p>Do a first pass to count the arcs, so that we don't allocate more memory than needed.</p>
<p>A second pass where we actually copy the subgraph. NOTE(user): there might seem to be a bit of duplication with <aclass="el"href="namespaceutil.html#acfecdce43e9933bde2a94fd879f12f5f"title="Creates a remapped copy of graph "graph", where node i becomes node new_node_index[i].">RemapGraph()</a>, but there is a key difference: the loop below only iterates on "nodes", which could be much smaller than all the graph's nodes. </p>
<pclass="definition">Definition at line <aclass="el"href="util_8h_source.html#l00290">290</a> of file <aclass="el"href="util_8h_source.html">util.h</a>.</p>
<p>Computes the weakly connected components of a directed graph that provides the OutgoingOrOppositeIncomingArcs() API, and returns them as a mapping from node to component index. </p>
<p>See GetConnectedComponens(). </p>
<pclass="definition">Definition at line <aclass="el"href="util_8h_source.html#l00132">132</a> of file <aclass="el"href="util_8h_source.html">util.h</a>.</p>
<pclass="definition">Definition at line <aclass="el"href="util_8h_source.html#l00195">195</a> of file <aclass="el"href="util_8h_source.html">util.h</a>.</p>
<li>A self-arc is an arc from a node to itself.</li>
<li>We say that an arc A->B is duplicate when there is another arc A->B in the same graph.</li>
<li>A graph is said "weakly connected" if it is connected when considering all arcs as undirected edges.</li>
<li>A graph is said "symmetric" iff for all (a, b), the number of arcs a->b is equal to the number of arcs b->a.</li>
</ul>
<p>All these diagnosis work in O(graph size), since the inverse Ackerman function is <= 5 for all practical instances, and are very fast.</p>
<p>If the graph is a "static" kind, they must be finalized, except for <aclass="el"href="namespaceutil.html#ac4af76993c891ee4ad507783edec2a1c"title="Here's a set of simple diagnosis tools.">GraphHasSelfArcs()</a> and <aclass="el"href="namespaceutil.html#a97311561fd1f01e9f35b2f7ce18b0af3">GraphIsWeaklyConnected()</a> which also support non-finalized StaticGraph<>. </p>
<pclass="definition">Definition at line <aclass="el"href="util_8h_source.html#l00187">187</a> of file <aclass="el"href="util_8h_source.html">util.h</a>.</p>
<p>Compare the graph to its reverse, one adjacency list at a time.</p>
<p>Create a reverse copy of the graph.</p>
<p>Compare the graph to its reverse, one adjacency list at a time. </p>
<pclass="definition">Definition at line <aclass="el"href="util_8h_source.html#l00213">213</a> of file <aclass="el"href="util_8h_source.html">util.h</a>.</p>
<pclass="definition">Definition at line <aclass="el"href="util_8h_source.html#l00242">242</a> of file <aclass="el"href="util_8h_source.html">util.h</a>.</p>
<p>Returns true iff the given vector is a permutation of [0..size()-1]. </p>
<pclass="definition">Definition at line <aclass="el"href="util_8h_source.html#l00143">143</a> of file <aclass="el"href="util_8h_source.html">util.h</a>.</p>
<tdclass="paramtype">const std::vector< int >& </td>
<tdclass="paramname"><em>arc_path</em> </td>
</tr>
<tr>
<td></td>
<td>)</td>
<td></td><td></td>
</tr>
</table>
</div><divclass="memdoc">
<p>Returns true iff the given path contains a cycle. </p>
<pclass="definition">Definition at line <aclass="el"href="util_8h_source.html#l00371">371</a> of file <aclass="el"href="util_8h_source.html">util.h</a>.</p>
<pclass="definition">Definition at line <aclass="el"href="graph_8h_source.html#l00737">737</a> of file <aclass="el"href="graph_8h_source.html">graph.h</a>.</p>
<p>We need a specialization for std::vector<bool>, because the default code uses (*array_to_permute)[0] as ElementType, which isn't 'bool' in that case. </p>
<pclass="definition">Definition at line <aclass="el"href="graph_8h_source.html#l00748">748</a> of file <aclass="el"href="graph_8h_source.html">graph.h</a>.</p>
<dlclass="todo"><dt><b><aclass="el"href="todo.html#_todo000012">Todo:</a></b></dt><dd>(user): consider slower but more memory efficient implementations that follow the cycles of the permutation and use a bitmap to indicate what has been permuted or to mark the beginning of each cycle. </dd></dl>
<p>Some compiler do not know typeof(), so we have to use this extra function internally. </p>
<pclass="definition">Definition at line <aclass="el"href="graph_8h_source.html#l00724">724</a> of file <aclass="el"href="graph_8h_source.html">graph.h</a>.</p>
<p>if (!SplitStringAndParse(line, " ", &absl::SimpleAtoi, &header_ints) || header_ints.size() < 2 || header_ints[0] < 0 || header_ints[1] < 0) { return util::Status( util::error::INVALID_ARGUMENT, absl::StrCat("First line of '", filename, "' should be at least two nonnegative integers.")); }</p>
<p>No coloring: all the nodes have the same color.</p>
<p>We don't add superfluous arcs to the graph, but we still keep reading the file, to get better error messages: we want to know the actual number of lines, and also want to check the validity of the superfluous arcs (i.e. that their src/dst nodes are ok). </p>
<pclass="definition">Definition at line <aclass="el"href="io_8h_source.html#l00132">132</a> of file <aclass="el"href="io_8h_source.html">io.h</a>.</p>
<p>if (!SplitStringAndParse(line, " ", &absl::SimpleAtoi, &header_ints) || header_ints.size() < 2 || header_ints[0] < 0 || header_ints[1] < 0) { return util::Status( util::error::INVALID_ARGUMENT, absl::StrCat("First line of '", filename, "' should be at least two nonnegative integers.")); }</p>
<p>No coloring: all the nodes have the same color.</p>
<p>We don't add superfluous arcs to the graph, but we still keep reading the file, to get better error messages: we want to know the actual number of lines, and also want to check the validity of the superfluous arcs (i.e. that their src/dst nodes are ok). </p>
<pclass="definition">Definition at line <aclass="el"href="io_8h_source.html#l00132">132</a> of file <aclass="el"href="io_8h_source.html">io.h</a>.</p>
<p>Creates a remapped copy of graph "graph", where node i becomes node new_node_index[i]. </p>
<p>"new_node_index" must be a valid permutation of [0..num_nodes-1] or the behavior is undefined (it may die). </p><dlclass="section note"><dt>Note</dt><dd>you can call <aclass="el"href="namespaceutil.html#ad7986b01cf61a31c09a27b4a97db6a83"title="Returns true iff the given vector is a permutation of [0..size()-1].">IsValidPermutation()</a> to check it yourself. </dd></dl>
<pclass="definition">Definition at line <aclass="el"href="util_8h_source.html#l00271">271</a> of file <aclass="el"href="util_8h_source.html">util.h</a>.</p>
<tdclass="paramtype">std::vector< int > * </td>
<tdclass="paramname"><em>arc_path</em> </td>
</tr>
<tr>
<td></td>
<td>)</td>
<td></td><td></td>
</tr>
</table>
</div><divclass="memdoc">
<p>Given an arc path, changes it to a sub-path with the same source and destination but without any cycle. </p>
<p>Nothing happen if the path was already without cycle.</p>
<p>The graph class should support Tail(arc) and Head(arc). They should both return an integer representing the corresponding tail/head of the passed arc.</p>
<dlclass="todo"><dt><b><aclass="el"href="todo.html#_todo000054">Todo:</a></b></dt><dd>(user): In some cases, there is more than one possible solution. We could take some arc costs and return the cheapest path instead. Or return the shortest path in term of number of arcs. </dd></dl>
<p>This maps each node to the latest arc in the given path that leaves it.</p>
<p>Special case for the destination. </p><dlclass="section note"><dt>Note</dt><dd>this requires that -1 is not a valid arc of Graph.</dd></dl>
<p>Reconstruct the path by starting at the source and then following the "next" arcs. We override the given arc_path at the same time.</p>
<p>This maps each node to the latest arc in the given path that leaves it.</p>
<p>Special case for the destination. </p><dlclass="section note"><dt>Note</dt><dd>this requires that -1 is not a valid arc of Graph.</dd></dl>
<p>Reconstruct the path by starting at the source and then following the "next" arcs. We override the given arc_path at the same time. </p>
<pclass="definition">Definition at line <aclass="el"href="util_8h_source.html#l00346">346</a> of file <aclass="el"href="util_8h_source.html">util.h</a>.</p>
<p>Returns a copy of "graph", without self-arcs and duplicate arcs. </p>
<pclass="definition">Definition at line <aclass="el"href="util_8h_source.html#l00324">324</a> of file <aclass="el"href="util_8h_source.html">util.h</a>.</p>
<p>Read a graph file in the simple ".g" format: the file should be a text file containing only space-separated integers, whose first line is: <num nodes>=""><num edges>=""> [<num_colors><index of first node with color #1><index of first node with color #2> ...] and whose subsequent lines represent edges if "directed" is false, or arcs if "directed" is true: <node1><node2>. </p>
<p>This returns a newly created graph upon success, which the user needs to take ownership of, or a failure status. See ortools/base/statusor.h.</p>
<p>If "num_nodes_with_color_or_null" is not nullptr, it will be filled with the color information: num_nodes_with_color_or_null[i] will be the number of nodes with color #i. Furthermore, nodes are sorted by color.</p>
<p>Examples: ///< Simply crash if the graph isn't successfully read from the file. typedef StaticGraph<> MyGraph; ///< This is just an example. std::unique_ptr<MyGraph> my_graph( ReadGraphFile<MyGraph>("graph.g", /*directed= </p>
<p>Writes a graph to the ".g" file format described above. </p>
<p>If "directed" is true, all arcs are written to the file. If it is false, the graph is expected to be undirected (i.e. the number of arcs a->b is equal to the number of arcs b->a for all nodes a,b); and only the arcs a->b where a<=b are written. Note however that in this case, the symmetry of the graph is not fully checked (only the parity of the number of non-self arcs is).</p>
<p>"num_nodes_with_color" is optional. If it is not empty, then the color information will be written to the header of the .g file. See ReadGraphFile.</p>
<p>This method is the reverse of ReadGraphFile (with the same value for "directed"). </p>
<p>In undirected mode, we must count the self-arcs separately. All other arcs should be duplicated.</p>
<p>In undirected mode, we must count the self-arcs separately. All other arcs should be duplicated. </p>
<pclass="definition">Definition at line <aclass="el"href="io_8h_source.html#l00223">223</a> of file <aclass="el"href="io_8h_source.html">io.h</a>.</p>
<pclass="definition">Definition at line <aclass="el"href="iterators_8h_source.html#l00030">30</a> of file <aclass="el"href="iterators_8h_source.html">iterators.h</a>.</p>
<pclass="definition">Definition at line <aclass="el"href="iterators_8h_source.html#l00031">31</a> of file <aclass="el"href="iterators_8h_source.html">iterators.h</a>.</p>