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); }
/* * 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>()); }
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(); }