Classes | Typedefs | Enumerations | Functions | Variables
util Namespace Reference

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. More...

Classes

class  BaseGraph
 Base class of all Graphs implemented here. More...
 
class  CompleteBipartiteGraph
 CompleteBipartiteGraph implementation ------------------------------------— Nodes and arcs are implicit and not stored. More...
 
class  CompleteGraph
 CompleteGraph implementation ---------------------------------------------— Nodes and arcs are implicit and not stored. More...
 
class  ListGraph
 Basic graph implementation without reverse arc. More...
 
class  ReverseArcListGraph
 Extends the ListGraph by also storing the reverse arcs. More...
 
class  ReverseArcMixedGraph
 This graph is a mix between the ReverseArcListGraph and the ReverseArcStaticGraph. More...
 
class  ReverseArcStaticGraph
 StaticGraph with reverse arc. More...
 
class  StaticGraph
 Most efficient implementation of a graph without reverse arcs: More...
 
class  SVector
 Forward declaration. More...
 
class  UndirectedAdjacencyListsOfDirectedGraph
 This can be used to view a directed graph (that supports reverse arcs) from graph.h as un undirected graph: operator[](node) returns a pseudo-container that iterates over all nodes adjacent to "node" (from outgoing or incoming arcs). More...
 

Typedefs

typedef ListGraph Graph
 Defining the simplest Graph interface as Graph for convenience. More...
 

Enumerations

enum  GraphToStringFormat { PRINT_GRAPH_ARCS, PRINT_GRAPH_ADJACENCY_LISTS, PRINT_GRAPH_ADJACENCY_LISTS_SORTED }
 Returns a std::string representation of a graph. More...
 

Functions

template<class UndirectedGraph >
std::vector< int > GetConnectedComponents (int num_nodes, const UndirectedGraph &graph)
 Finds the connected components of the graph, using BFS internally. More...
 
template<class IntVector , class Array , class ElementType >
void PermuteWithExplicitElementType (const IntVector &permutation, Array *array_to_permute, ElementType unused)
 Permutes the elements of array_to_permute: element #i will be moved to position permutation[i]. More...
 
template<class IntVector , class Array >
void Permute (const IntVector &permutation, Array *array_to_permute)
 
template<class IntVector >
void Permute (const IntVector &permutation, std::vector< bool > *array_to_permute)
 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. More...
 
 DEFINE_RANGE_BASED_ARC_ITERATION (ListGraph, Outgoing, Base::kNilArc)
 ListGraph implementation -------------------------------------------------—. More...
 
 DEFINE_RANGE_BASED_ARC_ITERATION (StaticGraph, Outgoing, DirectArcLimit(node))
 StaticGraph implementation -----------------------------------------------—. More...
 
 DEFINE_RANGE_BASED_ARC_ITERATION (ReverseArcListGraph, Outgoing, Base::kNilArc)
 ReverseArcListGraph implementation ---------------------------------------—. More...
 
 DEFINE_RANGE_BASED_ARC_ITERATION (ReverseArcListGraph, Incoming, Base::kNilArc)
 
 DEFINE_RANGE_BASED_ARC_ITERATION (ReverseArcListGraph, OutgoingOrOppositeIncoming, Base::kNilArc)
 
 DEFINE_RANGE_BASED_ARC_ITERATION (ReverseArcListGraph, OppositeIncoming, Base::kNilArc)
 
 DEFINE_RANGE_BASED_ARC_ITERATION (ReverseArcStaticGraph, Outgoing, DirectArcLimit(node))
 ReverseArcStaticGraph implementation -------------------------------------—. More...
 
 DEFINE_RANGE_BASED_ARC_ITERATION (ReverseArcStaticGraph, Incoming, ReverseArcLimit(node))
 
 DEFINE_RANGE_BASED_ARC_ITERATION (ReverseArcStaticGraph, OutgoingOrOppositeIncoming, DirectArcLimit(node))
 
 DEFINE_RANGE_BASED_ARC_ITERATION (ReverseArcStaticGraph, OppositeIncoming, ReverseArcLimit(node))
 
 DEFINE_RANGE_BASED_ARC_ITERATION (ReverseArcMixedGraph, Outgoing, DirectArcLimit(node))
 ReverseArcMixedGraph implementation --------------------------------------—. More...
 
 DEFINE_RANGE_BASED_ARC_ITERATION (ReverseArcMixedGraph, Incoming, Base::kNilArc)
 
 DEFINE_RANGE_BASED_ARC_ITERATION (ReverseArcMixedGraph, OutgoingOrOppositeIncoming, DirectArcLimit(node))
 
 DEFINE_RANGE_BASED_ARC_ITERATION (ReverseArcMixedGraph, OppositeIncoming, Base::kNilArc)
 
