Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
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
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
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 }
00132 }