Google OR-Tools v9.11
a fast and portable software suite for combinatorial optimization
|
A collections of i/o utilities for the Graph classes in ./graph.h. More...
Namespaces | |
namespace | graph |
namespace | internal |
Classes | |
class | BaseGraph |
class | BeginEndReverseIteratorWrapper |
class | BeginEndWrapper |
class | CompleteBipartiteGraph |
class | CompleteGraph |
class | IntegerRange |
class | IntegerRangeIterator |
Simple iterator on an integer range, see IntegerRange below. More... | |
class | ListGraph |
struct | MutableVectorIteration |
Allow iterating over a vector<T> as a mutable vector<T*>. More... | |
class | ReverseArcListGraph |
class | ReverseArcMixedGraph |
class | ReverseArcStaticGraph |
class | StaticGraph |
class | StatusBuilder |
class | SVector |
Forward declaration. More... | |
class | TopologicalSorter |
class | UndirectedAdjacencyListsOfDirectedGraph |
Typedefs | |
typedef ListGraph | Graph |
Defining the simplest Graph interface as Graph for convenience. | |
typedef ::util::internal::DenseIntTopologicalSorterTpl< true > | DenseIntStableTopologicalSorter |
typedef ::util::internal::DenseIntTopologicalSorterTpl< false > | DenseIntTopologicalSorter |
Enumerations | |
enum | GraphToStringFormat { PRINT_GRAPH_ARCS , PRINT_GRAPH_ADJACENCY_LISTS , PRINT_GRAPH_ADJACENCY_LISTS_SORTED } |
Returns a string representation of a graph. More... | |
Functions | |
StatusBuilder | AbortedErrorBuilder () |
StatusBuilder | AlreadyExistsErrorBuilder () |
StatusBuilder | CancelledErrorBuilder () |
StatusBuilder | DataLossErrorBuilder () |
StatusBuilder | DeadlineExceededErrorBuilder () |
StatusBuilder | FailedPreconditionErrorBuilder () |
StatusBuilder | InternalErrorBuilder () |
StatusBuilder | InvalidArgumentErrorBuilder () |
StatusBuilder | NotFoundErrorBuilder () |
StatusBuilder | OutOfRangeErrorBuilder () |
StatusBuilder | PermissionDeniedErrorBuilder () |
StatusBuilder | UnauthenticatedErrorBuilder () |
StatusBuilder | ResourceExhaustedErrorBuilder () |
StatusBuilder | UnavailableErrorBuilder () |
StatusBuilder | UnimplementedErrorBuilder () |
StatusBuilder | UnknownErrorBuilder () |
template<class UndirectedGraph , class NodeType > | |
std::vector< NodeType > | GetConnectedComponentsTpl (NodeType num_nodes, const UndirectedGraph &graph) |
template<class UndirectedGraph > | |
std::vector< int > | GetConnectedComponents (int num_nodes, const UndirectedGraph &graph) |
template<class IntVector , class Array , class ElementType > | |
void | PermuteWithExplicitElementType (const IntVector &permutation, Array *array_to_permute, ElementType unused) |
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) |
DEFINE_RANGE_BASED_ARC_ITERATION (ListGraph, Outgoing, Base::kNilArc) | |
ListGraph implementation -------------------------------------------------—. | |
DEFINE_RANGE_BASED_ARC_ITERATION (StaticGraph, Outgoing, DirectArcLimit(node)) | |
DEFINE_RANGE_BASED_ARC_ITERATION (ReverseArcListGraph, Outgoing, Base::kNilArc) | |
ReverseArcListGraph implementation ---------------------------------------—. | |
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 -------------------------------------—. | |
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 --------------------------------------—. | |
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. | |
template<class Graph > | |
absl::Status | WriteGraphToFile (const Graph &graph, const std::string &filename, bool directed, absl::Span< const int > num_nodes_with_color) |
template<typename Iterator > | |
BeginEndWrapper< Iterator > | BeginEndRange (Iterator begin, Iterator end) |
template<typename Iterator > | |
BeginEndWrapper< Iterator > | BeginEndRange (std::pair< Iterator, Iterator > begin_end) |
template<typename MultiMap > | |
BeginEndWrapper< typename MultiMap::iterator > | EqualRange (MultiMap &multi_map, const typename MultiMap::key_type &key) |
template<typename MultiMap > | |
BeginEndWrapper< typename MultiMap::const_iterator > | EqualRange (const MultiMap &multi_map, const typename MultiMap::key_type &key) |
template<typename Container > | |
BeginEndReverseIteratorWrapper< Container > | Reverse (const Container &c) |
std::unique_ptr< StaticGraph<> > | GenerateRandomMultiGraph (int num_nodes, int num_arcs, bool finalized, absl::BitGenRef gen) |
std::unique_ptr< StaticGraph<> > | GenerateRandomDirectedSimpleGraph (int num_nodes, int num_arcs, bool finalized, absl::BitGenRef gen) |
std::unique_ptr< StaticGraph<> > | GenerateRandomUndirectedSimpleGraph (int num_nodes, int num_edges, bool finalized, absl::BitGenRef gen) |
template<typename T > | |
ABSL_MUST_USE_RESULT bool | TopologicalSort (const std::vector< T > &nodes, const std::vector< std::pair< T, T > > &arcs, std::vector< T > *topological_order) |
template<typename T > | |
ABSL_MUST_USE_RESULT bool | TopologicalSort (const std::vector< T > &nodes, const std::vector< std::pair< T, T > > &arcs, std::vector< T > *topological_order, std::vector< T > *cycle) |
Override of the above that outputs the detected cycle. | |
template<typename T > | |
std::vector< T > | TopologicalSortOrDie (const std::vector< T > &nodes, const std::vector< std::pair< T, T > > &arcs) |
OrDie() variant of the above. | |
template<typename T > | |
ABSL_MUST_USE_RESULT bool | StableTopologicalSort (const std::vector< T > &nodes, const std::vector< std::pair< T, T > > &arcs, std::vector< T > *topological_order) |
template<typename T > | |
ABSL_MUST_USE_RESULT bool | StableTopologicalSort (const std::vector< T > &nodes, const std::vector< std::pair< T, T > > &arcs, std::vector< T > *topological_order, std::vector< T > *cycle) |
Override of the above that outputs the detected cycle. | |
template<typename T > | |
std::vector< T > | StableTopologicalSortOrDie (const std::vector< T > &nodes, const std::vector< std::pair< T, T > > &arcs) |
OrDie() variant of the above. | |
ABSL_MUST_USE_RESULT std::vector< int > | FindCycleInDenseIntGraph (int num_nodes, const std::vector< std::pair< int, int > > &arcs) |
______________________ END OF THE RECOMMENDED API ___________________________ | |
ABSL_MUST_USE_RESULT bool | DenseIntTopologicalSort (int num_nodes, const std::vector< std::pair< int, int > > &arcs, std::vector< int > *topological_order) |
Implementations of the "simple API" functions declared at the top. | |
std::vector< int > | DenseIntStableTopologicalSortOrDie (int num_nodes, const std::vector< std::pair< int, int > > &arcs) |
ABSL_MUST_USE_RESULT bool | DenseIntStableTopologicalSort (int num_nodes, const std::vector< std::pair< int, int > > &arcs, std::vector< int > *topological_order) |
std::vector< int > | DenseIntTopologicalSortOrDie (int num_nodes, const std::vector< std::pair< int, int > > &arcs) |
template<typename T > | |
bool | TopologicalSort (const std::vector< T > &nodes, const std::vector< std::pair< T, T > > &arcs, std::vector< T > *topological_order) |
template<typename T > | |
bool | TopologicalSort (const std::vector< T > &nodes, const std::vector< std::pair< T, T > > &arcs, std::vector< T > *topological_order, std::vector< T > *cycle) |
Override of the above that outputs the detected cycle. | |
template<typename T > | |
bool | StableTopologicalSort (const std::vector< T > &nodes, const std::vector< std::pair< T, T > > &arcs, std::vector< T > *topological_order) |
template<typename T > | |
bool | StableTopologicalSort (const std::vector< T > &nodes, const std::vector< std::pair< T, T > > &arcs, std::vector< T > *topological_order, std::vector< T > *cycle) |
Override of the above that outputs the detected cycle. | |
bool | IsSubsetOf0N (absl::Span< const int > v, int n) |
template<class Graph > | |
bool | GraphHasSelfArcs (const Graph &graph) |
Implementations of the templated methods. | |
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< Graph > | CopyGraph (const Graph &graph) |
Returns a fresh copy of a given graph. | |
template<class Graph > | |
std::unique_ptr< Graph > | RemapGraph (const Graph &graph, absl::Span< const int > new_node_index) |
template<class Graph > | |
std::unique_ptr< Graph > | GetSubgraphOfNodes (const Graph &graph, absl::Span< const int > nodes) |
template<class Graph > | |
std::vector< int > | GetWeaklyConnectedComponents (const Graph &graph) |
bool | IsValidPermutation (absl::Span< const int > v) |
Returns true iff the given vector is a permutation of [0..size()-1]. | |
template<class Graph > | |
std::unique_ptr< Graph > | RemoveSelfArcsAndDuplicateArcs (const Graph &graph) |
Returns a copy of "graph", without self-arcs and duplicate arcs. | |
template<class Graph > | |
void | RemoveCyclesFromPath (const Graph &graph, std::vector< int > *arc_path) |
template<class Graph > | |
bool | PathHasCycle (const Graph &graph, absl::Span< const int > arc_path) |
Returns true iff the given path contains a cycle. | |
template<class Graph > | |
std::vector< int > | ComputeOnePossibleReverseArcMapping (const Graph &graph, bool die_if_not_symmetric) |
A collections of i/o utilities for the Graph classes in ./graph.h.
A collections of utilities for the Graph classes in ./graph.h.
Helper classes to make it easy to implement range-based for loops.
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
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
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. These 3 functions give the full functionality of a BFS (Breadth-First-Search) on any type of Graph on dense integers that implements the [] operator to yield the adjacency list: graph[i] should yield a vector<int>-like object that lists all the (outgoing) neighbors of node #i.
If your graph is undirected, it means that for each edge (i,j), graph[i] must contain j and graph[j] must contain i.
Self-arcs and multi-arcs are supported, since they don't affect BFS.
These functions are fast: they have the optimal asymptotic complexity, and are reasonably optimized. You may still get performance gains if you implement your own BFS for your application. In particular, this API is optimized for repeated calls to GetBFSShortestPath(); if you only care about GetBFSDistances() there exists more optimized implementations.
ERRORS: This library does perform many checks at runtime, and returns an error Status if it detects a problem, but it doesn't fully protect you from crashes if the input is ill-formed in some ways this library can't check. For example, if calling graph[i] crashes for some i in 0..num_nodes-1, this won't detect it.
Example: const int num_nodes = 3; vector<vector<int>> graph(num_nodes) = {{1}, {0}, {1, 2}}; ///< 0↔1←2⟲ const int source = 1; vector<int> bfs_tree = GetBFSRootedTree(graph, num_nodes, source).value(); LOG(INFO) << DUMP_VARS(GetBFSDistances(bfs_tree)); for (int target : {0, 1, 2}) { vector<int> path = GetBFSShortestPath(bfs_tree, target); LOG(INFO) << DUMP_VARS(path); }
Would log this: GetBFSDistances(bfs_tree) = [1, 0, -1] path = [1, 0] path = [1] path = [] ///< no path from 1 to 2.
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
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
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.
Implementations of the method templates
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
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: 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: 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. vector<int> weights; weights.reserve(arc_capacity); ///< Optional, but help memory usage. for (...) { graph.AddArc(tail, head); weights.push_back(arc_weight); } ... 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]; } }
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
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 collection of functions to be used in unit tests involving the ortools/graph/... library.
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
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 provides topologically sorted traversal of the nodes of a directed acyclic graph (DAG) with up to INT_MAX nodes. It sorts ancestor nodes before their descendants. Multi-arcs are fine.
If your graph is not a DAG and you're reading this, you are probably looking for ortools/graph/strongly_connected_components.h which does the topological decomposition of a directed graph.
USAGE:
Recommended version for general usage. The stability makes it more deterministic, and its behavior is guaranteed to never change.
Definition at line 288 of file topologicalsorter.h.
Use this version if you are certain you don't care about the tie-breaking order and need the 5 to 10% performance gain. The performance gain can be more significant for large graphs with large numbers of source nodes (for example 2 Million nodes with 2 Million random edges sees a factor of 0.7 difference in completion time).
Definition at line 297 of file topologicalsorter.h.
typedef ListGraph util::Graph |
Returns a string representation of a graph.
|
inline |
Definition at line 79 of file status_builder.h.
|
inline |
Definition at line 83 of file status_builder.h.
|
inline |
Inline wrapper methods, to make the client code even simpler. The harm of overloading is probably less than the benefit of the nice, compact name, in this special case.
Definition at line 59 of file iterators.h.
|
inline |
Definition at line 63 of file iterators.h.
|
inline |
Definition at line 87 of file status_builder.h.
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.
PERFORMANCE: If you see this function taking too much memory and/or too much time, reach out to viger@: one could halve the memory usage and speed it up.
We need a multi-map since a given (tail,head) may appear several times. NOTE(user): It's free, in terms of space, to use InlinedVector<int, 4> rather than std::vector<int>.
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.
We need a multi-map since a given (tail,head) may appear several times. NOTE(user): It's free, in terms of space, to use InlinedVector<int, 4> rather than std::vector<int>.
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.
|
inline |
Definition at line 91 of file status_builder.h.
|
inline |
Definition at line 95 of file status_builder.h.
util::DEFINE_RANGE_BASED_ARC_ITERATION | ( | ListGraph | , |
Outgoing | , | ||
Base::kNilArc | ) |
ListGraph implementation -------------------------------------------------—.
util::DEFINE_RANGE_BASED_ARC_ITERATION | ( | ReverseArcListGraph | , |
Incoming | , | ||
Base::kNilArc | ) |
util::DEFINE_RANGE_BASED_ARC_ITERATION | ( | ReverseArcListGraph | , |
OppositeIncoming | , | ||
Base::kNilArc | ) |
util::DEFINE_RANGE_BASED_ARC_ITERATION | ( | ReverseArcListGraph | , |
Outgoing | , | ||
Base::kNilArc | ) |
ReverseArcListGraph implementation ---------------------------------------—.
util::DEFINE_RANGE_BASED_ARC_ITERATION | ( | ReverseArcListGraph | , |
OutgoingOrOppositeIncoming | , | ||
Base::kNilArc | ) |
util::DEFINE_RANGE_BASED_ARC_ITERATION | ( | ReverseArcMixedGraph | , |
Incoming | , | ||
Base::kNilArc | ) |
util::DEFINE_RANGE_BASED_ARC_ITERATION | ( | ReverseArcMixedGraph | , |
OppositeIncoming | , | ||
Base::kNilArc | ) |
util::DEFINE_RANGE_BASED_ARC_ITERATION | ( | ReverseArcMixedGraph | , |
Outgoing | , | ||
DirectArcLimit(node) | ) |
ReverseArcMixedGraph implementation --------------------------------------—.
util::DEFINE_RANGE_BASED_ARC_ITERATION | ( | ReverseArcMixedGraph | , |
OutgoingOrOppositeIncoming | , | ||
DirectArcLimit(node) | ) |
util::DEFINE_RANGE_BASED_ARC_ITERATION | ( | ReverseArcStaticGraph | , |
Incoming | , | ||
ReverseArcLimit(node) | ) |
util::DEFINE_RANGE_BASED_ARC_ITERATION | ( | ReverseArcStaticGraph | , |
OppositeIncoming | , | ||
ReverseArcLimit(node) | ) |
util::DEFINE_RANGE_BASED_ARC_ITERATION | ( | ReverseArcStaticGraph | , |
Outgoing | , | ||
DirectArcLimit(node) | ) |
ReverseArcStaticGraph implementation -------------------------------------—.
util::DEFINE_RANGE_BASED_ARC_ITERATION | ( | ReverseArcStaticGraph | , |
OutgoingOrOppositeIncoming | , | ||
DirectArcLimit(node) | ) |
util::DEFINE_RANGE_BASED_ARC_ITERATION | ( | StaticGraph | , |
Outgoing | , | ||
DirectArcLimit(node) | ) |
|
inline |
Definition at line 524 of file topologicalsorter.h.
|
inline |
Definition at line 569 of file topologicalsorter.h.
|
inline |
Implementations of the "simple API" functions declared at the top.
Definition at line 517 of file topologicalsorter.h.
|
inline |
Definition at line 564 of file topologicalsorter.h.
|
inline |
Definition at line 77 of file iterators.h.
|
inline |
Shortcut for BeginEndRange(multimap::equal_range(key)).
Definition at line 72 of file iterators.h.
|
inline |
Definition at line 99 of file status_builder.h.
|
inline |
______________________ END OF THE RECOMMENDED API ___________________________
Definition at line 145 of file topologicalsorter.h.
std::unique_ptr< StaticGraph<> > util::GenerateRandomDirectedSimpleGraph | ( | int | num_nodes, |
int | num_arcs, | ||
bool | finalized, | ||
absl::BitGenRef | gen ) |
Like GenerateRandomMultiGraph(), but with neither multi-arcs nor self-arcs: the generated graph will have exactly num_arcs arcs. It will be picked uniformly at random from the set of all simple graphs with that number of nodes and arcs.
Definition at line 161 of file random_graph.cc.
std::unique_ptr< StaticGraph<> > util::GenerateRandomMultiGraph | ( | int | num_nodes, |
int | num_arcs, | ||
bool | finalized, | ||
absl::BitGenRef | gen ) |
Generates a random graph where multi-arcs and self-arcs are allowed (and therefore expected): exactly "num_arcs" are generated, each from a node picked uniformly at random to another node picked uniformly at random. Calls Build() on the graph iff "finalized" is true.
Definition at line 54 of file random_graph.cc.
std::unique_ptr< StaticGraph<> > util::GenerateRandomUndirectedSimpleGraph | ( | int | num_nodes, |
int | num_edges, | ||
bool | finalized, | ||
absl::BitGenRef | gen ) |
Like GenerateRandomDirectedSimpleGraph(), but where an undirected edge is represented by two arcs: a->b and b->a. As a result, the amount of arcs in the generated graph is 2*num_edges.
Definition at line 167 of file random_graph.cc.
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 vector<vector<int>> graph = {{1, 3}, {0}, {4}, {0, 5}, {2}, {3}}; GetConnectedComponents(graph); ///< returns [0, 0, 1, 0, 1, 0].
Definition at line 78 of file connected_components.h.
std::vector< NodeType > util::GetConnectedComponentsTpl | ( | NodeType | num_nodes, |
const UndirectedGraph & | graph ) |
Generic version of GetConnectedComponents() (see below) that supports other integer types, e.g. int64_t for huge graphs with more than 2^31 nodes.
We use 'num_nodes' as special component id meaning 'unknown', because it's of the right type, and -1 is tricky to use with unsigned ints.
We use 'num_nodes' as special component id meaning 'unknown', because it's of the right type, and -1 is tricky to use with unsigned ints.
Definition at line 333 of file connected_components.h.
std::unique_ptr< Graph > util::GetSubgraphOfNodes | ( | const Graph & | graph, |
absl::Span< const 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).
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.
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 GetConnectedComponents().
Implementations of the templated methods.
Here's a set of simple diagnosis tools. Notes:
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<>.
std::string util::GraphToString | ( | const Graph & | graph, |
GraphToStringFormat | format ) |
|
inline |
Definition at line 103 of file status_builder.h.
|
inline |
Definition at line 107 of file status_builder.h.
bool util::IsSubsetOf0N | ( | absl::Span< const int > | v, |
int | n ) |
|
inline |
|
inline |
Definition at line 111 of file status_builder.h.
|
inline |
Definition at line 115 of file status_builder.h.
|
inline |
Definition at line 119 of file status_builder.h.
void util::Permute | ( | const IntVector & | permutation, |
Array * | array_to_permute ) |
void util::Permute | ( | const IntVector & | permutation, |
std::vector< bool > * | array_to_permute ) |
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.
Some compiler do not know typeof(), so we have to use this extra function internally.
std::unique_ptr< Graph > util::RemapGraph | ( | const Graph & | graph, |
absl::Span< const 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).
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.
This maps each node to the latest arc in the given path that leaves it.
Special case for the destination.
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.
Reconstruct the path by starting at the source and then following the "next" arcs. We override the given arc_path at the same time.
|
inline |
Definition at line 127 of file status_builder.h.
BeginEndReverseIteratorWrapper< Container > util::Reverse | ( | const Container & | c | ) |
Definition at line 99 of file iterators.h.
ABSL_MUST_USE_RESULT bool util::StableTopologicalSort | ( | const std::vector< T > & | nodes, |
const std::vector< std::pair< T, T > > & | arcs, | ||
std::vector< T > * | topological_order ) |
The "Stable" variants are a little slower but preserve the input order of nodes, if possible. More precisely, the returned topological order will be the lexicographically minimal valid order, where "lexicographic" applies to the indices of the nodes.
Definition at line 548 of file topologicalsorter.h.
bool util::StableTopologicalSort | ( | const std::vector< T > & | nodes, |
const std::vector< std::pair< T, T > > & | arcs, | ||
std::vector< T > * | topological_order ) |
The "Stable" variants are a little slower but preserve the input order of nodes, if possible. More precisely, the returned topological order will be the lexicographically minimal valid order, where "lexicographic" applies to the indices of the nodes.
Definition at line 548 of file topologicalsorter.h.
ABSL_MUST_USE_RESULT bool util::StableTopologicalSort | ( | const std::vector< T > & | nodes, |
const std::vector< std::pair< T, T > > & | arcs, | ||
std::vector< T > * | topological_order, | ||
std::vector< T > * | cycle ) |
Override of the above that outputs the detected cycle.
Definition at line 556 of file topologicalsorter.h.
bool util::StableTopologicalSort | ( | const std::vector< T > & | nodes, |
const std::vector< std::pair< T, T > > & | arcs, | ||
std::vector< T > * | topological_order, | ||
std::vector< T > * | cycle ) |
Override of the above that outputs the detected cycle.
Definition at line 556 of file topologicalsorter.h.
std::vector< T > util::StableTopologicalSortOrDie | ( | const std::vector< T > & | nodes, |
const std::vector< std::pair< T, T > > & | arcs ) |
OrDie() variant of the above.
Definition at line 581 of file topologicalsorter.h.
ABSL_MUST_USE_RESULT bool util::TopologicalSort | ( | const std::vector< T > & | nodes, |
const std::vector< std::pair< T, T > > & | arcs, | ||
std::vector< T > * | topological_order ) |
[Stable]TopologicalSort[OrDie]:
These variants are much slower than FastTopologicalSort(), but support non-integer (or integer, but sparse) nodes.
Definition at line 532 of file topologicalsorter.h.
bool util::TopologicalSort | ( | const std::vector< T > & | nodes, |
const std::vector< std::pair< T, T > > & | arcs, | ||
std::vector< T > * | topological_order ) |
[Stable]TopologicalSort[OrDie]:
These variants are much slower than FastTopologicalSort(), but support non-integer (or integer, but sparse) nodes.
Definition at line 532 of file topologicalsorter.h.
ABSL_MUST_USE_RESULT bool util::TopologicalSort | ( | const std::vector< T > & | nodes, |
const std::vector< std::pair< T, T > > & | arcs, | ||
std::vector< T > * | topological_order, | ||
std::vector< T > * | cycle ) |
Override of the above that outputs the detected cycle.
Definition at line 540 of file topologicalsorter.h.
bool util::TopologicalSort | ( | const std::vector< T > & | nodes, |
const std::vector< std::pair< T, T > > & | arcs, | ||
std::vector< T > * | topological_order, | ||
std::vector< T > * | cycle ) |
Override of the above that outputs the detected cycle.
Definition at line 540 of file topologicalsorter.h.
std::vector< T > util::TopologicalSortOrDie | ( | const std::vector< T > & | nodes, |
const std::vector< std::pair< T, T > > & | arcs ) |
OrDie() variant of the above.
Definition at line 575 of file topologicalsorter.h.
|
inline |
Definition at line 123 of file status_builder.h.
|
inline |
Definition at line 131 of file status_builder.h.
|
inline |
Definition at line 135 of file status_builder.h.
|
inline |
Definition at line 139 of file status_builder.h.
absl::Status util::WriteGraphToFile | ( | const Graph & | graph, |
const std::string & | filename, | ||
bool | directed, | ||
absl::Span< const 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.