DiaDes  0.1
DIAgnosis of Discrete-Event System
FGFS.hh
Go to the documentation of this file.
1 #ifndef __DIADES__AUTOMATA__FGFS_HH_
2 #define __DIADES__AUTOMATA__FGFS_HH_
3 
4 #include <utils/Random.hh>
5 #include <utils/GraphSearch.hh>
7 
8 
9 
10 
11 
12 namespace Diades
13 {
14  namespace Utils
15  {
16 
24  template<typename TIncidentEdges,
25  typename TOpposite,
26  typename TContainer,
27  typename TAccumulator,
28  typename TMark,
29  typename TSolution,
30  typename TPathCut>
31  class GFS : public GraphSearch<TIncidentEdges,TOpposite,TContainer,TAccumulator,
32  TMark,TSolution,TPathCut>
33  {
34  public:
35  typedef GraphSearch<TIncidentEdges,TOpposite,TContainer,TAccumulator,
36  TMark,TSolution,TPathCut> Search;
37  typedef typename Search::Graph Graph;
38  typedef typename Search::Node Node;
39  typedef typename Search::Container Container;
40  typedef typename Search::Opposite Opposite;
41  typedef typename Search::Solution Solution;
42  typedef typename Search::PathCut PathCut;
43  typedef typename Search::Accumulator Accumulator;
45 
46  public:
59  GFS(Graph & graph, const Container & nodes,
60  const Opposite & opposite, Solution & s,
61  PathCut & cut, Accumulator & results):
62  Search(graph,nodes,opposite,s,cut,results),
63  _atTop(true),
64  _current(0),
65  _vnodes(),_stack(),
66  _saturated(graph),
67  _visiting(graph)
68  {
69  _vnodes.reserve(nodes.size());
70  for(const typename Search::Node & node : nodes)
71  {
72  _vnodes.push_back(node);
73  }
74  }
75 
79  virtual ~GFS(){}
80 
85  virtual void initialize()
86  {
88  _atTop = true;
89  }
90 
91 
92 
93  bool saturated(const typename Search::Node & node) const
94  {
95  return _saturated.isMarked(node);
96  }
97 
98  bool visited(const typename Search::Node & node)
99  {
100  return Search::_m.isMarked(node);
101  }
102 
103  void setVisited(const typename Search::Node & node)
104  {
105  Search::_m.mark(node);
106  }
107 
108  void setSaturated(const typename Search::Node & node)
109  {
110  _saturated.mark(node);
111  }
112 
113 
114 
115  bool isVisiting(const typename Search::Node & node) const
116  {
117  return _visiting.isMarked(node);
118  }
119 
120  void setVisiting(const typename Search::Node & node)
121  {
122  _visiting.mark(node);
123  }
124 
125  void unsetVisiting(const typename Search::Node & node)
126  {
127  _visiting.unmark(node);
128  }
129 
130 
131 
138  bool finished() const
139  {
140  bool result = true;
141  unsigned index =0;
142  while(result && (index < _vnodes.size()))
143  {
144  result = result && saturated(_vnodes[index]);
145  ++index;
146  }
147  return result;
148  }
149 
150 
151 
156  void popStack()
157  {
158  while(!_stack.empty())
159  {
160  unsetVisiting(_stack.top());
161  Node n = _stack.top();
162  _stack.pop();
163  if((!_stack.empty()) && saturated(n))
164  {
165  // the node n is saturated it may be enough to saturate the node behind n in the stack
166  IncidentEdges edges(Search::_graph,_stack.top(),Search::_cut);
167  bool isSaturated = true;
168  typename IncidentEdges::Iterator edgeIt = edges.begin();
169  while(isSaturated && (edgeIt != edges.end()))
170  {
171  isSaturated = saturated(Search::_opposite.next(*edgeIt,_stack.top()));
172  ++edgeIt;
173  }
174  if(isSaturated)
175  {
176  setSaturated(_stack.top());
177  }
178  }
179  }
180  }
181 
186  void next()
187  {
188  if(!finished())
189  {
190  if(_atTop)
191  {
192 
193  _current = (unsigned) generateRandomValue(0,_vnodes.size()-1);
194  _stack.push(_vnodes[_current]);
195  setVisiting(_vnodes[_current]);
196  //cout << "at top: we choose " << _vnodes[_current] << endl;
197  _atTop = false;
198 
199  }
200 
201  setVisited(_stack.top());
202  Node n = _stack.top();
203  //cout << "VISITED NODE: " << n << endl;
204  if(Search::_s.isSolution(n))
205  {
206  Search::_results.push_back(n);
207  Search::_updated = true;
208  //cout << "SOLUTION" << endl;
209  setSaturated(n);
210  popStack();
211  }
212  else
213  {
214  IncidentEdges edges(Search::_graph,n,Search::_cut);
215  bool noEdges = true;
216  vector< typename Search::Node > nodes;
217  //cout << "NEXT NODES (STACKED): " << endl;
218  for(typename IncidentEdges::Iterator edgeIt = edges.begin();
219  edgeIt != edges.end();
220  ++edgeIt)
221  {
222  noEdges=false;
223  const Node & nextNode = Search::_opposite.next(*edgeIt,n);
224  if(!isVisiting(nextNode))
225  {
226  nodes.push_back(nextNode);
227  //cout << '\t' << nextNode << endl;
228  }
229  }
230  if(noEdges)
231  {
232  setSaturated(n);
233  popStack();
234  //cout << "NO NEXT NODE" << endl;
235  }
236  else
237  {
238  if(!nodes.empty())
239  {
240  typename Search::Node node = pickup(nodes);
241  if(!saturated(node))
242  {
243  _stack.push(node);
244  setVisiting(node);
245  }
246  else
247  {
248  //cout << "next node " << node << " is already SATURATED" << endl;
249  setSaturated(n);
250  popStack();
251  }
252  }
253  else
254  {
255  setSaturated(n);
256  popStack();
257  //cout << "NO NEXT NODE" << endl;
258  }
259  }
260  }
261  _atTop = _stack.empty();
262  }
263  }
264 
265 
266 
267 
268  private:
269  bool _atTop;
270  unsigned _current;
271  vector< typename Search::Node > _vnodes;
272  stack< typename Search::Node > _stack;
273  mutable TMark _saturated;
274  mutable TMark _visiting;
275 
276  private:
277 
278  typename Search::Node pickup(const vector< typename Search::Node > & nodes)
279  {
280  vector< typename Search::Node > visitedNodes;
281  visitedNodes.reserve(nodes.size());
282  vector< typename Search::Node > nonVisitedNodes;
283  nonVisitedNodes.reserve(nodes.size());
284  for(const typename Search::Node & node : nodes)
285  {
286  if(!saturated(node))
287  {
288  if(visited(node))
289  {
290  visitedNodes.push_back(node);
291  }
292  else
293  {
294  nonVisitedNodes.push_back(node);
295  }
296  }
297  }
298  if(!nonVisitedNodes.empty())
299  {
300  long index = Diades::Utils::generateRandomValue(0,nonVisitedNodes.size()-1);
301  return nonVisitedNodes[(unsigned) index];
302  }
303  if(!visitedNodes.empty())
304  {
305  long index = Diades::Utils::generateRandomValue(0,visitedNodes.size()-1);
306  return visitedNodes[(unsigned) index];
307  }
308  long index = Diades::Utils::generateRandomValue(0,nodes.size()-1);
309  return nodes[(unsigned) index];
310  }
311 
312 
313  };
314  };
315 
316 
317  namespace Automata
318  {
323 
324  };
325 };
326 #endif
Search::Node Node
Definition: FGFS.hh:38
IncidentEdges::Node Node
Definition: GraphSearch.hh:63
Search::Graph Graph
Definition: FGFS.hh:37
void setVisited(const typename Search::Node &node)
Definition: FGFS.hh:103
vector< typename Search::Node > _vnodes
Definition: FGFS.hh:271
TIncidentEdges IncidentEdges
Definition: GraphSearch.hh:58
ComposableModelSearch< Diades::Utils::GFS< NextTransitions, TargetDiagState, list< DiagState >, list< DiagState >, VisitedDiagState, IsCandidate, IncorrectPath > > FGFS
Definition: FGFS.hh:322
void setSaturated(const typename Search::Node &node)
Definition: FGFS.hh:108
Search::PathCut PathCut
Definition: FGFS.hh:42
const Opposite & _opposite
Definition: GraphSearch.hh:131
GraphSearch< TIncidentEdges, TOpposite, TContainer, TAccumulator, TMark, TSolution, TPathCut > Search
Definition: FGFS.hh:36
IncidentEdges::Graph Graph
Definition: GraphSearch.hh:62
stack< typename Search::Node > _stack
Definition: FGFS.hh:272
Random generation utilities.
bool saturated(const typename Search::Node &node) const
Definition: FGFS.hh:93
Namespace of the Diades project.
Search::Container Container
Definition: FGFS.hh:39
Search::IncidentEdges IncidentEdges
Definition: FGFS.hh:44
bool visited(const typename Search::Node &node)
Definition: FGFS.hh:98
unsigned _current
Definition: FGFS.hh:270
TMark _saturated
Definition: FGFS.hh:273
void setVisiting(const typename Search::Node &node)
Definition: FGFS.hh:120
Search::Node pickup(const vector< typename Search::Node > &nodes)
Definition: FGFS.hh:278
void unsetVisiting(const typename Search::Node &node)
Definition: FGFS.hh:125
virtual ~GFS()
Definition: FGFS.hh:79
virtual void initialize()
Definition: FGFS.hh:85
Search::Opposite Opposite
Definition: FGFS.hh:40
bool finished() const
Definition: FGFS.hh:138
long generateRandomValue(long lower, long upper)
void popStack()
Definition: FGFS.hh:156
Search::Solution Solution
Definition: FGFS.hh:41
TMark _visiting
Definition: FGFS.hh:274
Search::Accumulator Accumulator
Definition: FGFS.hh:43
GFS(Graph &graph, const Container &nodes, const Opposite &opposite, Solution &s, PathCut &cut, Accumulator &results)
Definition: FGFS.hh:59
bool isVisiting(const typename Search::Node &node) const
Definition: FGFS.hh:115