Пример #1
0
		/// <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;
		}
Пример #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];
		}
Пример #3
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;
		}
Пример #4
0
		public Path(Path p)
		{
			_nodes = p._nodes.Clone() as NodeCollection;
			_links = p._links.Clone() as LinkCollection;
			_items = p._items.Clone() as ArrayList;
		}
Пример #5
0
		public bool Contains(Path p)
		{
			return List.Contains(p);
		}
Пример #6
0
		public void Remove(Path p)
		{
			List.Remove(p);
		}
Пример #7
0
		public void Insert(int i, Path p)
		{
			List.Insert(i, p);
		}
Пример #8
0
		public void Add(Path p)
		{
			List.Add(p);
		}