// 힙 트리는 리스트 탐색에 비해 속도가 빠르다. n개의 데이터를 log2(n) 회의 탐색만으로 찾을 수 있어서 시간 복잡도가 줄어들기 때문이다. //---------------------------------------------------------------------------- // 3.1. 힙 트리 응용 - 제네릭 형식으로 만들기 // IComparable 인터페이스를 이용하여 우선순위를 비교한다. (int에는 기본적으로 적용되어 있다) public override void TestCode04() { code4 = "힙 트리 응용 - 제네릭으로 3번 코드 구현, 낮은 숫자 순으로"; D05_PriorityQueue <int> q = new D05_PriorityQueue <int>(); q.Push(-40); q.Push(-25); q.Push(-67); q.Push(-70); q.Push(-99); q.Push(-36); q.Push(-4); q.Push(-13); q.Push(-22); q.Push(-56); // 코드 3번의 팁 적용 while (q.Count > 0) { Debug.Log(-q.Pop()); } }
public override void TestCode05() { code5 = "힙 트리 응용 - 제네릭으로 직접 만든 클래스를 ID로 비교하기"; D05_PriorityQueue <D05_Knight> q = new D05_PriorityQueue <D05_Knight>(); q.Push(new D05_Knight() { Id = 20 }); q.Push(new D05_Knight() { Id = 5 }); q.Push(new D05_Knight() { Id = 35 }); q.Push(new D05_Knight() { Id = 25 }); q.Push(new D05_Knight() { Id = 40 }); q.Push(new D05_Knight() { Id = 10 }); while (q.Count > 0) { Debug.Log(q.Pop().Id); } }
//--------------------------------------------------------------------------------------- public void MakeAStarLogic2(E03_TileType[,] maze) { int mapSize = maze.GetLength(0); int goalY = mapSize - 2; int goalX = mapSize - 2; bool[,] closed = new bool[mapSize, mapSize]; int[,] open = new int[mapSize, mapSize]; for (int y = 0; y < mapSize; y++) { for (int x = 0; x < mapSize; x++) { open[y, x] = int.MaxValue; } } E03_Pos[,] from = new E03_Pos[mapSize, mapSize]; from[PosY, PosX] = new E03_Pos(PosY, PosX); D05_PriorityQueue <E03_PQNode> pq = new D05_PriorityQueue <E03_PQNode>(); open[PosY, PosX] = 10 * (Mathf.Abs(goalY - PosY) + Mathf.Abs(goalX - PosX)); pq.Push(new E03_PQNode() { F = open[PosY, PosX], G = 0, X = PosX, Y = PosY }); while (pq.Count > 0) { E03_PQNode node = pq.Pop(); int nowY = node.Y; int nowX = node.X; if (closed[nowY, nowX]) { continue; } if (nowY == goalY && nowX == goalX) { break; } for (int i = 0; i < forwardX2.Length; i++) { int nextY = nowY + forwardY2[i]; int nextX = nowX + forwardX2[i]; if (nextX < 0 || nextY < 0 || nextX >= mapSize || nextY >= mapSize) { continue; } if (maze[nextY, nextX] == E03_TileType.Wall) { continue; } if (closed[nextY, nextX]) { continue; } int g = node.G + moveCost2[i]; int h = 10 * (Mathf.Abs(goalY - nextY) + Mathf.Abs(goalX - nextX)); if (open[nextY, nextX] < g + h) { continue; } open[nextY, nextX] = g + h; pq.Push(new E03_PQNode() { F = g + h, G = g, X = nextX, Y = nextY }); from[nextY, nextX] = new E03_Pos(nowY, nowX); } } AStarRoad = MakeRoad(from, mapSize); }
//--------------------------------------------------------------------------------------- public void MakeAStarLogic(E03_TileType[,] maze) { int mapSize = maze.GetLength(0); int goalY = mapSize - 2; int goalX = mapSize - 2; int startY = PosY; int startX = PosX; bool[,] closed = new bool[mapSize, mapSize]; int[,] open = new int[mapSize, mapSize]; E03_Pos[,] from = new E03_Pos[mapSize, mapSize]; from[startY, startX] = new E03_Pos(startY, startX); for (int y = 0; y < open.GetLength(0); y++) { for (int x = 0; x < open.GetLength(1); x++) { open[y, x] = int.MaxValue; } } D05_PriorityQueue <E03_PQNode> pq = new D05_PriorityQueue <E03_PQNode>(); open[startY, startY] = Mathf.Abs(goalY - startY) + Math.Abs(goalX - startX) + 0; // 시작점이므로 현재까지 온 거리는 0이다. 사실 더해주지 않아도 무방하다. pq.Push(new E03_PQNode() { F = Mathf.Abs(goalY - startY) + Math.Abs(goalX - startX), G = 0, X = startX, Y = startY }); while (pq.Count > 0) { E03_PQNode node = pq.Pop(); if (closed[node.Y, node.X]) { continue; } closed[node.Y, node.X] = true; int nowY = node.Y; int nowX = node.X; if (nowY == goalY && nowX == goalX) { break; } for (int i = 0; i < forwardX.Length; i++) { int nextY = nowY + forwardY[i]; int nextX = nowX + forwardX[i]; if (nextX < 0 || nextY < 0 || nextX >= mapSize || nextY >= mapSize) { continue; } if (closed[nextY, nextX]) { continue; } if (maze[nextY, nextX] == E03_TileType.Wall) { continue; } int g = node.G + moveCost[i]; int h = Mathf.Abs(goalY - nowY) + Math.Abs(goalX - nowX); int distance = g + h; if (open[nextY, nextX] < distance) { continue; } pq.Push(new E03_PQNode() { F = distance, G = g, X = nextX, Y = nextY }); open[nextY, nextX] = distance; from[nextY, nextX] = new E03_Pos(nowY, nowX); } } AStarRoad = MakeRoad(from, mapSize); }