Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
st_number.cpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file st_number.cpp
1 /* This software is distributed under the GNU Lesser General Public License */
2 //==========================================================================
3 //
4 // st_number.cpp
5 //
6 //==========================================================================
7 // $Id: st_number.cpp,v 1.10 2001/11/07 13:58:11 pick Exp $
8 
9 #include <GTL/st_number.h>
10 
11 #include <cassert>
12 
13 #ifdef __GTL_MSVCC
14 # ifdef _DEBUG
15 # ifndef SEARCH_MEMORY_LEAKS_ENABLED
16 # error SEARCH NOT ENABLED
17 # endif
18 # define new DEBUG_NEW
19 # undef THIS_FILE
20  static char THIS_FILE[] = __FILE__;
21 # endif // _DEBUG
22 #endif // __GTL_MSVCC
23 
25 
27 {
28  node t = s.opposite (st);
29  dfs_num.init (G, 0);
30  low_num.init (G);
31  tree.init (G, list<edge>());
32  back.init (G, list<edge>());
33  forward.init (G, list<edge>());
34 
35  //
36  // There is a problem with node/edge maps of iterators with Visual C++
37  // which I donīt fully understand at the moment. Anyway the init for the
38  // maps below is only needed to allocate memory, which is done anyway, when
39  // values are assigned to it.
40  //
41 
42 #ifndef __GTL_MSVCC
43  to_low.init (G);
44  to_father.init (G);
45  pos.init (G);
46 #endif
47 
48  used.init (G,0);
49  act_dfs_num = 1;
51  is_biconn = true;
52 
53  //
54  // Do DFS with biconnectivity extensions.
55  //
56 
57  dfs_num[t] = act_dfs_num++;
58  low_num[t] = dfs_num[t];
59  new_nodes--;
60 
61  dfs_sub (s, t);
62 
63  if (new_nodes != 0) {
64  is_biconn = false;
65  }
66 
67  used[t] = used[s] = 1;
68 }
69 
70 
71 void pathfinder::dfs_sub (node& curr, node& father)
72 {
73  low_num[curr] = dfs_num[curr] = act_dfs_num++;
74  new_nodes--;
75 
78 
79  while (it != end) {
80  edge adj = *it;
81  node opp = curr.opposite(adj);
82 
83  if (dfs_num[opp] == 0) {
84 
85  list<edge>::iterator tmp =
86  tree[curr].insert (tree[curr].end(), adj);
87  to_father[opp] = tmp;
88 
89  dfs_sub (opp, curr);
90 
91  if (low_num[opp] < low_num[curr]) {
92  low_num[curr] = low_num[opp];
93  to_low[curr] = tmp;
94  }
95 
96  if (low_num[opp] >= dfs_num[curr]) {
97  is_biconn = false;
98  }
99 
100  } else if (opp != father && dfs_num[opp] < dfs_num[curr]) {
101  list<edge>::iterator back_pos =
102  back[curr].insert (back[curr].end(), adj);
103  list<edge>::iterator forward_pos =
104  forward[opp].insert (forward[opp].end(), adj);
105  pos[adj] = pos_pair (forward_pos, back_pos);
106 
107  if (dfs_num[opp] < low_num[curr]) {
108  low_num[curr] = dfs_num[opp];
109  to_low[curr] = back_pos;
110  }
111  }
112 
113  ++it;
114  }
115 }
116 
117 
118 //--------------------------------------------------------------------------
119 // ITERATOR
120 //--------------------------------------------------------------------------
121 
123  pf (_pf)
124 {
125  if (!pf.back[n].empty()) {
126  edge back = pf.back[n].front();
127  curr = n.opposite (back);
128  pf.used[curr] = 1;
129  pf.back[n].pop_front();
130  pf.forward[curr].erase (pf.pos[back].first);
131  state = END;
132 
133  } else if (!pf.tree[n].empty()) {
134  curr = n.opposite (pf.tree[n].front());
135  pf.used[curr] = 1;
136  pf.tree[n].pop_front();
137  state = DOWN;
138 
139  } else if (!pf.forward[n].empty()) {
140  edge forward = pf.forward[n].front();
141  curr = n.opposite (forward);
142  pf.forward[n].pop_front();
143  pf.back[curr].erase (pf.pos[forward].second);
144 
145  if (pf.used[curr]) {
146  state = END;
147  } else {
148  pf.used[curr] = 1;
149  state = UP;
150  }
151  }
152 }
153 
155 {
156  list<edge>::iterator tmp;
157  edge adj;
158  node opp;
159 
160  switch (state) {
161  case END :
162  curr = node();
163  break;
164 
165  case UP :
166  tmp = pf.to_father[curr];
167  curr = curr.opposite (*tmp);
168  pf.tree[curr].erase (tmp);
169 
170  if (pf.used[curr]) {
171  state = END;
172  } else {
173  pf.used[curr] = 1;
174  }
175 
176  break;
177 
178  case DOWN :
179  tmp = pf.to_low[curr];
180  adj = *tmp;
181  opp = curr.opposite (adj);
182 
183  if (pf.used[opp]) {
184  pf.forward[opp].erase (pf.pos[adj].first);
185  pf.back[curr].erase (tmp);
186  state = END;
187  } else {
188  pf.tree[curr].erase (tmp);
189  pf.used[opp] = 1;
190  }
191 
192  curr = opp;
193  break;
194 
195  default:
196  assert (0);
197  }
198 
199  return *this;
200 }
201 
202 
204 {
205  const_iterator tmp = *this;
206  operator++();
207  return tmp;
208 }
209 
210 
211 //--------------------------------------------------------------------------
212 // ST-NUMBER
213 //--------------------------------------------------------------------------
214 
216 {
217  if (G.is_directed()) return GTL_ERROR;
218 
219  pf = new pathfinder (G, st, s);
220 
221  return pf->is_valid() ? GTL_OK : GTL_ERROR;
222 }
223 
224 
226 {
227  list<node> order;
228  node t = s.opposite (st);
229  order.push_back (t);
230  node tmp = s;
231  pathfinder::const_iterator end = pf->end ();
232  int act_st = 1;
233 
234  while (tmp != t) {
235  pathfinder::const_iterator it = pf->path (tmp);
236  list<node>::iterator pos;
237 
238  if (it == end) {
239  st_num[tmp] = act_st++;
240  st_ord.push_back(tmp);
241  tmp = order.back();
242  order.pop_back();
243 
244  } else {
245  pos = order.end();
246 
247  while (it != end) {
248  pos = order.insert (pos, *it);
249  ++it;
250  }
251 
252  order.erase (pos);
253  }
254  }
255 
256  st_num[t] = act_st;
257  st_ord.push_back (t);
258 
259  delete pf;
260 
261  return GTL_OK;
262 }
263 
265 
266 //--------------------------------------------------------------------------
267 // end of file
268 //--------------------------------------------------------------------------