Skip to content

Latest commit

ย 

History

History
196 lines (145 loc) ยท 4.87 KB

Astar.md

File metadata and controls

196 lines (145 loc) ยท 4.87 KB

A*(AStar) ์•Œ๊ณ ๋ฆฌ์ฆ˜

์‹œ์ž‘ ๋…ธ๋“œ์™€ ๋ชฉ์ ์ง€ ๋…ธ๋“œ๋ฅผ ๋ถ„๋ช…ํ•˜๊ฒŒ ์ง€์ •ํ•ด ๋‘ ๋…ธ๋“œ ๊ฐ„์˜ ์ตœ๋‹จ ๊ฒฝ๋กœ๋ฅผ ํŒŒ์•…ํ•˜๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜

  • A* ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ ์ •ํ™•ํ•œ ์ตœ๋‹จ ๊ฒฝ๋กœ ๋ณด๋‹ค๋Š” ์ตœ๋‹จ ๊ฒฝ๋กœ์˜ ๊ทผ์‚ฌ๊ฐ’์„ ๊ตฌํ•œ๋‹ค
  • ํ˜„์žฌ ์œ„์น˜๊ฐ€ ์–ผ๋งˆ๋‚˜ ์ข‹์€ ์œ„์น˜์ธ์ง€ ์ ๋‹นํ•œ ํœด๋ฆฌ์Šคํ‹ฑ ํ•จ์ˆ˜๋ฅผ ํ†ตํ•ด ์ถ”์ •ํ•˜์—ฌ ์ ์ˆ˜๋ฅผ ๋งค๊ธด๋‹ค
  • ์ •ํ™•ํ•œ ์ •๋‹ต์„ ํฌ๊ธฐํ•œ ๋Œ€์‹  ํƒ์ƒ‰ ์†๋„๋Š” ๋‹ค์ต์ŠคํŠธ๋ผ์— ๋น„ํ•ด ํ›จ์”ฌ ๋น ๋ฅด๋‹ค

๋‹ค์ต์ŠคํŠธ๋ผ๋Š” ์‹œ์ž‘ ๋…ธ๋“œ๋กœ๋ถ€ํ„ฐ ๋ชจ๋“  ๋…ธ๋“œ๊นŒ์ง€์˜ ์ตœ๋‹จ ๊ฒฝ๋กœ๋ฅผ ๊ตฌํ•œ๋‹ค


๊ฒฝ๋กœ ์ฑ„์ 

๋‹ค์Œ์— ์–ด๋–ค ๋…ธ๋“œ๋ฅผ ์„ ํƒํ• ์ง€์— ๋Œ€ํ•œ ์ฑ„์ ์ด ์ด๋ฃจ์–ด์ง„๋‹ค


F = G + H

  • F: ํ˜„์žฌ๊นŒ์ง€ ์ด๋™ํ•˜๋Š”๋ฐ ๊ฑธ๋ฆฐ ๋น„์šฉ๊ณผ ์˜ˆ์ƒ ๋น„์šฉ์„ ํ•ฉ์นœ ์ด ๋น„์šฉ
  • G: ์‹œ์ž‘์ ์œผ๋กœ๋ถ€ํ„ฐ ํ˜„์žฌ ๋…ธ๋“œ๊นŒ์ง€์˜ ๊ฒฝ๋กœ๋ฅผ ๋”ฐ๋ผ ์ด๋™ํ•˜๋Š”๋ฐ ์†Œ์š”๋˜๋Š” ๋น„์šฉ
  • H: ํ˜„์žฌ ๋…ธ๋“œ๋กœ๋ถ€ํ„ฐ ๋ชฉ์ ์ง€๊นŒ์ง€์˜ ์†Œ์š”๋˜๋Š” ์˜ˆ์ƒ ๋น„์šฉ

H(Heuristic) ํœด๋ฆฌ์Šคํ‹ฑ

์–ด๋ฆผ์ง์ž‘, ์ฃผ๋จน ๊ตฌ๊ตฌ์‹ ๋“ฑ์œผ๋กœ ๋ถˆ๋ฆฌ๋ฉฐ ๊ฒฝํ—˜์— ๊ธฐ๋ฐ˜ํ•˜์—ฌ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ฑฐ๋‚˜ ๋ฐœ๊ฒฌํ•ด๋‚ด๋Š” ๋ฐฉ๋ฒ•์ด๋‹ค.

  • ์–ด์›์€ ๊ทธ๋ฆฌ์Šค์–ด Heutiskein์œผ๋กœ ์ฐพ์•„๋‚ด๋‹ค, ๋ฐœ๊ฒฌํ•˜๋‹ค ๋ผ๋Š” ๋œป์ด๋‹ค

