예제 #1
0
        private void Init()
        {
            DoubleBuffered = true;

            m_resultBox = new List <ResultBox>();
            Width       = (width + 1) * 10;
            Height      = (height + 1) * 10 + 100;
            MaximumSize = new Size(Width, Height);
            MaximizeBox = false;

            m_rectangles = new GridBox[width][];
            for (int widthTrav = 0; widthTrav < width; widthTrav++)
            {
                m_rectangles[widthTrav] = new GridBox[height];
                for (int heightTrav = 0; heightTrav < height; heightTrav++)
                {
                    if (widthTrav == 10 && heightTrav == 10)
                    {
                        m_rectangles[widthTrav][heightTrav] = new GridBox(widthTrav * 10, heightTrav * 10 + 50, BoxType.Start);
                    }
                    else if (widthTrav == 100 && heightTrav == 50)
                    {
                        m_rectangles[widthTrav][heightTrav] = new GridBox(widthTrav * 10, heightTrav * 10 + 50, BoxType.End);
                    }
                    else
                    {
                        m_rectangles[widthTrav][heightTrav] = new GridBox(widthTrav * 10, heightTrav * 10 + 50, BoxType.Normal);
                    }
                }
            }


            m_resultLine = new List <GridLine>();

            searchGrid = new StaticGrid(width, height);

            jumpParam = new AStarParam(searchGrid, 50, HeuristicMode.EUCLIDEAN);
        }
예제 #2
0
        /*
         * private class NodeComparer : IComparer<Node>
         * {
         *  public int Compare(Node x, Node y)
         *  {
         *      var result = (x.heuristicStartToEndLen - y.heuristicStartToEndLen);
         *      if (result < 0) return -1;
         *      else
         *      if (result > 0) return 1;
         *      else
         *      {
         *          return 0;
         *      }
         *  }
         * }
         */
        public static List <GridPos> FindPath(AStarParam iParam, bool iMultiThread, Label s)
        {
            object lo = new object();
            //var openList = new IntervalHeap<Node>(new NodeComparer());
            var openList  = new IntervalHeap <Node>();
            var startNode = iParam.StartNode;
            var endNode   = iParam.EndNode;
            var heuristic = iParam.HeuristicFunc;
            var grid      = iParam.SearchGrid;
            var weight    = iParam.Weight;


            startNode.startToCurNodeLen      = 0;
            startNode.heuristicStartToEndLen = 0;

            openList.Add(startNode);
            startNode.isOpened = true;

            while (openList.Count != 0)
            {
                var node = openList.DeleteMin();
                node.isClosed = true;

                if (node == endNode)
                {
                    return(Node.Backtrace(endNode));
                }

                var neighbors = grid.GetNeighbors(node);


                if (iMultiThread)
                {
                    s.Text = "true ";
                    Parallel.ForEach(neighbors, new ParallelOptions {
                        MaxDegreeOfParallelism = 2
                    }, neighbor =>
                    {
                        if (neighbor.isClosed)
                        {
                            return;
                        }

                        var x    = neighbor.x;
                        var y    = neighbor.y;
                        float ng = node.startToCurNodeLen + (float)((x - node.x == 0 || y - node.y == 0) ? 1 : Math.Sqrt(2));

                        if (!neighbor.isOpened || ng < neighbor.startToCurNodeLen)
                        {
                            neighbor.startToCurNodeLen = ng;
                            if (neighbor.heuristicCurNodeToEndLen == null)
                            {
                                neighbor.heuristicCurNodeToEndLen = weight * heuristic(Math.Abs(x - endNode.x), Math.Abs(y - endNode.y));
                            }
                            neighbor.heuristicStartToEndLen = neighbor.startToCurNodeLen + neighbor.heuristicCurNodeToEndLen.Value;
                            neighbor.parent = node;
                            if (!neighbor.isOpened)
                            {
                                lock (lo)
                                {
                                    openList.Add(neighbor);
                                }
                                neighbor.isOpened = true;
                            }
                            else
                            {
                            }
                        }
                    }
                                     );
                }
                else
                {
                    s.Text = "false ";
                    foreach (Node neighbor in neighbors)
                    {
                        if (neighbor.isClosed)
                        {
                            continue;
                        }

                        var   x  = neighbor.x;
                        var   y  = neighbor.y;
                        float ng = node.startToCurNodeLen + (float)((x - node.x == 0 || y - node.y == 0) ? 1 : Math.Sqrt(2));

                        if (!neighbor.isOpened || ng < neighbor.startToCurNodeLen)
                        {
                            neighbor.startToCurNodeLen = ng;
                            if (neighbor.heuristicCurNodeToEndLen == null)
                            {
                                neighbor.heuristicCurNodeToEndLen = weight * heuristic(Math.Abs(x - endNode.x), Math.Abs(y - endNode.y));
                            }
                            neighbor.heuristicStartToEndLen = neighbor.startToCurNodeLen + neighbor.heuristicCurNodeToEndLen.Value;
                            neighbor.parent = node;
                            if (!neighbor.isOpened)
                            {
                                lock (lo)
                                {
                                    openList.Add(neighbor);
                                }
                                neighbor.isOpened = true;
                            }
                            else
                            {
                            }
                        }
                    }
                }
            }
            return(new List <GridPos>());
        }
