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 | AnnotatedGraphBuildManager |
| class | ArcFunctorOrderingByTailAndHead |
| class | ArcIndexOrderingByTailNode |
| Logically this class should be defined inside OptimizeGraphLayout, but compilation fails if we do that because C++98 doesn't allow instantiation of member templates with function-scoped types as template parameters, which in turn is because those function-scoped types lack linkage. More... | |
| class | BronKerboschAlgorithm |
| Implements the Bron-Kerbosch algorithm for finding maximal cliques. More... | |
| class | ChristofidesPathSolver |
| class | ConnectedComponents |
| Template class implementing a Union-Find algorithm with path compression for maintaining the connected components of a graph. More... | |
| class | CostValueCycleHandler |
| class | EbertGraph |
| Forward declarations. More... | |
| class | EbertGraphBase |
| A template for the base class that holds the functionality that exists in common between the EbertGraph<> template and the ForwardEbertGraph<> template. More... | |
| class | ElementIterator |
| class | ForwardEbertGraph |
| A forward-star-only graph representation for greater efficiency in those algorithms that don't need reverse arcs. More... | |
| class | ForwardStaticGraph |
| class | GenericMaxFlow |
| Forward declaration. More... | |
| class | GenericMinCostFlow |
| Forward declaration. More... | |
| struct | graph_traits |
| Traits for EbertGraphBase types, for use in testing and clients that work with both forward-only and forward/reverse graphs. More... | |
| struct | graph_traits< ForwardEbertGraph< NodeIndexType, ArcIndexType > > |
| struct | graph_traits< ForwardStaticGraph< NodeIndexType, ArcIndexType > > |
| struct | Graphs |
| Since StarGraph does not have exactly the same interface as the other graphs, we define a correspondence there. More... | |
| struct | Graphs< operations_research::StarGraph > |
| class | HamiltonianPathSolver |
| class | LatticeMemoryManager |
| The Dynamic Programming (DP) algorithm memorizes the values f(set, node) for node in set, for all the subsets of cardinality <= max_card_. More... | |
| class | LinearSumAssignment |
| This class does not take ownership of its underlying graph. More... | |
| class | MaxFlow |
| Default instance MaxFlow that uses StarGraph. More... | |
| class | MaxFlowStatusClass |
| We want an enum for the Status of a max flow run, and we want this enum to be scoped under GenericMaxFlow<>. More... | |
| class | MinCostFlow |
| Default MinCostFlow instance that uses StarGraph. More... | |
| class | MinCostFlowBase |
| Different statuses for a solved problem. More... | |
| class | PermutationIndexComparisonByArcHead |
| class | PriorityQueueWithRestrictedPush |
| Specific but efficient priority queue implementation. More... | |
| class | PruningHamiltonianSolver |
| class | Set |
| class | SetRangeIterator |
| An iterator for sets of increasing corresponding values that have the same cardinality. More... | |
| class | SetRangeWithCardinality |
| class | SimpleMaxFlow |
| A simple and efficient max-cost flow interface. More... | |
| class | SimpleMinCostFlow |
| A simple and efficient min-cost flow interface. More... | |
| class | StarGraphBase |
| class | TailArrayManager |
Typedefs | |
| typedef int32 | NodeIndex |
| Standard instantiation of ForwardEbertGraph (named 'ForwardStarGraph') of EbertGraph (named 'StarGraph'); and relevant type shortcuts. More... | |
| typedef int32 | ArcIndex |
| typedef int64 | FlowQuantity |
| typedef int64 | CostValue |
| typedef EbertGraph< NodeIndex, ArcIndex > | StarGraph |
| typedef ForwardEbertGraph< NodeIndex, ArcIndex > | ForwardStarGraph |
| typedef ForwardStaticGraph< NodeIndex, ArcIndex > | ForwardStarStaticGraph |
| typedef ZVector< NodeIndex > | NodeIndexArray |
| typedef ZVector< ArcIndex > | ArcIndexArray |
| typedef ZVector< FlowQuantity > | QuantityArray |
| typedef ZVector< CostValue > | CostArray |
| typedef int | PathNodeIndex |
Enumerations | |
| enum | CliqueResponse { CliqueResponse::CONTINUE, CliqueResponse::STOP } |
| Possible return values of the callback for reporting cliques. More... | |
| enum | BronKerboschAlgorithmStatus { BronKerboschAlgorithmStatus::COMPLETED, BronKerboschAlgorithmStatus::INTERRUPTED } |
| The status value returned by BronKerboschAlgorithm::Run and BronKerboschAlgorithm::RunIterations. More... | |
Functions | |
| template<typename WeightFunctionType , typename GraphType > | |
| std::vector< typename GraphType::ArcIndex > | ComputeMinimumWeightMatchingWithMIP (const GraphType &graph, const WeightFunctionType &weight) |
| Computes a minimum weight perfect matching on an undirected graph using a Mixed Integer Programming model. More... | |
| void | FindCliques (std::function< bool(int, int)> graph, int node_count, std::function< bool(const std::vector< int > &)> callback) |
| Finds all maximal cliques, even of size 1, in the graph described by the graph callback. More... | |
| void | CoverArcsByCliques (std::function< bool(int, int)> graph, int node_count, std::function< bool(const std::vector< int > &)> callback) |
| Covers the maximum number of arcs of the graph with cliques. More... | |
| template<typename GraphType > | |
| bool | BuildLineGraph (const GraphType &graph, GraphType *const line_graph) |
| Builds a directed line graph for 'graph' (see "directed line graph" in http://en.wikipedia.org/wiki/Line_graph). More... | |
| template<typename Graph > | |
| bool | IsEulerianGraph (const Graph &graph) |
| Returns true if a graph is Eulerian, aka all its nodes are of even degree. More... | |
| template<typename NodeIndex , typename Graph > | |
| bool | IsSemiEulerianGraph (const Graph &graph, std::vector< NodeIndex > *odd_nodes) |
| Returns true if a graph is Semi-Eulerian, aka at most two of its nodes are of odd degree. More... | |
| template<typename NodeIndex , typename Graph > | |
| std::vector< NodeIndex > | BuildEulerianPathFromNode (const Graph &graph, NodeIndex root) |
| Builds an Eulerian path/trail on an undirected graph starting from node root. More... | |
| template<typename NodeIndex , typename Graph > | |
| std::vector< NodeIndex > | BuildEulerianTourFromNode (const Graph &graph, NodeIndex root) |
| Builds an Eulerian tour/circuit/cycle starting and ending at node root on an undirected graph. More... | |
| template<typename Graph > | |
| std::vector< typename Graph::NodeIndex > | BuildEulerianTour (const Graph &graph) |
| Same as above but without specifying a start/end root node (node 0 is taken as default root). More... | |
| template<typename Graph > | |
| std::vector< typename Graph::NodeIndex > | BuildEulerianPath (const Graph &graph) |
| Builds an Eulerian path/trail on an undirected graph. More... | |
| template<typename CostType , typename CostFunction > | |
| HamiltonianPathSolver< CostType, CostFunction > | MakeHamiltonianPathSolver (int num_nodes, CostFunction cost) |
| Utility function to simplify building a HamiltonianPathSolver from a functor. More... | |
| template<typename Graph > | |
| std::vector< typename Graph::ArcIndex > | BuildKruskalMinimumSpanningTreeFromSortedArcs (const Graph &graph, const std::vector< typename Graph::ArcIndex > &sorted_arcs) |
| Implementation of Kruskal's mininumum spanning tree algorithm (c.f. More... | |
| template<typename Graph , typename ArcComparator > | |
| std::vector< typename Graph::ArcIndex > | BuildKruskalMinimumSpanningTree (const Graph &graph, const ArcComparator &arc_comparator) |
| Version taking an arc comparator to sort graph arcs. More... | |
| template<typename Graph , typename ArcValue > | |
| std::vector< typename Graph::ArcIndex > | BuildPrimMinimumSpanningTree (const Graph &graph, const ArcValue &arc_value) |
| Implementation of Prim's mininumum spanning tree algorithm (c.f. More... | |
| bool | DijkstraShortestPath (int node_count, int start_node, int end_node, std::function< int64(int, int)> graph, int64 disconnected_distance, std::vector< int > *nodes) |
| Dijsktra Shortest path with callback based description of the graph. More... | |
| bool | StableDijkstraShortestPath (int node_count, int start_node, int end_node, std::function< int64(int, int)> graph, int64 disconnected_distance, std::vector< int > *nodes) |
| Stable version of the Dijsktra Shortest path with callback based description of the graph. More... | |
| bool | BellmanFordShortestPath (int node_count, int start_node, int end_node, std::function< int64(int, int)> graph, int64 disconnected_distance, std::vector< int > *nodes) |
| Bellman-Ford Shortest path with callback-based description of the graph. More... | |
| bool | AStarShortestPath (int node_count, int start_node, int end_node, std::function< int64(int, int)> graph, std::function< int64(int)> heuristic, int64 disconnected_distance, std::vector< int > *nodes) |
| A* Shortest path with function based description of the graph. More... | |
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. ChristofidesPathSolver computes an approximate solution to the Traveling Salesman Problen using the Christofides algorithm (c.f. https://en.wikipedia.org/wiki/Christofides_algorithm).
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. Maximal clique algorithms, based on the Bron-Kerbosch algorithm. See http://en.wikipedia.org/wiki/Bron-Kerbosch_algorithm and C. Bron and J. Kerbosch, Joep, "Algorithm 457: finding all cliques of an undirected graph", CACM 16 (9): 575-577, 1973. http://dl.acm.org/citation.cfm?id=362367&bnc=1.
Keywords: undirected graph, clique, clique cover, Bron, Kerbosch.
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. Graph connectivity algorithm for undirected graphs. Memory consumption: O(n) where m is the number of arcs and n the number of nodes.
(user): add depth-first-search based connectivity for directed graphs.
(user): add depth-first-search based biconnectivity for directed graphs.
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 few variations on a theme of the "star" graph representation by Ebert, as described in J. Ebert, "A versatile data structure for edge-oriented graph algorithms." Communications of the ACM 30(6):513-519 (June 1987). http://portal.acm.org/citation.cfm?id=214769
In this file there are three representations that have much in common. The general one, called simply EbertGraph, contains both forward- and backward-star representations. The other, called ForwardEbertGraph, contains only the forward-star representation of the graph, and is appropriate for applications where the reverse arcs are not needed.
The point of including all the representations in this one file is to capitalize, where possible, on the commonalities among them, and those commonalities are mostly factored out into base classes as described below. Despite the commonalities, however, each of the three representations presents a somewhat different interface because of their different underlying semantics. A quintessential example is that the AddArc() method, very natural for the EbertGraph representation, cannot exist for an inherently static representation like ForwardStaticGraph.
Many clients are expected to use the interfaces to the graph objects directly, but some clients are parameterized by graph type and need a consistent interface for their underlying graph objects. For such clients, a small library of class templates is provided to give a consistent interface to clients where the underlying graph interfaces differ. Examples are the AnnotatedGraphBuildManager<> template, which provides a uniform interface for building the various types of graphs; and the TailArrayManager<> template, which provides a uniform interface for applications that need to map from arc indices to arc tail nodes, accounting for the fact that such a mapping has to be requested explicitly from the ForwardStaticGraph and ForwardStarGraph representations.
There are two base class templates, StarGraphBase, and EbertGraphBase; their purpose is to hold methods and data structures that are in common among their descendants. Only classes that are leaves in the following hierarchy tree are eligible for free-standing instantiation and use by clients. The parentheses around StarGraphBase and EbertGraphBase indicate that they should not normally be instantiated by clients:
In the general EbertGraph case, the graph is represented with three arrays. Let n be the number of nodes and m be the number of arcs. Let i be an integer in [0..m-1], denoting the index of an arc.
The EbertGraph implementation has the following benefits:
The EbertGraph implementation differs from the implementation described in [Ebert 1987] in the following respects:
The ForwardEbertGraph representation is like the EbertGraph case described above, with the following modifications:
The ForwardStaticGraph representation is restricted yet farther than ForwardEbertGraph, with the benefit that it provides higher performance to those applications that can use it.
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. Utility to build Eulerian paths and tours on a graph. For more information, see https://en.wikipedia.org/wiki/Eulerian_path. As of 10/2015, only undirected graphs are supported.
Usage:
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. Temporary utility class needed as long as we have two slightly different graph interface: The one in ebert_graph.h and the one in graph.h
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. Solves the Shortest Hamiltonian Path Problem using a complete algorithm. The algorithm was first described in M. Held, R.M. Karp, A dynamic programming approach to sequencing problems, J. SIAM 10 (1962) 196-210
The Shortest Hamiltonian Path Problem (SHPP) is similar to the Traveling Salesperson Problem (TSP). You have to visit all the cities, starting from a given one and you do not need to return to your starting point. With the TSP, you can start anywhere, but you have to return to your start location.
By complete we mean that the algorithm guarantees to compute the optimal solution. The algorithm uses dynamic programming. Its time complexity is O(n^2 * 2^(n-1)), where n is the number of nodes to be visited, and '^' denotes exponentiation. Its space complexity is O(n * 2 ^ (n - 1)).
Here is how the algorithm works: Let us denote the nodes to be visited by their indices 0 .. n - 1 Let us pick 0 as the starting node. Let d(i,j) denote the distance (or cost) from i to j. f(S, j) where S is a set of nodes and j is a node in S is defined as follows: f(S, j) = min (i in S \ {j}, f(S \ {j}, i) + cost(i, j)) (j is an element of S)
The advantage of the Held and Karp formulation is that it enables:
The set S can be represented by an integer where bit i corresponds to element i in the set. In the following S denotes the integer corresponding to set S.
The dynamic programming iteration is implemented in the method Solve. The optimal value of the Hamiltonian path starting at 0 is given by min (i in S, f(2 ^ n - 1, i)) The optimal value of the Traveling Salesman tour is given by f(2 ^ n, 0). (There is actually no need to duplicate the first node, as all the paths are computed from node 0.)
To implement dynamic programming, we store the preceding results of computing f(S,j) in an array M[Offset(S,j)]. See the comments about LatticeMemoryManager::BaseOffset() to see how this is computed.
Keywords: Traveling Salesman, Hamiltonian Path, Dynamic Programming, Held, Karp.
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. An implementation of a push-relabel algorithm for the max flow problem.
In the following, we consider a graph G = (V,E,s,t) where V denotes the set of nodes (vertices) in the graph, E denotes the set of arcs (edges). s and t denote distinguished nodes in G called source and target. n = V denotes the number of nodes in the graph, and m = E denotes the number of arcs in the graph.
Each arc (v,w) is associated a capacity c(v,w).
A flow is a function from E to R such that:
a) f(v,w) <= c(v,w) for all (v,w) in E (capacity constraint.)
b) f(v,w) = -f(w,v) for all (v,w) in E (flow antisymmetry constraint.)
c) sum on v f(v,w) = 0 (flow conservation.)
The goal of this algorithm is to find the maximum flow from s to t, i.e. for example to maximize sum v f(s,v).
The starting reference for this class of algorithms is: A.V. Goldberg and R.E. Tarjan. A new approach to the maximum flow problem. ACM Symposium on Theory of Computing, pp. 136-146. http://portal.acm.org/citation.cfm?id=12144.
The basic idea of the algorithm is to handle preflows instead of flows, and to refine preflows until a maximum flow is obtained. A preflow is like a flow, except that the inflow can be larger than the outflow. If it is the case at a given node v, it is said that there is an excess at node v, and inflow = outflow + excess.
More formally, a preflow is a function f such that:
1) f(v,w) <= c(v,w) for all (v,w) in E (capacity constraint). c(v,w) is a value representing the maximum capacity for arc (v,w).
2) f(v,w) = -f(w,v) for all (v,w) in E (flow antisymmetry constraint)
3) excess(v) = sum on u f(u,v) >= 0 is the excess at node v, the algebraic sum of all the incoming preflows at this node.
Each node has an associated "height", in addition to its excess. The height of the source is defined to be equal to n, and cannot change. The height of the target is defined to be zero, and cannot change either. The height of all the other nodes is initialized at zero and is updated during the algorithm (see below). For those who want to know the details, the height of a node, corresponds to a reduced cost, and this enables one to prove that the algorithm actually computes the max flow. Note that the height of a node can be initialized to the distance to the target node in terms of number of nodes. This has not been tried in this implementation.
A node v is said to be active if excess(v) > 0.
In this case the following operations can be applied to it:
Before running Discharge, it is necessary to initialize the algorithm with a preflow. This is done in InitializePreflow, which saturates all the arcs leaving the source node, and sets the excess at the heads of those arcs accordingly.
The algorithm terminates when there are no remaining active nodes, i.e. all the excesses at all nodes are equal to zero. In this case, a maximum flow is obtained.
The complexity of this algorithm depends amongst other things on the choice of the next active node. It has been shown, for example in: L. Tuncel, "On the Complexity of Preflow-Push Algorithms for Maximum-Flow Problems", Algorithmica 11(4): 353-359 (1994). and J. Cheriyan and K. Mehlhorn, "An analysis of the highest-level selection rule in the preflow-push max-flow algorithm", Information processing letters, 69(5):239-242 (1999). http://www.math.uwaterloo.ca/~jcheriya/PS_files/me3.0.ps
...that choosing the active node with the highest level yields a complexity of O(n^2 * sqrt(m)).
This has been validated experimentally in: R.K. Ahuja, M. Kodialam, A.K. Mishra, and J.B. Orlin, "Computational Investigations of Maximum Flow Algorithms", EJOR 97:509-542(1997). http://jorlin.scripts.mit.edu/docs/publications/58-comput%20investigations%20of.pdf.
An interesting general reference on network flows is: R. K. Ahuja, T. L. Magnanti, J. B. Orlin, "Network Flows: Theory, Algorithms, and Applications," Prentice Hall, 1993, ISBN: 978-0136175490, http://www.amazon.com/dp/013617549X
Keywords: Push-relabel, max-flow, network, graph, Goldberg, Tarjan, Dinic, Dinitz.
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. An implementation of a cost-scaling push-relabel algorithm for the min-cost flow problem.
In the following, we consider a graph G = (V,E) where V denotes the set of nodes (vertices) in the graph, E denotes the set of arcs (edges). n = V denotes the number of nodes in the graph, and m = E denotes the number of arcs in the graph.
With each arc (v,w) is associated a nonnegative capacity u(v,w) (where 'u' stands for "upper bound") and a unit cost c(v,w). With each node v is associated a quantity named supply(v), which represents a supply of fluid (if >0) or a demand (if <0). Furthermore, no fluid is created in the graph so sum_{v in V} supply(v) = 0.
A flow is a function from E to R such that: a) f(v,w) <= u(v,w) for all (v,w) in E (capacity constraint). b) f(v,w) = -f(w,v) for all (v,w) in E (flow antisymmetry constraint). c) sum on v f(v,w) + supply(w) = 0 (flow conservation).
The cost of a flow is sum on (v,w) in E ( f(v,w) * c(v,w) ) [Note: It can be confusing to beginners that the cost is actually double the amount that it might seem at first because of flow antisymmetry.]
The problem to solve: find a flow of minimum cost such that all the fluid flows from the supply nodes to the demand nodes.
The principles behind this algorithm are the following: 1/ handle pseudo-flows instead of flows and refine pseudo-flows until an epsilon-optimal minimum-cost flow is obtained, 2/ deal with epsilon-optimal pseudo-flows.
1/ A pseudo-flow is like a flow, except that a node's outflow minus its inflow can be different from its supply. If it is the case at a given node v, it is said that there is an excess (or deficit) at node v. A deficit is denoted by a negative excess and inflow = outflow + excess. (Look at ortools/graph/max_flow.h to see that the definition of preflow is more restrictive than the one for pseudo-flow in that a preflow only allows non-negative excesses, i.e., no deficit.) More formally, a pseudo-flow is a function f such that: a) f(v,w) <= u(v,w) for all (v,w) in E (capacity constraint). b) f(v,w) = -f(w,v) for all (v,w) in E (flow antisymmetry constraint).
For each v in E, we also define the excess at node v, the algebraic sum of all the incoming preflows at this node, added together with the supply at v. excess(v) = sum on u f(u,v) + supply(v)
The goal of the algorithm is to obtain excess(v) = 0 for all v in V, while consuming capacity on some arcs, at the lowest possible cost.
2/ Internally to the algorithm and its analysis (but invisibly to the client), each node has an associated "price" (or potential), in addition to its excess. It is formally a function from E to R (the set of real numbers.). For a given price function p, the reduced cost of an arc (v,w) is: c_p(v,w) = c(v,w) + p(v) - p(w) (c(v,w) is the cost of arc (v,w).) For those familiar with linear programming, the price function can be viewed as a set of dual variables.
For a constant epsilon >= 0, a pseudo-flow f is said to be epsilon-optimal with respect to a price function p if for every residual arc (v,w) in E, c_p(v,w) >= -epsilon.
A flow f is optimal if and only if there exists a price function p such that no arc is admissible with respect to f and p.
If the arc costs are integers, and epsilon < 1/n, any epsilon-optimal flow is optimal. The integer cost case is handled by multiplying all the arc costs and the initial value of epsilon by (n+1). When epsilon reaches 1, and the solution is epsilon-optimal, it means: for all residual arc (v,w) in E, (n+1) * c_p(v,w) >= -1, thus c_p(v,w) >= -1/(n+1) >= 1/n, and the solution is optimal.
A node v is said to be active if excess(v) > 0. In this case the following operations can be applied to it:
Discharge itself is called by Refine. Refine first saturates all the admissible arcs, then builds a stack of active nodes. It then applies Discharge for each active node, possibly adding new ones in the process, until no nodes are active. In that case an epsilon-optimal flow is obtained.
Optimize iteratively calls Refine, while epsilon > 1, and divides epsilon by alpha (set by default to 5) before each iteration.
The algorithm starts with epsilon = C, where C is the maximum absolute value of the arc costs. In the integer case which we are dealing with, since all costs are multiplied by (n+1), the initial value of epsilon is (n+1)*C. The algorithm terminates when epsilon = 1, and Refine() has been called. In this case, a minimum-cost flow is obtained.
The complexity of the algorithm is O(n^2*m*log(n*C)) where C is the value of the largest arc cost in the graph.
IMPORTANT: The algorithm is not able to detect the infeasibility of a problem (i.e., when a bottleneck in the network prohibits sending all the supplies.) Worse, it could in some cases loop forever. This is why feasibility checking is enabled by default (FLAGS_min_cost_flow_check_feasibility=true.) Feasibility checking is implemented using a max-flow, which has a much lower complexity. The impact on performance is negligible, while the risk of being caught in an endless loop is removed. Note that using the feasibility checker roughly doubles the memory consumption.
The starting reference for this class of algorithms is: A.V. Goldberg and R.E. Tarjan, "Finding Minimum-Cost Circulations by Successive Approximation." Mathematics of Operations Research, Vol. 15, 1990:430-466. http://portal.acm.org/citation.cfm?id=92225
Implementation issues are tackled in: A.V. Goldberg, "An Efficient Implementation of a Scaling Minimum-Cost Flow Algorithm," Journal of Algorithms, (1997) 22:1-29 http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.31.258
A.V. Goldberg and M. Kharitonov, "On Implementing Scaling Push-Relabel Algorithms for the Minimum-Cost Flow Problem", Network flows and matching: First DIMACS implementation challenge, DIMACS Series in Discrete Mathematics and Theoretical Computer Science, (1993) 12:157-198. ftp://dimacs.rutgers.edu/pub/netflow/submit/papers/Goldberg-mincost/scalmin.ps and in: U. Bunnagel, B. Korte, and J. Vygen. “Efficient implementation of the Goldberg-Tarjan minimum-cost flow algorithm.” Optimization Methods and Software (1998) vol. 10, no. 2:157-174. http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.84.9897
We have tried as much as possible in this implementation to keep the notations and namings of the papers cited above, except for 'demand' or 'balance' which have been replaced by 'supply', with the according sign changes to better accommodate with the API of the rest of our tools. A demand is denoted by a negative supply.
An interesting general reference on network flows is: R. K. Ahuja, T. L. Magnanti, J. B. Orlin, "Network Flows: Theory, Algorithms, and Applications," Prentice Hall, 1993, ISBN: 978-0136175490, http://www.amazon.com/dp/013617549X
Keywords: Push-relabel, min-cost flow, network, graph, Goldberg, Tarjan, Dinic, Dinitz.
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.
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 contains various shortest paths utilities.
Keywords: directed graph, cheapest path, shortest path, Dijkstra, spp.
| typedef int32 operations_research::ArcIndex |
Definition at line 201 of file ebert_graph.h.
| typedef ZVector<ArcIndex> operations_research::ArcIndexArray |
Definition at line 208 of file ebert_graph.h.
| typedef ZVector<CostValue> operations_research::CostArray |
Definition at line 210 of file ebert_graph.h.
| typedef int64 operations_research::CostValue |
Definition at line 203 of file ebert_graph.h.
| typedef int64 operations_research::FlowQuantity |
Definition at line 202 of file ebert_graph.h.
Definition at line 205 of file ebert_graph.h.
Definition at line 206 of file ebert_graph.h.
| typedef int32 operations_research::NodeIndex |
Standard instantiation of ForwardEbertGraph (named 'ForwardStarGraph') of EbertGraph (named 'StarGraph'); and relevant type shortcuts.
Unless their use cases prevent them from doing so, users are encouraged to use StarGraph or ForwardStarGraph according to whether or not they require reverse arcs to be represented explicitly. Along with either graph representation, the other type shortcuts here will often come in handy.
Definition at line 192 of file ebert_graph.h.
| typedef ZVector<NodeIndex> operations_research::NodeIndexArray |
Definition at line 207 of file ebert_graph.h.
| typedef int operations_research::PathNodeIndex |
Definition at line 450 of file hamiltonian_path.h.
| typedef ZVector<FlowQuantity> operations_research::QuantityArray |
Definition at line 209 of file ebert_graph.h.
Definition at line 204 of file ebert_graph.h.
|
strong |
The status value returned by BronKerboschAlgorithm::Run and BronKerboschAlgorithm::RunIterations.
| Enumerator | |
|---|---|
| COMPLETED | The algorithm has enumerated all maximal cliques. |
| INTERRUPTED | The search algorithm was interrupted either because it reached the iteration limit or because the clique callback returned CliqueResponse::STOP. |
|
strong |
Possible return values of the callback for reporting cliques.
The returned value determines whether the algorithm will continue the search.
| Enumerator | |
|---|---|
| CONTINUE | The algorithm will continue searching for other maximal cliques. |
| STOP | The algorithm will stop the search immediately. The search can be resumed by calling BronKerboschAlgorithm::Run (resp. RunIterations) again. |
| bool operations_research::AStarShortestPath | ( | int | node_count, |
| int | start_node, | ||
| int | end_node, | ||
| std::function< int64(int, int)> | graph, | ||
| std::function< int64(int)> | heuristic, | ||
| int64 | disconnected_distance, | ||
| std::vector< int > * | nodes | ||
| ) |
A* Shortest path with function based description of the graph.
The graph function returns the distance between two nodes, a distance of 'disconnected_distance' indicates no arcs between these two nodes. Additionally, the heuristic callback returns a an approximate distance between the node and the target, which guides the search. If the heuristic is admissible (ie. never overestimates cost), the A* algorithm returns an optimal solution. This function returns true if 'start_node' and 'end_node' are connected, false otherwise.
| bool operations_research::BellmanFordShortestPath | ( | int | node_count, |
| int | start_node, | ||
| int | end_node, | ||
| std::function< int64(int, int)> | graph, | ||
| int64 | disconnected_distance, | ||
| std::vector< int > * | nodes | ||
| ) |
Bellman-Ford Shortest path with callback-based description of the graph.
The callback returns the distance between two nodes, a distance of 'disconnected_distance' indicates no arcs between these two nodes. Ownership of the callback is taken by the function that will delete it in the end. This function returns true if 'start_node' and 'end_node' are connected, false otherwise. If true, it will fill the 'nodes' vector with the sequence of nodes on the shortest path between 'start_node' and 'end_node'.
| std::vector<typename Graph::NodeIndex> operations_research::BuildEulerianPath | ( | const Graph & | graph | ) |
Builds an Eulerian path/trail on an undirected graph.
This function works only on Reverse graphs (cf. ortools/graph/graph.h). Returns an empty tour if a tour cannot be built. As of 10/2015, assumes the graph is connected.
Definition at line 138 of file eulerian_path.h.
| std::vector<NodeIndex> operations_research::BuildEulerianPathFromNode | ( | const Graph & | graph, |
| NodeIndex | root | ||
| ) |
Builds an Eulerian path/trail on an undirected graph starting from node root.
Supposes the graph is connected and is eulerian or semi-eulerian. This is an implementation of Hierholzer's algorithm. If m is the number of edges in the graph and n the number of nodes, time and memory complexity is O(n + m).
Definition at line 74 of file eulerian_path.h.
| std::vector<typename Graph::NodeIndex> operations_research::BuildEulerianTour | ( | const Graph & | graph | ) |
Same as above but without specifying a start/end root node (node 0 is taken as default root).
Definition at line 128 of file eulerian_path.h.
| std::vector<NodeIndex> operations_research::BuildEulerianTourFromNode | ( | const Graph & | graph, |
| NodeIndex | root | ||
| ) |
Builds an Eulerian tour/circuit/cycle starting and ending at node root on an undirected graph.
This function works only on Reverse graphs (cf. ortools/graph/graph.h). Returns an empty tour if either root is invalid or if a tour cannot be built. As of 10/2015, assumes the graph is connected.
Definition at line 116 of file eulerian_path.h.
| std::vector<typename Graph::ArcIndex> operations_research::BuildKruskalMinimumSpanningTree | ( | const Graph & | graph, |
| const ArcComparator & | arc_comparator | ||
| ) |
Version taking an arc comparator to sort graph arcs.
Usage: ListGraph<int, int> graph(...); const auto arc_cost = [&graph](int arc) { return f(graph.Tail(arc), graph.Head(arc)); }; std::vector<int> mst = BuildKruskalMinimumSpanningTree( graph, [&arc_cost](int a, int b) { return arc_cost(a) < arc_cost(b); });
Definition at line 91 of file minimum_spanning_tree.h.
| std::vector<typename Graph::ArcIndex> operations_research::BuildKruskalMinimumSpanningTreeFromSortedArcs | ( | const Graph & | graph, |
| const std::vector< typename Graph::ArcIndex > & | sorted_arcs | ||
| ) |
Implementation of Kruskal's mininumum spanning tree algorithm (c.f.
https://en.wikipedia.org/wiki/Kruskal%27s_algorithm). Returns the index of the arcs appearing in the tree; will return a forest if the graph is disconnected. Nodes without any arcs will be ignored. Each arc of the graph is interpreted as an undirected arc. Complexity of the algorithm is O(E * log(E)) where E is the number of arcs in the graph. Memory usage is O(E * log(E)).
Version taking sorted graph arcs. Allows somewhat incremental recomputation of minimum spanning trees as most of the processing time is spent sorting arcs. Usage: ListGraph<int, int> graph(...); std::vector<int> sorted_arcs = ...; std::vector<int> mst = BuildKruskalMinimumSpanningTreeFromSortedArcs( graph, sorted_arcs);
Definition at line 50 of file minimum_spanning_tree.h.
| bool operations_research::BuildLineGraph | ( | const GraphType & | graph, |
| GraphType *const | line_graph | ||
| ) |
Builds a directed line graph for 'graph' (see "directed line graph" in http://en.wikipedia.org/wiki/Line_graph).
Arcs of the original graph become nodes and the new graph contains only nodes created from arcs in the original graph (we use the notation (a->b) for these new nodes); the index of the node (a->b) in the new graph is exactly the same as the index of the arc a->b in the original graph. An arc from node (a->b) to node (c->d) in the new graph is added if and only if b == c in the original graph. This method expects that 'line_graph' is an empty graph (it has no nodes and no arcs). Returns false on an error.
Sizing then filling.
Definition at line 2088 of file ebert_graph.h.
| std::vector<typename Graph::ArcIndex> operations_research::BuildPrimMinimumSpanningTree | ( | const Graph & | graph, |
| const ArcValue & | arc_value | ||
| ) |
Implementation of Prim's mininumum spanning tree algorithm (c.f.
https://en.wikipedia.org/wiki/Prim's_algorithm) on undirected connected graphs. Returns the index of the arcs appearing in the tree. Complexity of the algorithm is O(E * log(V)) where E is the number of arcs in the graph, V is the number of vertices. Memory usage is O(V) + memory taken by the graph. Usage: ListGraph<int, int> graph(...); const auto arc_cost = [&graph](int arc) -> int64 { return f(graph.Tail(arc), graph.Head(arc)); }; std::vector<int> mst = BuildPrimMinimumSpanningTree(graph, arc_cost);
This struct represents entries in the adjustable priority queue which maintains active nodes (not added to the tree yet) in decreasing insertion cost order. AdjustablePriorityQueue requires the existence of the SetHeapIndex and GetHeapIndex methods.
Definition at line 117 of file minimum_spanning_tree.h.
| std::vector<typename GraphType::ArcIndex> operations_research::ComputeMinimumWeightMatchingWithMIP | ( | const GraphType & | graph, |
| const WeightFunctionType & | weight | ||
| ) |
Computes a minimum weight perfect matching on an undirected graph using a Mixed Integer Programming model.
The model is composed of Boolean decision variables to select matching arcs and constraints ensuring that each node appears in exactly one selected arc. The objective is to minimize the sum of the weights of selected arcs. It is assumed the graph is symmetrical.
Creating arc-selection Boolean variable.
Creating matching constraint: for all node i, sum(j) arc(i,j) + sum(j) arc(j,i) = 1
Definition at line 107 of file christofides.h.
| void operations_research::CoverArcsByCliques | ( | std::function< bool(int, int)> | graph, |
| int | node_count, | ||
| std::function< bool(const std::vector< int > &)> | callback | ||
| ) |
Covers the maximum number of arcs of the graph with cliques.
The graph is described by the graph callback. graph->Run(i, j) indicates if there is an arc between i and j. This function takes ownership of 'callback' and deletes it after it has run. It calls 'callback' upon each clique. It ignores cliques of size 1.
| bool operations_research::DijkstraShortestPath | ( | int | node_count, |
| int | start_node, | ||
| int | end_node, | ||
| std::function< int64(int, int)> | graph, | ||
| int64 | disconnected_distance, | ||
| std::vector< int > * | nodes | ||
| ) |
Dijsktra Shortest path with callback based description of the graph.
The callback returns the distance between two nodes, a distance of 'disconnected_distance' indicates no arcs between these two nodes. Ownership of the callback is taken by the function that will delete it in the end. This function returns true if 'start_node' and 'end_node' are connected, false otherwise.
| void operations_research::FindCliques | ( | std::function< bool(int, int)> | graph, |
| int | node_count, | ||
| std::function< bool(const std::vector< int > &)> | callback | ||
| ) |
Finds all maximal cliques, even of size 1, in the graph described by the graph callback.
graph->Run(i, j) indicates if there is an arc between i and j. This function takes ownership of 'callback' and deletes it after it has run. If 'callback' returns true, then the search for cliques stops.
| bool operations_research::IsEulerianGraph | ( | const Graph & | graph | ) |
Returns true if a graph is Eulerian, aka all its nodes are of even degree.
Definition at line 40 of file eulerian_path.h.
| bool operations_research::IsSemiEulerianGraph | ( | const Graph & | graph, |
| std::vector< NodeIndex > * | odd_nodes | ||
| ) |
Returns true if a graph is Semi-Eulerian, aka at most two of its nodes are of odd degree.
odd_nodes is filled with odd nodes of the graph.
Definition at line 55 of file eulerian_path.h.
| HamiltonianPathSolver<CostType, CostFunction> operations_research::MakeHamiltonianPathSolver | ( | int | num_nodes, |
| CostFunction | cost | ||
| ) |
Utility function to simplify building a HamiltonianPathSolver from a functor.
Definition at line 599 of file hamiltonian_path.h.
| bool operations_research::StableDijkstraShortestPath | ( | int | node_count, |
| int | start_node, | ||
| int | end_node, | ||
| std::function< int64(int, int)> | graph, | ||
| int64 | disconnected_distance, | ||
| std::vector< int > * | nodes | ||
| ) |
Stable version of the Dijsktra Shortest path with callback based description of the graph.
The callback returns the distance between two nodes, a distance of 'disconnected_distance' indicates no arcs between these two nodes. Ownership of the callback is taken by the function that will delete it in the end. This function returns true if 'start_node' and 'end_node' are connected, false otherwise.