【发布时间】:2011-12-10 21:56:10
【问题描述】:
我正在做一个项目,我需要找到从单一来源到单一目的地的最短路径。我只能右转,所以有时我需要右转三个而不是左转。我已经把算法搞定了(我想),但是我在打印之后的路径时遇到了问题。我在每个图块上都保留了一个来自指针,但是当我从最后开始并遵循来自指针时,获取三个权限的时间会导致一个循环,因为来自指针被新的指针覆盖.如何识别这种循环模式并回到正轨以打印完整路径?
这是我的 backTracker 类
class backTracker {
int rows;
int cols;
tile** map;
tile* start;
tile* end;
int rightTurns;
int loopTracker;
bool done;
int** visits;
MyStack visited;
public:
backTracker(int inRows, int inCols, tile** inMap, tile* inStart,
tile* inEnd, int** &inVisits) {
rows = inRows;
cols = inCols;
map = inMap;
start = inStart;
end = inEnd;
rightTurns = 0;
loopTracker = 0;
done = false;
visits = inVisits;
}
void findPath() {
backTrack(start);
}
private:
void backTrack(tile* currTile) {
if (currTile == end || done) {
cout << "end found" << endl;
done = true;
return;
}
else if (promising(currTile)) {
//if it's the start tile, check all directions
if (currTile->cameFrom == 0) {
tile* next;
int cRow = currTile->row;
int cCol = currTile->col;
if (cRow != 0) {
next = &map[cRow-1][cCol];
next->cameFrom = currTile;
next->directionFrom = 'N';
backTrack(next);
}
if (cRow != rows - 1) {
next = &map[cRow+1][cCol];
next->cameFrom = currTile;
next->directionFrom = 'S';
backTrack(next);
}
if (cCol != cols - 1) {
next = &map[cRow][cCol+1];
next->cameFrom = currTile;
next->directionFrom = 'E';
backTrack(next);
}
if (cCol != 0) {
next = &map[cRow][cCol-1];
next->cameFrom = currTile;
next->directionFrom = 'W';
backTrack(next);
}
}
//otherwise check straight and right
else {
currTile->straight = 0; //the tile in the straight direction
currTile->right = 0;//the tile to the right of the straight tile
//easier to read
int row = currTile->row;
int col = currTile->col;
bool good = false;
//find the straight and right tiles depending on current
//direction, also check if the tile has been visited from
//that direction already
if (currTile->directionFrom == 'N') {
if (col != cols - 1) {
if (map[row][col+1].directionFrom != 'E') {
currTile->right = &map[row][col+1];
currTile->right->directionFrom = 'E';
good = true;
tile* right = currTile->right;
right->cameFrom = currTile;
backTrack(right);
}
}
if (row != 0) {
//if it hasn't already been visited from this direction
if (map[row-1][col].directionFrom != 'N') {
currTile->straight = &map[row-1][col];
good = true;
tile* str = currTile->straight;
str->cameFrom = currTile;
//going straight so direction is the same
str->directionFrom = currTile->directionFrom;
backTrack(str);
}
}
}
else if (currTile->directionFrom == 'W') {
if (row != 0) {
if (map[row-1][col].directionFrom != 'N') {
currTile->right = &map[row-1][col];
currTile->right->directionFrom = 'N';
good = true;
tile* right = currTile->right;
right->cameFrom = currTile;
backTrack(right);
}
}
if (col != 0) {
if (map[row][col-1].directionFrom != 'W') {
currTile->straight = &map[row][col-1];
good = true;
tile* str = currTile->straight;
str->cameFrom = currTile;
//going straight so direction is the same
str->directionFrom = currTile->directionFrom;
backTrack(str);
}
}
}
else if (currTile->directionFrom == 'S') {
if (col != 0) {
if (map[row][col-1].directionFrom != 'W') {
currTile->right = &map[row][col-1];
currTile->right->directionFrom = 'W';
good = true;
tile* right = currTile->right;
right->cameFrom = currTile;
backTrack(right);
}
}
if (row != rows - 1) {
if (map[row+1][col].directionFrom != 'S') {
currTile->straight = &map[row+1][col];
good = true;
tile* str = currTile->straight;
str->cameFrom = currTile;
//going straight so direction is the same
str->directionFrom = currTile->directionFrom;
backTrack(str);
}
}
}
else if (currTile->directionFrom == 'E'){
if (row != row - 1) {
if (map[row+1][col].directionFrom != 'S') {
currTile->right = &map[row+1][col];
currTile->right->directionFrom = 'S';
good = true;
tile* right = currTile->right;
right->cameFrom = currTile;
backTrack(right);
}
}
if (col != cols - 1) {
if (map[row][col+1].directionFrom != 'E') {
currTile->straight = &map[row][col+1];
good = true;
tile* str = currTile->straight;
str->cameFrom = currTile;
//going straight so direction is the same
str->directionFrom = currTile->directionFrom;
backTrack(str);
}
}
}
}
}
}
//checks for walls
bool promising(tile* currTile) {
if (currTile->type == WALL) {
return false;
}
else {
return true;
}
}
【问题讨论】:
-
您能给我们提供任何具体信息吗?一个图像?代码?描述问题的论文?
-
是上课用的,政策是不在任何地方公开发布代码……我是用回溯算法找路径的,环境就是一个字母网格,'X '成为一堵墙'。作为一个有效的移动空间。抱歉,我无法为您提供更多信息。
-
我认为您应该只保留一组经过的图块,而不是依赖图块来保存该信息。你不会有任何歧义。
-
如何区分路径中的图块和仅访问过的图块?
-
只存储您要到达的图块的坐标。
标签: c++ graph shortest-path