예제 #3
0
        private void Redraw()
        {
            foreach (GridLine l in m_resultLine)
            {
                l.Dispose();
            }
            m_resultLine = new List <GridLine>();
            List <GridPos> resultList = new List <GridPos>();

            searchGrid = new StaticGrid(width, height);
            jumpParam  = new AStarParam(searchGrid, 50, HeuristicMode.EUCLIDEAN);
            Invalidate();

            for (int resultTrav = 0; resultTrav < m_resultLine.Count; resultTrav++)
            {
                m_resultLine[resultTrav].Dispose();
            }
            m_resultLine.Clear();
            for (int resultTrav = 0; resultTrav < m_resultBox.Count; resultTrav++)
            {
                m_resultBox[resultTrav].Dispose();
            }
            m_resultBox.Clear();

            GridPos startPos = new GridPos();
            GridPos endPos   = new GridPos();

            for (int widthTrav = 0; widthTrav < width; widthTrav++)
            {
                for (int heightTrav = 0; heightTrav < height; heightTrav++)
                {
                    if (m_rectangles[widthTrav][heightTrav].boxType != BoxType.Wall)
                    {
                        searchGrid.SetWalkableAt(new GridPos(widthTrav, heightTrav), true);
                    }
                    else
                    {
                        searchGrid.SetWalkableAt(new GridPos(widthTrav, heightTrav), false);
                    }
                    if (m_rectangles[widthTrav][heightTrav].boxType == BoxType.Start)
                    {
                        startPos.x = widthTrav;
                        startPos.y = heightTrav;
                    }
                    if (m_rectangles[widthTrav][heightTrav].boxType == BoxType.End)
                    {
                        endPos.x = widthTrav;
                        endPos.y = heightTrav;
                    }
                }
            }
            System.Diagnostics.Stopwatch s = new System.Diagnostics.Stopwatch();
            s.Start();
            jumpParam.Reset(startPos, endPos);
            resultList = AStarFinder.FindPath(jumpParam, isMultiThreading, lb_istrue);
            double time = s.ElapsedMilliseconds;

            s.Reset();


            if (isMultiThreading)
            {
                lb_multi.Text = "Time elapsed with multithreading: " + time + " ms.";
            }
            else
            {
                lb_multi.Text = "Time elapsed without multithreading: " + time + " ms.";
            }

            for (int resultTrav = 0; resultTrav < resultList.Count - 1; resultTrav++)
            {
                m_resultLine.Add(new GridLine(m_rectangles[resultList[resultTrav].x][resultList[resultTrav].y], m_rectangles[resultList[resultTrav + 1].x][resultList[resultTrav + 1].y]));
            }
            for (int widthTrav = 0; widthTrav < jumpParam.SearchGrid.width; widthTrav++)
            {
                for (int heightTrav = 0; heightTrav < jumpParam.SearchGrid.height; heightTrav++)
                {
                    if (jumpParam.SearchGrid.GetNodeAt(widthTrav, heightTrav) == null)
                    {
                        continue;
                    }
                    if (jumpParam.SearchGrid.GetNodeAt(widthTrav, heightTrav).isOpened)
                    {
                        ResultBox resultBox = new ResultBox(widthTrav * 10, heightTrav * 10 + 50, ResultBoxType.Opened);
                        m_resultBox.Add(resultBox);
                    }
                    if (jumpParam.SearchGrid.GetNodeAt(widthTrav, heightTrav).isClosed)
                    {
                        ResultBox resultBox = new ResultBox(widthTrav * 10, heightTrav * 10 + 50, ResultBoxType.Closed);
                        m_resultBox.Add(resultBox);
                    }
                }
            }
            Invalidate();
        }