ํœด๋ฆฌ์Šคํ‹ฑ์ด๋ž€ ์ƒํ™ฉ๊ณผ ์ง๊ด€์— ๋”ฐ๋ผ ํ–‰๋™ํ•˜์—ฌ ์‹œํ–‰์ฐฉ์˜ค๋ฅผ ๊ฒช๊ณ  ์ง€์‹์„ ์–ป์–ด ์ƒ๊ฐ์„ ๋ฐœ์ „์‹œํ‚ค๋Š” ๋ฐฉ๋ฒ•์ด๋‹ค


๋งจํ•ดํŠผ ๊ฑฐ๋ฆฌ(Manhattan Distance)

๊ฐ ์ขŒํ‘œ์˜ ์ฐจ๋ฅผ ๋ชจ๋‘ ๋”ํ•œ ๊ฒƒ์„ ๊ฑฐ๋ฆฌ๋กœ ํ•œ๋‹ค



๋งจํ•ดํŠผ ๊ฑฐ๋ฆฌ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ˆ˜์‹์œผ๋กœ ๊ฑฐ๋ฆฌ๋ฅผ ๊ตฌํ•œ๋‹ค


  • $|x1-x2| + |y1-y2|$

์šฐ๋ฆฌ๊ฐ€ ์‹ค์ƒํ™œ์—์„œ ์‚ฌ์šฉํ•˜๋Š” ๊ฑฐ๋ฆฌ๋Š” ์œ ํด๋ฆฌ๋“œ ๊ฑฐ๋ฆฌ๋กœ ์ผ๋ฐ˜์ ์œผ๋กœ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๊ฑฐ๋ฆฌ๋ฅผ ๊ตฌํ•œ๋‹ค


  • $\sqrt{(x1-x2)^2 + (y1-y2)^2}$

A* Code

