广度优先搜索(Breadth First
Search,简称BFS),又称为宽度优先搜索。它和深度优先搜索(Depth First
Search,简称DFS)一样,是一种图形搜索算法,用来遍历或搜索树或图的算法,从而找到最短路径。它们主要的不同在于它们寻路的决策,正如其名称所示,深度优先搜索会优先探索不同层的节点,而广度优先搜索会优先探索同一层的节点。下图就很明显可以看出它们决策的区别。
privatevoidBfs(int[][] mapInfo, int[][] globalPrice, List<Vector2Int> curPath, Vector2Int pos) { if (pos == target) { this.curPath = new List<Vector2Int>(curPath); return; } int row = mapInfo.Length; int col = mapInfo[0].Length; int r = pos.x, c = pos.y;
for (int j = -1; j < 2; j += 2) { int curC = c + j; if (curC >= 0 && curC < col && mapInfo[r][curC] > 0 && globalPrice[r][c] + mapInfo[r][curC] < globalPrice[r][curC]) { globalPrice[r][curC] = globalPrice[r][c] + mapInfo[r][curC]; Vector2Int curPos = new Vector2Int(r, curC); curPath.Add(curPos); Bfs(mapInfo, globalPrice, curPath, curPos); curPath.RemoveAt(curPath.Count - 1); } }
privatevoidDfs(int[][] mapInfo, int[][] globalPrice, List<Vector2Int> curPath, Vector2Int pos) { if (pos == target) { this.curPath = new List<Vector2Int>(curPath); return; } int row = mapInfo.Length; int col = mapInfo[0].Length; int r = pos.x, c = pos.y;
for (int i = -1; i < 2; i += 2) { int curR = r + i; if (curR >= 0 && curR < row && mapInfo[curR][c] > 0 && globalPrice[r][c] + mapInfo[curR][c] < globalPrice[curR][c]) { globalPrice[curR][c] = globalPrice[r][c] + mapInfo[curR][c]; Vector2Int curPos = new Vector2Int(curR, c); curPath.Add(curPos); Dfs(mapInfo, globalPrice, curPath, curPos); curPath.RemoveAt(curPath.Count - 1); } }
for (int j = -1; j < 2; j += 2) { int curC = c + j; if (curC >= 0 && curC < col && mapInfo[r][curC] > 0 && globalPrice[r][c] + mapInfo[r][curC] < globalPrice[r][curC]) { globalPrice[r][curC] = globalPrice[r][c] + mapInfo[r][curC]; Vector2Int curPos = new Vector2Int(r, curC); curPath.Add(curPos); Dfs(mapInfo, globalPrice, curPath, curPos); curPath.RemoveAt(curPath.Count - 1); } } }
privatevoidDijkstraFun(int[][] mapInfo, int[][] globalPrice, Vector2Int[][] pathOffset, Vector2Int startPos) { int row = mapInfo.Length; int col = mapInfo[0].Length; List<Vector2Int> priQueue = new List<Vector2Int>(); priQueue.Add(startPos); globalPrice[startPos.x][startPos.y] = 0; while (priQueue.Count > 0) { var curVal = priQueue[priQueue.Count - 1]; priQueue.RemoveAt(priQueue.Count - 1); for (int i = -1; i < 2; i += 2) { int x = curVal.x + i; int y = curVal.y; if (x > -1 && x < row && mapInfo[x][y] > 0 && globalPrice[curVal.x][curVal.y] + mapInfo[x][y] < globalPrice[x][y]) { globalPrice[x][y] = globalPrice[curVal.x][curVal.y] + mapInfo[x][y]; priQueue.Add(new Vector2Int(x, y)); pathOffset[x][y] = new Vector2Int(-i, 0); } }
for (int i = -1; i < 2; i += 2) { int x = curVal.x; int y = curVal.y + i; if (y > -1 && y < col && mapInfo[x][y] > 0 && globalPrice[curVal.x][curVal.y] + mapInfo[x][y] < globalPrice[x][y]) { globalPrice[x][y] = globalPrice[curVal.x][curVal.y] + mapInfo[x][y]; priQueue.Add(new Vector2Int(x, y)); pathOffset[x][y] = new Vector2Int(0, -i); } }
privatevoidAStarFun(int[][] mapInfo, int[][] globalPrice, Vector2Int[][] pathOffset, Vector2Int startPos, Vector2Int targetPos) { int row = mapInfo.Length; int col = mapInfo[0].Length; List<Vector3Int> priQueue = new List<Vector3Int>(); priQueue.Add(new Vector3Int(startPos.x,startPos.y,0)); curNode = startPos; globalPrice[startPos.x][startPos.y] = 0; while (priQueue.Count > 0) { var curVal = priQueue[priQueue.Count - 1]; curNode = new Vector2Int(curVal.x,curVal.y); if (curNode == targetPos) break;
priQueue.RemoveAt(priQueue.Count - 1); for (int i = -1; i < 2; i += 2) { int x = curVal.x + i; int y = curVal.y; var curNodePos = new Vector2Int(x, y); if (x > -1 && x < row) { if (mapInfo[x][y] > 0) { if (mapInfo[x][y] + globalPrice[curVal.x][curVal.y] < globalPrice[x][y]) { globalPrice[x][y] = mapInfo[x][y] + globalPrice[curVal.x][curVal.y]; priQueue.Add(new Vector3Int(x, y, HeuristicFun(mapInfo[x][y], curNodePos, targetPos))); pathOffset[x][y] = new Vector2Int(-i, 0); } } else { globalPrice[x][y] = int.MinValue; } } }
for (int i = -1; i < 2; i += 2) { int x = curVal.x; int y = curVal.y + i; var curNodePos = new Vector2Int(x, y); if (y > -1 && y < col) { if (mapInfo[x][y] > 0) { if (mapInfo[x][y] + globalPrice[curVal.x][curVal.y] < globalPrice[x][y]) { globalPrice[x][y] = mapInfo[x][y] + globalPrice[curVal.x][curVal.y]; priQueue.Add(new Vector3Int(x, y, HeuristicFun(mapInfo[x][y], curNodePos, targetPos))); pathOffset[x][y] = new Vector2Int(0, -i); } } else { globalPrice[x][y] = int.MinValue; } } }