template<class Graph >
std::string GraphToString (const Graph &graph, GraphToStringFormat format)
 Implementations of the templated methods. More...
 
false ValueOrDie ())
 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>. More...
 
if (!error_or_graph.ok())
 
template<class Graph >
***util::StatusOr< Graph * > ReadGraphFile (const std::string &filename, bool directed, std::vector< int > *num_nodes_with_color_or_null)
 
template<class Graph >
util::Status WriteGraphToFile (const Graph &graph, const std::string &filename, bool directed, const std::vector< int > &num_nodes_with_color)
 Writes a graph to the ".g" file format described above. More...
 
template<class Graph >
util::StatusOr< Graph * > ReadGraphFile (const std::string &filename, bool directed, std::vector< int > *num_nodes_with_color_or_null)
 
template<class Graph >
bool GraphHasSelfArcs (const Graph &graph)
 Here's a set of simple diagnosis tools. More...
 
template<class Graph >
bool GraphHasDuplicateArcs (const Graph &graph)
 
template<class Graph >
bool GraphIsSymmetric (const Graph &graph)
 
template<class Graph >
bool GraphIsWeaklyConnected (const Graph &graph)
 
template<class Graph >
std::unique_ptr< GraphCopyGraph (const Graph &graph)
 Returns a fresh copy of a given graph. More...
 
template<class Graph >
std::unique_ptr< GraphRemapGraph (const Graph &graph, const std::vector< int > &new_node_index)
 Creates a remapped copy of graph "graph", where node i becomes node new_node_index[i]. More...
 
template<class Graph >
std::unique_ptr< GraphGetSubgraphOfNodes (const Graph &graph, const std::vector< int > &nodes)
 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. More...
 
template<class Graph >
std::vector< int > GetWeaklyConnectedComponents (const Graph &graph)
 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. More...
 
bool IsSubsetOf0N (const std::vector< int > &v, int n)
 Returns true iff the given vector is a subset of [0..n-1], i.e. More...
 
bool IsValidPermutation (const std::vector< int > &v)
 Returns true iff the given vector is a permutation of [0..size()-1]. More...
 
template<class Graph >
std::unique_ptr< GraphRemoveSelfArcsAndDuplicateArcs (const Graph &graph)
 Returns a copy of "graph", without self-arcs and duplicate arcs. More...
 
template<class Graph >
void RemoveCyclesFromPath (const Graph &graph, std::vector< int > *arc_path)
 Given an arc path, changes it to a sub-path with the same source and destination but without any cycle. More...
 
template<class Graph >
bool PathHasCycle (const Graph &graph, const std::vector< int > &arc_path)
 Returns true iff the given path contains a cycle. More...
 
template<class Graph >
std::vector< int > ComputeOnePossibleReverseArcMapping (const Graph &graph, bool die_if_not_symmetric)
 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). More...
 

Variables

***util::StatusOr< MyGraph * > error_or_graph
 < More complicated error handling. More...
 
 else
 
 false
 This is useful for wrapping iterators of a class that support many different iterations. More...
 
*OutgoingArcIterator this
 

Detailed Description

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.

Implementations of the method templates.

