Add() 공개 메소드

Adds an element to the heap and bubbles up.
public Add ( Node, element ) : void
element Node, element to add
리턴 void
예제 #1
0
파일: TopK.cs 프로젝트: susingh/questions
        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());
        }
예제 #3
0
        //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());
        }
예제 #4
0
    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));
        }
예제 #6
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);
        }
예제 #7
0
    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()
    }
예제 #8
0
    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);
            }
        }
    }
예제 #9
0
            /// <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);
            }
예제 #10
0
    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);
    }
예제 #11
0
        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;
        }
예제 #12
0
        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);
        }
예제 #13
0
        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);
                    }
                }
            }
        }
예제 #14
0
            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);
    }
예제 #16
0
    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());
        }
예제 #18
0
        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)));
        }
예제 #19
0
        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());
        }
예제 #21
0
        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);
        }
예제 #22
0
        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);
        }
예제 #23
0
        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;
                }
            }
        }
예제 #24
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);
    }
예제 #25
0
        /// <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);
        }
예제 #26
0
        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));
        }
예제 #29
0
        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());
        }
예제 #31
0
        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);
        }
예제 #32
0
        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);
        }
예제 #33
0
        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);
        }
예제 #34
0
        /// <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;
        }
예제 #35
0
        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;
            }
        }
예제 #36
0
        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());
        }
예제 #37
0
        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();
        }
예제 #38
0
        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());
        }
예제 #39
0
        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);
            }
        }
예제 #40
0
파일: PathFinder.cs 프로젝트: sgf/Yupi
        /// <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;
        }
예제 #41
0
		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;
			}
		}
예제 #42
0
파일: PathFinder.cs 프로젝트: BjkGkh/Boon
        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;
        }
예제 #43
0
    /// <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
    }
예제 #44
0
 public void TestAddAndCount()
 {
     var minHeap = new MinHeap<long>();
     minHeap.Add(9999999999);
     Assert.AreEqual(1, minHeap.Count);
 }
예제 #45
0
        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;
        }
예제 #46
0
        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);
        }
예제 #47
0
        /// <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
        }
예제 #48
0
    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;
    }
예제 #49
0
        /// <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);
                }
            }
        }
예제 #50
0
        /// <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
        }
예제 #51
0
파일: PathFinder.cs 프로젝트: BjkGkh/Azure2
        /// <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;
        }