Skip to content

Commit 5219f50

Browse files
authored
Features/best first search (#44)
* feat: Best first search
1 parent bcaf217 commit 5219f50

1 file changed

Lines changed: 125 additions & 0 deletions

File tree

Searching/Best_First_Search.cpp

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
#include <iostream>
2+
#include <vector>
3+
#include <set>
4+
#include <cmath>
5+
#include <algorithm>
6+
7+
using namespace std;
8+
9+
const int N = 3;
10+
11+
// Goal state
12+
vector<vector<int>> goal = {
13+
{1, 2, 3},
14+
{4, 5, 6},
15+
{7, 8, 0}
16+
};
17+
18+
int dx[] = {-1, 1, 0, 0};
19+
int dy[] = {0, 0, -1, 1};
20+
string dir[] = {"Up", "Down", "Left", "Right"};
21+
22+
struct Puzzle {
23+
vector<vector<int>> board;
24+
int x, y;
25+
string path;
26+
27+
Puzzle(vector<vector<int>> b, int x_, int y_, string p = "") : board(b), x(x_), y(y_), path(p) {}
28+
29+
bool isGoal() const {
30+
return board == goal;
31+
}
32+
33+
int heuristic() const {
34+
int dist = 0;
35+
for (int i = 0; i < N; i++)
36+
for (int j = 0; j < N; j++)
37+
if (board[i][j] != 0) {
38+
int val = board[i][j] - 1;
39+
int targetX = val / N;
40+
int targetY = val % N;
41+
dist += abs(i - targetX) + abs(j - targetY);
42+
}
43+
return dist;
44+
}
45+
};
46+
47+
// Global variables to track best solution
48+
int bestCost = 501;
49+
string bestPath = "";
50+
51+
set<vector<vector<int>>> visited;
52+
53+
void BestFirstSearch(Puzzle current, int depth = 0, int maxDepth = 500) {
54+
int estimate = depth + current.heuristic();
55+
56+
// Prune if worse than best
57+
if (estimate >= bestCost || depth > maxDepth)
58+
return;
59+
60+
// Goal check
61+
if (current.isGoal()) {
62+
if (depth < bestCost) {
63+
bestCost = depth;
64+
bestPath = current.path;
65+
}
66+
return;
67+
}
68+
69+
visited.insert(current.board);
70+
71+
vector<Puzzle> nextStates;
72+
73+
// Generate next states
74+
for (int i = 0; i < 4; i++) {
75+
int newX = current.x + dx[i];
76+
int newY = current.y + dy[i];
77+
if (newX >= 0 && newX < N && newY >= 0 && newY < N) {
78+
vector<vector<int>> newBoard = current.board;
79+
swap(newBoard[current.x][current.y], newBoard[newX][newY]);
80+
81+
if (visited.count(newBoard)) continue;
82+
83+
nextStates.emplace_back(newBoard, newX, newY, current.path + " " + dir[i]);
84+
}
85+
}
86+
87+
// Sort by heuristic (Greedy Best-First)
88+
sort(nextStates.begin(), nextStates.end(), [](const Puzzle& a, const Puzzle& b) {
89+
return a.heuristic() < b.heuristic();
90+
});
91+
92+
// Recurse
93+
for (Puzzle& next : nextStates) {
94+
BestFirstSearch(next, depth + 1, maxDepth);
95+
}
96+
97+
// Backtrack: remove from visited
98+
visited.erase(current.board);
99+
}
100+
101+
int main() {
102+
vector<vector<int>> start = {
103+
{1, 2, 3},
104+
{4, 0, 5},
105+
{6, 7, 8}
106+
};
107+
108+
// Find the position of 0
109+
int x = 0, y = 0;
110+
for (int i = 0; i < N; i++)
111+
for (int j = 0; j < N; j++)
112+
if (start[i][j] == 0) x = i, y = j;
113+
114+
Puzzle startPuzzle(start, x, y);
115+
BestFirstSearch(startPuzzle);
116+
117+
if (bestCost < 501) {
118+
cout << "Solved! Cost: " << bestCost << endl;
119+
cout << "Path: " << bestPath << endl;
120+
} else {
121+
cout << "No solution found within depth limit." << endl;
122+
}
123+
124+
return 0;
125+
}

0 commit comments

Comments
 (0)