/// <summary> /// Adds an event to the interest list /// </summary> /// <param name="eventData">Event to add</param> /// <param name="handler">Collection of callbacks that will handle this /// event</param> public void EnqueueEvent(InterestListEvent eventData, InterestListEventHandler handler) { double?priority = handler.PriorityCallback(eventData, m_presence); // If this event has a non-null priority for this presence, enqueue it if (priority.HasValue) { QueuedInterestListEvent qile = new QueuedInterestListEvent(eventData, priority.Value, handler); lock (m_syncRoot) { C5.PriorityQueueHandle handle; if (m_eventIDs.TryGetValue(eventData.ID, out handle)) { // An event with the same ID already exists in the priority queue. Combine this update with the previous one qile = handler.CombineCallback(m_eventHeap[handle], qile); m_eventHeap.Replace(handle, qile); } else { // This event ID is new m_eventHeap.Add(ref handle, qile); m_eventIDs.Add(eventData.ID, handle); } } } }
public T this[I key] { get { C5.IPriorityQueueHandle <IndexedItem> handle; if (_index.TryGetValue(key, out handle)) { IndexedItem item; _priQueue.Find(handle, out item); return(item.Value); } throw new KeyNotFoundException(); } set { C5.IPriorityQueueHandle <IndexedItem> handle; if (_index.TryGetValue(key, out handle)) { _priQueue.Replace(handle, new IndexedItem { Key = key, Value = value }); } else { this.Add(key, value); } } }
public static IEnumerable <IPathNode <N> > GetReachableNodes <N>(N start, float maxCost) where N : INode <N> { C5.IDictionary <N, PathNode <N> > nodeDictionary = new C5.HashDictionary <N, PathNode <N> >(); C5.IPriorityQueue <PathNode <N> > openSet = new C5.IntervalHeap <PathNode <N> >(new PathNodeComparer <N>(), C5.MemoryType.Normal); C5.ICollection <N> closedSet = new C5.HashSet <N>(); C5.ArrayList <IPathNode <N> > res = new C5.ArrayList <IPathNode <N> >(C5.MemoryType.Normal); PathNode <N> curNode = new PathNode <N>(start); curNode.g = 0; nodeDictionary.Add(start, curNode); while (true) { res.Add(curNode); foreach (IEdge <N> edge in curNode.node) { N other = edge.GetEnd(); if (!closedSet.Contains(other)) { PathNode <N> otherNode = null; if (!nodeDictionary.Find(ref other, out otherNode)) { otherNode = new PathNode <N>(other); nodeDictionary.Add(other, otherNode); } float newG = edge.GetCost() + curNode.g; if (otherNode.g > newG) { otherNode.g = newG; if (otherNode.queueHandle != null) { openSet.Replace(otherNode.queueHandle, otherNode); } otherNode.prev = curNode; } if (otherNode.queueHandle == null) { C5.IPriorityQueueHandle <PathNode <N> > handle = null; openSet.Add(ref handle, otherNode); otherNode.queueHandle = handle; } } } if (openSet.IsEmpty) { return(res); } closedSet.Add(curNode.node); curNode = openSet.DeleteMin(); if (curNode.g > maxCost) { return(res); } } }
void UpdateImageInQueue(J2KImage image) { lock (m_syncRoot) { try { m_priorityQueue.Replace(image.PriorityQueueHandle, image); } catch (Exception) { image.PriorityQueueHandle = null; m_priorityQueue.Add(ref image.PriorityQueueHandle, image); } } }
private void UpdateImageInQueue(J2KImage image) { lock (m_priorityQueue) { J2KImage existingImage; if (m_priorityQueue.Find(image.PriorityQueueHandle, out existingImage)) { try { m_priorityQueue.Replace(image.PriorityQueueHandle, image); return; } catch { } } image.PriorityQueueHandle = null; m_priorityQueue.Add(ref image.PriorityQueueHandle, image); m_queuedTextures[image.TextureID] = image; } }
public static List <OutputCommand> Pathfind(MajorModelEntities model, RoomNumber start, RoomNumber finish, PathfindingSettings settings) { var dictionary = new Dictionary <RoomNumber, RoomInfo>(); var queue = new C5.IntervalHeap <RoomInfo>(new RoomInfoComparer()); var firstRoom = model.GetRoom(start); var firstInfo = new RoomInfo() { Room = firstRoom, Distance = 0 }; queue.Add(ref firstInfo.Handle, firstInfo); dictionary[firstRoom.RoomNumber] = firstInfo; RoomInfo destination = null; while (!queue.IsEmpty) { var info = queue.DeleteMin(); // we found the finish, so exit. if (info.Room.RoomNumber == finish) { destination = info; break; } var exits = from exit in info.Room.GetExits() where exit.ExitType != ExitType.RemoteAction select exit; foreach (var exit in exits) { // query the exit to see if it can be used in our current state. var requirements = exit.CanUseExit(model, settings); if (requirements.Method == ExitMethod.CannotPass) { continue; } var adjacentNumber = exit.AdjacentRoomNumber; RoomInfo adjacent = null; if (!dictionary.TryGetValue(adjacentNumber, out adjacent)) { adjacent = new RoomInfo(); adjacent.Room = model.GetRoom(adjacentNumber); adjacent.Distance = Int32.MaxValue; dictionary[adjacentNumber] = adjacent; } int travelCost = 1; // TODO: set to 1 for now, adjust later as heuristics play out. if (info.Distance + travelCost < adjacent.Distance) { adjacent.Distance = info.Distance + travelCost; adjacent.Previous = info; adjacent.PreviousExit = exit; adjacent.Requirements = requirements; if (adjacent.Handle == null) { queue.Add(ref adjacent.Handle, adjacent); } else { queue.Replace(adjacent.Handle, adjacent); } } } } if (destination != null) { List <OutputCommand> list = new List <OutputCommand>(); var x = destination; while (x.Previous != null) { list.Add(x.PreviousExit.GetOutputCommand(x.Requirements)); x = x.Previous; } list.Reverse(); return(list); } else { return(null); } }
/// <summary> /// Finds a path between startPoint and endPoint. /// </summary> /// <param name="startPoint">Starting point</param> /// <param name="endPoint">Ending point</param> /// <returns>Path that connects start and end point</returns> public Path FindPath(Point startPoint, Point endPoint) { if (this.Collides(startPoint) || this.Collides(endPoint)) { return null; } this.StartPoint = startPoint; this.EndPoint = endPoint; // initialize the open set of nodes with start point C5.IPriorityQueue<State> openSet = new C5.IntervalHeap<State>(); // associate handles with points var handles = new Dictionary<Point, C5.IPriorityQueueHandle<State>>(); // add start point to queue and associate point with handle C5.IPriorityQueueHandle<State> handle = null; openSet.Add(ref handle, new State {Point = startPoint, Heuristic = 0}); handles.Add(this.StartPoint, handle); var closedSet = new HashSet<Point>(); // the g-score is the distance from start point to the current point var gScore = new Dictionary<Point, double> {{startPoint, 0}}; // the f-score is the g-score plus heuristic var fScore = new Dictionary<Point, double> {{startPoint, Utils.Distance(startPoint, this.EndPoint)}}; // cameFrom is used to reconstruct path when target is found var cameFrom = new Dictionary<Point, Point>(); // process nodes in the open set... while (!openSet.IsEmpty) { // fetch highest priority node, i.e. the one with // lowest heuristic value State minState = openSet.DeleteMin(); Point x = minState.Point; handles.Remove(x); if (x == this.EndPoint) { // we found a solution return this.ReconstructPath(cameFrom); } closedSet.Add(x); var neighbours = this.GetNeighbours(x); // for each neighbour... foreach (var y in neighbours) { if (closedSet.Contains(y)) { continue; } // total cost from start var tentativeGScore = gScore[x] + Utils.Distance(x, y); bool tentativeIsBetter; Point point = y; handle = null; if (!openSet.Exists(s => s.Point == point) && !closedSet.Contains(y)) { // will get priority adjusted further down openSet.Add(ref handle, new State {Point = point}); handles.Add(point, handle); tentativeIsBetter = true; } else if (tentativeGScore < gScore[y]) { tentativeIsBetter = true; } else { tentativeIsBetter = false; } if (tentativeIsBetter) { // update f-score of y cameFrom[y] = x; gScore[y] = tentativeGScore; fScore[y] = gScore[y] + Utils.Distance(y, this.EndPoint); var heuristic = fScore[y]; // set priority of y if (handle == null) { handle = handles[point]; } openSet.Replace(handle, new State {Heuristic = heuristic, Point = y}); } } } return null; }
static void doPriorityQueueSkeletonCode(Node rootNode, Heuristic selectedHeuristic, IComparer <Node> selectedComparer, Stopwatch timer) { C5.IntervalHeap <Node> nodeQueue = new C5.IntervalHeap <Node>(selectedComparer); nodeQueue.Add(rootNode); //repeated state checking tools HashSet <int> previouslyExpanded = new HashSet <int> { }; Dictionary <int, Node> idsToNode = new Dictionary <int, Node> { }; int nodesPoppedOffQueue = 0; int maxQueueSize = 1; //rootNode is in there while (nodeQueue.Count > 0) { //heap extracts minimum based on selected comparer Node currentNode = nodeQueue.DeleteMin(); nodesPoppedOffQueue += 1; Board currentBoard = currentNode.board; //keeps track of expanded states //we are currently expanding this state. previouslyExpanded.Add(currentBoard.Id); if (currentBoard.isInEndState()) { handleEndState(currentNode, nodesPoppedOffQueue, maxQueueSize); return; } List <Board> children = currentBoard.GenerateNextStates(); foreach (Board child in children) { if (!previouslyExpanded.Contains(child.Id)) { int childPotentialCost = selectedHeuristic.getHeuristicScore(currentNode, child); Node childNode = new Node(child, currentNode, currentNode.cost + child.TileMoved, currentNode.depth + 1, childPotentialCost); C5.IPriorityQueueHandle <Node> h = null; if (idsToNode.ContainsKey(child.Id)) { //already seen this node somewhere. check queue for cheaper, otherwise don't add Node currentNodeInQueue = idsToNode[child.Id]; int currentCostInQueue = currentNodeInQueue.heuristicCost; if (childPotentialCost < currentCostInQueue) { //replace the node with the same configuration with the cheaper one //update the handle in the queue appropriately for future reference h = currentNodeInQueue.handle; nodeQueue.Replace(currentNodeInQueue.handle, childNode); childNode.handle = h; } else { //do not add this child, the one in the queue already is cheaper } } else { //never seen this child before, add it nodeQueue.Add(ref h, childNode); childNode.handle = h; idsToNode.Add(child.Id, childNode); } } } //update maxQueueSize, done adding all potential children if (maxQueueSize < nodeQueue.Count) { maxQueueSize = nodeQueue.Count; } } }
public static IEnumerable <IPathNode <N> > GetShortestPath <N>(N start, N goal, IHeuristic <N> heuristic) where N : INode <N> { C5.IDictionary <N, PathNode <N> > nodeDictionary = new C5.HashDictionary <N, PathNode <N> >(); C5.IPriorityQueue <PathNode <N> > openSet = new C5.IntervalHeap <PathNode <N> >(new PathNodeComparer <N>()); C5.ICollection <N> closedSet = new C5.HashSet <N>(); PathNode <N> curNode = new PathNode <N>(start); curNode.g = 0; nodeDictionary.Add(start, curNode); while (true) { foreach (IEdge <N> edge in curNode.Node) { N other = edge.GetEnd(); if (!closedSet.Contains(other)) { PathNode <N> otherNode = null; if (!nodeDictionary.Find(ref other, out otherNode)) { otherNode = new PathNode <N>(other); nodeDictionary.Add(other, otherNode); } float newG = edge.GetCost() + curNode.g; if (otherNode.g > newG) { otherNode.g = newG; if (otherNode.queueHandle != null) { openSet.Replace(otherNode.queueHandle, otherNode); } otherNode.prev = curNode; } if (otherNode.queueHandle == null) { otherNode.h = heuristic.MinDist(other, goal); C5.IPriorityQueueHandle <PathNode <N> > handle = null; openSet.Add(ref handle, otherNode); otherNode.queueHandle = handle; } } } if (openSet.IsEmpty) { return(null); } closedSet.Add(curNode.Node); curNode = openSet.DeleteMin(); if (curNode.Node.Equals(goal)) { C5.ArrayList <IPathNode <N> > res = new C5.ArrayList <IPathNode <N> >(); do { res.Add(curNode); curNode = curNode.prev; } while (curNode != null); res.Reverse(); return(res); } } }