protected override CompleteNode GetNextCompleteNode(CompleteNode currentNode, List <Node> incompleteNodes, DateTime when) { var queue = _priorityQueues[Thread.CurrentThread]; var candidates = new ConcurrentBag <CompleteNode>(); Parallel.Invoke( () => { GetRouteCandidates(currentNode, incompleteNodes, when, null).ForEach(c => candidates.Add(c)); }, () => { GetTransferCandidates(currentNode, incompleteNodes, when).ForEach(c => candidates.Add(c)); }); foreach (var cnode in candidates) { var qnode = queue.GetNode(cnode.stopId); if ((qnode == null) || (qnode.departureTime > cnode.departureTime)) { queue.UpdateNode(cnode); } } return(queue.Pop()); }
public CompleteNode(CompleteNode node) { if (node == null) { throw new ArgumentNullException(); } if (node.departureTime != null) { departureTime = new TimeSpan(node.departureTime.Ticks); } if (node.viaNode != null) { viaNode = new CompleteNode(node.viaNode); } if (node.usedEdges != null) { usedEdges = new Stack<Edge>(); node.usedEdges.Reverse().ToList().ForEach(n => usedEdges.Push(n.Clone())); } if (node.usedRouteIds != null) { usedRouteIds = new Stack<int>(node.usedRouteIds.Reverse()); } stopId = node.stopId; }
public CompleteNode(CompleteNode node) { if (node == null) { throw new ArgumentNullException(); } if (node.departureTime != null) { departureTime = new TimeSpan(node.departureTime.Ticks); } if (node.viaNode != null) { viaNode = new CompleteNode(node.viaNode); } if (node.usedEdges != null) { usedEdges = new Stack <Edge>(); node.usedEdges.Reverse().ToList().ForEach(n => usedEdges.Push(n.Clone())); } if (node.usedRouteIds != null) { usedRouteIds = new Stack <int>(node.usedRouteIds.Reverse()); } stopId = node.stopId; }
/// <summary> /// currentNode-ból gyaloglással elérhető csomópontok és azok költsége (incompleteNodes-ból válogatva) /// </summary> /// <param name="currentNode"></param> /// <param name="incompleteNodes"></param> /// <param name="when"></param> /// <returns></returns> protected List <CompleteNode> GetTransferCandidates(CompleteNode currentNode, List <Node> incompleteNodes, DateTime when) { var candidates = new List <CompleteNode>(); if ((currentNode.usedEdges.Count > 0) && (currentNode.usedEdges.Peek() is TransferEdge)) { // Ha az előző művelet átszállás volt, akkor ne szálljunk át mégegyszer return(candidates); } int?groupId = GetStop(currentNode.stopId).GroupId; if (groupId != null) { var stopsInGroup = GetStopsInGroup(groupId); if (stopsInGroup == null) { // Ha árva vagyok, akkor üreset adok vissza return(candidates); } // Szomszédok vizsgálata foreach (var stop in stopsInGroup) { if (stop.DbId == currentNode.stopId) { // Saját magunkkal nem foglalkozunk continue; } if (!incompleteNodes.Exists(ic => ic.stopId == stop.DbId)) { // Csak akkor foglalkozzunk vele, ha még nem dolgoztuk fel continue; } var edge = new TransferEdge(stop.DbId, currentNode.departureTime, this.GetStop(currentNode.stopId), this.GetStop(stop.DbId)); var edgeCost = edge.GetCost(); if (edgeCost != null) { var usedEdges = new Stack <Edge>(currentNode.usedEdges.Reverse()); usedEdges.Push(edge); candidates.Add(new CompleteNode { stopId = stop.DbId, viaNode = currentNode, departureTime = currentNode.departureTime.Add(TimeSpan.FromMinutes((int)edgeCost)), usedEdges = usedEdges, usedRouteIds = new Stack <int>(currentNode.usedRouteIds.Reverse()) }); } } } return(candidates); }
public void Push(CompleteNode node) { if (_idMap.ContainsKey(node.stopId)) { UpdateNode(node); return; } var insertedIndex = _storage.Count; _storage.Add(node); _idMap.Add(node.stopId, insertedIndex); BubbleUp(insertedIndex); }
/// <summary> /// Új kifejtett csomópont választása /// </summary> /// <param name="currentNode"></param> /// <param name="incompleteNodes"></param> /// <param name="when"></param> /// <returns></returns> protected virtual CompleteNode GetNextCompleteNode(CompleteNode currentNode, List <Node> incompleteNodes, DateTime when) { try { var candidates = new List <CompleteNode>(); candidates.AddRange(GetRouteCandidates(currentNode, incompleteNodes, when)); candidates.AddRange(GetTransferCandidates(currentNode, incompleteNodes, when)); #region A legolcsóbb továbblépés megkeresése { var minimalDeparture = candidates.Min(c => c.departureTime); return(candidates.First(c => c.departureTime == minimalDeparture)); } #endregion } catch { return(null); } }
public void UpdateNode(CompleteNode node) { if (!_idMap.ContainsKey(node.stopId)) { Push(node); return; } int i = _idMap[node.stopId]; var originalNode = _storage[i]; _storage[i] = new CompleteNode(node); if (originalNode.departureTime > node.departureTime) { BubbleUp(i); } else { PushDown(i); } }
protected override CompleteNode GetNextCompleteNode(CompleteNode currentNode, List<Node> incompleteNodes, DateTime when) { var queue = _priorityQueues[Thread.CurrentThread]; var candidates = new ConcurrentBag<CompleteNode>(); Parallel.Invoke( () => { GetRouteCandidates(currentNode, incompleteNodes, when, null).ForEach(c => candidates.Add(c)); }, () => { GetTransferCandidates(currentNode, incompleteNodes, when).ForEach(c => candidates.Add(c)); }); foreach (var cnode in candidates) { var qnode = queue.GetNode(cnode.stopId); if ((qnode == null) || (qnode.departureTime > cnode.departureTime)) { queue.UpdateNode(cnode); } } return queue.Pop(); }
public override List <Edge> GetShortestRoute(int sourceStopId, int destinationStopId, DateTime when) { Console.WriteLine("Looking for route between '" + GetStop(sourceStopId).StopName + "' and '" + GetStop(destinationStopId).StopName + "'"); var result = new List <Edge>(); var completeNodes = new List <CompleteNode>(); var inclompleteNodes = new List <Node>(); bool traceComplete = false; // Kezdetben csak a forráspont van kész, nem vezet hozzá semmi completeNodes.Add(new CompleteNode { stopId = sourceStopId, departureTime = when.TimeOfDay, viaNode = null, usedEdges = new Stack <Edge>(), usedRouteIds = new Stack <int>() }); // Mindenki mást pedig várakozik a kifejtésre foreach (var stop in AllStops.Where(s => s.DbId != sourceStopId)) { inclompleteNodes.Add(new Node { stopId = stop.DbId }); } // Az útvonalkereső hurok while ((!traceComplete) && (inclompleteNodes.Count > 0)) { Console.WriteLine("Iteration: " + completeNodes.Count + " cnodes, " + inclompleteNodes.Count + " icnodes"); CompleteNode nextNode = null; var lck = new Object(); var garbage = new ConcurrentBag <CompleteNode>(); #region Következő csomópont keresése { completeNodes.AsParallel().ForAll( currentNode => { var candidate = GetNextCompleteNode(currentNode, inclompleteNodes, when); if (candidate != null) { // van kimenő él // atomi művelet!! lock (lck) { if ((nextNode == null) || (candidate.departureTime < nextNode.departureTime)) { nextNode = candidate; } } } else { garbage.Add(currentNode); } }); } #endregion if (nextNode == null) { Console.WriteLine("No route between '" + GetStop(sourceStopId).StopName + "' and '" + GetStop(destinationStopId).StopName + "'"); break; } // Takarítás garbage.ToList().ForEach(g => completeNodes.Remove(g)); garbage = new ConcurrentBag <CompleteNode>(); // Áthelyezés a kész csomópontok közé completeNodes.Add(nextNode); var removedNode = inclompleteNodes.Single(n => n.stopId == nextNode.stopId); inclompleteNodes.Remove(removedNode); // Ha megtaláltuk a célt, akkor leállunk if (nextNode.stopId == destinationStopId) { traceComplete = true; Console.WriteLine("Trace complete between '" + GetStop(sourceStopId).StopName + "' and '" + GetStop(destinationStopId).StopName + "'"); Console.WriteLine("Shortest path Found. # of used routes: " + nextNode.usedRouteIds.Count + " | arrival: " + nextNode.departureTime.ToString()); result.AddRange(nextNode.usedEdges.Reverse()); result.ToList().ForEach( e => { Console.WriteLine(e.GetType().Name + " " + e.ToString()); }); } } return(result); }
/// <summary> /// currentNode-ból járművel elérhető csomópontok és azok költsége (incompleteNodes-ból válogatva) /// </summary> /// <param name="currentNode"></param> /// <param name="incompleteNodes"></param> /// <param name="when"></param> /// <returns></returns> protected List <CompleteNode> GetRouteCandidates(CompleteNode currentNode, List <Node> incompleteNodes, DateTime when, int?limitOfRoutes = 5) { var candidates = new List <CompleteNode>(); var routes = GetRoutes(currentNode.stopId); if (routes == null) { return(candidates); } foreach (var routeId in routes) { bool isKnownRouteId = currentNode.usedRouteIds.Contains(routeId); if (!(isKnownRouteId && (currentNode.usedRouteIds.Peek() != routeId))) { // A járatok nem újrafelhasználhatóak! foreach (var stop in GetEndpoints(currentNode.stopId, routeId)) { if (!incompleteNodes.Exists(ic => ic.stopId == stop.DbId)) { // Csak akkor foglalkozzunk vele, ha még nem dolgoztuk fel continue; } var edge = new RouteEdge(stop.DbId, routeId, when, currentNode.departureTime); var edgeCost = edge.GetCost(); if (edgeCost != null) { var usedEdges = new Stack <Edge>(currentNode.usedEdges.Reverse()); #region Check for hidden transfers { // Ha ugyanannál a megállónál száll át... if ((usedEdges.Count > 0) && (usedEdges.Peek() is RouteEdge)) { if (((RouteEdge)usedEdges.Peek()).RouteId != edge.RouteId) { var stp = GetStop(currentNode.stopId); usedEdges.Push(new TransferEdge(stp.DbId, currentNode.departureTime, stp, stp)); edgeCost += usedEdges.Peek().GetCost(); } } } #endregion usedEdges.Push(edge); var usedRouteIds = new Stack <int>(currentNode.usedRouteIds.Reverse()); if (!isKnownRouteId) { usedRouteIds.Push(routeId); } if ((limitOfRoutes == null) || (usedRouteIds.Count <= limitOfRoutes)) { candidates.Add(new CompleteNode { stopId = stop.DbId, viaNode = currentNode, departureTime = currentNode.departureTime.Add(TimeSpan.FromMinutes((int)edgeCost)), usedEdges = usedEdges, usedRouteIds = new Stack <int>(usedRouteIds.Reverse()) }); } } } } } return(candidates); }
public override List <Edge> GetShortestRoute(int sourceStopId, int destinationStopId, DateTime when) { if (!_priorityQueues.ContainsKey(Thread.CurrentThread)) { var storage = new BinaryHeapPriorityQueue(); _priorityQueues.Add(Thread.CurrentThread, storage); } var result = new List <Edge>(); #region Dijkstra { int iterationCount = 0; Console.WriteLine("Looking for route between '" + GetStop(sourceStopId).StopName + "' and '" + GetStop(destinationStopId).StopName + "'"); var inclompleteNodes = new List <Node>(); bool traceComplete = false; // Kezdetben csak a forráspont van kész, nem vezet hozzá semmi var currentNode = new CompleteNode { stopId = sourceStopId, departureTime = when.TimeOfDay, viaNode = null, usedEdges = new Stack <Edge>(), usedRouteIds = new Stack <int>() }; // Mindenki mást pedig várakozik a kifejtésre foreach (var stop in AllStops.Where(s => s.DbId != sourceStopId)) { inclompleteNodes.Add(new Node { stopId = stop.DbId }); } // Az útvonalkereső hurok while ((!traceComplete) && (inclompleteNodes.Count > 0)) { if ((iterationCount % 25) == 0) { Console.WriteLine("Iteration: " + ((iterationCount / 25) + 1) + " x 25 | with " + inclompleteNodes.Count + " icnodes"); iterationCount++; } currentNode = GetNextCompleteNode(currentNode, inclompleteNodes, when); if (currentNode == null) { Console.WriteLine("No route between '" + GetStop(sourceStopId).StopName + "' and '" + GetStop(destinationStopId).StopName + "'"); break; } // Áthelyezés a kész csomópontok közé { var removedNode = inclompleteNodes.Single(n => n.stopId == currentNode.stopId); inclompleteNodes.Remove(removedNode); } // Ha megtaláltuk a célt, akkor leállunk if (currentNode.stopId == destinationStopId) { traceComplete = true; Console.WriteLine("Trace complete between '" + GetStop(sourceStopId).StopName + "' and '" + GetStop(destinationStopId).StopName + "'"); Console.WriteLine("Shortest path Found. # of used routes: " + currentNode.usedRouteIds.Count + " | arrival: " + currentNode.departureTime.ToString()); result.AddRange(currentNode.usedEdges.Reverse()); result.ForEach( e => { Console.WriteLine(e.GetType().Name + " " + e.ToString()); }); } } } #endregion if (_priorityQueues.ContainsKey(Thread.CurrentThread)) { _priorityQueues.Remove(Thread.CurrentThread); } return(result); }
public override List<Edge> GetShortestRoute(int sourceStopId, int destinationStopId, DateTime when) { if (!_priorityQueues.ContainsKey(Thread.CurrentThread)) { var storage = new BinaryHeapPriorityQueue(); _priorityQueues.Add(Thread.CurrentThread, storage); } var result = new List<Edge>(); #region Dijkstra { int iterationCount = 0; Console.WriteLine("Looking for route between '" + GetStop(sourceStopId).StopName + "' and '" + GetStop(destinationStopId).StopName + "'"); var inclompleteNodes = new List<Node>(); bool traceComplete = false; // Kezdetben csak a forráspont van kész, nem vezet hozzá semmi var currentNode = new CompleteNode { stopId = sourceStopId, departureTime = when.TimeOfDay, viaNode = null, usedEdges = new Stack<Edge>(), usedRouteIds = new Stack<int>() }; // Mindenki mást pedig várakozik a kifejtésre foreach (var stop in AllStops.Where(s => s.DbId != sourceStopId)) { inclompleteNodes.Add(new Node { stopId = stop.DbId }); } // Az útvonalkereső hurok while ((!traceComplete) && (inclompleteNodes.Count > 0)) { if ((iterationCount % 25) == 0) { Console.WriteLine("Iteration: " + ((iterationCount / 25) + 1) + " x 25 | with " + inclompleteNodes.Count + " icnodes"); iterationCount++; } currentNode = GetNextCompleteNode(currentNode, inclompleteNodes, when); if (currentNode == null) { Console.WriteLine("No route between '" + GetStop(sourceStopId).StopName + "' and '" + GetStop(destinationStopId).StopName + "'"); break; } // Áthelyezés a kész csomópontok közé { var removedNode = inclompleteNodes.Single(n => n.stopId == currentNode.stopId); inclompleteNodes.Remove(removedNode); } // Ha megtaláltuk a célt, akkor leállunk if (currentNode.stopId == destinationStopId) { traceComplete = true; Console.WriteLine("Trace complete between '" + GetStop(sourceStopId).StopName + "' and '" + GetStop(destinationStopId).StopName + "'"); Console.WriteLine("Shortest path Found. # of used routes: " + currentNode.usedRouteIds.Count + " | arrival: " + currentNode.departureTime.ToString()); result.AddRange(currentNode.usedEdges.Reverse()); result.ForEach( e => { Console.WriteLine(e.GetType().Name + " " + e.ToString()); }); } } } #endregion if (_priorityQueues.ContainsKey(Thread.CurrentThread)) { _priorityQueues.Remove(Thread.CurrentThread); } return result; }
/// <summary> /// currentNode-ból gyaloglással elérhető csomópontok és azok költsége (incompleteNodes-ból válogatva) /// </summary> /// <param name="currentNode"></param> /// <param name="incompleteNodes"></param> /// <param name="when"></param> /// <returns></returns> protected List<CompleteNode> GetTransferCandidates(CompleteNode currentNode, List<Node> incompleteNodes, DateTime when) { var candidates = new List<CompleteNode>(); if ((currentNode.usedEdges.Count > 0) && (currentNode.usedEdges.Peek() is TransferEdge)) { // Ha az előző művelet átszállás volt, akkor ne szálljunk át mégegyszer return candidates; } int? groupId = GetStop(currentNode.stopId).GroupId; if (groupId != null) { var stopsInGroup = GetStopsInGroup(groupId); if (stopsInGroup == null) { // Ha árva vagyok, akkor üreset adok vissza return candidates; } // Szomszédok vizsgálata foreach (var stop in stopsInGroup) { if (stop.DbId == currentNode.stopId) { // Saját magunkkal nem foglalkozunk continue; } if (!incompleteNodes.Exists(ic => ic.stopId == stop.DbId)) { // Csak akkor foglalkozzunk vele, ha még nem dolgoztuk fel continue; } var edge = new TransferEdge(stop.DbId, currentNode.departureTime, this.GetStop(currentNode.stopId), this.GetStop(stop.DbId)); var edgeCost = edge.GetCost(); if (edgeCost != null) { var usedEdges = new Stack<Edge>(currentNode.usedEdges.Reverse()); usedEdges.Push(edge); candidates.Add(new CompleteNode { stopId = stop.DbId, viaNode = currentNode, departureTime = currentNode.departureTime.Add(TimeSpan.FromMinutes((int)edgeCost)), usedEdges = usedEdges, usedRouteIds = new Stack<int>(currentNode.usedRouteIds.Reverse()) }); } } } return candidates; }
/// <summary> /// currentNode-ból járművel elérhető csomópontok és azok költsége (incompleteNodes-ból válogatva) /// </summary> /// <param name="currentNode"></param> /// <param name="incompleteNodes"></param> /// <param name="when"></param> /// <returns></returns> protected List<CompleteNode> GetRouteCandidates(CompleteNode currentNode, List<Node> incompleteNodes, DateTime when, int? limitOfRoutes = 5) { var candidates = new List<CompleteNode>(); var routes = GetRoutes(currentNode.stopId); if (routes == null) { return candidates; } foreach (var routeId in routes) { bool isKnownRouteId = currentNode.usedRouteIds.Contains(routeId); if (!(isKnownRouteId && (currentNode.usedRouteIds.Peek() != routeId))) { // A járatok nem újrafelhasználhatóak! foreach (var stop in GetEndpoints(currentNode.stopId, routeId)) { if (!incompleteNodes.Exists(ic => ic.stopId == stop.DbId)) { // Csak akkor foglalkozzunk vele, ha még nem dolgoztuk fel continue; } var edge = new RouteEdge(stop.DbId, routeId, when, currentNode.departureTime); var edgeCost = edge.GetCost(); if (edgeCost != null) { var usedEdges = new Stack<Edge>(currentNode.usedEdges.Reverse()); #region Check for hidden transfers { // Ha ugyanannál a megállónál száll át... if ((usedEdges.Count > 0) && (usedEdges.Peek() is RouteEdge)) { if (((RouteEdge)usedEdges.Peek()).RouteId != edge.RouteId) { var stp = GetStop(currentNode.stopId); usedEdges.Push(new TransferEdge(stp.DbId, currentNode.departureTime, stp, stp)); edgeCost += usedEdges.Peek().GetCost(); } } } #endregion usedEdges.Push(edge); var usedRouteIds = new Stack<int>(currentNode.usedRouteIds.Reverse()); if (!isKnownRouteId) { usedRouteIds.Push(routeId); } if ((limitOfRoutes == null) || (usedRouteIds.Count <= limitOfRoutes)) { candidates.Add(new CompleteNode { stopId = stop.DbId, viaNode = currentNode, departureTime = currentNode.departureTime.Add(TimeSpan.FromMinutes((int)edgeCost)), usedEdges = usedEdges, usedRouteIds = new Stack<int>(usedRouteIds.Reverse()) }); } } } } } return candidates; }
/// <summary> /// Új kifejtett csomópont választása /// </summary> /// <param name="currentNode"></param> /// <param name="incompleteNodes"></param> /// <param name="when"></param> /// <returns></returns> protected virtual CompleteNode GetNextCompleteNode(CompleteNode currentNode, List<Node> incompleteNodes, DateTime when) { try { var candidates = new List<CompleteNode>(); candidates.AddRange(GetRouteCandidates(currentNode, incompleteNodes, when)); candidates.AddRange(GetTransferCandidates(currentNode, incompleteNodes, when)); #region A legolcsóbb továbblépés megkeresése { var minimalDeparture = candidates.Min(c => c.departureTime); return candidates.First(c => c.departureTime == minimalDeparture); } #endregion } catch { return null; } }