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