You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

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

http://www.apache.org/licenses/LICENSE-2.0

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: https://en.wikipedia.org/wiki/Connected_component_(graph_theory)

If you have a fixed graph where the node are dense integers, use GetConnectedComponents(): it's very fast and uses little memory.

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]ConnectedComponentsFinder class, which uses the union-find algorithm aka disjoint sets: https://en.wikipedia.org/wiki/Disjoint-set_data_structure.

You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

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.

The main ideas are:

Terminology:

Provided implementations:

Utility classes & functions:

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. } }

Iteration over the arcs touching a node:

And two more involved ones:

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.

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.

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);

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]) ... }

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] ...; }

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. ...

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.

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 Graph::NodeIndex node : graph.AllNodes()) { for (const Graph::ArcIndex arc : graph.OutgoingOrOppositeIncomingArcs(node)) { destination = graph.Head(arc); annotation = edge_annotations[arc < 0 ? graph.OppositeArc(arc) : arc]; } }

Note
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:

You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

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.

You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

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.

You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

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.

Typedef Documentation

◆ Graph

Defining the simplest Graph interface as Graph for convenience.

Definition at line 2358 of file graph.h.

Enumeration Type Documentation

◆ GraphToStringFormat

Returns a std::string representation of a graph.

Enumerator
PRINT_GRAPH_ARCS 

One arc per line, eg. "3->1".

PRINT_GRAPH_ADJACENCY_LISTS 

One space-separated adjacency list per line, eg.

"3: 5 1 3 1". Nodes with no outgoing arc get an empty list.

PRINT_GRAPH_ADJACENCY_LISTS_SORTED 

Ditto, but the adjacency lists are sorted.

Definition at line 38 of file io.h.

Function Documentation

◆ ComputeOnePossibleReverseArcMapping()

template<class Graph >
std::vector< int > util::ComputeOnePossibleReverseArcMapping ( const Graph graph,
bool  die_if_not_symmetric 
)

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).

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.

Self-arcs are always mapped to themselves.

Note
since graphs may have multi-arcs, the mapping isn't necessarily unique, hence the function name.

Special case: directly map any self-arc to itself.

Lookup for the reverse arc of the current one...

Found a reverse arc! Store the mapping and remove the reverse arc from the map.

Reverse arc not in the map. Add the current arc to the map.

Algorithm check, for debugging.

Special case: directly map any self-arc to itself.

Lookup for the reverse arc of the current one...

Found a reverse arc! Store the mapping and remove the reverse arc from the map.

Reverse arc not in the map. Add the current arc to the map.

Algorithm check, for debugging.

Definition at line 382 of file util.h.

◆ CopyGraph()

template<class Graph >
std::unique_ptr< Graph > util::CopyGraph ( const Graph graph)

Returns a fresh copy of a given graph.

Definition at line 258 of file util.h.

◆ DEFINE_RANGE_BASED_ARC_ITERATION() [1/14]

util::DEFINE_RANGE_BASED_ARC_ITERATION ( ListGraph  ,
Outgoing  ,
Base::kNilArc   
)

ListGraph implementation -------------------------------------------------—.

◆ DEFINE_RANGE_BASED_ARC_ITERATION() [2/14]

util::DEFINE_RANGE_BASED_ARC_ITERATION ( StaticGraph  ,
Outgoing  ,
DirectArcLimit(node)   
)

StaticGraph implementation -----------------------------------------------—.

◆ DEFINE_RANGE_BASED_ARC_ITERATION() [3/14]

util::DEFINE_RANGE_BASED_ARC_ITERATION ( ReverseArcListGraph  ,
Outgoing  ,
Base::kNilArc   
)

ReverseArcListGraph implementation ---------------------------------------—.

◆ DEFINE_RANGE_BASED_ARC_ITERATION() [4/14]

util::DEFINE_RANGE_BASED_ARC_ITERATION ( ReverseArcListGraph  ,
Incoming  ,
Base::kNilArc   
)

