Exemplo n.º 1
0
        /// <summary>
        /// Finds and returns the shortest path between from and to,
        /// considering the weight of the nodes, the weight of the
        /// links or both.
        /// </summary>
        public static Path FindShortestPath(IGraph graph, INode from, INode to,
                                            bool useNodeWeights, bool useLinkWeights)
        {
            if (!useNodeWeights && !useLinkWeights)
            {
                return(FindShortestPath(graph, from, to));
            }

            // Find all paths between from and to and
            // pick the less heavy one
            PathList paths = FindPaths(graph, from, to, false);

            if (paths.Count == 0)
            {
                return(null);
            }

            SortedList table = new SortedList();

            foreach (Path path in paths)
            {
                table[path.GetWeight(useNodeWeights, useLinkWeights)] = path;
            }

            // Return the first path
            return(table[table.GetKey(0)] as Path);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Finds the longest path between two nodes.
        /// Returns null if no path exists.
        /// </summary>
        public static Path FindLongestPath(IGraph graph, INode from, INode to)
        {
            PathList paths = FindPaths(graph, from, to, false);

            if (paths.Count > 0)
            {
                return(paths[paths.Count - 1]);
            }
            else
            {
                return(null);
            }
        }
Exemplo n.º 3
0
        /// <summary>
        /// Finds and returns the shortest path between from and to.
        /// Returns null if no path exists.
        /// </summary>
        public static Path FindShortestPath(IGraph graph, INode from, INode to)
        {
            PathList paths = FindPaths(graph, from, to, true);

            if (paths.Count > 0)
            {
                return(paths[0]);
            }
            else
            {
                return(null);
            }
        }
Exemplo n.º 4
0
        /// <summary>
        /// Detects whether the specified node participates in a cycle.
        /// </summary>
        public static Path FindCycle(IGraph graph, INode participant)
        {
            PathList cycles = FindPaths(graph, participant, participant, false);

            if (cycles.Count > 0)
            {
                // Remove the last node from the path to avoid duplicates
                Path path = cycles[0];
                path.Nodes.RemoveAt(path.Nodes.Count - 1);
                path.Items.RemoveAt(path.Items.Count - 1);

                return(path);
            }

            return(null);
        }
Exemplo n.º 5
0
        /// <summary>
        /// Detects whether there is a cycle in a graph.
        /// </summary>
        public static Path FindCycle(IGraph graph)
        {
            foreach (INode node in graph.Nodes)
            {
                PathList cycles = FindPaths(graph, node, node, false);

                if (cycles.Count > 0)
                {
                    // Remove the last node from the path to avoid duplicates
                    Path path = cycles[0];
                    path.Nodes.RemoveAt(path.Nodes.Count - 1);
                    path.Items.RemoveAt(path.Items.Count - 1);

                    return(path);
                }
            }

            return(null);
        }
Exemplo n.º 6
0
        public static PathList FindAllCycles(IGraph graph)
        {
            PathList result = new PathList();

            foreach (INode node in graph.Nodes)
            {
                PathList cycles = FindPaths(graph, node, node, false);

                // Remove the last node from the path to avoid duplicates
                foreach (Path path in cycles)
                {
                    path.Nodes.RemoveAt(path.Nodes.Count - 1);
                    path.Items.RemoveAt(path.Items.Count - 1);
                }

                // Add cycles to result list skipping equal sycles.
                foreach (Path path in cycles)
                {
                    bool found = false;
                    foreach (Path path2 in result)
                    {
                        if (path2.SameCycle(path))
                        {
                            found = true;
                            break;
                        }
                    }

                    if (!found)
                    {
                        result.Add(path);
                    }
                }
            }

            return(result);
        }
Exemplo n.º 7
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;
		}
Exemplo n.º 8
0
		public static PathList FindAllCycles(IGraph graph)
		{
			PathList result = new PathList();

			foreach (INode node in graph.Nodes)
			{
				PathList cycles = FindPaths(graph, node, node, false);

				// Remove the last node from the path to avoid duplicates
				foreach (Path path in cycles)
				{
					path.Nodes.RemoveAt(path.Nodes.Count - 1);
					path.Items.RemoveAt(path.Items.Count - 1);
				}

				// Add cycles to result list skipping equal sycles.
				foreach (Path path in cycles)
				{
					bool found = false;
					foreach (Path path2 in result)
					{
						if (path2.SameCycle(path))
						{
							found = true;
							break;
						}
					}

					if (!found)
						result.Add(path);
				}
			}

			return result;
		}
Exemplo n.º 9
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];
		}
Exemplo n.º 10
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);
        }
Exemplo n.º 11
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]);
        }