Symphony 1.0
Loading...
Searching...
No Matches
search.cpp
Go to the documentation of this file.
1#include "search.h"
2#include "utils.cpp"
3#include <queue>
4#include <memory>
5#include <iostream>
6#include <unordered_set>
7#include <algorithm>
8#include <vector>
9#include <functional>
10#include <omp.h>
11
12
13Search *create_search(SearchAlgorithmIndex search_algorithm_index, Problem *problem) {
14 switch (search_algorithm_index) {
16 return new BreadthFirstSearch(problem);
17 case A_STAR:
18 return new AStarSearch(problem);
19 case BEAM_SEARCH:
20 return new BeamSearch(problem, 2);
21 default:
22 return nullptr;
23 }
24}
25
27
29 Node * current = this->node;
30 std::vector<Action> actions;
31 auto parent = current->parent;
32 // Traverse the solution path by following the parent pointers
33 while (parent != nullptr) {
34 actions.push_back(*current->action);
35 current = parent.get();
36 parent = current->parent;
37 }
38
39 for (auto it = actions.rbegin(); it != actions.rend(); ++it) {
40 std::cout << it->name << std::endl;
41 }
42
43}
44
45std::shared_ptr<Node> BreadthFirstSearch::search() {
46 std::queue<std::shared_ptr<Node>> frontier;
47 auto initial_state = problem->initial_state();
48 auto root = std::make_shared<Node>(
49 nullptr,
50 std::shared_ptr<State>(initial_state),
51 nullptr,
52 0,
53 problem->heuristic(initial_state)
54 );
55 frontier.push(root);
56 while (!frontier.empty()) {
57 auto node = frontier.front();
58 frontier.pop();
59
60 State *state = node->state.get();
61 if (problem->goal_test(state)) {
62 return node;
63 }
64 #pragma omp parallel for shared(frontier) schedule(dynamic) if (frontier.size() > 1000)
65 for (const auto &action : problem->actions(node->state)) {
66 auto child = std::make_shared<Node>(
67 std::shared_ptr<Node>(node),
68 action->effect,
69 action,
70 node->path_cost + action->cost,
71 problem->heuristic(action->effect.get())
72 );
73 frontier.push(child);
74 }
75 }
76 // Return nullptr if no solution is found
77 return nullptr;
78}
79
81
82std::shared_ptr<Node> AStarSearch::search() {
83 std::priority_queue<std::shared_ptr<Node>, std::vector<std::shared_ptr<Node>>, NodeComparator> frontier;
84 // Initialize the root node with the problem's initial state
85 std::unordered_set<std::shared_ptr<State>> explored; // Set of explored states
86 auto initial_state = problem->initial_state();
87 auto root = std::make_shared<Node>(
88 nullptr, // Parent node
89 std::shared_ptr<State>(initial_state), // Initial state (shared_ptr)
90 nullptr, // No action
91 0, // Path cost
92 problem->heuristic(initial_state) // Heuristic value
93 );
94 frontier.push(root);
95
96 while (!frontier.empty()) {
97 auto node = frontier.top();
98 frontier.pop();
99
100 // Check if the goal state is reached
101 State *state = node->state.get();
102 if (problem->goal_test(state)) {
103 return node;
104 }
105
106 // Skip the node if it has already been explored
107 if (explored.find(node->state) != explored.end()) {
108 continue;
109 }
110 explored.insert(node->state);
111
112 // Expand the node by generating its child nodes
113 for (const auto &action : problem->actions(node->state)) {
114 auto child = std::make_shared<Node>(
115 std::shared_ptr<Node>(node), // Parent node
116 action->effect,
117 action, // Pointer to the action
118 node->path_cost + action->cost, // Path cost
119 problem->heuristic(action->effect.get()) // Heuristic value
120 );
121 frontier.push(child);
122 }
123 }
124
125 // Return nullptr if no solution is found
126 return nullptr;
127}
128
129
130
131
133
134std::shared_ptr<Node> BeamSearch::search() {
135 // Priority queue to maintain the beam
136 using Beam = std::vector<std::shared_ptr<Node>>;
137 Beam beam;
138
139 // Initialize the root node
140 auto initial_state = problem->initial_state();
141 auto root = std::make_shared<Node>(
142 nullptr,
143 std::shared_ptr<State>(initial_state),
144 nullptr,
145 0,
146 problem->heuristic(initial_state)
147 );
148
149 beam.push_back(root);
150
151 while (!beam.empty()) {
152 // Sort beam nodes based on their f(n) = path_cost + heuristic
153 std::sort(beam.begin(), beam.end(), [](const std::shared_ptr<Node>& a, const std::shared_ptr<Node>& b) {
154 return (a->path_cost + a->heuristic) < (b->path_cost + b->heuristic);
155 });
156
157 // Keep only the top k nodes (beam width)
158 if (beam.size() > beam_width) {
159 beam.resize(beam_width);
160 }
161
162 Beam next_beam;
163
164 // Expand each node in the current beam
165 for (const auto& node : beam) {
166 if (problem->goal_test(node->state.get())) {
167 return node; // Goal found
168 }
169
170 // Generate successors
171 for (const auto& action : problem->actions(node->state)) {
172 auto child = std::make_shared<Node>(
173 node,
174 action->effect,
175 action,
176 node->path_cost + action->cost,
177 problem->heuristic(action->effect.get())
178 );
179 next_beam.push_back(child);
180 }
181 }
182
183 beam = std::move(next_beam);
184 }
185
186 return nullptr;
187}
std::shared_ptr< Node > search() override
Definition search.cpp:82
int beam_width
Definition search.h:99
std::shared_ptr< Node > search() override
Definition search.cpp:134
~BeamSearch() override
Definition search.cpp:132
Breadth-first search algorithm implementation.
Definition search.h:67
std::shared_ptr< Node > search() override
Breadth-first search algorithm implementation. The breadth-first search algorithm explores a graph by...
Definition search.cpp:45
Definition search.h:17
std::shared_ptr< Node > parent
Definition search.h:21
const std::shared_ptr< Action > action
Definition search.h:27
Represents an abstract problem that needs to be solved.
Definition definitions.h:63
virtual bool goal_test(State *state)=0
Tests if a given state satisfies the goal condition.
virtual double heuristic(State *state)=0
Computes a heuristic estimate for a given state.
virtual std::vector< std::shared_ptr< Action > > actions(std::shared_ptr< State > state)=0
Retrieves the set of actions applicable to a given state.
virtual State * initial_state()
Retrieves the initial state of the problem.
Definition definitions.h:80
Problem * problem
Definition search.h:52
Node * node
Definition search.h:59
void print()
Definition search.cpp:28
Represents an abstract state in a problem.
Definition definitions.h:18
Search * create_search(SearchAlgorithmIndex search_algorithm_index, Problem *problem)
Factory method to create a search object based on the specified search algorithm.
Definition search.cpp:13
SearchAlgorithmIndex
Definition search.h:102
@ A_STAR
Definition search.h:105
@ BEAM_SEARCH
Definition search.h:106
@ BREADTH_FIRST_SEARCH
Definition search.h:103