/// <summary> /// Removes nodes that are part of redundant paths. /// </summary> /// <param name="graph">De Bruijn graph</param> /// <param name="nodesList">Path nodes to be deleted</param> public void RemoveErroneousNodes(DeBruijnGraph graph, DeBruijnPathList nodesList) { DeBruijnGraph.ValidateGraph(graph); if (nodesList == null) { throw new ArgumentNullException("nodesList"); } _graph = graph; // Neighbors of all nodes have to be updated. HashSet <DeBruijnNode> deleteNodes = new HashSet <DeBruijnNode>( nodesList.Paths.AsParallel().SelectMany(nl => nl.PathNodes)); // Update extensions for deletion // No need for read-write lock as deleteNode's dictionary is being read, // and only other graph node's dictionaries are updated Parallel.ForEach(deleteNodes, node => { foreach (DeBruijnNode extension in node.LeftExtensionNodes.Keys.Union(node.RightExtensionNodes.Keys)) { // If the neighbor is also to be deleted, there is no use of updation in that case if (!deleteNodes.Contains(extension)) { extension.RemoveExtensionThreadSafe(node); } } }); // Delete nodes from graph _graph.RemoveNodes(deleteNodes); }
/// <summary> /// Removes nodes that are part of dangling links. /// </summary> /// <param name="deBruijnGraph">Input graph.</param> /// <param name="nodesList">List of dangling link nodes.</param> public void RemoveErroneousNodes(DeBruijnGraph deBruijnGraph, DeBruijnPathList nodesList) { // Argument Validation if (deBruijnGraph == null) { throw new ArgumentNullException("deBruijnGraph"); } if (nodesList == null) { throw new ArgumentNullException("nodesList"); } HashSet <DeBruijnNode> lastNodes = new HashSet <DeBruijnNode>(nodesList.Paths.Select(nl => nl.PathNodes.Last())); // Update extensions and Delete nodes from graph. deBruijnGraph.RemoveNodes( nodesList.Paths.AsParallel().SelectMany(nodes => { RemoveLinkNodes(nodes, lastNodes); return(nodes.PathNodes); })); }