80 {
82 std::map<vertex_t, bool> used_hits;
83
84 for (vertex_t i = 0; i < numSpacepoints; i++) {
86 used_hits[i] = false;
87 }
88 for(size_t idx=0; idx < rowIndices.size(); ++idx) {
89 add_edge(rowIndices[idx], colIndices[idx], edgeWeights[idx],
G);
90 }
91
92
94
95 UndirectedGraph ugraph;
96
97 for (auto v : boost::make_iterator_range(vertices(newG))) {
98 auto name = boost::get(boost::vertex_name, newG, v);
99 add_vertex(name, ugraph);
100 }
101
102 auto [edge_b, edge_e] = boost::edges(newG);
103 for (
auto it = edge_b;
it != edge_e; ++
it) {
104 int source = boost::source(*it, newG);
105 int target = boost::target(*it, newG);
106 add_edge(source, target, ugraph);
107 }
108
109 std::vector<std::vector<vertex_t>> sub_graphs =
getSimplePath(ugraph);
110
111 for (const auto& track : sub_graphs) {
112 for (auto hit_id : track) {
113 used_hits[hit_id] = true;
114 }
115 }
116
117 std::vector<Vertex> topo_order;
118 boost::topological_sort(newG, std::back_inserter(topo_order));
119
120
121 auto next_node_fn = [&](
const Graph &
G, vertex_t current_hit) {
123 };
124
125
126 for(auto it = topo_order.rbegin(); it != topo_order.rend(); ++it) {
128 int hit_id = boost::get(boost::vertex_name, newG, node_id);
129 if (used_hits[hit_id]) continue;
130
131
132 auto roads =
buildRoads(newG, node_id, next_node_fn, used_hits);
133 used_hits[node_id] = true;
134 if (roads.empty()) {
135 continue;
136 }
137
138
139 std::vector<int>& longest_road = *std::max_element(roads.begin(), roads.end(),
140 [](
const std::vector<int> &
a,
const std::vector<int> &b) {
141 return a.size() < b.size();
142 });
143
144 if (longest_road.size() >= 3) {
145 std::vector<vertex_t>
track;
146 for (int node_id : longest_road) {
147 auto hit_id = boost::get(boost::vertex_name, newG, node_id);
148 used_hits[hit_id] = true;
149 track.push_back(hit_id);
150 }
151 sub_graphs.push_back(std::move(track));
152 }
153 }
154
155
156 tracks.clear();
157 for (const auto& track : sub_graphs) {
158 std::vector<uint32_t> this_track{
track.begin(),
track.end()};
159 tracks.push_back(std::move(this_track));
160 }
161}
std::vector< std::vector< vertex_t > > buildRoads(const Graph &G, vertex_t starting_node, std::function< std::vector< vertex_t >(const Graph &, vertex_t)> next_node_fn, std::map< vertex_t, bool > &used_hits)
std::vector< vertex_t > findNextNode(const Graph &G, vertex_t current_hit, float th_min, float th_add)
Graph cleanupGraph(const Graph &G, float ccCut)
std::vector< std::vector< vertex_t > > getSimplePath(const UndirectedGraph &G)