Satsuma
a delicious .NET graph library
 All Classes Namespaces Files Functions Variables Enumerations Enumerator Properties Pages
Dfs.cs
Go to the documentation of this file.
1 #region License
2 /*This file is part of Satsuma Graph Library
3 Copyright © 2013 Balázs Szalkai
4 
5 This software is provided 'as-is', without any express or implied
6 warranty. In no event will the authors be held liable for any damages
7 arising from the use of this software.
8 
9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it
11 freely, subject to the following restrictions:
12 
13  1. The origin of this software must not be misrepresented; you must not
14  claim that you wrote the original software. If you use this software
15  in a product, an acknowledgment in the product documentation would be
16  appreciated but is not required.
17 
18  2. Altered source versions must be plainly marked as such, and must not be
19  misrepresented as being the original software.
20 
21  3. This notice may not be removed or altered from any source
22  distribution.*/
23 #endregion
24 
25 using System;
26 using System.Collections.Generic;
27 using System.Linq;
28 
29 namespace Satsuma
30 {
32  public abstract class Dfs
33  {
34  public enum Direction
35  {
37  Undirected,
39  Forward,
41  Backward
42  }
43 
44  protected IGraph Graph { get; private set; }
45  private HashSet<Node> traversed;
46  private ArcFilter arcFilter;
47 
49  protected int Level { get; private set; }
50 
55  public void Run(IGraph graph, IEnumerable<Node> roots = null)
56  {
57  Graph = graph;
58 
59  Direction direction;
60  Start(out direction);
61  switch (direction)
62  {
63  case Direction.Undirected: arcFilter = ArcFilter.All; break;
64  case Direction.Forward: arcFilter = ArcFilter.Forward; break;
65  default: arcFilter = ArcFilter.Backward; break;
66  }
67 
68  traversed = new HashSet<Node>();
69  foreach (var node in (roots ?? Graph.Nodes()))
70  {
71  if (traversed.Contains(node)) continue;
72 
73  Level = 0;
74  if (!Traverse(node, Arc.Invalid)) break;
75  }
76  traversed = null;
77 
78  StopSearch();
79  }
80 
81  private bool Traverse(Node node, Arc arc)
82  {
83  traversed.Add(node);
84  if (!NodeEnter(node, arc)) return false;
85 
86  foreach (var b in Graph.Arcs(node, arcFilter))
87  {
88  if (b == arc) continue;
89 
90  Node other = Graph.Other(b, node);
91  if (traversed.Contains(other))
92  {
93  if (!BackArc(node, b)) return false;
94  continue;
95  }
96 
97  Level++;
98  if (!Traverse(other, b)) return false;
99  Level--;
100  }
101 
102  return NodeExit(node, arc);
103  }
104 
106  protected abstract void Start(out Direction direction);
107 
113  protected virtual bool NodeEnter(Node node, Arc arc) { return true; }
114 
120  protected virtual bool NodeExit(Node node, Arc arc) { return true; }
121 
127  protected virtual bool BackArc(Node node, Arc arc) { return true; }
128 
130  protected virtual void StopSearch() { }
131  }
132 }