◆ DEFINE_RANGE_BASED_ARC_ITERATION() [5/14]

util::DEFINE_RANGE_BASED_ARC_ITERATION ( ReverseArcListGraph  ,
OutgoingOrOppositeIncoming  ,
Base::kNilArc   
)

◆ DEFINE_RANGE_BASED_ARC_ITERATION() [6/14]

util::DEFINE_RANGE_BASED_ARC_ITERATION ( ReverseArcListGraph  ,
OppositeIncoming  ,
Base::kNilArc   
)

◆ DEFINE_RANGE_BASED_ARC_ITERATION() [7/14]

util::DEFINE_RANGE_BASED_ARC_ITERATION ( ReverseArcStaticGraph  ,
Outgoing  ,
DirectArcLimit(node)   
)

ReverseArcStaticGraph implementation -------------------------------------—.

◆ DEFINE_RANGE_BASED_ARC_ITERATION() [8/14]

util::DEFINE_RANGE_BASED_ARC_ITERATION ( ReverseArcStaticGraph  ,
Incoming  ,
ReverseArcLimit(node)   
)

◆ DEFINE_RANGE_BASED_ARC_ITERATION() [9/14]

util::DEFINE_RANGE_BASED_ARC_ITERATION ( ReverseArcStaticGraph  ,
OutgoingOrOppositeIncoming  ,
DirectArcLimit(node)   
)

◆ DEFINE_RANGE_BASED_ARC_ITERATION() [10/14]

util::DEFINE_RANGE_BASED_ARC_ITERATION ( ReverseArcStaticGraph  ,
OppositeIncoming  ,
ReverseArcLimit(node)   
)

◆ DEFINE_RANGE_BASED_ARC_ITERATION() [11/14]

util::DEFINE_RANGE_BASED_ARC_ITERATION ( ReverseArcMixedGraph  ,
Outgoing  ,
DirectArcLimit(node)   
)

ReverseArcMixedGraph implementation --------------------------------------—.

◆ DEFINE_RANGE_BASED_ARC_ITERATION() [12/14]

util::DEFINE_RANGE_BASED_ARC_ITERATION ( ReverseArcMixedGraph  ,
Incoming  ,
Base::kNilArc   
)

◆ DEFINE_RANGE_BASED_ARC_ITERATION() [13/14]

util::DEFINE_RANGE_BASED_ARC_ITERATION ( ReverseArcMixedGraph  ,
OutgoingOrOppositeIncoming  ,
DirectArcLimit(node)   
)

◆ DEFINE_RANGE_BASED_ARC_ITERATION() [14/14]

util::DEFINE_RANGE_BASED_ARC_ITERATION ( ReverseArcMixedGraph  ,
OppositeIncoming  ,
Base::kNilArc   
)

◆ GetConnectedComponents()

template<class UndirectedGraph >
std::vector< int > util::GetConnectedComponents ( int  num_nodes,
const UndirectedGraph &  graph 
)

Finds the connected components of the graph, using BFS internally.

Works on any undirected 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>>.

"Undirected" means that for all y in graph[x], x is in graph[y].

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.

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].

Definition at line 289 of file connected_components.h.

◆ GetSubgraphOfNodes()

template<class Graph >
std::unique_ptr< Graph > util::GetSubgraphOfNodes ( const Graph graph,
const std::vector< int > &  nodes 
)

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.

See https://en.wikipedia.org/wiki/Induced_subgraph . The "nodes" must be a valid subset (no repetitions) of [0..graph.num_nodes()-1], or the behavior is undefined (it may die).

Note
you can call IsSubsetOf0N() to check it yourself.

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.

Do a first pass to count the arcs, so that we don't allocate more memory than needed.

A second pass where we actually copy the subgraph. NOTE(user): there might seem to be a bit of duplication with RemapGraph(), but there is a key difference: the loop below only iterates on "nodes", which could be much smaller than all the graph's nodes.

Do a first pass to count the arcs, so that we don't allocate more memory than needed.

