/// <summary> /// Finds the longest path in the graph. The time limit /// specifies the maximum duration of the search process /// in milliseconds. /// Returns null if no path exists. /// </summary> public static Path FindLongestPath(IGraph graph, long timeLimit) { PathList paths = new PathList(); // create initial set of paths of length zero foreach (INode node in graph.Nodes) { // create a path consisting only of this node Path path = new Path(); path.Add(node); paths.Add(path); // paths in which this node participates PathStats pathStats = new PathStats(); pathStats.currentSet.Add(path, path); node.Data = pathStats; } long startMillis = DateTime.Now.Ticks / 10000; // find set of paths that are one node longer than in previous set bool morePathsAdded = false; do { morePathsAdded = false; PathList newPaths = new PathList(); // try to extend each path in the previous set foreach (Path path in paths) { INode lastNode = path.Nodes[path.Nodes.Count - 1]; foreach (ILink link in lastNode.OutLinks) { INode nodeToAdd = graph.Directed ? link.Destination : link.GetOppositeNode(lastNode); // test for cycles PathStats testPaths = nodeToAdd.Data as PathStats; if (testPaths.currentSet.Contains(path)) continue; // extend the path with this node Path newPath = new Path(path); newPath.Add(link, nodeToAdd); // update all nodes in the new path foreach (INode node in newPath.Nodes) { PathStats nodePaths = node.Data as PathStats; nodePaths.newSet.Add(newPath, newPath); } // add to the new set morePathsAdded = true; newPaths.Add(newPath); } } if (morePathsAdded) { paths = newPaths; // remove shorter paths from node associated path lists // they are not needed in next iterations foreach (INode node in graph.Nodes) { PathStats nodePaths = node.Data as PathStats; Hashtable swap = nodePaths.currentSet; nodePaths.currentSet = nodePaths.newSet; nodePaths.newSet = swap; nodePaths.newSet.Clear(); } } // Check time limit if (timeLimit > 0 && DateTime.Now.Ticks / 10000 - startMillis > timeLimit) break; } while (morePathsAdded); // cleanup foreach (INode node in graph.Nodes) node.Data = null; if (paths.Count == 0) return null; return paths[0]; }
/// <summary> /// Finds the longest path in the graph. The time limit /// specifies the maximum duration of the search process /// in milliseconds. /// Returns null if no path exists. /// </summary> public static Path FindLongestPath(IGraph graph, long timeLimit) { PathList paths = new PathList(); // create initial set of paths of length zero foreach (INode node in graph.Nodes) { // create a path consisting only of this node Path path = new Path(); path.Add(node); paths.Add(path); // paths in which this node participates PathStats pathStats = new PathStats(); pathStats.currentSet.Add(path, path); node.Data = pathStats; } long startMillis = DateTime.Now.Ticks / 10000; // find set of paths that are one node longer than in previous set bool morePathsAdded = false; do { morePathsAdded = false; PathList newPaths = new PathList(); // try to extend each path in the previous set foreach (Path path in paths) { INode lastNode = path.Nodes[path.Nodes.Count - 1]; foreach (ILink link in lastNode.OutLinks) { INode nodeToAdd = graph.Directed ? link.Destination : link.GetOppositeNode(lastNode); // test for cycles PathStats testPaths = nodeToAdd.Data as PathStats; if (testPaths.currentSet.Contains(path)) { continue; } // extend the path with this node Path newPath = new Path(path); newPath.Add(link, nodeToAdd); // update all nodes in the new path foreach (INode node in newPath.Nodes) { PathStats nodePaths = node.Data as PathStats; nodePaths.newSet.Add(newPath, newPath); } // add to the new set morePathsAdded = true; newPaths.Add(newPath); } } if (morePathsAdded) { paths = newPaths; // remove shorter paths from node associated path lists // they are not needed in next iterations foreach (INode node in graph.Nodes) { PathStats nodePaths = node.Data as PathStats; Hashtable swap = nodePaths.currentSet; nodePaths.currentSet = nodePaths.newSet; nodePaths.newSet = swap; nodePaths.newSet.Clear(); } } // Check time limit if (timeLimit > 0 && DateTime.Now.Ticks / 10000 - startMillis > timeLimit) { break; } }while (morePathsAdded); // cleanup foreach (INode node in graph.Nodes) { node.Data = null; } if (paths.Count == 0) { return(null); } return(paths[0]); }