๐A* ์๊ณ ๋ฆฌ์ฆ์ด๋?
A* ์๊ณ ๋ฆฌ์ฆ์ ์ต๋จ ๊ฑฐ๋ฆฌ ์๊ณ ๋ฆฌ์ฆ ์ค ํ๋๋ก, ์ถ๋ฐ ๋ ธ๋์์๋ถํฐ ๋ชฉํ ๋ ธ๋๊น์ง ๊ฐ๋ ์ต๋จ ๊ฒฝ๋ก๋ฅผ ์ฐพ์๋ธ๋ค.
์ต๋จ ๊ฒฝ๋ก ์๊ณ ๋ฆฌ์ฆ Visualization
https://qiao.github.io/PathFinding.js/visual/
๐์ฝ๋
Node.js
package astar;
public class Node {
Integer x;
Integer y;
Integer startd;
Integer destd;
Integer total;
Node parents;
public Node(Integer x, Integer y) {
this.x = x;
this.y = y;
parents = null;
}
}
Astar.java
package astar;
import java.util.*;
public class Astar {
final Integer DEFAULT_COST = 10;
final Integer DEFAULT_DIAGONAL = 14;
//์ํ์ข์ฐ, ๋๊ฐ์ ์์ข ์์ฐ ํ์ข ํ์ฐ
final Integer XPOS[] = {0, 0, -1, 1, -1, 1, -1, 1 };
final Integer YPOS[] = {-1, 1, 0, 0, -1, -1, 1, 1 };
//๋งต์ ํฌ๊ธฐ๋ฅผ ์ ์ฅํ๋ ๋ณ์
Integer mapX;
Integer mapY;
//์ด๋ฆฐ, ๋ซํ ๋ชฉ๋ก ์ ์ฅํ ๋ณ์
List<Node> open;
List<Node> close;
List<Node> block;
//์ด๊ธฐํ ํ ๋ ๋งต ์ ๋ณด๋ฅผ ์ ๋ฌ ๋ฐ์์ ์ถ๋ฐ์ง์ ๋ชฉ์ ์ง์ ์ขํ๋ฅผ ๋ณ์์ ์ ์ฅ
Integer[][] map;
Node start;
Node goal;
public Astar(Integer[][] map) {
this.map = map;
mapX = map[0].length;
mapY = map.length;
//์ด๋ฆฐ ๋ชฉ๋ก, ๋ซํ ๋ชฉ๋ก ์ด๊ธฐํ
open = new ArrayList<>();
close = new ArrayList<>();
block = new ArrayList<>();
//์ถ๋ฐ์ , ๋์ฐฉ์ , ์ฅ์ ๋ฌผ ์ด๊ธฐํ
init();
start.startd = 0;
start.destd = Math.abs(goal.x - start.x) *10 + Math.abs(goal.y - start.y) *10;
start.total = start.startd + start.destd;
}
void init(){
for (int i = 0; i < map.length; i++) {
for (int j = 0; j < map[i].length; j++) {
if(map[i][j] == 1){
System.out.printf("์ถ๋ฐ์ : (%d, %d)", j, i);
start = new Node(j, i);
}
else if(map[i][j] == 2){
System.out.printf("๋์ฐฉ์ : (%d, %d)", j, i);
goal = new Node(j, i);
}
else if(map[i][j] == 3){
// System.out.printf("์ฅ์ ๋ฌผ: (%d, %d)", j, i);
block.add(new Node(j, i));
}
}
}
}
public void findPath() {
// ์์์ ๋ฅผ '์ด๋ฆฐ ๋ชฉ๋ก'์ ๋ฃ๋๋ค.
open.add(start);
// ์ด๋ฆฐ ๋ชฉ๋ก์ด ๋น์ด ์์ง ์์ผ๋ฉด ๋ฐ๋ณต, ๋ฆฌ์คํธ๊ฐ ๋น์ด์๋์ง ์๋์ง ํ์ธ์ ๋ฆฌ์คํธ๋ณ์.isEmpty()
while(!open.isEmpty()) {
//์ด๋ฆฐ ๋ชฉ๋ก์์ F๊ฐ์ด ๊ฐ์ฅ ์ ์ ํ๋๋ฅผ ๊ฐ์ ธ์จ๋ค(๊ฐ์ ธ์จ ๋
ธ๋๋ ๋ชฉ๋ก์์ ์ญ์ )
open.sort(new Comparator<Node>() {
@Override
public int compare(Node o1, Node o2) {
return o1.total<o2.total ? o1.total:o2.total;
}
});
Node node = open.get(0);
System.out.printf("\n์ด๋ฆฐ ๋ชฉ๋ก์์ [%d, %d], Total = %d ๋ฅผ ๊บผ๋ด์์ต๋๋ค.\n",
node.x, node.y, node.total);
open.remove(0);
//๊ฐ์ ธ์จ ๋
ธ๋๋ ๋ซํ ๋ชฉ๋ก์ ๋ฃ์ด์ค๋ค.
close.add(node);
//๋ง์ฝ ๊ฐ์ ธ์จ ๋
ธ๋๊ฐ ์ต์ข
๋ชฉ์ ์ง๋ฉด, ์ต์ข
๊ฒฝ๋ก ์ถ๋ ฅ!
if(goal.x==node.x && goal.y==node.y) {
printPath(node);
break;
}
else {
// ๊ฐ์ ธ์จ ๋
ธ๋์ ์ธ์ ๋
ธ๋ ์ค ๊ฐ ์ ์๋ ๋
ธ๋์ ๊ฐ์ฒด๋ฅผ ์์ฑ
// ์์ฑํ ๋
ธ๋์ ๋ถ๋ชจ ๋
ธ๋๋ฅผ ํ์ฌ ๋
ธ๋๋ก ์ง์
// ์์ ํ ๋
ธ๋์ FGH ๊ณ์ฐ
// ์์ฑํ ๋
ธ๋๋ฅผ ์ด๋ฆฐ ๋ชฉ๋ก์ ๋ฃ๋๋ค(์ค๋ณต๋ ๋
ธ๋๋ ์ถ๊ฐ X).
for (int i = 0; i < 8; i++) {
int nx = node.x + XPOS[i];
int ny = node.y + YPOS[i];
if(nx < 0 || ny <0 || nx > mapX || ny > mapY) continue;
if(ifContains(block, nx, ny)) continue;
if(ifContains(open, nx, ny) || ifContains(close, nx, ny)) continue;
Node newNode = new Node(nx, ny);
newNode.parents = node;
if(i <= 4) {
newNode.startd = node.startd + DEFAULT_COST;
}
else {
newNode.startd = node.startd + DEFAULT_DIAGONAL;
}
newNode.destd = Math.abs(goal.x - nx)*10 + Math.abs(goal.y - ny)*10;
newNode.total = newNode.startd + newNode.destd;
addAdjacentNodes(newNode);
}
}
}
}
private void printPath(Node node){
// ํน์ ๋
ธ๋๋ฅผ ํ๋ ์ ๋ฌ ๋ฐ์์
// ๋ถ๋ชจ ๋ถ๋ชจ ๋ถ๋ชจ ์ฐพ์๊ฐ์ ์ถ๋ฐ์ง๊ฐ ๋์ค๋ฉด
// ์ถ๋ฐ์ง ๋ถํฐ ์ถ๋ ฅ
if(node.x == start.x && node.y==start.y){
for (int i = 0; i < mapX; i++) {
for (int j = 0; j < mapY; j++) {
System.out.print(map[i][j]+ " ");
}
System.out.println();
}
return;
}
// System.out.printf("%d, %d \n", node.x, node.y);
if(node.x == goal.x && node.y == goal.y);
else map[node.y][node.x] = 8;
printPath(node.parents);
}
private void addAdjacentNodes(Node node) {
// ์ธ์ ๋
ธ๋๋ฅผ ์ด๋ฆฐ ๋ชฉ๋ก์ ์ถ๊ฐํ๋๋ฐ ์ค๋ณต ์๋๊ฒ
open.add(node);
// System.out.printf("์ธ์ ๋
ธ๋[%d, %d], Total = %d ๊ฐ ์ถ๊ฐ๋์์ต๋๋ค.\n", node.x, node.y, node.total );
}
private boolean ifContains(List<Node> list, Integer x, Integer y){
for (int i = 0; i < list.size() ; i++) {
if(list.get(i).x == x && list.get(i).y == y ) return true;
}
return false;
}
}
Test.java
package astar;
public class Test {
public static void main(String[] args) {
//์ถ๋ฐ์ : 1
//๋์ฐฉ์ : 2
//์ฅ์ ๋ฌผ: 3
Integer[][] map = {
{0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,3,0,0,0,0},
{0,0,0,0,0,3,0,0,0,0},
{0,0,0,0,0,3,0,2,0,0},
{0,0,0,0,1,3,0,0,0,0},
{0,0,0,3,3,3,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0}
};
Astar astar = new Astar(map);
astar.findPath();
}
}
์คํ ๊ฒฐ๊ณผ
๐์ฐธ๊ณ
'โก๐ฉโ๐ป โก > ยบ Java' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[์๊ณ ๋ฆฌ์ฆ] ๋ฒ๋ธ ์ ๋ ฌ(Bubble sort) (1) | 2023.12.11 |
---|---|
[์๋ฃ๊ตฌ์กฐ] ์ด์ง ํ์ ํธ๋ฆฌ ๊ตฌํ | Java (0) | 2023.12.09 |
[์๋ฃ๊ตฌ์กฐ] ๋ฆฌ์คํธ (List) ๊ตฌํ (Java) (0) | 2023.12.05 |
[Java] ์ฌ๊ท | ํ๋ ธ์ด ํ (0) | 2023.12.04 |
[์๋ฃ๊ตฌ์กฐ] ํ (Queue) ๊ตฌํ (Java) (0) | 2023.12.04 |