A second pass where we actually copy the subgraph. NOTE(user): there might seem to be a bit of duplication with RemapGraph(), but there is a key difference: the loop below only iterates on "nodes", which could be much smaller than all the graph's nodes.

Definition at line 290 of file util.h.

◆ GetWeaklyConnectedComponents()

template<class Graph >
std::vector<int> util::GetWeaklyConnectedComponents ( const Graph graph)

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.

See GetConnectedComponens().

Definition at line 132 of file util.h.

◆ GraphHasDuplicateArcs()

template<class Graph >
bool util::GraphHasDuplicateArcs ( const Graph graph)

Definition at line 195 of file util.h.

◆ GraphHasSelfArcs()

template<class Graph >
bool util::GraphHasSelfArcs ( const Graph graph)

Here's a set of simple diagnosis tools.

Implementations of the templated methods.

Notes:

  • A self-arc is an arc from a node to itself.
  • We say that an arc A->B is duplicate when there is another arc A->B in the same graph.
  • A graph is said "weakly connected" if it is connected when considering all arcs as undirected edges.
  • 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.

All these diagnosis work in O(graph size), since the inverse Ackerman function is <= 5 for all practical instances, and are very fast.

If the graph is a "static" kind, they must be finalized, except for GraphHasSelfArcs() and GraphIsWeaklyConnected() which also support non-finalized StaticGraph<>.

Definition at line 187 of file util.h.

◆ GraphIsSymmetric()

template<class Graph >
bool util::GraphIsSymmetric ( const Graph graph)

Create a reverse copy of the graph.

Compare the graph to its reverse, one adjacency list at a time.

Create a reverse copy of the graph.

Compare the graph to its reverse, one adjacency list at a time.

Definition at line 213 of file util.h.

◆ GraphIsWeaklyConnected()

template<class Graph >
bool util::GraphIsWeaklyConnected ( const Graph graph)

Definition at line 242 of file util.h.

◆ GraphToString()

template<class Graph >
std::string util::GraphToString ( const Graph graph,
GraphToStringFormat  format 
)

Implementations of the templated methods.

Definition at line 107 of file io.h.

◆ if()

* util::if ( !error_or_graph.  ok())

Definition at line 76 of file io.h.

◆ IsSubsetOf0N()

bool util::IsSubsetOf0N ( const std::vector< int > &  v,
int  n 
)

Returns true iff the given vector is a subset of [0..n-1], i.e.

all elements i are such that 0 <= i < n and no two elements are equal. "n" must be >= 0 or the result is undefined.

◆ IsValidPermutation()

bool util::IsValidPermutation ( const std::vector< int > &  v)
inline

Returns true iff the given vector is a permutation of [0..size()-1].

Definition at line 143 of file util.h.

◆ PathHasCycle()

template<class Graph >
bool util::PathHasCycle ( const Graph graph,
const std::vector< int > &  arc_path 
)

Returns true iff the given path contains a cycle.

Definition at line 371 of file util.h.

◆ Permute() [1/2]

template<class IntVector , class Array >
void util::Permute ( const IntVector &  permutation,
Array *  array_to_permute 
)

Definition at line 737 of file graph.h.

◆ Permute() [2/2]

template<class IntVector >
void util::Permute ( const IntVector &  permutation,
std::vector< bool > *  array_to_permute 
)

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.

Definition at line 748 of file graph.h.

◆ PermuteWithExplicitElementType()

template<class IntVector , class Array , class ElementType >
void util::PermuteWithExplicitElementType ( const IntVector &  permutation,
Array *  array_to_permute,
ElementType  unused 
)

Permutes the elements of array_to_permute: element #i will be moved to position permutation[i].

permutation must be either empty (in which case nothing happens), or a permutation of [0, permutation.size()).

The algorithm is fast but need extra memory for a copy of the permuted part of array_to_permute.

