|
@@ -10,6 +10,7 @@
|
|
|
#include <cstdlib>
|
|
|
#include <ctime>
|
|
|
#include <stack>
|
|
|
+#include <queue>
|
|
|
|
|
|
using namespace std;
|
|
|
|
|
@@ -161,6 +162,7 @@ class World
|
|
|
|
|
|
|
|
|
|
|
|
+
|
|
|
// Depth-first search
|
|
|
// starting from tile number origin, find a path to tile number t
|
|
|
// return true if such a path exists, false otherwise
|
|
@@ -214,8 +216,85 @@ class World
|
|
|
} while (!targetIsReached && !open.empty());
|
|
|
|
|
|
// Remove origin and target
|
|
|
- discovered.pop_front();
|
|
|
- discovered.pop_back();
|
|
|
+ if (!discovered.empty()) {
|
|
|
+ discovered.pop_front();
|
|
|
+
|
|
|
+ if (!discovered.empty())
|
|
|
+ discovered.pop_back();
|
|
|
+ }
|
|
|
+
|
|
|
+ // Build path
|
|
|
+ if (targetIsReached) {
|
|
|
+ do {
|
|
|
+ path.push_back(current);
|
|
|
+ current = previous[current];
|
|
|
+ } while (current != origin);
|
|
|
+
|
|
|
+ path.pop_front();
|
|
|
+ }
|
|
|
+
|
|
|
+ return targetIsReached;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Breadth-first search
|
|
|
+ // starting from tile number origin, find a path to tile number t
|
|
|
+ // return true if such a path exists, false otherwise
|
|
|
+ // if it exists the path is given in variable path (hence the reference &)
|
|
|
+ const bool bfs(unsigned int origin, unsigned int target, list<unsigned int>& path, list<unsigned int>& discovered)
|
|
|
+ {
|
|
|
+ bool targetIsReached = false;
|
|
|
+
|
|
|
+ bool explored[size];
|
|
|
+ unsigned int previous[size];
|
|
|
+
|
|
|
+ for (unsigned int k(0); k < size; k ++) {
|
|
|
+ explored[k] = false;
|
|
|
+ previous[k] = k;
|
|
|
+ }
|
|
|
+
|
|
|
+ explored[origin] = true;
|
|
|
+
|
|
|
+
|
|
|
+ stack<unsigned int> open;
|
|
|
+ open.push(origin);
|
|
|
+
|
|
|
+ int current;
|
|
|
+ int neighbour;
|
|
|
+ unsigned int succs[4];
|
|
|
+ unsigned int nbSuccs;
|
|
|
+
|
|
|
+ do {
|
|
|
+ current = open.top();
|
|
|
+ open.pop();
|
|
|
+
|
|
|
+ nbSuccs = successors(current, succs);
|
|
|
+
|
|
|
+ for (unsigned int i(0); i < nbSuccs; i++) {
|
|
|
+ neighbour = succs[i];
|
|
|
+
|
|
|
+ if (!explored[neighbour]) {
|
|
|
+ open.push(neighbour);
|
|
|
+ previous[neighbour] = current;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // Current tile is now processed
|
|
|
+ explored[current] = true;
|
|
|
+
|
|
|
+ discovered.push_back(current);
|
|
|
+
|
|
|
+ // Stop if target found
|
|
|
+ targetIsReached = (current == target);
|
|
|
+
|
|
|
+ } while (!targetIsReached && !open.empty());
|
|
|
+
|
|
|
+ // Remove origin and target
|
|
|
+ if (!discovered.empty()) {
|
|
|
+ discovered.pop_front();
|
|
|
+
|
|
|
+ if (!discovered.empty())
|
|
|
+ discovered.pop_back();
|
|
|
+ }
|
|
|
|
|
|
// Build path
|
|
|
if (targetIsReached) {
|
|
@@ -247,7 +326,7 @@ class World
|
|
|
cout << "FAILURE ..." << endl;
|
|
|
|
|
|
cout << discovered.size() << " tiles discovered;" << endl;
|
|
|
- cout << path.size() << " path length.";
|
|
|
+ cout << path.size() << " path length." << endl;
|
|
|
}
|
|
|
};
|
|
|
|
|
@@ -271,15 +350,25 @@ int main()
|
|
|
w.markOne(end, TARGET);
|
|
|
w.display();
|
|
|
|
|
|
- // Find a path with Depth-First Search
|
|
|
+ // 1
|
|
|
+ cout << endl << "Depth-First Search" << endl;
|
|
|
+
|
|
|
World dfsWorld(w);
|
|
|
list<unsigned int> dfsPath;
|
|
|
list<unsigned int> dfsDiscovered;
|
|
|
- bool exitFound = dfsWorld.dfs(start, end, dfsPath, dfsDiscovered);
|
|
|
+ bool dfsExitFound = dfsWorld.dfs(start, end, dfsPath, dfsDiscovered);
|
|
|
|
|
|
- // Display DFS
|
|
|
- cout << endl << "Depth-First Search" << endl;
|
|
|
- dfsWorld.showResults(exitFound, dfsDiscovered, dfsPath);
|
|
|
+ dfsWorld.showResults(dfsExitFound, dfsDiscovered, dfsPath);
|
|
|
+
|
|
|
+ // 2
|
|
|
+ cout << endl << "Breadth-First Search" << endl;
|
|
|
+
|
|
|
+ World bfsWorld(w);
|
|
|
+ list<unsigned int> bfsPath;
|
|
|
+ list<unsigned int> bfsDiscovered;
|
|
|
+ bool bfsExitFound = bfsWorld.bfs(start, end, bfsPath, bfsDiscovered);
|
|
|
+
|
|
|
+ bfsWorld.showResults(bfsExitFound, bfsDiscovered, bfsPath);
|
|
|
|
|
|
// End
|
|
|
return 0;
|