Beispiel #1
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];
		}
Beispiel #2
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]);
        }