internal static BidirectionalGraph <TEdgeData> CreateSubGraph <TEdgeData>(this BidirectionalGraphDirectNodeAccess <TEdgeData> graph, Dictionary <long, bool> nodesOfSubGraph) { var newGraph = new BidirectionalGraph <TEdgeData>(); foreach (var node in nodesOfSubGraph) { var newInEdges = newGraph.GetOrCreateInEdges(node.Key); foreach (var inEdge in graph.InEdges(node.Key)) { if (nodesOfSubGraph.ContainsKey(inEdge.Source)) { newInEdges.Add(inEdge); } } var newOutEdges = newGraph.GetOrCreateOutEdges(node.Key); foreach (var outEdge in graph.OutEdges(node.Key)) { if (nodesOfSubGraph.ContainsKey(outEdge.Target)) { newOutEdges.Add(outEdge); } } } return(newGraph); }
internal static Dictionary <long, bool> GetAncestors <TEdgeData>(this BidirectionalGraphDirectNodeAccess <TEdgeData> graph, IEnumerable <long> targetNodes, Func <long, bool> ignoreNodeFunc, Func <Edge <TEdgeData>, bool> ignoreEdgeFunc = null) { // standard behavior: do not ignore node or edge // node in toNodes are their own ancestors, if they are not ignored by ignoreNodeFunc // based on DFS https://en.wikipedia.org/wiki/Depth-first_search var ancestors = new Dictionary <long, bool>(); var nodesToTraverse = new Stack <long>(); foreach (var node in targetNodes) { nodesToTraverse.Push(node); } while (nodesToTraverse.Count > 0) { var currentNode = nodesToTraverse.Pop(); var isIgnored = (ignoreNodeFunc != null && ignoreNodeFunc(currentNode)); var alreadyDiscovered = ancestors.ContainsKey(currentNode); if (!(isIgnored || alreadyDiscovered)) { ancestors.Add(currentNode, true); foreach (var inEdge in graph.InEdges(currentNode)) { if (ignoreEdgeFunc == null || !ignoreEdgeFunc(inEdge)) { nodesToTraverse.Push(inEdge.Source); } } } } return(ancestors); }
internal static Dictionary <long, bool> GetAncestors <TEdgeData>(this BidirectionalGraphDirectNodeAccess <TEdgeData> graph, Dictionary <long, bool> targetNodes) { // standard behavior: do not ignore node or edge // node in toNodes are their own ancestors, if they are not ignored by ignoreNodeFunc // based on DFS https://en.wikipedia.org/wiki/Depth-first_search var nodesAdded = new Dictionary <long, bool>(); var nodesToTraverse = new Stack <long>(); foreach (var node in targetNodes) { nodesToTraverse.Push(node.Key); } while (nodesToTraverse.Count > 0) { var currentNode = nodesToTraverse.Pop(); var alreadyDiscovered = nodesAdded.ContainsKey(currentNode); if (!alreadyDiscovered) { nodesAdded.Add(currentNode, true); foreach (var inEdge in graph.InEdges(currentNode)) { nodesToTraverse.Push(inEdge.Source); } } } return(nodesAdded); }
public BidirectionalGraphSubViewDecorator(BidirectionalGraphDirectNodeAccess <TEdgeData> baseGraph, Func <long, bool> ignoreNodeFunc = null, Func <Edge <TEdgeData>, bool> ignoreEdgeFunc = null) { _baseGraph = baseGraph; _ignoreNodeFunc = ignoreNodeFunc; _ignoreEdgeFunc = ignoreEdgeFunc; }
internal static void GetAncestors(this BidirectionalGraphDirectNodeAccess graph, Func <int, bool> nodeIsAncestor, Action <int> nodeSetAncestor, IEnumerable <int> targetNodes, Func <int, bool> ignoreNodeFunc, Func <Edge, bool> ignoreEdgeFunc = null) { // standard behavior: do not ignore node or edge // node in toNodes are their own ancestors, if they are not ignored by ignoreNodeFunc // based on DFS https://en.wikipedia.org/wiki/Depth-first_search var nodesToTraverse = new Stack <int>(); foreach (var node in targetNodes) { nodesToTraverse.Push(node); } while (nodesToTraverse.Count > 0) { var currentNode = nodesToTraverse.Pop(); var isIgnored = (ignoreNodeFunc != null && ignoreNodeFunc(currentNode)); var alreadyDiscovered = nodeIsAncestor(currentNode); if (!(isIgnored || alreadyDiscovered)) { nodeSetAncestor(currentNode); foreach (var inEdge in graph.InEdges(currentNode)) { if (ignoreEdgeFunc == null || !ignoreEdgeFunc(inEdge)) { nodesToTraverse.Push(inEdge.Source); } } } } }
public BidirectionalGraphSubViewDecorator(BidirectionalGraphDirectNodeAccess baseGraph, Func <int, bool> ignoreNodeFunc = null, Func <Edge, bool> ignoreEdgeFunc = null) { _baseGraph = baseGraph; _ignoreNodeFunc = ignoreNodeFunc; _ignoreEdgeFunc = ignoreEdgeFunc; }