尝试在图中找到最短路径时无限循环

Infinite loop when trying to find the shortest path in a graph

我修改了以下代码以满足我在图中查找路径的需要

//H-File
#include<iostream>
#include <list>
using namespace std;
#ifndef _Graph__
#define _Graph__


class Graph
{
    int V; // No. of vertices in graph
    list<int> *adj; // Pointer to an array containing adjacency lists

    // A recursive function used by printAllPaths()
    void printAllPathsUtil(int , int , bool [], int [], int &);

public:
    Graph(int V); // Constructor
    void addEdge(int u, int v);
    void printAllPaths(int s, int d);
};

void solveMaze(string name, int start, int end);



#endif /* defined(__Graph__) */

    //CPP FILE
Graph::Graph(int V)
{
    this->V = V;
    adj = new list<int>[V];
}

void Graph::addEdge(int u, int v)
{
    adj[u].push_back(v); // Add v to u’s list.
}

// Prints all paths from 's' to 'd'
void Graph::printAllPaths(int s, int d)
{
    // Mark all the vertices as not visited
    bool *visited = new bool[V];

    // Create an array to store paths
    int *path = new int[V];
    int path_index = 0; // Initialize path[] as empty

    // Initialize all vertices as not visited
    for (int i = 0; i < V; i++)
        visited[i] = false;

    // Call the recursive helper function to print all paths
    printAllPathsUtil(s, d, visited, path, path_index);
}


void Graph::printAllPathsUtil(int u, int d, bool visited[], int path[], int &path_index){
    // Mark the current node and store it in path[]
    visited[u] = true;
    path[path_index] = u;
    path_index++;

    // If current vertex is same as destination, then print
    // current path[]
    if (u == d)
    {
        int steps;
        for (int i = 0; i<path_index; i++){
            cout << path[i] << " ";
            steps = i;
        }

        cout << endl;
        cout << "Length of path is " << steps << endl;
    }
    else // If current vertex is not destination
    {
        // Recur for all the vertices adjacent to current vertex
        list<int>::iterator i;
        for (i = adj[u].begin(); i != adj[u].end(); ++i)
            if (!visited[*i])
                printAllPathsUtil(*i, d, visited, path, path_index);
    }

    // Remove current vertex from path[] and mark it as unvisited
    path_index--;
    visited[u] = false;
}

void solveMaze(string name, int start, int end){
    vector<int> graphData;
    ifstream f(name);
    if (f.is_open()) {
        string line;
        getline(f, line);
        char c;
        while (f >> c) {
            if (c == '1') {
                graphData.push_back(1);
            }
            else if (c =='0') {
                graphData.push_back(0);
            }
        }
        f.close();
    }


    int numRooms = int(graphData.size()/4);
    int numCols = sqrt(graphData.size()/4);
    cout << "numCols: " << numCols << endl;
    cout << "rooms: "<< numRooms << endl;
    cout << endl;
    cout << endl;

    Graph maze(numRooms);
    for(int room = 0; room < numRooms; ++room){
        //if room is on top row and left corner
        if(room == 0){

            if(graphData[(room*4+1)] == 1){//You are at room 0, checking room 1
                maze.addEdge(room, room+1);
                cout << "a ";
                cout << "room " << room << " to " << room+1 << endl;
            }
            if(graphData[(room*4+2)] == 1){//Checking below room zero
               maze.addEdge(room, room+numCols);
                cout << "b ";
                cout << "room " << room << " to " << room+numCols << endl;
            }
        }

        //if room is on top row
        if(room < numCols && room !=0){
            if(graphData[(room*4+1)] == 1){//Check to east
                maze.addEdge(room, room+1);
                cout << "c ";
                cout << "room " << room << " to " << room+1 << endl;
            }
            if(graphData[(room*4+2)] == 1){//Checking to south
                maze.addEdge(room, room+numCols);
                cout << "d ";
                cout << "room " << room << " to " << room+numCols << endl;
            }

        }

        //if room is on top row and right corner
        if(room == numCols-1){
            if(graphData[(room*4+2)] == 1){//Checking to south
                maze.addEdge(room, room+numCols);
                cout << "e ";
                cout << "room " << room << " to " << room+numCols << endl;
            }

        }
        //if room is on middle row and left room
        if((room >= numCols) && (room%numCols == 0)){
            if(graphData[(room*4+1)] == 1){//Check to east
                maze.addEdge(room, room+1);
                cout << "f ";
                cout << "room " << room << " to " << room+1 << endl;
            }
            if(graphData[(room*4+2)] == 1){//Checking to south
                maze.addEdge(room, room+numCols);
                cout << "g ";
                cout << "room " << room << " to " << room+numCols << endl;
            }

        }

        //if room is on middle row and right room
        if((room > numCols) && (room%numCols == numCols-1)){
            if(graphData[(room*4+2)] == 1){//Checking to south
                maze.addEdge(room, room+numCols);
                cout << "h ";
                cout << "room " << room << " to " << room+numCols << endl;
            }

        }

        //if room is on bottom row but not the room on the right corner
        if(room > numCols && (room == numRooms-numCols)){
            if(graphData[(room*4+1)] == 1){//Check to east
                maze.addEdge(room, room+1);
                cout << "i ";
                cout << "room " << room << " to " << room+1 << endl;
            }

        }
        //else room is just in middle rows
        if((room > numCols) && (room%numCols != numCols-1) && (room%numCols != 0)){
            if(graphData[(room*4+1)] == 1){//Check to east
                maze.addEdge(room, room+1);
                cout << "j ";
                cout << "room " << room << " to " << room+1 << endl;
            }
            if(graphData[(room*4+2)] == 1){//Checking to south
                maze.addEdge(room, room+numCols);
                cout << "k ";
                cout << "room " << room << " to " << room+numCols << endl;
            }

        }
    }
    cout << endl;
    cout << endl;
    cout << "Finding all paths from " << start << " to " << end << "..." << endl;

    maze.printAllPaths(start, end);
}

它工作得很好,除了当我遇到图表中的死胡同而不得不回头的情况时。它继续采用相同的路径,因此陷入无限循环。我不确定如何解决这个问题。明确一点:如果我有像

这样的连接
A--B--C--D--E
   |
   F

它会从A到B再到F然后再回到B再到F。我希望它从 A 到 B 再到 F,然后回到 B,然后再到 C。有什么想法吗?

printAllPathsUtil中:

// Recur for all the vertices adjacent to current vertex
list<int>::iterator i;
  for (i = adj[u].begin(); i != adj[u].end(); ++i)
    if (!visited[*i])
      printAllPathsUtil(*i, d, visited, path, path_index);

// Remove current vertex from path[] and mark it as unvisited
visited[u] = false;

因此,在 完成探索 F 之前,您不会将 B 标记为已访问。并且在 之后,您不会将 F 标记为已访问 你已经完成了对 B 的探索。 于是你在这两个房间之间来回穿梭,仿佛冲进了一条无尽的走廊。

在您探索相邻房间之前将 B 标记为已访问