Skip to content

Commit

Permalink
solution tracking included
Browse files Browse the repository at this point in the history
  • Loading branch information
velocitatem committed Dec 16, 2024
1 parent d7b7162 commit 426f66f
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 35 deletions.
42 changes: 22 additions & 20 deletions examples/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,32 +34,30 @@ class VacuumCleaner : public Problem {
}
return !vacuum_state->dirty0 && !vacuum_state->dirty1;
}
std::vector<Action> actions(std::shared_ptr<State> state) override {
auto *vacuum_state = dynamic_cast<VacuumState *>(state.get());
std::vector<Action> actions;
std::vector<std::shared_ptr<Action>> actions(std::shared_ptr<State> state) override {
auto vacuum_state = std::dynamic_pointer_cast<VacuumState>(state);
std::vector<std::shared_ptr<Action>> actions;

// Define lambda to create a new VacuumState safely
auto create_state = [&](int x, bool dirty0, bool dirty1) {
return std::make_shared<VacuumState>(x, dirty0, dirty1);
};

// Check possible moves and construct actions
// Add possible actions with smart pointers
if (vacuum_state->x == 0) {
if (vacuum_state->dirty0) {
actions.emplace_back("Suck", 1, std::make_shared<VacuumState>(*vacuum_state), create_state(0, false, vacuum_state->dirty1));
actions.push_back(std::make_shared<Action>("Suck", 1, state, create_state(0, false, vacuum_state->dirty1)));
} else {
actions.emplace_back("Right", 1, std::make_shared<VacuumState>(*vacuum_state), create_state(1, vacuum_state->dirty0, vacuum_state->dirty1));
actions.push_back(std::make_shared<Action>("Right", 1, state, create_state(1, vacuum_state->dirty0, vacuum_state->dirty1)));
}
} else {
if (vacuum_state->dirty1) {
actions.emplace_back("Suck", 1, std::make_shared<VacuumState>(*vacuum_state), create_state(1, vacuum_state->dirty0, false));
actions.push_back(std::make_shared<Action>("Suck", 1, state, create_state(1, vacuum_state->dirty0, false)));
} else {
actions.emplace_back("Left", 1, std::make_shared<VacuumState>(*vacuum_state), create_state(0, vacuum_state->dirty0, vacuum_state->dirty1));
actions.push_back(std::make_shared<Action>("Left", 1, state, create_state(0, vacuum_state->dirty0, vacuum_state->dirty1)));
}
}
return actions;


return actions;
}

double heuristic(State *state) override {
Expand Down Expand Up @@ -125,32 +123,34 @@ class MazeProblem : public Problem {
auto *maze_state = dynamic_cast<MazeState *>(state);
return maze_state->maze[maze_state->x][maze_state->y] == -1;
}
std::vector<Action> actions(std::shared_ptr<State> state) override {
auto *maze_state = dynamic_cast<MazeState *>(state.get());
std::vector<Action> actions;

// Define lambda to create a new MazeState safely
std::vector<std::shared_ptr<Action>> actions(std::shared_ptr<State> state) override {
auto maze_state = std::dynamic_pointer_cast<MazeState>(state);
std::vector<std::shared_ptr<Action>> actions;

auto create_state = [&](int x, int y) {
return std::make_shared<MazeState>(maze_state->maze, x, y);
};

// Check possible moves and construct actions
// Add possible actions with smart pointers
if (maze_state->x > 0 && maze_state->maze[maze_state->x - 1][maze_state->y] != 1) {
actions.emplace_back("Up", 1, std::make_shared<MazeState>(*maze_state), create_state(maze_state->x - 1, maze_state->y));
actions.push_back(std::make_shared<Action>("Up", 1, state, create_state(maze_state->x - 1, maze_state->y)));
}
if (maze_state->x < maze_state->maze.size() - 1 && maze_state->maze[maze_state->x + 1][maze_state->y] != 1) {
actions.emplace_back("Down", 1, std::make_shared<MazeState>(*maze_state), create_state(maze_state->x + 1, maze_state->y));
actions.push_back(std::make_shared<Action>("Down", 1, state, create_state(maze_state->x + 1, maze_state->y)));
}
if (maze_state->y > 0 && maze_state->maze[maze_state->x][maze_state->y - 1] != 1) {
actions.emplace_back("Left", 1, std::make_shared<MazeState>(*maze_state), create_state(maze_state->x, maze_state->y - 1));
actions.push_back(std::make_shared<Action>("Left", 1, state, create_state(maze_state->x, maze_state->y - 1)));
}
if (maze_state->y < maze_state->maze[0].size() - 1 && maze_state->maze[maze_state->x][maze_state->y + 1] != 1) {
actions.emplace_back("Right", 1, std::make_shared<MazeState>(*maze_state), create_state(maze_state->x, maze_state->y + 1));
actions.push_back(std::make_shared<Action>("Right", 1, state, create_state(maze_state->x, maze_state->y + 1)));
}

return actions;
}



double heuristic(State *state) override {
auto *maze_state = dynamic_cast<MazeState *>(state);
return abs(maze_state->x - 3) + abs(maze_state->y - 3);
Expand Down Expand Up @@ -184,6 +184,8 @@ int main () {
std::cout << "Solution found!" << std::endl;
State *maze_state = node->state.get();
maze_state->print();
Solution solution(node.get());
solution.print();
} else {
std::cout << "Solution not found!" << std::endl;
}
Expand Down
2 changes: 1 addition & 1 deletion include/definitions.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ class Problem {
* @param state The current state.
* @return A vector of actions applicable to the given state.
*/
virtual std::vector<Action> actions(std::shared_ptr<State> state) = 0;
virtual std::vector<std::shared_ptr<Action>> actions(std::shared_ptr<State> state) = 0;

/**
* @brief Computes a heuristic estimate for a given state.
Expand Down
6 changes: 3 additions & 3 deletions include/search.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,17 @@

class Node {
public:
std::weak_ptr<Node> parent; // Weak pointer to prevent circular references
std::shared_ptr<Node> parent; // Weak pointer to prevent circular references
std::shared_ptr<State> state; // Smart pointer to manage state memory
const Action *action; // Pointer to an immutable Action object
const std::shared_ptr<Action> action; // Pointer to an immutable Action object
double path_cost; // Cost to reach this node
double heuristic; // Heuristic value (if applicable)

// Default constructor
Node() : action(nullptr), path_cost(0), heuristic(0) {}

// Parameterized constructor
Node(std::shared_ptr<Node> parent, std::shared_ptr<State> state, const Action *action, double path_cost, double heuristic)
Node(std::shared_ptr<Node> parent, std::shared_ptr<State> state, const std::shared_ptr<Action> action, double path_cost, double heuristic)
: parent(parent), state(state), action(action), path_cost(path_cost), heuristic(heuristic) {}
};

Expand Down
23 changes: 12 additions & 11 deletions src/search.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,15 @@ Search *create_search(SearchAlgorithmIndex search_algorithm_index, Problem *prob

BreadthFirstSearch::~BreadthFirstSearch() { }


void Solution::print() {
std::weak_ptr<Node> current = node->parent;
Node * current = this->node;
std::vector<Action> actions;
while (current.lock()) {
auto parent = current.lock();
actions.push_back(*parent->action);
current = parent->parent;
auto parent = current->parent;
// Traverse the solution path by following the parent pointers
while (parent != nullptr) {
actions.push_back(*current->action);
current = parent.get();
parent = current->parent;
}

for (auto it = actions.rbegin(); it != actions.rend(); ++it) {
Expand Down Expand Up @@ -62,11 +63,11 @@ std::shared_ptr<Node> BreadthFirstSearch::search() {
// Expand the node by generating its child nodes
for (const auto &action : problem->actions(node->state)) {
auto child = std::make_shared<Node>(
node, // Parent node
action.effect, // Resulting state (shared_ptr)
&action, // Pointer to the action
node->path_cost + action.cost, // Cumulative path cost
problem->heuristic(action.effect.get()) // Heuristic value
std::shared_ptr<Node>(node), // Parent node
action->effect,
action, // Pointer to the action
node->path_cost + action->cost, // Path cost
problem->heuristic(action->effect.get()) // Heuristic value
);
frontier.push(child);
}
Expand Down

0 comments on commit 426f66f

Please sign in to comment.