connected_components.cc
Go to the documentation of this file.
00001 /*
00002  * Copyright 2016 The Cartographer Authors
00003  *
00004  * Licensed under the Apache License, Version 2.0 (the "License");
00005  * you may not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  *      http://www.apache.org/licenses/LICENSE-2.0
00009  *
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS,
00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015  */
00016 
00017 #include "cartographer/mapping/internal/connected_components.h"
00018 
00019 #include <algorithm>
00020 
00021 #include "absl/container/flat_hash_set.h"
00022 #include "cartographer/mapping/proto/connected_components.pb.h"
00023 #include "glog/logging.h"
00024 
00025 namespace cartographer {
00026 namespace mapping {
00027 
00028 ConnectedComponents::ConnectedComponents()
00029     : lock_(), forest_(), connection_map_() {}
00030 
00031 void ConnectedComponents::Add(const int trajectory_id) {
00032   absl::MutexLock locker(&lock_);
00033   forest_.emplace(trajectory_id, trajectory_id);
00034 }
00035 
00036 void ConnectedComponents::Connect(const int trajectory_id_a,
00037                                   const int trajectory_id_b) {
00038   absl::MutexLock locker(&lock_);
00039   Union(trajectory_id_a, trajectory_id_b);
00040   auto sorted_pair = std::minmax(trajectory_id_a, trajectory_id_b);
00041   ++connection_map_[sorted_pair];
00042 }
00043 
00044 void ConnectedComponents::Union(const int trajectory_id_a,
00045                                 const int trajectory_id_b) {
00046   forest_.emplace(trajectory_id_a, trajectory_id_a);
00047   forest_.emplace(trajectory_id_b, trajectory_id_b);
00048   const int representative_a = FindSet(trajectory_id_a);
00049   const int representative_b = FindSet(trajectory_id_b);
00050   forest_[representative_a] = representative_b;
00051 }
00052 
00053 int ConnectedComponents::FindSet(const int trajectory_id) {
00054   auto it = forest_.find(trajectory_id);
00055   CHECK(it != forest_.end());
00056   if (it->first != it->second) {
00057     // Path compression for efficiency.
00058     it->second = FindSet(it->second);
00059   }
00060   return it->second;
00061 }
00062 
00063 bool ConnectedComponents::TransitivelyConnected(const int trajectory_id_a,
00064                                                 const int trajectory_id_b) {
00065   if (trajectory_id_a == trajectory_id_b) {
00066     return true;
00067   }
00068 
00069   absl::MutexLock locker(&lock_);
00070 
00071   if (forest_.count(trajectory_id_a) == 0 ||
00072       forest_.count(trajectory_id_b) == 0) {
00073     return false;
00074   }
00075   return FindSet(trajectory_id_a) == FindSet(trajectory_id_b);
00076 }
00077 
00078 std::vector<std::vector<int>> ConnectedComponents::Components() {
00079   // Map from cluster exemplar -> growing cluster.
00080   absl::flat_hash_map<int, std::vector<int>> map;
00081   absl::MutexLock locker(&lock_);
00082   for (const auto& trajectory_id_entry : forest_) {
00083     map[FindSet(trajectory_id_entry.first)].push_back(
00084         trajectory_id_entry.first);
00085   }
00086 
00087   std::vector<std::vector<int>> result;
00088   result.reserve(map.size());
00089   for (auto& pair : map) {
00090     result.emplace_back(std::move(pair.second));
00091   }
00092   return result;
00093 }
00094 
00095 std::vector<int> ConnectedComponents::GetComponent(const int trajectory_id) {
00096   absl::MutexLock locker(&lock_);
00097   const int set_id = FindSet(trajectory_id);
00098   std::vector<int> trajectory_ids;
00099   for (const auto& entry : forest_) {
00100     if (FindSet(entry.first) == set_id) {
00101       trajectory_ids.push_back(entry.first);
00102     }
00103   }
00104   return trajectory_ids;
00105 }
00106 
00107 int ConnectedComponents::ConnectionCount(const int trajectory_id_a,
00108                                          const int trajectory_id_b) {
00109   absl::MutexLock locker(&lock_);
00110   const auto it =
00111       connection_map_.find(std::minmax(trajectory_id_a, trajectory_id_b));
00112   return it != connection_map_.end() ? it->second : 0;
00113 }
00114 
00115 proto::ConnectedComponents ToProto(
00116     std::vector<std::vector<int>> connected_components) {
00117   proto::ConnectedComponents proto;
00118   for (auto& connected_component : connected_components) {
00119     std::sort(connected_component.begin(), connected_component.end());
00120   }
00121   std::sort(connected_components.begin(), connected_components.end());
00122   for (const auto& connected_component : connected_components) {
00123     auto* proto_connected_component = proto.add_connected_component();
00124     for (const int trajectory_id : connected_component) {
00125       proto_connected_component->add_trajectory_id(trajectory_id);
00126     }
00127   }
00128   return proto;
00129 }
00130 
00131 }  // namespace mapping
00132 }  // namespace cartographer


cartographer
Author(s): The Cartographer Authors
autogenerated on Thu May 9 2019 02:27:35