Todo:
(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.

Some compiler do not know typeof(), so we have to use this extra function internally.

Definition at line 724 of file graph.h.

◆ ReadGraphFile() [1/2]

template<class Graph >
* * * util::StatusOr<Graph*> util::ReadGraphFile ( const std::string &  filename,
bool  directed,
std::vector< int > *  num_nodes_with_color_or_null 
)

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.")); }

No coloring: all the nodes have the same color.

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).

Definition at line 132 of file io.h.

◆ ReadGraphFile() [2/2]

template<class Graph >
util::StatusOr<Graph*> util::ReadGraphFile ( const std::string &  filename,
bool  directed,
std::vector< int > *  num_nodes_with_color_or_null 
)

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.")); }

No coloring: all the nodes have the same color.

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).

Definition at line 132 of file io.h.

◆ RemapGraph()

template<class Graph >
std::unique_ptr< Graph > util::RemapGraph ( const Graph graph,
const std::vector< int > &  new_node_index 
)

Creates a remapped copy of graph "graph", where node i becomes node new_node_index[i].

"new_node_index" must be a valid permutation of [0..num_nodes-1] or the behavior is undefined (it may die).

Note
you can call IsValidPermutation() to check it yourself.

Definition at line 271 of file util.h.

◆ RemoveCyclesFromPath()

template<class Graph >
void util::RemoveCyclesFromPath ( const Graph graph,
std::vector< int > *  arc_path 
)

Given an arc path, changes it to a sub-path with the same source and destination but without any cycle.

Nothing happen if the path was already without cycle.

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.

Todo:
(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.

This maps each node to the latest arc in the given path that leaves it.

Special case for the destination.

Note
this requires that -1 is not a valid arc of Graph.

Reconstruct the path by starting at the source and then following the "next" arcs. We override the given arc_path at the same time.

This maps each node to the latest arc in the given path that leaves it.

Special case for the destination.

Note
this requires that -1 is not a valid arc of Graph.

Reconstruct the path by starting at the source and then following the "next" arcs. We override the given arc_path at the same time.

Definition at line 346 of file util.h.

◆ RemoveSelfArcsAndDuplicateArcs()

template<class Graph >
std::unique_ptr< Graph > util::RemoveSelfArcsAndDuplicateArcs ( const Graph graph)

Returns a copy of "graph", without self-arcs and duplicate arcs.

Definition at line 324 of file util.h.

◆ ValueOrDie()

false util::ValueOrDie ( )

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>.

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.

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.

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=

◆ WriteGraphToFile()

template<class Graph >
util::Status util::WriteGraphToFile ( const Graph graph,
const std::string &  filename,
bool  directed,
const std::vector< int > &  num_nodes_with_color 
)

Writes a graph to the ".g" file format described above.

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).

"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.

This method is the reverse of ReadGraphFile (with the same value for "directed").

In undirected mode, we must count the self-arcs separately. All other arcs should be duplicated.

In undirected mode, we must count the self-arcs separately. All other arcs should be duplicated.

Definition at line 223 of file io.h.

Variable Documentation

◆ else

util::else
Initial value:
{
* std::unique_ptr<MyGraph> my_graph(error_or_graph.ValueOrDie())
***util::StatusOr< MyGraph * > error_or_graph
< More complicated error handling.
Definition: io.h:74

Definition at line 78 of file io.h.

◆ error_or_graph

* * * util::StatusOr<MyGraph*> util::error_or_graph
Initial value:
=
* ReadGraphFile<MyGraph>("graph.g", false)

< More complicated error handling.

Definition at line 74 of file io.h.

◆ false

util::false

This is useful for wrapping iterators of a class that support many different iterations.

For instance, on a Graph class, one can write:

BeginEndWrapper<OutgoingArcIterator> Graph::OutgoingArcs(NodeInde node) const { return BeginEndRange( OutgoingArcIterator(*this, node, /*at_end=

Definition at line 30 of file iterators.h.

◆ this

* OutgoingArcIterator util::this

Definition at line 31 of file iterators.h.