/// <summary> /// Recurcively find all paths from node to finishNode. /// Deep graph search algorithm is used. /// </summary> /// <param name="node">node</param> private void FindPaths(RoadNode node) { if (node == null) { return; } if (node == finishNode) { //if we have reached finish node, remember the current path pathsFound.Add((RoadPath)currentPath.Clone()); } else { List <RoadNode> neighbours = GetNeighbours(node); foreach (RoadNode neighbour in neighbours) { if (!visitedNodes.Contains(neighbour)) { visitedNodes.Add(neighbour); currentPath.Push(neighbour); FindPaths(neighbour); visitedNodes.Remove(neighbour); currentPath.Pop(); } } } }
/// <summary> /// Find all paths in road graph from start node to finish node /// </summary> /// <returns>Found paths</returns> public List <RoadPath> FindAllPaths() { CheckMapErrors(roadMap); startNode = roadMap.Nodes.Where(n => n.Role == RoadNodeRole.Start).Single(); finishNode = roadMap.Nodes.Where(n => n.Role == RoadNodeRole.Finish).Single(); visitedNodes.Add(startNode); currentPath.Push(startNode); FindPaths(startNode); return(pathsFound); }
/// <summary> /// Find all paths in road graph from start node to finish node /// </summary> /// <returns>Found paths</returns> public List<RoadPath> FindAllPaths() { CheckMapErrors(roadMap); startNode = roadMap.Nodes.Where(n => n.Role == RoadNodeRole.Start).Single(); finishNode = roadMap.Nodes.Where(n => n.Role == RoadNodeRole.Finish).Single(); visitedNodes.Add(startNode); currentPath.Push(startNode); FindPaths(startNode); return pathsFound; }
/// <summary> /// Get non-crashed nodes connected with the node /// </summary> /// <param name="node"></param> /// <returns>list of neighbour nodes</returns> private List <RoadNode> GetNeighbours(RoadNode node) { if (node == null) { return(null); } List <RoadNode> neighbours = new List <RoadNode>(); foreach (var link in node.Links) { RoadNode neighbourByLink = roadMap.Nodes.Where(n => n.Id == link.RefNodeId).Single(); if (neighbourByLink.State == RoadNodeState.Ok) { neighbours.Add(neighbourByLink); } } return(neighbours); }
/// <summary> /// Parse source road map XML document /// </summary> /// <param name="sourceXml">road map XML document</param> /// <returns>parsed RoadMap object</returns> public static RoadMap ParseRoadMapXml(XmlDocument sourceXml) { if (sourceXml == null) { return(null); } RoadMap roadMap = new RoadMap(); if (ValidateSchema(sourceXml)) { XmlNode graph = sourceXml.SelectNodes("/graph").Item(0); XmlNodeList nodes = graph.SelectNodes("node"); foreach (XmlNode node in nodes) { RoadNodeRole nodeRole = RoadNodeRole.Normal; if (node.Attributes["role"] != null && node.Attributes["role"].Value == "start") { nodeRole = RoadNodeRole.Start; } else if (node.Attributes["role"] != null && node.Attributes["role"].Value == "finish") { nodeRole = RoadNodeRole.Finish; } RoadNodeState nodeState = RoadNodeState.Ok; if (node.Attributes["status"] != null && node.Attributes["status"].Value == "crash") { nodeState = RoadNodeState.Crash; } int nodeId = Convert.ToInt32(node.Attributes["id"].Value); RoadNode roadNode = new RoadNode(nodeId, nodeRole, nodeState); XmlNodeList links = node.SelectNodes("link"); foreach (XmlNode link in links) { int linkRef = Convert.ToInt32(link.Attributes["ref"].Value); int linkWeight = Convert.ToInt32(link.Attributes["weight"].Value); RoadLink roadLink = new RoadLink(linkWeight, linkRef); roadNode.Links.Add(roadLink); } roadMap.Nodes.Add(roadNode); } } return(roadMap); }
/// <summary> /// Parse source road map XML document /// </summary> /// <param name="sourceXml">road map XML document</param> /// <returns>parsed RoadMap object</returns> public static RoadMap ParseRoadMapXml(XmlDocument sourceXml) { if (sourceXml == null) return null; RoadMap roadMap = new RoadMap(); if (ValidateSchema(sourceXml)) { XmlNode graph = sourceXml.SelectNodes("/graph").Item(0); XmlNodeList nodes = graph.SelectNodes("node"); foreach (XmlNode node in nodes) { RoadNodeRole nodeRole = RoadNodeRole.Normal; if (node.Attributes["role"] != null && node.Attributes["role"].Value == "start") { nodeRole = RoadNodeRole.Start; } else if (node.Attributes["role"] != null &&node.Attributes["role"].Value == "finish") { nodeRole = RoadNodeRole.Finish; } RoadNodeState nodeState = RoadNodeState.Ok; if (node.Attributes["status"] != null && node.Attributes["status"].Value == "crash") { nodeState = RoadNodeState.Crash; } int nodeId = Convert.ToInt32(node.Attributes["id"].Value); RoadNode roadNode = new RoadNode(nodeId, nodeRole, nodeState); XmlNodeList links = node.SelectNodes("link"); foreach (XmlNode link in links) { int linkRef = Convert.ToInt32(link.Attributes["ref"].Value); int linkWeight = Convert.ToInt32(link.Attributes["weight"].Value); RoadLink roadLink = new RoadLink(linkWeight, linkRef); roadNode.Links.Add(roadLink); } roadMap.Nodes.Add(roadNode); } } return roadMap; }
/// <summary> /// Check if all links between nodes are correct. /// </summary> /// <param name="roadMap">road map to check</param> /// <returns>String with errors descriptions or empty string if no errors found</returns> private string CheckLinks(RoadMap roadMap) { string errors = string.Empty; foreach (var node in roadMap.Nodes) { foreach (var link in node.Links) { try { //check if exactly one node exists by link ref RoadNode neighbourByLink = roadMap.Nodes.Where(n => n.Id == link.RefNodeId).Single(); //check if exactly one back link exists and has the same weight as direct link RoadLink backLink = neighbourByLink.Links.Where(l => l.RefNodeId == node.Id && l.Weight == link.Weight).Single(); } catch (InvalidOperationException) { errors += string.Format("Node {0} has wrong link\n", node.Id); } } } return(errors); }
/// <summary> /// Get non-crashed nodes connected with the node /// </summary> /// <param name="node"></param> /// <returns>list of neighbour nodes</returns> private List<RoadNode> GetNeighbours(RoadNode node) { if (node == null) return null; List<RoadNode> neighbours = new List<RoadNode>(); foreach (var link in node.Links) { RoadNode neighbourByLink = roadMap.Nodes.Where(n => n.Id == link.RefNodeId).Single(); if (neighbourByLink.State == RoadNodeState.Ok) { neighbours.Add(neighbourByLink); } } return neighbours; }
/// <summary> /// Recurcively find all paths from node to finishNode. /// Deep graph search algorithm is used. /// </summary> /// <param name="node">node</param> private void FindPaths(RoadNode node) { if (node == null) return; if (node == finishNode) { //if we have reached finish node, remember the current path pathsFound.Add((RoadPath)currentPath.Clone()); } else { List<RoadNode> neighbours = GetNeighbours(node); foreach (RoadNode neighbour in neighbours) { if (!visitedNodes.Contains(neighbour)) { visitedNodes.Add(neighbour); currentPath.Push(neighbour); FindPaths(neighbour); visitedNodes.Remove(neighbour); currentPath.Pop(); } } } }