Satsuma
a delicious .NET graph library
 All Classes Namespaces Files Functions Variables Enumerations Enumerator Properties Pages
Subgraph.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 {
40  public sealed class Subgraph : IGraph
41  {
42  private IGraph graph;
43 
44  private bool defaultNodeEnabled;
45  private HashSet<Node> nodeExceptions = new HashSet<Node>();
46  private bool defaultArcEnabled;
47  private HashSet<Arc> arcExceptions = new HashSet<Arc>();
48 
49  public Subgraph(IGraph graph)
50  {
51  this.graph = graph;
52 
53  EnableAllNodes(true);
54  EnableAllArcs(true);
55  }
56 
59  public void EnableAllNodes(bool enabled)
60  {
61  defaultNodeEnabled = enabled;
62  nodeExceptions.Clear();
63  }
64 
67  public void EnableAllArcs(bool enabled)
68  {
69  defaultArcEnabled = enabled;
70  arcExceptions.Clear();
71  }
72 
75  public void Enable(Node node, bool enabled)
76  {
77  bool exception = (defaultNodeEnabled != enabled);
78  if (exception)
79  nodeExceptions.Add(node);
80  else nodeExceptions.Remove(node);
81  }
82 
85  public void Enable(Arc arc, bool enabled)
86  {
87  bool exception = (defaultArcEnabled != enabled);
88  if (exception)
89  arcExceptions.Add(arc);
90  else arcExceptions.Remove(arc);
91  }
92 
94  public bool IsEnabled(Node node)
95  {
96  return defaultNodeEnabled ^ nodeExceptions.Contains(node);
97  }
98 
100  public bool IsEnabled(Arc arc)
101  {
102  return defaultArcEnabled ^ arcExceptions.Contains(arc);
103  }
104 
105  public Node U(Arc arc)
106  {
107  return graph.U(arc);
108  }
109 
110  public Node V(Arc arc)
111  {
112  return graph.V(arc);
113  }
114 
115  public bool IsEdge(Arc arc)
116  {
117  return graph.IsEdge(arc);
118  }
119 
120  private IEnumerable<Node> NodesInternal()
121  {
122  foreach (var node in graph.Nodes())
123  if (IsEnabled(node)) yield return node;
124  }
125 
126  public IEnumerable<Node> Nodes()
127  {
128  if (nodeExceptions.Count == 0)
129  {
130  if (defaultNodeEnabled) return graph.Nodes();
131  return Enumerable.Empty<Node>();
132  }
133  return NodesInternal();
134  }
135 
136  public IEnumerable<Arc> Arcs(ArcFilter filter = ArcFilter.All)
137  {
138  foreach (var arc in graph.Arcs(filter))
139  if (IsEnabled(arc) && IsEnabled(graph.U(arc)) && IsEnabled(graph.V(arc))) yield return arc;
140  }
141 
142  public IEnumerable<Arc> Arcs(Node u, ArcFilter filter = ArcFilter.All)
143  {
144  if (!IsEnabled(u)) yield break;
145  foreach (var arc in graph.Arcs(u, filter))
146  if (IsEnabled(arc) && IsEnabled(graph.Other(arc, u))) yield return arc;
147  }
148 
149  public IEnumerable<Arc> Arcs(Node u, Node v, ArcFilter filter = ArcFilter.All)
150  {
151  if (!IsEnabled(u) || !IsEnabled(v)) yield break;
152  foreach (var arc in graph.Arcs(u, v, filter))
153  if (IsEnabled(arc)) yield return arc;
154  }
155 
156  public int NodeCount()
157  {
158  return defaultNodeEnabled ? graph.NodeCount() - nodeExceptions.Count : nodeExceptions.Count;
159  }
160 
161  public int ArcCount(ArcFilter filter = ArcFilter.All)
162  {
163  if (nodeExceptions.Count == 0 && filter == ArcFilter.All)
164  return defaultNodeEnabled ?
165  (defaultArcEnabled ? graph.ArcCount() - arcExceptions.Count : arcExceptions.Count)
166  : 0;
167 
168  return Arcs(filter).Count();
169  }
170 
171  public int ArcCount(Node u, ArcFilter filter = ArcFilter.All)
172  {
173  return Arcs(u, filter).Count();
174  }
175 
176  public int ArcCount(Node u, Node v, ArcFilter filter = ArcFilter.All)
177  {
178  return Arcs(u, v, filter).Count();
179  }
180 
181  public bool HasNode(Node node)
182  {
183  return graph.HasNode(node) && IsEnabled(node);
184  }
185 
186  public bool HasArc(Arc arc)
187  {
188  return graph.HasArc(arc) && IsEnabled(arc);
189  }
190  }
191 }