GCC Code Coverage Report


Directory: ./
File: src/leaf-connected-comp.cc
Date: 2025-05-07 11:07:45
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