Generated on: Thu Mar 29 07:46:58 PDT 2012 for custom file set | ||
|
||
00001 // Copyright 2010-2012 Google 00002 // Licensed under the Apache License, Version 2.0 (the "License"); 00003 // you may not use this file except in compliance with the License. 00004 // You may obtain a copy of the License at 00005 // 00006 // http://www.apache.org/licenses/LICENSE-2.0 00007 // 00008 // Unless required by applicable law or agreed to in writing, software 00009 // distributed under the License is distributed on an "AS IS" BASIS, 00010 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00011 // See the License for the specific language governing permissions and 00012 // limitations under the License. 00013 00014 // Graph connectivity algorithm for undirected graphs. 00015 // Memory consumption: O(n) where m is the number of arcs and n the number 00016 // of nodes. 00017 // TODO(user): add depth-first-search based connectivity for directed graphs. 00018 // TODO(user): add depth-first-search based biconnectivity for directed graphs. 00019 00020 #ifndef OR_TOOLS_GRAPH_CONNECTIVITY_H_ 00021 #define OR_TOOLS_GRAPH_CONNECTIVITY_H_ 00022 00023 #include "base/integral_types.h" 00024 #include "base/logging.h" 00025 #include "base/macros.h" 00026 #include "graph/ebert_graph.h" 00027 00028 namespace operations_research { 00029 00030 // Template class implementing a Union-Find algorithm with path compression for 00031 // maintaining the connected components of a graph. 00032 // See Cormen et al. 2nd Edition. MIT Press, 2001. ISBN 0-262-03293-7. 00033 // Chapter 21: Data structures for Disjoint Sets, pp. 498–524. 00034 // and Tarjan (1975). Efficiency of a Good But Not Linear Set 00035 // Union Algorithm. Journal of the ACM 22(2):215–225 00036 // It is implemented as a template so that the size of NodeIndex can be chosen 00037 // depending on the size of the graphs considered. 00038 // The main interest is that arcs do not need to be kept. Thus the memory 00039 // complexity is O(n) where n is the number of nodes in the graph. 00040 // The complexity of this algorithm is O(n . alpha(n)) where alpha(n) is 00041 // the inverse Ackermann function. alpha(n) <= log(log(log(..log(log(n))..) 00042 // In practice alpha(n) <= 5. 00043 // See Tarjan and van Leeuwen (1984). Worst-case analysis of set union 00044 // algorithms. Journal of the ACM 31(2):245–281. 00045 // 00046 // Usage example: 00047 // ConnectedComponents components; 00048 // components.Init(num_nodes); 00049 // for (ArcIndex arc = 0; arc < num_arcs; ++arc) { 00050 // components.AddArc(tail[arc], head[arc]); 00051 // } 00052 // int num_connected_components = components.GetNumberOfConnectedComponents(); 00053 // if (num_connected_components == 1) { 00054 // // Graph is completely connected. 00055 // } 00056 // // Group the nodes in the same connected component together. 00057 // // group[class_number][i] contains the i-th node in group class_number. 00058 // hash_map<NodeIndex, std::vector<NodeIndex> > group(num_connected_components); 00059 // for (NodeIndex node = 0; node < num_nodes; ++node) { 00060 // group[components.GetClassRepresentative(node)].push_back(node); 00061 // } 00062 // 00063 // NodeIndex is used to denote both a node index and a number of nodes, 00064 // as passed as parameter to Init. 00065 // 00066 // Keywords: graph, connected components. 00067 00068 class ConnectedComponents { 00069 public: 00070 ConnectedComponents() : min_index_(0), 00071 max_index_(StarGraph::kMaxNumNodes), 00072 max_seen_index_(0), 00073 class_(), 00074 class_size_() {} 00075 00076 ~ConnectedComponents() {} 00077 00078 // Reserves memory for num_nodes and resets the data structures. 00079 void Init(NodeIndex num_nodes) { 00080 Init(0, num_nodes - 1); 00081 } 00082 00083 // Adds the information that NodeIndex tail and NodeIndex head are connected. 00084 void AddArc(NodeIndex tail, NodeIndex head); 00085 00086 // Adds a complete StarGraph to the object. Note that Depth-First Search 00087 // is a better algorithm for finding connected components on graphs. 00088 // TODO(user): implement Depth-First Search-based connected components finder. 00089 void AddGraph(const StarGraph& graph); 00090 00091 // Compresses the path for node. 00092 NodeIndex CompressPath(NodeIndex node); 00093 00094 // Returns the equivalence class representative for node. 00095 NodeIndex GetClassRepresentative(NodeIndex node); 00096 00097 // Returns the number of connected components. Allocates num_nodes_ bits for 00098 // the computation. 00099 NodeIndex GetNumberOfConnectedComponents(); 00100 00101 // Merges the equivalence classes of node1 and node2. 00102 void MergeClasses(NodeIndex node1, NodeIndex node2); 00103 00104 private: 00105 // Initializes the object and allocates memory. 00106 void Init(NodeIndex min_index, NodeIndex max_index); 00107 00108 // The minimum index for nodes in the graph. 00109 NodeIndex min_index_; 00110 00111 // The exact number of nodes in the graph. 00112 NodeIndex max_index_; 00113 00114 // The maximum node index seen during AddArc. (set to Graph::num_nodes() by 00115 // AddGraph.) 00116 NodeIndex max_seen_index_; 00117 00118 // The equivalence class representative for each node. 00119 NodeIndexArray class_; 00120 00121 // The size of each equivalence class of each node. Used to compress the paths 00122 // and therefore achieve better time complexity. 00123 NodeIndexArray class_size_; 00124 00125 DISALLOW_COPY_AND_ASSIGN(ConnectedComponents); 00126 }; 00127 00128 } // namespace operations_research 00129 00130 #endif // OR_TOOLS_GRAPH_CONNECTIVITY_H_