递归查找图矩阵 DFS 中的所有路径

Recursion find all paths in graph matrix DFS

我正在尝试使用递归方法实现基于深度优先搜索的两个函数。我最终试图将运行时与 warshall 的算法(我已经在使用)进行比较。当我打印我的矩阵时,它偏离了几个路径。

递归可能会让我失望,这是我的弱点。由于顶部的 if 语句 if(iIndex1 == iIndex2) return TRUE;,当我尝试查找是否存在来自 (A,A)、(B,B)、(C,C) 等的路径时,我总是会得到 1 即使没有从 A 到 A 的路径。

typedef enum { FALSE, TRUE } bool;

/* Recursive function will determine if there is a path from index 1 to 2
 * Based of DFS
 */
bool recPathExists( Graph G, int iIndex1, int iIndex2 )
{
    int j;
    G.nodeArray[iIndex1].visited = TRUE;
    if(iIndex1 == iIndex2){
            return TRUE;
    }
    for(j = 0; j < G.iNumNodes; j++){
        if(!G.nodeArray[j].visited && G.adjMatrix[iIndex1][j]==1){
            if(recPathExists(G, j, iIndex2))
                return TRUE;
        }
    }
    return FALSE;
}

/* Write a function to find all pairs of nodes which have paths between them.
 * Store this information in the provided pathMatrix.
 */
void allPathsRecFunc( Graph G , int **pathMatrix )
{
    int i, j;
    for(i = 0; i < G.iNumNodes; i++){
        for(j = 0; j < G.iNumNodes; j++){
            if(recPathExists(G, i , j)== TRUE){
                pathMatrix[i][j] = 1;
            }
            resetVisited(G); //resets all nodes to FALSE
        }
    }
}

应该是什么

A   0 1 1 1 1 1 1 1 
B   0 1 0 0 1 1 1 1 
C   0 1 0 0 1 1 1 1 
D   0 0 0 0 0 0 0 0 
E   0 0 0 0 0 0 0 0 
F   0 1 0 0 1 1 1 1 
G   0 1 0 0 1 1 1 1 
H   0 1 0 0 1 1 1 1 

我得到了什么

A   1 1 1 1 1 1 1 1 
B   0 1 0 0 1 1 1 1 
C   0 1 1 0 1 1 1 1 
D   0 0 0 1 0 0 0 0 
E   0 0 0 0 1 0 0 0 
F   0 1 0 0 1 1 1 1 
G   0 1 0 0 1 1 1 1 
H   0 1 0 0 1 1 1 1

我的深度优先搜索使用递归,但它输出一个父数组,尽管功能应该是相同的。它获得了完美的成绩,所以我知道它有效。希望对你有帮助。

https://github.com/grantSwalwell/Data-Structures/blob/master/Depth%20First%20Search.h

算法~

  1. 布尔数组,访问标记节点
  2. 搜索数字数组来衡量访问深度
  3. 深度增加并得出搜索数
  4. 在 0,0 调用 DFS
  5. 对于每个未访问的邻居
  6. DFS深度+1,搜索=深度,访问=真
  7. return父数组,显示搜索模式

    // Depth First Search recursive helper method
    
    
    void DFS(Graph& G, int v0, Array<bool>* visited, Array<int>* search, int 
    depth)
    {
    
        // set visited
        (*visited)[v0] = true;
    
        // set search num
        (*search)[v0] = depth;
    
        // iterate through neighbors
        for (int i = 0; i < G.nodes(); i++)
        {
            // if i is a neighbor
            if (G.edge(i, v0))
            {
                // if it has not been visited
                if (!(*visited)[i])
                {
                     // call DFS
                     DFS(G, i, visited, search, depth + 1);
                 }
             } // end if
         } // end for
    }
    
    // Depth First Search
    Array<int>* DFS(Graph& G, int v0)
    {
    
        // visited array
        Array<bool>* visited = new Array<bool>(G.nodes());
    
        // search number array, order of visitation
        Array<int>* search = new Array<int>(G.nodes());
    
        // initialize both arrays
        for (int i = 0; i < G.nodes(); i++)
        {
            (*visited)[i] = false;
            (*search)[i] = 1;
        }
    
        // create depth field
        int depth = 1;
    
        // call DFS
        DFS(G, v0, visited, search, depth);
    
        return search;
    
    };
    

您的问题可能在这里:

for(j = 0; j < G.iNumNodes; j++)
{
    if(!G.nodeArray[j].visited && G.adjMatrix[iIndex1][j] == 1)
    {
        return recPathExists(G, j, iIndex2);
    }
}

通过 returnrecPathExists 上递归的结果,您没有检查循环中可以到达的其他可能节点(本质上,您过早地返回失败,并且缺少可能的路径)。

我相信你只需要一点点修改:

for(j = 0; j < G.iNumNodes; j++)
{
    if(!G.nodeArray[j].visited && G.adjMatrix[iIndex1][j] == 1)
    {
        if (recPathExists(G, j, iIndex2))
            return TRUE;
    }
}

即"if a path does exist, return as we've found it. If not, keep looking".