// ์ ์ˆ˜ ๋งค๊ธฐ๊ธฐ
	// F = G + H
	// F = ์ตœ์ข… ์ ์ˆ˜ (์ž‘์„ ์ˆ˜๋ก ์ข‹์Œ, ๊ฒฝ๋กœ์— ๋”ฐ๋ผ ๋‹ฌ๋ผ์ง)
	// G = ์‹œ์ž‘์ ์—์„œ ํ•ด๋‹น ์ขŒํ‘œ๊นŒ์ง€ ์ด๋™ํ•˜๋Š”๋ฐ ๋“œ๋Š” ๋น„์šฉ (์ž‘์„ ์ˆ˜๋ก ์ข‹์Œ, ๊ฒฝ๋กœ์— ๋”ฐ๋ผ ๋‹ฌ๋ผ์ง)
	// H = ๋ชฉ์ ์ง€์—์„œ ์–ผ๋งˆ๋‚˜ ๊ฐ€๊นŒ์šด์ง€ (์ž‘์„ ์ˆ˜๋ก ์ข‹์Œ, ๊ณ ์ •)

	Pos start = _pos;
	Pos dest = _board->GetExitPos();

	enum
	{
		DIR_COUNT = 8
	};

	Pos front[] =
	{
		Pos { -1, 0},	// UP
		Pos { 0, -1},	// LEFT
		Pos { 1, 0},	// DOWN
		Pos { 0, 1},	// RIGHT
		Pos {-1, -1},	// UP_LEFT
		Pos {1, -1},	// DOWN_LEFT
		Pos {1, 1},		// DOWN_RIGHT
		Pos {-1, 1},	// UP_RIGHT
	};

	int32 cost[] =
	{
		10, // UP
		10, // LEFT
		10, // DOWN
		10, // RIGHT
		14,
		14,
		14,
		14
	};

	const int32 size = _board->GetSize();

	// ClosedList
	// close[y][x] -> (y, x)์— ๋ฐฉ๋ฌธ์„ ํ–ˆ๋Š”์ง€ ์—ฌ๋ถ€
	vector<vector<bool>> closed(size, vector<bool>(size, false));

	// best[y][x] -> ์ง€๊ธˆ๊นŒ์ง€ (y, x)์— ๋Œ€ํ•œ ๊ฐ€์žฅ ์ข‹์€ ๋น„์šฉ (์ž‘์„ ์ˆ˜๋ก ์ข‹์Œ)
	vector<vector<int32>> best(size, vector<int32>(size, INT32_MAX));

	// ๋ถ€๋ชจ ์ถ”์  ์šฉ๋„
	map<Pos, Pos> parent;

	// OpenList
	priority_queue<PQNode, vector<PQNode>, greater<PQNode>> pq;

	// 1) ์˜ˆ์•ฝ(๋ฐœ๊ฒฌ) ์‹œ์Šคํ…œ ๊ตฌํ˜„
	// - ์ด๋ฏธ ๋” ์ข‹์€ ๊ฒฝ๋กœ๋ฅผ ์ฐพ์•˜๋‹ค๋ฉด ์Šคํ‚ต
	// 2) ๋’ค๋Šฆ๊ฒŒ ๋” ์ข‹์€ ๊ฒฝ๋กœ๊ฐ€ ๋ฐœ๊ฒฌ๋  ์ˆ˜ ์žˆ์Œ -> ์˜ˆ์™ธ ์ฒ˜๋ฆฌ ํ•„์ˆ˜
	// - openList์—์„œ ์ฐพ์•„์„œ ์ œ๊ฑฐํ•œ๋‹ค๊ฑฐ๋‚˜.
	// - pq์—์„œ popํ•œ ๋‹ค์Œ์— ๋ฌด์‹œํ•œ๋‹ค๊ฑฐ๋‚˜.
	
	// ์ดˆ๊ธฐ๊ฐ’
	{
		int32 g = 0;
		int32 h = 10 * (abs(dest.y - start.y) + abs(dest.x - start.x));
		pq.push(PQNode{ g + h, g, start });
		best[start.y][start.x] = g + h;
		parent[start] = start;
	}

	while (pq.empty() == false)
	{
		// ์ œ์ผ ์ข‹์€ ํ›„๋ณด๋ฅผ ์ฐพ๋Š”๋‹ค
		PQNode node = pq.top();
		pq.pop();

		// ๋™์ผํ•œ ์ขŒํ‘œ๋ฅผ ์—ฌ๋Ÿฌ ๊ฒฝ๋กœ๋กœ ์ฐพ์•„์„œ\
		// ๋” ๋น ๋ฅธ ๊ฒฝ๋กœ๋กœ ์ธํ•ด์„œ ์ด๋ฏธ ๋ฐฉ๋ฌธ(closed)๋œ ๊ฒฝ์šฐ ์Šคํ‚ต
		// [์„ ํƒ]
		if (closed[node.pos.y][node.pos.x])
			continue;
		if (best[node.pos.y][node.pos.x] < node.f)
			continue;

		// ๋ฐฉ๋ฌธ
		closed[node.pos.y][node.pos.x] = true;

		// ๋ชฉ์ ์ง€์— ๋„์ฐฉํ–ˆ์œผ๋ฉด ๋ฐ”๋กœ ์ข…๋ฃŒ
		if (node.pos == dest)
			break;

		for (int32 dir = 0; dir < DIR_COUNT; dir++)
		{
			Pos nextPos = node.pos + front[dir];
			// ๊ฐˆ ์ˆ˜ ์žˆ๋Š” ์ง€์—ญ์€ ๋งž๋Š”์ง€ ํ™•์ธ
			if (CanGo(nextPos) == false)
				continue;
			// [์„ ํƒ] ์ด๋ฏธ ๋ฐฉ๋ฌธํ•œ ๊ณณ์ด๋ฉด ์Šคํ‚ต
			if (closed[nextPos.y][nextPos.x])
				continue;

			// ๋น„์šฉ ๊ณ„์‚ฐ
			int32 g = node.g + cost[dir];
			int32 h = 10 * (abs(dest.y - nextPos.y) + abs(dest.x - nextPos.x));
			// ๋‹ค๋ฅธ ๊ฒฝ๋กœ์—์„œ ๋” ๋น ๋ฅธ ๊ธธ์„ ์ฐพ์•˜์œผ๋ฉด ์Šคํ‚ต
			if (best[nextPos.y][nextPos.x] <= g + h)
				continue;

			// ์˜ˆ์•ฝ ์ง„ํ–‰
			best[nextPos.y][nextPos.x] = g + h;
			pq.push(PQNode{ g + h, g, nextPos });
			parent[nextPos] = node.pos;
		}
	}

	// ๊ฑฐ๊พธ๋กœ ๊ฑฐ์Šฌ๋Ÿฌ ์˜ฌ๋ผ๊ฐ„๋‹ค
	Pos pos = dest;

	_path.clear();
	_pathIndex = 0;

	while (true)
	{
		_path.push_back(pos);

		// ์‹œ์ž‘์ ์€ ์ž์‹ ์ด ๊ณง ๋ถ€๋ชจ์ด๋‹ค
		if (pos == parent[pos])
			break;

		pos = parent[pos];
	}

	std::reverse(_path.begin(), _path.end());