/// <summary> /// Determines whether the current path traverses the same /// nodes as the specified path in the same order, disregard /// which one is the starting node. /// </summary> public bool SameCycle(Path path) { ArrayList items = path._items.Clone() as ArrayList; if (items.Count != _items.Count) return false; int iterations = items.Count; for (int i = 0; i < iterations; i++) { if (SameCycle(items)) return true; object item = items[0]; items.RemoveAt(0); items.Add(item); } return false; }
/// <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]; }
private static PathList FindPaths(IGraph graph, INode from, INode to, bool shortestOnly) { PathList result = new PathList(); Path path = null; if (from == to && shortestOnly) { // Return a collection with a single path consisting of a single node. path = new Path(); path.Add(from); result.Add(path); return result; } // Perform the search PathList tempCol = new PathList(); Path tempPath; // Create the first path, constisting only of the first node tempCol.Add(tempPath = new Path()); tempPath.Add(from); bool pathFound = false; while (true) { int size = tempCol.Count; if (size == 0) break; if (pathFound && shortestOnly) break; // For all paths - get their next nodes for (int i = 0; i < size; i++) { tempPath = tempCol[0]; tempCol.RemoveAt(0); // Get the last node for this path and find its successors INode lastNode = tempPath.Nodes[tempPath.Nodes.Count - 1]; LinkCollection links = lastNode.OutLinks; foreach (ILink link in links) { INode nextNode; // Get the next node in the path nextNode = graph.Directed ? link.Destination : link.GetOppositeNode(lastNode); // Check if the path target is reached if (nextNode.Equals(to)) { // We've reached the end Path newPath = new Path(tempPath); newPath.Add(link, nextNode); result.Add(newPath); pathFound = true; continue; } // The node does not belong to the path -> add it if (!tempPath.Contains(nextNode)) { Path newPath = new Path(tempPath); newPath.Add(link, nextNode); tempCol.Add(newPath); } } } } return result; }
public Path(Path p) { _nodes = p._nodes.Clone() as NodeCollection; _links = p._links.Clone() as LinkCollection; _items = p._items.Clone() as ArrayList; }
public bool Contains(Path p) { return List.Contains(p); }
public void Remove(Path p) { List.Remove(p); }
public void Insert(int i, Path p) { List.Insert(i, p); }
public void Add(Path p) { List.Add(p); }