GCC Code Coverage Report


Directory: ./
File: src/leaf-connected-comp.cc
Date: 2025-03-07 11:10:46
Exec Total Coverage
Lines: 0 131 0.0%
Branches: 0 158 0.0%

Line Branch Exec Source
1 // Copyright (c) 2016, Joseph Mirabel
2 // Authors: Joseph Mirabel (joseph.mirabel@laas.fr)
3 //
4
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are
7 // met:
8 //
9 // 1. Redistributions of source code must retain the above copyright
10 // notice, this list of conditions and the following disclaimer.
11 //
12 // 2. Redistributions in binary form must reproduce the above copyright
13 // notice, this list of conditions and the following disclaimer in the
14 // documentation and/or other materials provided with the distribution.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
27 // DAMAGE.
28
29 #include <hpp/manipulation/graph/state.hh>
30 #include <hpp/manipulation/leaf-connected-comp.hh>
31 #include <hpp/manipulation/roadmap.hh>
32
33 namespace hpp {
34 namespace manipulation {
35 void LeafConnectedComp::clean(LeafConnectedComps_t& set) {
36 for (LeafConnectedComps_t::iterator it = set.begin(); it != set.end(); ++it) {
37 (*it)->explored_ = false;
38 }
39 }
40
41 LeafConnectedCompPtr_t LeafConnectedComp::create(const RoadmapPtr_t& roadmap) {
42 LeafConnectedCompPtr_t shPtr =
43 LeafConnectedCompPtr_t(new LeafConnectedComp(roadmap));
44 shPtr->init(shPtr);
45 return shPtr;
46 }
47
48 void LeafConnectedComp::addNode(const RoadmapNodePtr_t& node) {
49 assert(state_);
50 graph::StatePtr_t state = roadmap_.lock()->getState(node);
51
52 // Sanity check
53 if (state_ == state) // Oops
54 throw std::runtime_error(
55 "RoadmapNode of LeafConnectedComp must be in"
56 " the same state");
57 nodes_.push_back(node);
58 }
59
60 void LeafConnectedComp::setFirstNode(const RoadmapNodePtr_t& node) {
61 assert(!state_);
62 state_ = roadmap_.lock()->getState(node);
63 nodes_.push_back(node);
64 }
65
66 bool LeafConnectedComp::canReach(const LeafConnectedCompPtr_t& cc) {
67 // Store visited connected components for further cleaning.
68 LeafConnectedComp::LeafConnectedComps_t explored;
69 std::deque<RawPtr_t> queue;
70 queue.push_back(this);
71 explored_ = true;
72 explored.insert(this);
73 while (!queue.empty()) {
74 RawPtr_t current = queue.front();
75 queue.pop_front();
76 if (current == cc.get()) {
77 clean(explored);
78 return true;
79 }
80 for (LeafConnectedComp::LeafConnectedComps_t::iterator itChild =
81 current->to_.begin();
82 itChild != current->to_.end(); ++itChild) {
83 RawPtr_t child = *itChild;
84 if (!child->explored_) {
85 child->explored_ = true;
86 explored.insert(child);
87 queue.push_back(child);
88 }
89 }
90 }
91 clean(explored);
92 return false;
93 }
94
95 bool LeafConnectedComp::canReach(
96 const LeafConnectedCompPtr_t& cc,
97 LeafConnectedComp::LeafConnectedComps_t& ccToThis) {
98 bool reachable = false;
99 // Store visited connected components
100 LeafConnectedComp::LeafConnectedComps_t exploredForward;
101 std::deque<RawPtr_t> queue;
102 queue.push_back(this);
103 explored_ = true;
104 exploredForward.insert(this);
105 while (!queue.empty()) {
106 RawPtr_t current = queue.front();
107 queue.pop_front();
108 if (current == cc.get()) {
109 reachable = true;
110 exploredForward.insert(current);
111 } else {
112 for (LeafConnectedComp::LeafConnectedComps_t::iterator itChild =
113 current->to_.begin();
114 itChild != current->to_.end(); ++itChild) {
115 RawPtr_t child = *itChild;
116 if (!child->explored_) {
117 child->explored_ = true;
118 exploredForward.insert(child);
119 queue.push_back(child);
120 }
121 }
122 }
123 }
124 // Set visited connected components to unexplored
125 clean(exploredForward);
126 if (!reachable) return false;
127
128 // Store visited connected components
129 LeafConnectedComps_t exploredBackward;
130 queue.push_back(cc.get());
131 cc->explored_ = true;
132 exploredBackward.insert(cc.get());
133 while (!queue.empty()) {
134 RawPtr_t current = queue.front();
135 queue.pop_front();
136 if (current == this) {
137 exploredBackward.insert(current);
138 } else {
139 for (LeafConnectedComps_t::iterator itChild = current->from_.begin();
140 itChild != current->from_.end(); ++itChild) {
141 RawPtr_t child = *itChild;
142 if (!child->explored_) {
143 child->explored_ = true;
144 exploredBackward.insert(child);
145 queue.push_back(child);
146 }
147 }
148 }
149 }
150 // Set visited connected components to unexplored
151 clean(exploredBackward);
152 std::set_intersection(exploredForward.begin(), exploredForward.end(),
153 exploredBackward.begin(), exploredBackward.end(),
154 std::inserter(ccToThis, ccToThis.begin()));
155 return true;
156 }
157
158 void LeafConnectedComp::merge(const LeafConnectedCompPtr_t& other) {
159 assert(other);
160 assert(weak_.lock().get() == this);
161
162 // Tell other's nodes that they now belong to this connected component
163 for (RoadmapNodes_t::iterator itNode = other->nodes_.begin();
164 itNode != other->nodes_.end(); ++itNode) {
165 (*itNode)->leafConnectedComponent(weak_.lock());
166 }
167 // Add other's nodes to this list.
168 nodes_.insert(nodes_.end(), other->nodes_.begin(), other->nodes_.end());
169
170 // Tell other's reachableTo's that other has been replaced by this
171 for (LeafConnectedComps_t::iterator itcc = other->to_.begin();
172 itcc != other->to_.end(); ++itcc) {
173 (*itcc)->from_.erase(other.get());
174 (*itcc)->from_.insert(this);
175 }
176
177 // Tell other's reachableFrom's that other has been replaced by this
178 for (LeafConnectedComps_t::iterator itcc = other->from_.begin();
179 itcc != other->from_.end(); ++itcc) {
180 (*itcc)->to_.erase(other.get());
181 (*itcc)->to_.insert(this);
182 }
183
184 LeafConnectedComps_t tmp;
185 std::set_union(to_.begin(), to_.end(), other->to_.begin(), other->to_.end(),
186 std::inserter(tmp, tmp.begin()));
187 to_ = tmp;
188 tmp.clear();
189 to_.erase(other.get());
190 to_.erase(this);
191 std::set_union(from_.begin(), from_.end(), other->from_.begin(),
192 other->from_.end(), std::inserter(tmp, tmp.begin()));
193 from_ = tmp;
194 tmp.clear();
195 from_.erase(other.get());
196 from_.erase(this);
197 }
198
199 WeighedLeafConnectedCompPtr_t WeighedLeafConnectedComp::create(
200 const RoadmapPtr_t& roadmap) {
201 WeighedLeafConnectedCompPtr_t shPtr =
202 WeighedLeafConnectedCompPtr_t(new WeighedLeafConnectedComp(roadmap));
203 shPtr->init(shPtr);
204 return shPtr;
205 }
206
207 void WeighedLeafConnectedComp::merge(const LeafConnectedCompPtr_t& otherCC) {
208 WeighedLeafConnectedCompPtr_t other =
209 HPP_DYNAMIC_PTR_CAST(WeighedLeafConnectedComp, otherCC);
210 value_type r = ((value_type)nodes_.size()) /
211 (value_type)(nodes_.size() + other->nodes_.size());
212
213 LeafConnectedComp::merge(otherCC);
214 weight_ *= other->weight_; // TODO a geometric mean would be more natural.
215 p_ = r * p_ + (1 - r) * other->p_;
216 }
217
218 void WeighedLeafConnectedComp::setFirstNode(const RoadmapNodePtr_t& node) {
219 LeafConnectedComp::setFirstNode(node);
220 std::vector<value_type> p = state_->neighbors().probabilities();
221 p_.resize(p.size());
222 edges_ = state_->neighbors().values();
223 for (std::size_t i = 0; i < p.size(); ++i) p_[i] = p[i];
224 }
225
226 std::size_t WeighedLeafConnectedComp::indexOf(const graph::EdgePtr_t e) const {
227 std::size_t i = 0;
228 for (; i < edges_.size(); ++i)
229 if (edges_[i] == e) break;
230 return i;
231 }
232 } // namespace manipulation
233 } // namespace hpp
234