CMS 3D CMS Logo

graph_path.h
Go to the documentation of this file.
1 #ifndef graph_path_h
2 #define graph_path_h
3 
4 
5 
6 #include <map>
7 #include <set>
8 #include <vector>
9 #include <iostream>
11 
12 template <class N, class E>
13 class GraphPath
14 {
15 public:
16  typedef pair<N,N> segment_type;
17  //FIXME: GraphPath: find memory optimized representation of type paths_type ...
18  typedef std::map< segment_type, set< segment_type > > paths_type;
19  typedef set< std::vector<N> > paths_set;
20  typedef std::vector< pair<N,N> > chain_type;
21  typedef std::vector<std::vector<segment_type> > result_type;
22  GraphPath(const graph<N,E> & g, const N & root);
24  bool fromTo(const N & from, const N & to, std::vector< std::vector<N> > & result) const;
25 
26  void calcPaths(const graph<N,E>& g, const N & root);
27  void findSegments(const N & n, set< segment_type >& result);
28  void stream(std::ostream&);
29 
34  bool paths2(const segment_type & ft, result_type& result) const;
35 
36 //private:
37  void update(segment_type & s, result_type & r, int pos) const;
38  paths_type paths_;
39 };
40 
41 
42 template <class N, class M>
43 std::ostream & operator<<(std::ostream & os, const pair<N,M> & p)
44 {
45  os << p.first << ":" << p.second;
46 }
47 
48 /*
49 template <class N>
50 std::ostream & operator<<(std::ostream & os, const std::vector<N> & v)
51 {
52  typename std::vector<N>::const_iterator it = v.begin();
53  os << '[';
54  for(; it != v.end(); ++it)
55  os << *it << ' ';
56  os << ']' << std::endl;
57  return os;
58 }
59 
60 */
61 /*
62 template <class N>
63 std::ostream & operator<<(std::ostream & os, const std::vector< std::vector< N > > & p)
64 {
65  std::vector< std::vector<N> >::const_iterator paths_it = p.begin();
66  for(; paths_it != p.end(); ++paths_it) {
67  std::vector<N>::const_iterator path_it = paths_it->begin();
68  for(; path_it != paths_it->end(); ++paths_it)
69  os << *path_it << '-';
70  os << std::endl;
71  }
72 
73  return os;
74 }
75 
76 
77 template <class N>
78 std::ostream & operator<<(std::ostream & os, const std::vector< std::vector< pair<N,N> > > & p)
79 {
80  std::vector< std::vector<pair<N,N> > >::const_iterator paths_it = p.begin();
81  for(; paths_it != p.end(); ++paths_it) {
82  std::vector<pair<N,N> >::const_iterator path_it = paths_it->begin();
83  for(; path_it != paths_it->end(); ++paths_it)
84  os << '[' << path_it->first << ' ' << path_it->second << "]-";
85  os << std::endl;
86  }
87 
88  return os;
89 }
90 */
91 
92 
93 template <class N, class E>
94 bool GraphPath<N,E>::fromTo(const N & from, const N & to, std::vector< std::vector<N> > & result) const
95 {
96  result_type tres;
97  bool rslt=false;
98  if (paths2(segment_type(from,to),tres)) {
99  typename result_type::iterator rit = tres.begin(); // iterator over std::vector< std::vector<seg_t> >
100  for (; rit!=tres.end(); ++rit) {
101  N & target = (*rit)[0].second;
102  typename std::vector<segment_type>::reverse_iterator pit = rit->rbegin();
103  typename std::vector<segment_type>::reverse_iterator pend = rit->rend();
104  --pend;
105  std::vector<N> v(1,(*rit)[0].first); // <A,X> -> <A>
106  //std::cout << pit->first << '-';
107  ++pit;
108  for(; pit!=pend; ++pit) {
109  v.push_back(pit->second);
110  //std::cout << pit->second << '-';
111  }
112  //std::cout << target << std::endl;
113  v.push_back(target);
114  result.push_back(v);
115  }
116 
117  rslt=true;
118  }
119 
120  return rslt;
121 }
122 
123 
124 template <class N, class E>
126 {
127  typename paths_type::const_iterator git = paths_.find(ft);
128  if (git==paths_.end()) {
129  result.clear();
130  return false;
131  }
132 
133  std::vector<segment_type> v;
134  v.push_back(git->first);
135  result.push_back(v); // starting point; the set will be enlarged & the std::vectors inside
136  // get pushed_back as new path-segments appear ...
137 
138  // find a possible direct-connetion:
139  //set<segment_type>::iterator direct_it =
140 
141  bool goOn(true);
142 
143  while(goOn) {
144  //FIXME: use size_type whenever possible ..
145  int u = result.size();
146  int i;
147  int cntdwn=u;
148  for (i=0; i<u; ++i) {
149  segment_type & upd_seg = result[i].back();
150  if (upd_seg.first!=upd_seg.second) // only update result if not <X,X> !!
151  update(upd_seg,result,i); // adds new paths ..
152  else
153  --cntdwn;
154  }
155  goOn = bool(cntdwn);
156 
157  //std::cout << "0.--: cntdwn=" << cntdwn << std::endl;
158  /* PRINT THE RESULT
159  result_type::iterator rit = result.begin();
160  for(; rit!=result.end(); ++rit) {
161  std::vector<segment_type>::iterator pit = rit->begin();
162  for(; pit!=rit->end(); ++pit) {
163  std::cout << "[" << pit->first << "," << pit->second << "] ";
164  }
165  std::cout << std::endl;
166  }
167  std::cout << "===========" << std::endl;
168  */
169  }
170  return true;
171 }
172 
173 
174 template <class N, class E>
176 {
177  // s ... segment, which is used to find its children
178  // result ... std::vector of path-std::vectors
179  // u ... path in result which is currently under observation, s is it's 'back'
180  const set<segment_type> & segs = paths_.find(s)->second;
181  typename set<segment_type>::const_iterator segit = segs.begin();
182 
183  if (segs.size()==0) {
184  cerr << "you should never get here: GraphPath::update(...)" << std::endl;
185  exit(1);
186  }
187  /*
188  std::cout << "1. s=" << s.first << " " << s.second
189  << " aseg=" << segit->first << " " << segit->second << std::endl;
190  */
191  std::vector<segment_type> temp_pth = result[u];
192  ++segit;
193  for (; segit!=segs.end(); ++segit) { // create new pathes (whenever a the path-tree is branching)
194  std::vector<segment_type> v = temp_pth;
195  v.push_back(*segit);
196  result.push_back(v);
197  }
198  temp_pth.push_back(*segs.begin()); // just append the first new segment to the existing one (also, when no branch!)
199  result[u]=temp_pth;
200 }
201 
202 
203 template <class N, class E>
205 {
206  calcPaths(g,root);
207 }
208 
215 template <class N, class E>
216 void GraphPath<N,E>::calcPaths(const graph<N,E>& g, const N & n)
217 {
218  // find n(ode) in g(raph) and all its children (get rid of the
219  // multiconnections ...
220  //set< pair<N,E> > nodes;
221  pair<bool,graph<N,E>::neighbour_range> childRange = g.nodes(n);
222  if (!childRange.first)
223  return;
224 
225  set<N> children;
226  typename set< pair<N,E> >::const_iterator nit = childRange.second.first;
227  for(; nit!=childRange.second.second; ++nit)
228  children.insert(nit->first);
229 
230  // iterate over children and ..
231  typename set<N>::iterator cit = children.begin();
232  for(; cit!=children.end(); ++cit) {
233  segment_type key = segment_type(n,*cit); // create new direct path-segment
234  segment_type direct = segment_type(*cit,*cit);
235  set< segment_type > temp;
236  temp.insert(direct); // add direct connection as first member of set,
237  // but not as <A,B> but as <B,B> to mark a direct connection
238  //if(n != *cit) {
239  paths_.insert(std::make_pair(key,temp));
240  findSegments(n,temp); // look for previous segments leading to n
241  typename set< segment_type >::iterator sit = temp.begin();
242  for (; sit!=temp.end(); ++sit) { // iterator over already linked segments
243  if (sit->first != key.second) // don't insert <B,B> as key!
244  paths_[segment_type(sit->first,key.second)].insert(*sit);
245  }
246  //}
247  //calcPath(g,*cit);
248  }
249  for(cit=children.begin();cit!=children.end();++cit) {
250  //if (n != * cit)
251  calcPaths(g,*cit);
252  }
253 }
254 
255 
256 template <class N, class E>
257 void GraphPath<N,E>::findSegments(const N & n, set< segment_type >& result)
258 {
259  typename paths_type::iterator pit = paths_.begin();
260  for (; pit!=paths_.end(); ++pit) {
261  if (pit->first.second == n)
262  result.insert(pit->first);
263  }
264 }
265 
266 template <class N, class E>
267 void GraphPath<N,E>::stream(std::ostream & os)
268 {
269  typename paths_type::iterator it = paths_.begin();
270  for(; it!=paths_.end(); ++it) {
271  os << "[" << it->first.first << "->" << it->first.second << "] : ";
272  typename set<segment_type>::iterator sit = it->second.begin();
273  os << "< ";
274  for(; sit!=it->second.end();++sit) {
275  os << " [" << sit->first << "->" << sit->second << "] ";
276  }
277  os << " >" << std::endl;
278 
279  }
280 }
281 #endif
bool fromTo(const N &from, const N &to, std::vector< std::vector< N > > &result) const
Definition: graph_path.h:94
void stream(std::ostream &)
Definition: graph_path.h:267
void findSegments(const N &n, set< segment_type > &result)
Definition: graph_path.h:257
std::map< segment_type, set< segment_type > > paths_type
Definition: graph_path.h:18
std::vector< pair< N, N > > chain_type
Definition: graph_path.h:20
The Signals That Services Can Subscribe To This is based on ActivityRegistry and is current per Services can connect to the signals distributed by the ActivityRegistry in order to monitor the activity of the application Each possible callback has some defined which we here list in angle e g
Definition: Activities.doc:4
pair< N, N > segment_type
Definition: graph_path.h:16
set< std::vector< N > > paths_set
Definition: graph_path.h:19
std::vector< std::vector< segment_type > > result_type
Definition: graph_path.h:21
Definition: adjgraph.h:12
void update(segment_type &s, result_type &r, int pos) const
Definition: graph_path.h:175
#define N
Definition: blowfish.cc:9
void calcPaths(const graph< N, E > &g, const N &root)
Definition: graph_path.h:216
~GraphPath()
Definition: graph_path.h:23
bool paths2(const segment_type &ft, result_type &result) const
Definition: graph_path.h:125
paths_type paths_
Definition: graph_path.h:38
GraphPath(const graph< N, E > &g, const N &root)
Definition: graph_path.h:204