YARP
Yet Another Robot Platform
Graph.cpp
Go to the documentation of this file.
1 /*
2  * SPDX-FileCopyrightText: 2006-2021 Istituto Italiano di Tecnologia (IIT)
3  * SPDX-License-Identifier: BSD-3-Clause
4  */
5 
6 #include <yarp/os/Log.h>
7 #include <yarp/os/LogStream.h>
8 #include <yarp/profiler/Graph.h>
9 #include <algorithm>
10 #include <stack>
11 
12 //#include <sstream>
13 //#include <iostream>
14 using namespace yarp::profiler::graph;
15 using namespace yarp::os;
16 
17 
23  const yarp::profiler::graph::Vertex& secondV,
24  yarp::os::Property property)
25 {
26  firstVertex = &firstV;
27  secondVertex = &secondV;
28  Edge::property = property;
29 }
30 
31 Edge::Edge(const Edge& edge)
32 {
33  property = edge.property;
34  firstVertex = edge.firstVertex;
35  secondVertex = edge.secondVertex;
36 }
37 
38 Edge::~Edge() = default;
39 
40 const Vertex& Edge::first() const {
41  return *firstVertex;
42 }
43 
44 const Vertex& Edge::second() const {
45  return *secondVertex;
46 }
47 
48 
50  return (firstVertex == edge.firstVertex &&
51  secondVertex == edge.secondVertex &&
52  property.toString() == edge.property.toString());
53 }
54 
55 
59 Vertex::Vertex(const yarp::os::Property &prop) : property(prop) { }
60 
61 
62 Vertex::Vertex(const Vertex &vertex) = default;
63 
64 Vertex::~Vertex() = default;
65 
66 void Vertex::insertOuts(const yarp::profiler::graph::Edge& edge) {
67  if (find(outs.begin(), outs.end(), edge) != outs.end()) {
68  return;
69  }
70  outs.push_back(edge);
71 }
72 
73 void Vertex::insertIns(const yarp::profiler::graph::Edge& edge) {
74  if (find(ins.begin(), ins.end(), edge) != ins.end()) {
75  return;
76  }
77  ins.push_back(edge);
78 }
79 
80 /*
81 bool Vertex::operator == (const yarp::profiler::graph::Vertex &v1) const {
82  return property.toString() == v1.property.toString();
83 }
84 */
85 
86 bool Vertex::operator<(const Vertex &v1) const {
87  return property.toString() < v1.property.toString();
88 }
89 
90 
96 Graph::Graph() = default;
97 
98 /*
99 Graph::Graph(yarp::profiler::graph::Graph& graph) {
100  mVertices == graph.mVertices;
101 }
102 */
103 
105  auto itr = mVertices.begin();
106  for(;itr!=mVertices.end(); itr++) {
107  Vertex* v = *itr;
108  delete v;
109  }
110 }
111 
112 /*
113 void Graph::insert(Vertex *vertex) {
114  yAssert(vertex != NULL);
115  mVertices.push_back(vertex);
116 }
117 */
118 
119 
121  pvertex_iterator itr = find(vertex);
122  if (itr != mVertices.end()) {
123  return itr;
124  }
125  // Vertex* v = new Vertex(vertex);
126  mVertices.push_back((Vertex*) &vertex);
127  return mVertices.end()-1;
128 }
129 
130 
131 void Graph::remove(const Vertex &vertex){
132  remove(find(vertex));
133 }
134 
136  if (vi == mVertices.end()) {
137  return;
138  }
139  Vertex* v = *vi;
140  mVertices.erase(vi);
141  delete v;
142 }
143 
144 void Graph::insertEdge(const Vertex &v1, const Vertex &v2, const yarp::os::Property &property) {
145  insert(v1); // insert also checks for dubplication
146  insert(v2);
147  insertEdge(find(v1), find(v2), property);
148 }
149 
150 
152  const yarp::os::Property& property) {
153  yAssert(vi1 != mVertices.end());
154  yAssert(vi2 != mVertices.end());
155  Edge edge(**vi1, **vi2, property);
156  (**vi1).insertOuts(edge);
157  (**vi2).insertIns(edge);
158 }
159 
160 const pvertex_iterator Graph::find(const Vertex &vertex) {
161  auto itr = mVertices.begin();
162  for(;itr!=mVertices.end(); itr++) {
163  if (*(*itr) == vertex) {
164  return itr;
165  }
166  }
167  return mVertices.end();
168 
169 }
170 
171 size_t Graph::size() {
172  auto itr = mVertices.begin();
173  size_t count = 0;
174  for (; itr != mVertices.end(); itr++) {
175  count += (**itr).degree();
176  }
177  return count/2;
178 }
179 
181  return mVertices.size();
182 }
183 
184 
185 void Graph::clear() {
186  auto itr = mVertices.begin();
187  for (; itr != mVertices.end(); itr++) {
188  delete *itr;
189  }
190  mVertices.clear();
191 }
192 
193 
195  graph_subset& scc,
196  std::stack<Vertex*>&S, int& index) {
197  //yDebug()<<"Visiting"<<v->property.find("name").asString()<<index;
198  // Set the depth index for v to the smallest unused index
199  v->property.put("index", index);
200  v->property.put("lowlink", index);
201  index++;
202  S.push(v);
203  v->property.put("onStack", 1);
204  // Consider successors of v
205  const edge_set& outs = v->outEdges();
206  edge_const_iterator eitr;
207  for(eitr = outs.begin(); eitr!=outs.end(); eitr++) {
208  const Edge& e = (*eitr);
209  const Vertex& w = e.second();
210  //yDebug()<<"successors:"<<w.property.find("name").asString();
211  if(!w.property.check("index")) {
212  // Successor w has not yet been visited; recurse on it
213  strongConnect((Vertex*)(&w), scc, S, index);
214  int lowlink = std::min(v->property.find("lowlink").asInt32(),
215  w.property.find("lowlink").asInt32());
216  v->property.put("lowlink", lowlink);
217 
218  } else if (w.property.check("onStack")) {
219  // Successor w is in stack S and hence in the current SCC
220  int lowlink = std::min(v->property.find("lowlink").asInt32(),
221  w.property.find("index").asInt32());
222  v->property.put("lowlink", lowlink);
223  }
224  } // end successors
225 
226  // If v is a root node, pop the stack and generate an SCC
227  if(v->property.find("lowlink").asInt32() == v->property.find("index").asInt32()) {
228  // start a new strongly connected component
229  pvertex_set vset;
230  Vertex* w;
231  do {
232  w = S.top();
233  S.pop();
234  w->property.unput("onStack");
235  //add w to current strongly connected component
236  vset.push_back(w);
237  } while(!S.empty() && w != v);
238  //output the current strongly connected component
239  if(vset.size() > 1) {
240  scc.push_back(vset);
241  //yInfo()<<"\nSCC:";
242  //for(int i=0; i<vset.size(); i++)
243  // yInfo()<<vset[i]->property.find("name").asString();
244  }
245  }
246 }
247 
248 
250  scc.clear();
251 
252  // clear corresponding nodes propperties
254  const pvertex_set& vertices = graph.vertices();
255  for(vitr = vertices.begin(); vitr!=vertices.end(); vitr++) {
256  Vertex* v = (*vitr);
257  v->property.unput("onStack");
258  v->property.unput("index");
259  v->property.unput("lowlink");
260  }
261 
262  std::stack<Vertex*> S;
263  int index = 0;
264  for(vitr = vertices.begin(); vitr!=vertices.end(); vitr++) {
265  Vertex* v = (*vitr);
266  if (!v->property.check("index")) {
267  strongConnect(v, scc, S, index);
268  }
269  }
270  return true;
271 }
void strongConnect(Vertex *v, graph_subset &scc, std::stack< Vertex * > &S, int &index)
Definition: Graph.cpp:194
std::vector< pvertex_set > graph_subset
Definition: Graph.h:41
edge_set::const_iterator edge_const_iterator
Definition: Graph.h:35
pvertex_set::const_iterator pvertex_const_iterator
Definition: Graph.h:39
std::vector< yarp::profiler::graph::Vertex * > pvertex_set
Definition: Graph.h:37
pvertex_set::iterator pvertex_iterator
Definition: Graph.h:38
std::vector< yarp::profiler::graph::Edge > edge_set
Definition: Graph.h:33
#define yAssert(x)
Definition: Log.h:294
A class for storing options and configuration information.
Definition: Property.h:34
Value & find(const std::string &key) const override
Gets a value corresponding to a given keyword.
Definition: Property.cpp:1051
std::string toString() const override
Return a standard text representation of the content of the object.
Definition: Property.cpp:1069
void put(const std::string &key, const std::string &value)
Associate the given key with the given string.
Definition: Property.cpp:1015
bool check(const std::string &key) const override
Check if there exists a property of the given name.
Definition: Property.cpp:1041
void unput(const std::string &key)
Remove the association from the given key to a value, if present.
Definition: Property.cpp:1046
virtual std::int32_t asInt32() const
Get 32-bit integer value.
Definition: Value.cpp:204
static bool calcSCC(yarp::profiler::graph::Graph &graph, graph_subset &scc)
calcSCC
Definition: Graph.cpp:249
The yarp::profiler::graph::Edge class.
Definition: Graph.h:49
virtual bool operator==(const yarp::profiler::graph::Edge &edge) const
Definition: Graph.cpp:49
const yarp::profiler::graph::Vertex & second() const
Definition: Graph.cpp:44
Edge(const yarp::profiler::graph::Vertex &firstV, const yarp::profiler::graph::Vertex &secondV, yarp::os::Property property="")
yarp::profiler::graph::Edge
Definition: Graph.cpp:22
yarp::os::Property property
Definition: Graph.h:65
const yarp::profiler::graph::Vertex & first() const
Definition: Graph.cpp:40
The yarp::profiler::graph::Graph class.
Definition: Graph.h:108
void insertEdge(const Vertex &v1, const Vertex &v2, const yarp::os::Property &property="")
Definition: Graph.cpp:144
const pvertex_set & vertices()
Definition: Graph.h:130
const pvertex_iterator find(const Vertex &v1)
Definition: Graph.cpp:160
void remove(const Vertex &vertex)
Definition: Graph.cpp:131
Graph()
yarp::profiler::graph::Graph
pvertex_iterator insert(const Vertex &vertex)
Definition: Graph.cpp:120
The yarp::profiler::graph::Vertex class.
Definition: Graph.h:76
yarp::os::Property property
Definition: Graph.h:93
virtual bool operator<(const Vertex &v1) const
Definition: Graph.cpp:86
const edge_set & outEdges() const
Definition: Graph.h:83
Vertex(const yarp::os::Property &prop)
yarp::profiler::graph::Vertex
Definition: Graph.cpp:59
An interface to the operating system, including Port based communication.