private static void PrintTopK(Stream ip, int k, int magicNumber) { MinHeap <int> heap = new MinHeap <int>(); int val; while ((val = ip.Next()) != -1) { if (val == magicNumber) { // print the heap continue; } if (heap.Count == k) { if (heap.Peek() < val) { heap.Delete(); heap.Add(val); } } else { heap.Add(val); } } }
public void TestComparer() { MinHeap <int> minHeap = new MinHeap <int>(new ReverseIntComparer()); int items = 10; minHeap.Add(10); minHeap.Add(1); minHeap.Add(9); minHeap.Add(2); minHeap.Add(8); minHeap.Add(3); minHeap.Add(7); minHeap.Add(4); minHeap.Add(6); minHeap.Add(5); StringBuilder actual = new StringBuilder(); for (int i = 0; i < items; i++) { actual.Append(minHeap.Remove()); } string expected = "10987654321"; Assert.AreEqual(expected, actual.ToString()); }
//SOLUTION FOR LEETCODE QUESTION: //253 - MEETING ROOMS II - Given an array of meeting time intervals intervals where intervals[i] = [starti, endi], //return the minimum number of conference rooms required. //*****DIFFICULTY - MEDIUM***** /// <summary> /// Method the returns minimum number of meeting rooms needed given an array of meeting intervals /// </summary> /// <param name="intervals"></param> /// <returns>Number of meeting rooms</returns> public int MinMeetingRooms(int[][] intervals) { //Sort intervals by starting time Array.Sort(intervals, (item1, item2) => { return(item1[0].CompareTo(item2[0])); }); //Invoking MiniHeap class var minHeap = new MinHeap(intervals.Length); //Add the end time of the first interval to the MinHeap minHeap.Add(intervals[0][1]); //For each other interval, check if the start time is less than the current min on heap for (int i = 1; i < intervals.Length; i++) { //If true add the end of current interval to MinHeap if (intervals[i][0] >= minHeap.Peek()) { minHeap.Pop(); } //If false, pop the min and add the current end time to heap minHeap.Add(intervals[i][1]); } //The number of elements left in the MinHeap will tell us the number of rooms needed return(minHeap.Count()); }
public int KthSmallest(int[][] matrix, int k) { int n = matrix.Length; int size = Math.Min(n, k); int currentRank = 1; MinHeap minHeap = new MinHeap(size); for (int row = 0; row < size; row++) { minHeap.Add(new MatrixInfo(matrix[row][0], row, 0)); } while (minHeap.Size() > 0) { if (currentRank == k) { return(minHeap.ExtractMin().Value); } MatrixInfo min = minHeap.ExtractMin(); if (min.Col + 1 < n) { var m = new MatrixInfo(matrix[min.Row][min.Col + 1], min.Row, min.Col + 1); minHeap.Add(m); } currentRank++; } return(0); }
public void AddSameKeyThrowException() { var heap = new MinHeap <string, double, Dictionary <string, int> >(); heap.Add("item1", 3.0); Assert.Throws <ArgumentException>(() => heap.Add("item1", 4.0)); }
public static int Run(int[] input) { if (input == null || input.Length == 0) { throw new InvalidOperationException(); } var root = input[0]; var left = new MaxHeap <int>(); var right = new MinHeap <int>(); for (var i = 1; i < input.Length; i++) { var current = input[i]; if (current <= root) { if (left.Count > right.Count) { if (left.GetRoot() > current) { right.Add(root); root = left.Pop(); left.Add(current); } else { right.Add(root); root = current; } } else { left.Add(current); } } else { if (right.Count + 1 > left.Count) { if (right.GetRoot() < current) { left.Add(root); root = right.Pop(); right.Add(current); } else { left.Add(root); root = current; } } else { right.Add(current); } } } return(root); }
private void CalculateIntegrateField() { InitGrid(); MinHeap <Node> open_set = new MinHeap <Node>(size_x * size_y); open_set.Add(World2Node(player_pos)); while (open_set.Count > 0) { Node cur_node = open_set.RemoveFirst(); cur_node.mem_closed_set = true; foreach (Node neighbour in GetNeighbours(cur_node)) { if (neighbour.IsWalkable() && !neighbour.mem_closed_set) { float cost = cur_node.cost_val + CalculateCost(cur_node.grid_x, cur_node.grid_y, neighbour.grid_x, neighbour.grid_y); if (cost < neighbour.cost_val) { neighbour.cost_val = cost; neighbour.parent = cur_node; } if (!open_set.Contains(neighbour)) { open_set.Add(neighbour); } else { open_set.UpdateItem(neighbour); } } } } //Debug.Log() }
public void AddNum(int num) { if (maxH.GetSize() > 0 && num >= maxH.Peek()) // If num is bigger than the 1st half it goes to the 2nd half { minH.Add(num); } else { maxH.Add(num); } if (Math.Abs(maxH.GetSize() - minH.GetSize()) > 1) // If there are more than one number of difference { if (maxH.GetSize() > minH.GetSize()) { int number = maxH.Pull(); minH.Add(number); } else { int number = minH.Pull(); maxH.Add(number); } } }
/// <summary> /// /// </summary> void ProcessEdge(Edge edge, Operand o) { int owningPolygon = (int)o; if (edge.From == edge.To) { return; } SweepEvent from = new SweepEvent(edge.From, true, owningPolygon, null); SweepEvent to = new SweepEvent(edge.To, true, owningPolygon, from); from.Other = to; if (from.Point.x < to.Point.x) { to.Left = false; } else if (from.Point.x > to.Point.x) { from.Left = false; } else if (from.Point.y < to.Point.y) { to.Left = false; // the line segment is vertical. The bottom endpoint is the left endpoint } else { from.Left = false; } futureSweepLineEvents.Add(from); futureSweepLineEvents.Add(to); }
IEnumerator FindAIPath(Vector3 startPos, Vector3 targetPos) { Vector3[] waypoints = new Vector3[0]; bool pathSuccess = false; Node startNode = grid.NodeFromWorldPoint(startPos); Node targetNode = grid.NodeFromWorldPoint(targetPos); if ((startNode.walkable && startNode.aiWalkable) && (targetNode.walkable && targetNode.aiWalkable)) { MinHeap <Node> openSet = new MinHeap <Node>(grid.MaxSize); HashSet <Node> closedSet = new HashSet <Node>(); openSet.Add(startNode); while (openSet.Count > 0) { Node currentNode = openSet.RemoveFirst(); closedSet.Add(currentNode); if (currentNode == targetNode) { pathSuccess = true; break; } foreach (Node neighbour in grid.GetNeighbours(currentNode)) { if (!(neighbour.walkable && neighbour.aiWalkable) || closedSet.Contains(neighbour)) { continue; } int newMovementCostToNeighbour = currentNode.gCost + GetDistance(currentNode, neighbour); if (newMovementCostToNeighbour < neighbour.gCost || !openSet.Contains(neighbour)) { neighbour.gCost = newMovementCostToNeighbour; neighbour.hCost = GetDistance(neighbour, targetNode); neighbour.parent = currentNode; if (!openSet.Contains(neighbour)) { openSet.Add(neighbour); } else { openSet.UpdateItem(neighbour); } } } } } yield return(null); if (pathSuccess) { waypoints = RetracePath(startNode, targetNode); } requestManager.FinishedProcessingPath(waypoints, pathSuccess); }
public ListNode MergeKLists1(ListNode[] lists) { ListNode result = new ListNode(0); ListNode pointer = result; MinHeap mh = new MinHeap(); foreach (ListNode node in lists) { if (node != null) { mh.Add(node); } } while (mh.Count > 0) { ListNode node = mh.PopMin(); if (node.next != null) { mh.Add(node.next); } pointer.next = node; pointer = pointer.next; } return result.next; }
public int LargestSumAfterKNegations(int[] A, int K) { var minheap = new MinHeap <int>(); int sum = 0; foreach (var num in A) { sum += num; minheap.Add(num); } int counter = 0; while (counter < K) { if (minheap.Peek() <= 0) { var newVal = Math.Abs(minheap.Poll()); sum += newVal * 2; minheap.Add(newVal); } else { var newVal = minheap.Poll(); sum -= newVal * 2; minheap.Add(-newVal); } ++counter; } return(sum); }
public static void FindMinPath(Node source, Dictionary <Node, List <Connection> > graph) { MinHeap <Node> minHeap = new MinHeap <Node>(); foreach (var node in graph) { node.Key.DijkstraDistance = long.MaxValue; } source.DijkstraDistance = 0L; minHeap.Add(source); while (minHeap.Count > 0) { Node currentNode = minHeap.Remove(); foreach (var connection in graph[currentNode]) { long distance = currentNode.DijkstraDistance + connection.Distance; if (distance < connection.Node.DijkstraDistance) { connection.Node.DijkstraDistance = distance; minHeap.Add(connection.Node); } } } }
void UpdatePossibleBridges(SimpleClosedPath exterior, SimpleClosedPath mainHole) { possibleBridges.Clear(); foreach (Vector2 from in mainHole.Points()) { foreach (SimpleClosedPath hole in exterior.Holes()) { if (hole == mainHole) { continue; } foreach (Vector2 to in hole.Points()) { possibleBridges.Add(new ExtendedEdge(from, to)); } } foreach (Vector2 to in exterior.Points()) { possibleBridges.Add(new ExtendedEdge(from, to)); } } // possibleBridges.Sort(bridgeComparer); }
static long OperationCount(long minAllowedNumber, long[] initialNumbers) { var minHeap = new MinHeap(); for (var i = 0; i < initialNumbers.Length; i++) { minHeap.Add(initialNumbers[i]); } long operationCount = 0; var currentMin = minHeap.PeekMin(); while (minHeap.Count >= 2 && minHeap.PeekMin() < minAllowedNumber) { operationCount++; var minElement = minHeap.RemoveMin(); var secondMinElement = minHeap.RemoveMin(); var newElement = minElement + (2 * secondMinElement); minHeap.Add(newElement); currentMin = minHeap.PeekMin(); } if (currentMin < minAllowedNumber) { return(-1); } return(operationCount); }
private bool Finding(LinkE s, LinkE e) { bool bo = false; MinHeap <LinkE> heap = new MinHeap <LinkE>(); heap.Add(s); LinkE current; while (heap.Count > 0) { current = heap.ExtractMin(); Debug.Log(current); Map[current.R, current.C] = false; //设为已走过 if (current.EqualTo(end)) { end.Pre = current.Pre; return(true); } List <LinkE> nextElements = GetNextElements(current); if (nextElements.Count > 0) { for (int i = 0; i < nextElements.Count; i++) { nextElements[i].Pre = current; heap.Add(nextElements[i]); } } } return(bo); }
public void TestRemove_TenItems() { MinHeap <int> minHeap = new MinHeap <int>(); int items = 10; minHeap.Add(10); minHeap.Add(1); minHeap.Add(9); minHeap.Add(2); minHeap.Add(8); minHeap.Add(3); minHeap.Add(7); minHeap.Add(4); minHeap.Add(6); minHeap.Add(5); StringBuilder actual = new StringBuilder(); for (int i = 0; i < items; i++) { actual.Append(minHeap.Remove()); } string expected = "12345678910"; Assert.AreEqual(expected, actual.ToString()); }
public void AddFailsWhenReachedCapacity() { MinHeap heap = new MinHeap(2); heap.Add(new Node(5)); heap.Add(new Node(3)); Assert.False(heap.Add(new Node(2))); }
public void MinHeap_Test1() { var heap = new MinHeap <int>(); heap.Add(42); heap.Add(48); heap.Add(6); Assert.Equal(6, heap.GetMin()); }
public void TestPeek_NonEmptyHeap() { MinHeap <int> minHeap = new MinHeap <int>(); minHeap.Add(90); minHeap.Add(5); minHeap.Add(15); minHeap.Add(89); Assert.AreEqual(5, minHeap.Peek()); }
public void GetMinTest() { var heap = new MinHeap <int, int>(); heap.Add(42, -1); heap.Add(5, 6); var Min = heap.Min; Assert.AreEqual(42, Min.Key); Assert.AreEqual(-1, Min.Value); }
private MinHeap <int> getExampleHeap() { MinHeap <int> h = new MinHeap <int>(); h.Add(4); h.Add(5); h.Add(3); h.Add(1); h.Add(2); return(h); }
static void GetMedian(Stream ip) { int val; MinHeap <int> rHeap = new MinHeap <int>(); MaxHeap <int> lHeap = new MaxHeap <int>(); double runningMedian = 0.0; while ((val = ip.Next()) != -1) { if (rHeap.Count == lHeap.Count) { if (val < runningMedian) { lHeap.Add(val); runningMedian = lHeap.Peek(); } else { rHeap.Add(val); runningMedian = rHeap.Peek(); } } else if (lHeap.Count > rHeap.Count) { if (val < runningMedian) { rHeap.Add(lHeap.Delete()); lHeap.Add(val); } else { rHeap.Add(val); } runningMedian = (lHeap.Peek() + rHeap.Peek()) / 2.0; } else { if (val < runningMedian) { lHeap.Add(val); } else { lHeap.Add(rHeap.Delete()); rHeap.Add(val); } runningMedian = (lHeap.Peek() + rHeap.Peek()) / 2.0; } } }
//Astar implementation public static LinkedList <Road> CreateJourney(Road start, Road destination) { HashSet <Road> closedList = new HashSet <Road>(); RoadComparer comp = new RoadComparer(); comp.destination = destination; Heap <Road> openList = new MinHeap <Road>(comp); Dictionary <Road, Road> cameFrom = new Dictionary <Road, Road>(); Dictionary <Road, float> nodeScore = new Dictionary <Road, float>(); openList.Add(start); nodeScore[start] = 0f; while (openList.Count != 0) { Road currentBest = openList.ExtractDominating(); //goal if (Mathf.Approximately(0f, RoadDistance(destination, currentBest))) { return(CreatePath(start, cameFrom, destination)); } closedList.Add(currentBest); //expand nodes going from current best List <Road> successors = currentBest.neighbourRoads; foreach (Road successor in successors) { if (closedList.Contains(successor)) { continue; } float tentative = nodeScore[currentBest] + RoadDistance(currentBest, successor); float oldBestScore; if (!nodeScore.TryGetValue(successor, out oldBestScore)) { oldBestScore = float.MaxValue; } if (!openList.SlowContains(successor) || tentative < oldBestScore) { cameFrom[successor] = currentBest; nodeScore[successor] = tentative; if (!openList.SlowContains(successor)) { openList.Add(successor); } } } } return(null); }
/// <summary>Find the closest path towards the exit. /// <para>Returns null if no path was found.</para> /// <para>NOTE: It can return null if <paramref name="start"/> is inside a closed door's position.</para> /// </summary> private Breadcrumb PathfindGenerateCrumbs(IMyCubeGrid grid, ref Vector3I start) // used in a background thread { scanned.Clear(); openList.Clear(); var startBreadcrumb = new Breadcrumb(start); openList.Add(startBreadcrumb); var directions = Base6Directions.IntDirections; while (openList.HasNext()) { var crumb = openList.GetFirst(); if (DistanceToBox(crumb.Position, grid.Min, grid.Max) < 0) { return(crumb); // found outside of grid, terminate. } for (int i = 0; i < directions.Length; ++i) { if (ShouldCancelTask) { return(null); } var dir = directions[i]; var moveId = new MoveId(ref crumb.Position, ref dir); if (!scanned.Contains(moveId)) // ensure we didn't already check this position+direction { scanned.Add(moveId); var target = crumb.Position + dir; var distToOutside = DistanceToBox(target, grid.Min, grid.Max) + 1; // adding 1 to offset edges if (distToOutside < 0) // gone outside of edge already, exit { return(crumb); } if (IsInInflatedBounds(grid, target) && !IsPressurized(grid, crumb.Position, target)) { int pathCost = crumb.PathCost + 1; // direction movement cost, always 1 in our case int cost = pathCost + distToOutside; // using distance to box edge instead of a predefined end openList.Add(new Breadcrumb(target, cost, pathCost, crumb)); } } } } return(null); }
public void MinReturnsHeapRoot() { MinHeap heap = new MinHeap(4); heap.Add(new Node(5)); heap.Add(new Node(3)); heap.Add(new Node(2)); heap.Add(new Node(7)); Assert.Equal(2, heap.Min().Distance); }
public void TestClear() { MinHeap <int> minHeap = new MinHeap <int>(); minHeap.Add(1); minHeap.Add(2); minHeap.Add(3); minHeap.Clear(); Assert.AreEqual(0, minHeap.Count); minHeap.Peek(); }
public void ContainsKeyTest() { var heap = new MinHeap <string, int, Dictionary <string, int> >(); heap.Add("item1", 3); heap.Add("item2", 4); heap.Add("item3", 8); Assert.IsTrue(heap.ContainsKey("item2")); Assert.IsFalse(heap.ContainsKey("item4")); Assert.Throws <ArgumentNullException>(() => heap.ContainsKey(null)); }
public void AssertThat_Remove_UpdatesMinimum() { IMinHeap <int> heap = new MinHeap <int>(); heap.Add(5); heap.Add(3); heap.Add(7); Assert.AreEqual(3, heap.RemoveMin()); Assert.AreEqual(5, heap.RemoveMin()); Assert.AreEqual(7, heap.RemoveMin()); }
public void IndexerTest() { var heap = new MinHeap <string, int, Dictionary <string, int> >(); heap.Add("item1", 3); heap.Add("item2", 4); heap.Add("item3", 8); Assert.AreEqual(8, heap["item3"]); Assert.Throws <KeyNotFoundException>(() => heap["item5"].ToString()); }
public MinHeap <Point> ExtractPoints(SortedSet <Segment> path) { MinHeap <Point> points = new MinHeap <Point>(); foreach (Segment item in path) { points.Add(item.Minimum); points.Add(item.Maximum); } return(points); }
public void RemoveItemsFromMinHeapCorrectlyUpdatesMinimum() { MinHeap<int> heap = new MinHeap<int>(); heap.Add(5); heap.Add(3); heap.Add(7); Assert.AreEqual(3, heap.RemoveMin()); Assert.AreEqual(5, heap.Minimum); }
public void AddItemToMinHeapCorrectlyUpdatesMinimum() { MinHeap<int> heap = new MinHeap<int>(); heap.Add(5); Assert.AreEqual(5, heap.Minimum); heap.Add(3); Assert.AreEqual(3, heap.Minimum); heap.Add(7); Assert.AreEqual(3, heap.Minimum); }
/// <summary> /// call this to plan a path between points /// </summary> /// <param name="begin"></param> /// <param name="end"></param> /// <returns></returns> public Route FindRoute(Location begin, Location end) { HashSet<MapTile> tilesToReset = new HashSet<MapTile>();//all tiles that need to be reset MapTile mapEnd = Map[end.Row, end.Col]; MapTile mapBegin = Map[begin.Row, begin.Col]; tilesToReset.Add(mapBegin); mapBegin.CostKnown = 0; mapBegin.Heuristic = Globals.state.GetDistance(begin, end); mapBegin.CostEstimate = mapBegin.CostKnown + mapBegin.Heuristic; MinHeap<MapTile> OpenSet = new MinHeap<MapTile>(); OpenSet.Add(mapBegin); while (!OpenSet.IsEmpty) { MapTile current = OpenSet.ExtractMin(); if (current == mapEnd) return BuildRoute(mapEnd, tilesToReset);//reset after the oath is build, we need those pi pointers foreach (Direction d in (Direction[])Enum.GetValues(typeof(Direction))) { Location tile = Globals.state.GetDestination(current.GetLocation, d); MapTile neighbour = Map[tile.Row, tile.Col]; bool succesful = Relax(current, neighbour, mapEnd); tilesToReset.Add(neighbour);//hashset will not contain duplicates if (!neighbour.InOpenSet && succesful) { OpenSet.Add(neighbour); neighbour.InOpenSet = true;//openset is a min heap, no O(1) lookup so store this in the tile } else { if (neighbour.InOpenSet && succesful) { OpenSet.ChangeKey(neighbour, neighbour.CostEstimate); } } } } foreach (MapTile t in tilesToReset)//no route found, still need to reset t.Reset(); return null; }
public static IEnumerable<int> GetMedians(IEnumerable<int> sequence) { var enumerator = sequence.GetEnumerator(); var smallestNumbers = new MaxHeap<int>(); var largestNumbers = new MinHeap<int>(); if (enumerator.MoveNext()) { var number = enumerator.Current; smallestNumbers.Add(number); yield return smallestNumbers.Max; } while (enumerator.MoveNext()) { var number = enumerator.Current; if (smallestNumbers.Count <= largestNumbers.Count) { if (number > largestNumbers.Min) { var min = largestNumbers.ExtractMin(); smallestNumbers.Add(min); largestNumbers.Add(number); } else { smallestNumbers.Add(number); } } else { if (number < smallestNumbers.Max) { var max = smallestNumbers.ExtractMax(); largestNumbers.Add(max); smallestNumbers.Add(number); } else { largestNumbers.Add(number); } } yield return smallestNumbers.Max; } }
public void TestInsert() { var list = new List<int> { 1, 9, 3, 6, 5, 2, 7, 11, 9 }; var minHeap = new MinHeap(); list.ForEach(elem => minHeap.Add(elem)); Assert.AreEqual(1, minHeap.peekMin()); }
public void InsertLotsOfNumbersToMinHeap() { var numbers = new int[] { 12,12,12,12,12,12,13,12,13,11,12,12,13,12,12,12,13,13,12,13,13,13,12,12,13,12,13,12,13,13,12,14,12,12,13,12,12,13,13,12,14,13,12,12,13,13,13,13,13,13,13,12,13,13,14,13,13,13,13,13, }; MinHeap<int> heap = new MinHeap<int>(100, Comparer<int>.Default); foreach (var number in numbers) heap.Add(number); while (heap.Count > 0) heap.RemoveMin(); }
public void BulkInsertToMinHeap() { var values = new[] { 1, 2, 5, 213, 25, 3, 2, 5, 3, 2, 45, 2, 5, 2, 2, 4, 6, 32, 75, 5, 47, 7, 4, 3, 5, 34, 4 }; var heap = new MinHeap<int>(100, Comparer<int>.Default); heap.Add(values); //Sort values and test that the heap returns them in the same order Array.Sort(values); foreach (var value in values) Assert.AreEqual(value, heap.RemoveMin()); }
public void testBunchOfInsertionsAndDeletions() { var list = new List<double> { 74, 101, 11, 1000, 4, -101, -1000 }; var minHeap = new MinHeap(); list.ForEach(elem => minHeap.Add(elem)); list.Sort(); var mins = new List<double>(); for (int i = 0; i < list.Count; i++) { mins.Add(minHeap.removeMin()); } List<Tuple<double, double>> expectedVsActual = list.Zip(mins, Tuple.Create).ToList(); foreach(var tuple in expectedVsActual) { Assert.AreEqual(tuple.Item1, tuple.Item2); } }
/// <summary> /// Finds the path reversed. /// </summary> /// <param name="roomUserable">The user.</param> /// <param name="whatIsDiag">if set to <c>true</c> [diag].</param> /// <param name="gameLocalMap">The map.</param> /// <param name="startMap">The start.</param> /// <param name="endMap">The end.</param> /// <returns>PathFinderNode.</returns> public static PathFinderNode FindPathReversed(RoomUser roomUserable, bool whatIsDiag, Gamemap gameLocalMap, Vector2D startMap, Vector2D endMap) { MinHeap<PathFinderNode> minSpanTreeCost = new MinHeap<PathFinderNode>(256); PathFinderNode[,] pathFinderMap = new PathFinderNode[gameLocalMap.Model.MapSizeX, gameLocalMap.Model.MapSizeY]; PathFinderNode pathFinderStart = new PathFinderNode(startMap) {Cost = 0}; PathFinderNode pathFinderEnd = new PathFinderNode(endMap); pathFinderMap[pathFinderStart.Position.X, pathFinderStart.Position.Y] = pathFinderStart; minSpanTreeCost.Add(pathFinderStart); while (minSpanTreeCost.Count > 0) { pathFinderStart = minSpanTreeCost.ExtractFirst(); pathFinderStart.InClosed = true; for (int index = 0; (whatIsDiag ? (index < DiagMovePoints.Length ? 1 : 0) : (index < NoDiagMovePoints.Length ? 1 : 0)) != 0; index++) { Vector2D realEndPosition = pathFinderStart.Position + (whatIsDiag ? DiagMovePoints[index] : NoDiagMovePoints[index]); bool isEndOfPath = (realEndPosition.X == endMap.X) && (realEndPosition.Y == endMap.Y); if (gameLocalMap.IsValidStep(roomUserable, new Vector2D(pathFinderStart.Position.X, pathFinderStart.Position.Y), realEndPosition, isEndOfPath, roomUserable.AllowOverride)) { PathFinderNode pathFinderSecondNodeCalculation; if (pathFinderMap[realEndPosition.X, realEndPosition.Y] == null) { pathFinderSecondNodeCalculation = new PathFinderNode(realEndPosition); pathFinderMap[realEndPosition.X, realEndPosition.Y] = pathFinderSecondNodeCalculation; } else pathFinderSecondNodeCalculation = pathFinderMap[realEndPosition.X, realEndPosition.Y]; if (!pathFinderSecondNodeCalculation.InClosed) { int internalSpanTreeCost = 0; if (pathFinderStart.Position.X != pathFinderSecondNodeCalculation.Position.X) internalSpanTreeCost++; if (pathFinderStart.Position.Y != pathFinderSecondNodeCalculation.Position.Y) internalSpanTreeCost++; int loopTotalCost = pathFinderStart.Cost + internalSpanTreeCost + pathFinderSecondNodeCalculation.Position.GetDistanceSquared(endMap); if (loopTotalCost < pathFinderSecondNodeCalculation.Cost) { pathFinderSecondNodeCalculation.Cost = loopTotalCost; pathFinderSecondNodeCalculation.Next = pathFinderStart; } if (!pathFinderSecondNodeCalculation.InOpen) { if (pathFinderSecondNodeCalculation.Equals(pathFinderEnd)) { pathFinderSecondNodeCalculation.Next = pathFinderStart; return pathFinderSecondNodeCalculation; } pathFinderSecondNodeCalculation.InOpen = true; minSpanTreeCost.Add(pathFinderSecondNodeCalculation); } } } } } return null; }
public static PathFinderNode FindPathReversed(RoomUser User, bool Diag, Gamemap Map, Vector2D Start, Vector2D End) { MinHeap<PathFinderNode> minHeap = new MinHeap<PathFinderNode>(256); PathFinderNode[,] array = new PathFinderNode[Map.Model.MapSizeX, Map.Model.MapSizeY]; PathFinderNode pathFinderNode = new PathFinderNode(Start); pathFinderNode.Cost = 0; PathFinderNode breadcrumb = new PathFinderNode(End); array[pathFinderNode.Position.X, pathFinderNode.Position.Y] = pathFinderNode; minHeap.Add(pathFinderNode); checked { while (minHeap.Count > 0) { pathFinderNode = minHeap.ExtractFirst(); pathFinderNode.InClosed = true; int num = 0; while (Diag ? (num < PathFinder.DiagMovePoints.Length) : (num < PathFinder.NoDiagMovePoints.Length)) { Vector2D vector2D = pathFinderNode.Position + (Diag ? PathFinder.DiagMovePoints[num] : PathFinder.NoDiagMovePoints[num]); bool endOfPath = vector2D.X == End.X && vector2D.Y == End.Y; if (Map.IsValidStep(User, new Vector2D(pathFinderNode.Position.X, pathFinderNode.Position.Y), vector2D, endOfPath, User.AllowOverride)) { PathFinderNode pathFinderNode2; if (array[vector2D.X, vector2D.Y] == null) { pathFinderNode2 = new PathFinderNode(vector2D); array[vector2D.X, vector2D.Y] = pathFinderNode2; } else { pathFinderNode2 = array[vector2D.X, vector2D.Y]; } if (!pathFinderNode2.InClosed) { int num2 = 0; if (pathFinderNode.Position.X != pathFinderNode2.Position.X) { num2++; } if (pathFinderNode.Position.Y != pathFinderNode2.Position.Y) { num2++; } int num3 = pathFinderNode.Cost + num2 + pathFinderNode2.Position.GetDistanceSquared(End); if (num3 < pathFinderNode2.Cost) { pathFinderNode2.Cost = num3; pathFinderNode2.Next = pathFinderNode; } if (!pathFinderNode2.InOpen) { if (pathFinderNode2.Equals(breadcrumb)) { pathFinderNode2.Next = pathFinderNode; return pathFinderNode2; } pathFinderNode2.InOpen = true; minHeap.Add(pathFinderNode2); } } } num++; } } return null; } }
public static PathFinderNode FindPathReversed(RoomUser User, bool Diag, Gamemap Map, Vector2D Start, Vector2D End) { var OpenList = new MinHeap<PathFinderNode>(256); var PfMap = new PathFinderNode[Map.Model.MapSizeX, Map.Model.MapSizeY]; PathFinderNode Node; Vector2D Tmp; int Cost; int Diff; var Current = new PathFinderNode(Start); Current.Cost = 0; var Finish = new PathFinderNode(End); PfMap[Current.Position.X, Current.Position.Y] = Current; OpenList.Add(Current); while (OpenList.Count > 0) { Current = OpenList.ExtractFirst(); Current.InClosed = true; for (int i = 0; Diag ? i < DiagMovePoints.Length : i < NoDiagMovePoints.Length; i++) { Tmp = Current.Position + (Diag ? DiagMovePoints[i] : NoDiagMovePoints[i]); bool IsFinalMove = (Tmp.X == End.X && Tmp.Y == End.Y); if (Map.IsValidStep(new Vector2D(Current.Position.X, Current.Position.Y), Tmp, IsFinalMove, User.AllowOverride)) { if (PfMap[Tmp.X, Tmp.Y] == null) { Node = new PathFinderNode(Tmp); PfMap[Tmp.X, Tmp.Y] = Node; } else { Node = PfMap[Tmp.X, Tmp.Y]; } if (!Node.InClosed) { Diff = 0; if (Current.Position.X != Node.Position.X) { Diff += 1; } if (Current.Position.Y != Node.Position.Y) { Diff += 1; } Cost = Current.Cost + Diff + Node.Position.GetDistanceSquared(End); if (Cost < Node.Cost) { Node.Cost = Cost; Node.Next = Current; } if (!Node.InOpen) { if (Node.Equals(Finish)) { Node.Next = Current; return Node; } Node.InOpen = true; OpenList.Add(Node); } } } } } return null; }
/// <summary> /// Method that switfly finds the best path from start to end. Doesn't reverse outcome /// </summary> /// <returns>The end SearchNode where each .next is a step back</returns> private SearchNode FindPathReversed(Point2 start, Point2 end) { SearchNode startNode = new SearchNode(start, 0, 0, null); MinHeap openList = new MinHeap(); openList.Add(startNode); int sx = myBoard.boardWidth; int sy = myBoard.boardHeight; bool[] brWorld = new bool[sx * sy]; brWorld[start.x + (start.y) * sx] = true; Point2[] tilesAround; while (openList.HasNext()) { SearchNode current = openList.ExtractFirst(); tilesAround = (current.position.y % 2 == 0)? aroundEven : aroundOdd; for (int i = 0; i < tilesAround.Length; i++) { Point2 tmpy = tilesAround[i]; Point2 tmp = current.position + tmpy; if (tmp == end) { //int cst = tileList[tmp.y][tmp.x].GetComponent<HexTile>().stepCost; return new SearchNode(end, current.pathCost, current.cost, current); } int brWorldIdx = tmp.x + (tmp.y) * sx; if (hex_accessible(tmp) && brWorld[brWorldIdx] == false) { brWorld[brWorldIdx] = true; //int pathCost = current.pathCost + surr.Cost; int pathCost = current.pathCost + 1; int cost = pathCost + tmp.GetDistanceSquared(end); SearchNode node = new SearchNode(tmp, cost, pathCost, current); openList.Add(node); } } } return null; //no path found }
public void TestAddAndCount() { var minHeap = new MinHeap<long>(); minHeap.Add(9999999999); Assert.AreEqual(1, minHeap.Count); }
public static VoronoiGraph ComputeVoronoiGraph(IEnumerable<Vector2> points) { var pq = new MinHeap<VEvent>(); var currentCircles = new Dictionary<VDataNode, VCircleEvent>(); var vg = new VoronoiGraph(); VNode rootNode = null; foreach (var v in points) { pq.Add(new VDataEvent(v)); } while (pq.Count > 0) { var ve = pq.RemoveMin(); VDataNode[] circleCheckList; if (ve is VDataEvent) { rootNode = VNode.ProcessDataEvent(ve as VDataEvent, rootNode, vg, ve.Y, out circleCheckList); } else if (ve is VCircleEvent) { currentCircles.Remove(((VCircleEvent)ve).NodeN); if (!((VCircleEvent)ve).Valid) continue; rootNode = VNode.ProcessCircleEvent(ve as VCircleEvent, rootNode, vg, out circleCheckList); } else throw new Exception("Got event of type " + ve.GetType() + "!"); foreach (var vd in circleCheckList) { if (currentCircles.ContainsKey(vd)) { currentCircles[vd].Valid = false; currentCircles.Remove(vd); } var vce = VNode.CircleCheckDataNode(vd, ve.Y); if (vce != null) { pq.Add(vce); currentCircles[vd] = vce; } } var evt = ve as VDataEvent; if (evt != null) { var dp = evt.DataPoint; foreach (var vce in currentCircles.Values) { if (Vector2.Distance(dp, vce.Center) < vce.Y - vce.Center.Y && Math.Abs(Vector2.Distance(dp, vce.Center) - (vce.Y - vce.Center.Y)) > 1e-10) vce.Valid = false; } } } VNode.CleanUpTree(rootNode as VEdgeNode); foreach (var ve in vg.Edges) { if (ve.Done) continue; if (!ve.VVertexB.HasValue) { ve.AddVertex(VvInfinite); if (Math.Abs(ve.LeftData.Y - ve.RightData.Y) < 1e-10 && ve.LeftData.X < ve.RightData.X) { var t = ve.LeftData; ve.LeftData = ve.RightData; ve.RightData = t; } } } var minuteEdges = new List<Edge>(); foreach (var ve in vg.Edges) { if (!ve.IsPartlyInfinite && ve.VVertexA.Equals(ve.VVertexB)) { minuteEdges.Add(ve); // prevent rounding errors from expanding to holes foreach (var ve2 in vg.Edges) { if (ve2.VVertexA.Equals(ve.VVertexA)) ve2.VVertexA = ve.VVertexA; if (ve2.VVertexB.Equals(ve.VVertexA)) ve2.VVertexB = ve.VVertexA; } } } foreach (var ve in minuteEdges) vg.MutableEdges.Remove(ve); return vg; }
private static void MinTest() { Console.WriteLine("\nThis section is to test the MIN HEAP class.\n"); string sort_error = "The current value is not grater than the next value on the array."; string pop_error = "The current value is not less than the next value on the array"; string invariant_error = "The invariants have been broken."; MinHeap<int> myHeap = new MinHeap<int>(); int[] numberList = new int[] { 2, 5, 9, 2, 8, 1, 4, 7, 3, 6 }; Console.WriteLine("Adding the following numbers to the heap: [{0}]\n", string.Join(", ", numberList)); foreach (int number in numberList) myHeap.Add(number); Console.WriteLine("New Heap: [{0}]\n", string.Join(", ", myHeap)); Console.WriteLine("Performing Heap Sort...\n"); myHeap.Sort(); TestMinSort(myHeap, sort_error); Console.WriteLine("New Heap: [{0}]\n", string.Join(", ", myHeap)); Console.WriteLine("Rebuilding Heap...\n"); myHeap.BuildHeap(); Console.WriteLine("New Heap: [{0}]\n", string.Join(", ", myHeap)); Console.WriteLine("Poping the top value until heap is empty...\n"); TestMinPop(myHeap, pop_error); int elements = 20000; myHeap = new MinHeap<int>(elements); int[] random_list = RandomIntArray(elements); Console.WriteLine("Adding {0} values to a new heap and verifying the invariants...\n", elements); Console.WriteLine("This part will take a while...\n"); foreach (int number in random_list) { myHeap.Add(number); TestMinInvariant(myHeap, invariant_error); } Console.WriteLine("Heap too big to print on console, current elements in heap: {0}\n", myHeap.Count); Console.WriteLine("Going to pop half of the values out of the heap and verifying the invariants...\n"); Console.WriteLine("Again... This part will take a while...\n"); for (int i = 0; i < elements / 2; i++) { myHeap.PopMin(); TestMinInvariant(myHeap, invariant_error); } Console.WriteLine("Heap too big to print on console, current elements in heap: {0}\n", myHeap.Count); }
/// <summary> /// Method that switfly finds the best path from start to end. Doesn't reverse outcome /// </summary> /// <returns>The end breadcrump where each next is a step back)</returns> private static BreadCrumb FindPathReversed(Level world, BotMap level, Point3D start, Point3D end) { MinHeap<BreadCrumb> openList = new MinHeap<BreadCrumb>(256); BreadCrumb[, ,] brWorld = new BreadCrumb[world.Size.x, world.Size.y, world.Size.z]; BreadCrumb node; Point3D tmp; int cost; int diff; BreadCrumb current = new BreadCrumb(start); current.cost = 0; BreadCrumb finish = new BreadCrumb(end); try { brWorld[current.position.X, current.position.Y, current.position.Z] = current; } catch { return current; } openList.Add(current); while (openList.Count > 0) { //Find best item and switch it to the 'closedList' current = openList.ExtractFirst(); current.onClosedList = true; //Find neighbours for (int i = 0; i < surrounding.Length; i++) { tmp = current.position + surrounding[i]; if ((tmp.X <= -1 || tmp.Y <= -1 || tmp.Z <= -1) || (tmp.X >= level.Size.x || tmp.Y >= level.Size.y || tmp.Z >= level.Size.z)) break; TriBool block = false; try { block = level.AirMap[tmp.X, tmp.Z, tmp.Y]; //Check if block is air } catch { } if (block != TriBool.Unknown) { //Check if we've already examined a neighbour, if not create a new node for it. if (brWorld[tmp.X, tmp.Y, tmp.Z] == null) { node = new BreadCrumb(tmp); brWorld[tmp.X, tmp.Y, tmp.Z] = node; } else { node = brWorld[tmp.X, tmp.Y, tmp.Z]; } //If the node is not on the 'closedList' check it's new score, keep the best if (!node.onClosedList) { diff = 0; if (current.position.X != node.position.X) { diff += 1; } if (current.position.Y != node.position.Y) { diff += 1; } if (current.position.Z != node.position.Z) { diff += 1; } if (block == false) //Solid but breakable, allows bot to go through solid areas { diff += 50; } cost = current.cost + diff + node.position.GetDistanceSquared(end); if (cost < node.cost) { node.cost = cost; node.next = current; } //If the node wasn't on the openList yet, add it if (!node.onOpenList) { //Check to see if we're done if (node.Equals(finish)) { node.next = current; return node; } node.onOpenList = true; openList.Add(node); } } } } } return null; //no path found }
public List<Node> Astar(Node start, Node goal) { if (start == null || goal == null){ return null; } if (start == goal) { return new List<Node> {start}; } foreach(Node node in objectManager.NodeManager.nodes) { node.Reset(); } MinHeap openSet = new MinHeap(start); start.IsInOpenSet = true; start.gScore = 0; start.fScore = start.gScore + Heuristic_cost_estimate (goal, start); Node current = null; while (openSet.Count() > 0) { current = openSet.GetRoot (); current.IsInOpenSet = false; current.IsInClosedSet = true; if (current == goal) { return Reconstruct_path (start, goal); } foreach (Node neighbor in current.BorderTiles) { if(neighbor == null || !neighbor.IsWalkable || neighbor.IsInClosedSet) continue; // if the new gscore is lower replace it int tentativeGscore = current.gScore + Heuristic_cost_estimate (current, neighbor); if (!neighbor.IsInOpenSet || tentativeGscore < neighbor.gScore) { neighbor.parent = current; neighbor.gScore = tentativeGscore; neighbor.fScore = neighbor.gScore + Heuristic_cost_estimate (goal, neighbor); if (!neighbor.IsInOpenSet){ openSet.Add (neighbor); neighbor.IsInOpenSet = true; } else { openSet.Reevaluate(neighbor); } } } } // Fail return null; }
/// <summary> /// Neighbour handling of our AStar algorithm. /// </summary> private void HandleNeighbours(AStarNode current, List<MeshNode> neighbours, MinHeap<AStarNode> workingQueue, PointSet<float> workingCoords, PointSet<float> exploredCoords, Vector2 end) { foreach (MeshNode neighbour in neighbours) { // neighbour will be added if neither in workingQueue(workingCoords) nor exploredCoords if (!exploredCoords.Contains(neighbour.mVector.X, neighbour.mVector.Y) && !workingCoords.Contains(neighbour.mVector.X, neighbour.mVector.Y)) { double neighbourCostsToEnd = HelperMethods.EuklidDistance(neighbour.mVector, end); double neighbourLatestCosts = current.mLatestCosts + HelperMethods.EuklidDistance(current.mNode.mVector, neighbour.mVector); AStarNode neighbour2 = new AStarNode(neighbourLatestCosts, neighbourCostsToEnd, neighbour, current); // add neighbour with its heuristic value to workingQueue: workingQueue.Add(HeuristicValue(neighbour2), neighbour2); workingCoords.Add(neighbour.mVector.X, neighbour.mVector.Y); } } }
/// <summary> /// Method that switfly finds the best path from start to end. Doesn't reverse outcome /// </summary> /// <returns>The end breadcrump where each .next is a step back)</returns> private static BreadCrumb FindPathReversed(World world, Point3D start, Point3D end) { MinHeap<BreadCrumb> openList = new MinHeap<BreadCrumb>(256); BreadCrumb[, ,] brWorld = new BreadCrumb[world.Right, world.Top, world.Back]; BreadCrumb node; Point3D tmp; int cost; int diff; int count; BreadCrumb current = new BreadCrumb(start); current.cost = 0; BreadCrumb finish = new BreadCrumb(end); if (current.position.X < 0 || current.position.X > brWorld.GetUpperBound(0) || current.position.Y < 0 || current.position.Y > brWorld.GetUpperBound(0)) return null; brWorld[current.position.X, current.position.Y, current.position.Z] = current; openList.Add(current); count = 0; while (openList.Count > 0) { //Find best item and switch it to the 'closedList' current = openList.ExtractFirst(); current.onClosedList = true; //Find neighbours for (int i = 0; i < surrounding.Length; i++) { tmp = current.position + surrounding[i]; if (world.PositionIsFree(tmp) || (tmp.X==end.X && tmp.Y==end.Y && tmp.Z==end.Z)) { //Check if we've already examined a neighbour, if not create a new node for it. if (brWorld[tmp.X, tmp.Y, tmp.Z] == null) { node = new BreadCrumb(tmp); brWorld[tmp.X, tmp.Y, tmp.Z] = node; } else { node = brWorld[tmp.X, tmp.Y, tmp.Z]; } //If the node is not on the 'closedList' check it's new score, keep the best if (!node.onClosedList) { diff = 0; if (current.position.X != node.position.X) { diff += 1; } if (current.position.Y != node.position.Y) { diff += 1; } if (current.position.Z != node.position.Z) { diff += 1; } cost = current.cost + diff + node.position.GetDistanceSquared(end); if (cost < node.cost) { node.cost = cost; node.next = current; } //If the node wasn't on the openList yet, add it if (!node.onOpenList) { //Check to see if we're done if (node.Equals(finish)) { node.next = current; return node; } node.onOpenList = true; openList.Add(node); } } } } count++; if (count > 1000) return null; } return null; //no path found }
/// <summary> /// Finds the path reversed. /// </summary> /// <param name="RoomUserable">The user.</param> /// <param name="WhatIsDiag">if set to <c>true</c> [diag].</param> /// <param name="GameLocalMap">The map.</param> /// <param name="StartMap">The start.</param> /// <param name="EndMap">The end.</param> /// <returns>PathFinderNode.</returns> public static PathFinderNode FindPathReversed(RoomUser RoomUserable, bool WhatIsDiag, Gamemap GameLocalMap, Vector2D StartMap, Vector2D EndMap) { MinHeap<PathFinderNode> MinSpanTreeCost = new MinHeap<PathFinderNode>(256); PathFinderNode[,] PathFinderMap = new PathFinderNode[GameLocalMap.Model.MapSizeX, GameLocalMap.Model.MapSizeY]; PathFinderNode PathFinderStart = new PathFinderNode(StartMap) { Cost = 0 }; PathFinderNode PathFinderEnd = new PathFinderNode(EndMap); PathFinderMap[PathFinderStart.Position.X, PathFinderStart.Position.Y] = PathFinderStart; MinSpanTreeCost.Add(PathFinderStart); int loop_variable_one, InternalSpanTreeCost, loop_total_cost; while (MinSpanTreeCost.Count > 0) { PathFinderStart = MinSpanTreeCost.ExtractFirst(); PathFinderStart.InClosed = true; loop_variable_one = 0; while ((WhatIsDiag ? (loop_variable_one < DiagMovePoints.Length) : (loop_variable_one < NoDiagMovePoints.Length))) { Vector2D RealEndPosition = PathFinderStart.Position + (WhatIsDiag ? DiagMovePoints[loop_variable_one] : NoDiagMovePoints[loop_variable_one]); bool IsEndOfPath = ((RealEndPosition.X == EndMap.X) && (RealEndPosition.Y == EndMap.Y)); if (GameLocalMap.IsValidStep(RoomUserable, new Vector2D(PathFinderStart.Position.X, PathFinderStart.Position.Y), RealEndPosition, IsEndOfPath, RoomUserable.AllowOverride)) { PathFinderNode PathFinderSecondNodeCalculation; if (PathFinderMap[RealEndPosition.X, RealEndPosition.Y] == null) { PathFinderSecondNodeCalculation = new PathFinderNode(RealEndPosition); PathFinderMap[RealEndPosition.X, RealEndPosition.Y] = PathFinderSecondNodeCalculation; } else { PathFinderSecondNodeCalculation = PathFinderMap[RealEndPosition.X, RealEndPosition.Y]; } if (!PathFinderSecondNodeCalculation.InClosed) { InternalSpanTreeCost = 0; if (PathFinderStart.Position.X != PathFinderSecondNodeCalculation.Position.X) InternalSpanTreeCost++; if (PathFinderStart.Position.Y != PathFinderSecondNodeCalculation.Position.Y) InternalSpanTreeCost++; loop_total_cost = PathFinderStart.Cost + InternalSpanTreeCost + PathFinderSecondNodeCalculation.Position.GetDistanceSquared(EndMap); if (loop_total_cost < PathFinderSecondNodeCalculation.Cost) { PathFinderSecondNodeCalculation.Cost = loop_total_cost; PathFinderSecondNodeCalculation.Next = PathFinderStart; } if (!PathFinderSecondNodeCalculation.InOpen) { if (PathFinderSecondNodeCalculation.Equals(PathFinderEnd)) { PathFinderSecondNodeCalculation.Next = PathFinderStart; return PathFinderSecondNodeCalculation; } PathFinderSecondNodeCalculation.InOpen = true; MinSpanTreeCost.Add(PathFinderSecondNodeCalculation); } } } loop_variable_one++; } } return null; }