我需要计算从一个起点到另一个终点的距离和路径。 http://coliru.stacked-crooked.com/a/b15078829f49df3c
int pathExists(char maze[][10], int sr, int sc, int er, int ec, int distance, int direction) {
/*if(maze[sr][sc] != '.') . es visitable, x pared
return 0;
*/
int lmin=99, l;
if(maze[sr][sc] != '.') //You cannot visit it, or is wall or is @ visited
return 0;
if(sr == er && sc == ec) {
display(maze);
cout << "Distance to end point is: " << distance << endl;
//if ( lmin==l) PathBueno = PathInt;
for (int i = 0; i < PathInt.size(); i++) {
cout << PathInt[i];
}
return distance;
}
/*
if(distance == 15) {
cout << "Cant make it in 15 steps" << endl;
return 0;
}
*/
// path.push_back(vertex);
//Path.append(direction);
PathInt.push_back(direction);
maze[sr][sc] = '@'; // anything non-'.' will do
//Row -- Norte
l = pathExists(maze, sr - 1, sc, er, ec, distance + 1,1);
if(l > 0 && l<lmin) {
lmin = l;
// Path.append("N");
}
//Row ++ Sur
l = pathExists(maze, sr + 1, sc, er, ec, distance + 1,2);
if(l > 0 && l<lmin) {
lmin = l;
//Path.append("S");
}
//Column -- Oeste
l = pathExists(maze, sr, sc - 1, er, ec, distance + 1,3);
if(l > 0 && l<lmin)
{
lmin = l;
//Path.append("W");
}
//Column ++ Este
l = pathExists(maze, sr, sc + 1, er, ec, distance + 1,4);
if(l > 0 && l<lmin)
{
lmin = l;
//Path.append("E");
}
maze[sr][sc] = '.'; //restore
PathInt.pop_back();
//if ( Path.size() > 2) Path.erase(Path.size() - 1);
return lmin;
}
我一直在尝试很多东西。但是我不能在PathGood
中打印或保存从一个点到另一个点的最短路径。
在示例中,我想从8.4移动到8.1 ...所以最短路径有3步距离,路径是EEE或333(假设3是EAST)。
可验证的例子:
int main() {
char maze[10][10] = {
{'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X'},
{'X', '.', '.', '.', '.', '.', '.', '.', '.', 'X'},
{'X', '.', 'X', 'X', 'X', 'X', '.', 'X', 'X', 'X'},
{'X', '.', '.', 'X', '.', 'X', '.', '.', '.', 'X'},
{'X', '.', '.', 'X', '.', '.', '.', 'X', '.', 'X'},
{'X', '.', 'X', 'X', '.', 'X', 'X', 'X', '.', 'X'},
{'X', '.', 'X', '.', '.', '.', '.', 'X', 'X', 'X'},
{'X', '.', '.', 'X', 'X', '.', 'X', 'X', '.', 'X'},
{'X', '.', '.', '.', '.', '.', '.', '.', '.', 'X'},
{'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X'}
};
Path.clear();
int slen = pathExists(maze,8,4, 8, 1,0,0);
if(slen) {
cout << "Solvable in "<<slen<<" steps !" << endl;
// cout << "Complete path is : " << Path;
// std::cout << "Complete path is : " << PathGood;
}
else
cout << "Out of luck!" << endl;
cin.get();
//int len, i;
/* len = (int)strlen(string);
for (int i = 0; i < PathBueno.size(); i++) {
cout << PathBueno[i];
}*/
}
我试图在pacman游戏中给一些IA给鬼。所以我需要知道步骤中的最短距离(避开墙壁)然后开始移动。
任何帮助将不胜感激......
顺便说一下,我正在尝试使用DFS,我认为BFS会更有效率,所以如果有人可以帮助将它转换为BFS ..(BFS比DFS更好)
现在我知道什么是更好的解决方案,但我不知道要采取哪个方向,因为程序可以存储最佳路径。
PS:
我开始尝试使用字符串并附加字符和“N”,“W”,“S”等等...
答案 0 :(得分:0)
问题是您没有存储最短路径(PathMin
?)。
解决此问题的方法不止一种。在您的代码中,pathExists
返回int
,这是最短路径的长度。相反,它可以返回vector<int>
这是最短的路径。
我认为BFS比DFS更适合这项任务;将此代码转换为BFS将很困难。我建议你保持一个位置矢量,就像一队搜索者从起点向外穿过迷宫。搜索者轮流移动;当一个搜索者可以进行多次移动时,它会分成多个搜索者;当一个搜索者不动,它就会死去;当搜索者到达目的地时,搜索结束。
答案 1 :(得分:0)
感谢@Beta,但经过大量测试后,我发现这个结果非常完美:
#include <iostream>
#include <algorithm>
#include <iterator>
#include <string>
#include <map>
using namespace std;
//using String = char *;
std::string Path;
std::string PathGood;
vector<int> PathInt;
vector<int> PathBueno;
std::map < int, vector<int>> lista;
template<typename T>
ostream& operator<< (ostream& out, const vector<T>& v) {
out << "[";
size_t last = v.size() - 1;
for(size_t i = 0; i < v.size(); ++i) {
out << v[i];
if (i != last)
out << ", ";
}
out << "]";
return out;
}
/*std::map<char,int> mymap;
// first insert function version (single parameter):
mymap.insert ( std::pair<char,int>('a',100) );
mymap.insert ( std::pair<char,int>('z',200) );
ret = mymap.insert ( std::pair<char,int>('z',500) );
if (ret.second==false) {
std::cout << "element 'z' already existed";
std::cout << " with a value of " << ret.first->second << '\n';
}
*/
void display(char maze[][10]) {
for(int i = 0; i < 10; i++) {
copy(maze[i], maze[i] + 10, ostream_iterator<char>(cout, ""));
cout << endl;
}
}
int pathExists(char maze[][10], int sr, int sc, int er, int ec, int distance, int direction) {
/*if(maze[sr][sc] != '.') . es visitable, x pared
return 0;
*/
int lmin=99, l;
if(maze[sr][sc] != '.') //You cannot visit it, or is wall or is @ visited
return 0;
if(sr == er && sc == ec) {
display(maze);
cout << "Distance to end point is: " << distance << endl;
cout << "Ultima direccion ess: " << direction << endl;
//if ( lmin==l) PathBueno = PathInt;
PathInt.push_back(direction);
lista.insert ( std::pair<int,vector<int>>(distance,PathInt));
PathInt.pop_back();
return distance;
}
/*
if(distance == 15) {
cout << "Cant make it in 15 steps" << endl;
return 0;
}
*/
// path.push_back(vertex);
//Path.append(direction);
PathInt.push_back(direction);
maze[sr][sc] = '@'; // anything non-'.' will do
//Row -- Norte
l = pathExists(maze, sr - 1, sc, er, ec, distance + 1,1);
if(l > 0 && l<lmin) {
lmin = l;
// Path.append("N");
}
//Row ++ Sur
l = pathExists(maze, sr + 1, sc, er, ec, distance + 1,2);
if(l > 0 && l<lmin) {
lmin = l;
//Path.append("S");
}
//Column -- Oeste
l = pathExists(maze, sr, sc - 1, er, ec, distance + 1,3);
if(l > 0 && l<lmin)
{
lmin = l;
//Path.append("W");
}
//Column ++ Este
l = pathExists(maze, sr, sc + 1, er, ec, distance + 1,4);
if(l > 0 && l<lmin)
{
lmin = l;
//Path.append("E");
}
maze[sr][sc] = '.'; //restore
PathInt.pop_back();
//if ( Path.size() > 2) Path.erase(Path.size() - 1);
return lmin;
}
int main() {
char maze[10][10] = {
{'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X'},
{'X', '.', '.', '.', '.', '.', '.', '.', '.', 'X'},
{'X', '.', 'X', 'X', 'X', 'X', '.', 'X', 'X', 'X'},
{'X', '.', '.', 'X', '.', 'X', '.', '.', '.', 'X'},
{'X', '.', '.', 'X', '.', '.', '.', 'X', '.', 'X'},
{'X', '.', 'X', 'X', '.', 'X', 'X', 'X', '.', 'X'},
{'X', '.', 'X', '.', '.', '.', '.', 'X', 'X', 'X'},
{'X', '.', '.', 'X', 'X', '.', 'X', 'X', '.', 'X'},
{'X', '.', '.', '.', '.', '.', '.', '.', '.', 'X'},
{'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X'}
};
Path.clear();
int slen = pathExists(maze,5,4, 3, 1,0,0);
if(slen) {
cout << "Solvable in "<<slen<<" steps !" << endl;
// cout << "Complete path is : " << Path;
// std::cout << "Complete path is : " << PathGood;
}
else
cout << "Out of luck!" << endl;
cin.get();
// showing contents:
std::map<int,std::vector<int>>::iterator it = lista.begin();
std::cout << "Mi lista contains:\n";
for (it=lista.begin(); it!=lista.end(); ++it)
std::cout << it->first << " => " << it->second << '\n';
int direccionb = lista.find(slen)->second[1];
cout << "La direccion buena de la buena es :" << direccionb << endl;
}