Multigraph中的所有简单路径(Depth First Traversal)

时间:2013-07-18 16:27:03

标签: java graph-theory depth-first-search

在阅读并搜索了一段时间后,我仍然无法理解多重图的深度优先遍历(或搜索)(两个顶点可以有多个边缘)。 / p>

我在另一个问题上找到了这个答案:

Graph Algorithm To Find All Connections Between Two Arbitrary Vertices

这是一个很好的答案,但它仅适用于简单图形。

简而言之,我需要多图中从顶点A到顶点B的所有简单路径(无重复顶点),而不仅仅是最短路径。

我正在使用JGraphT在Java中实现它,如果有任何帮助的话。我不介意另一种语言的解决方案。如果这也有任何帮助,则图表是定向和加权的。

P.S。我不关心算法的运行时间(我会缓存结果)。

我正在寻找类似于链接问题中的输出的输出(我有更多信息附加到边缘,但这与遍历没有多大关系:

All paths connecting B to E:
B->E
B->F->E
B->F->C->E
B->A->C->E
B->A->C->F->E

谢谢。

2 个答案:

答案 0 :(得分:1)

多图和普通图实际上不需要不同的代码。在这两种情况下,您将需要知道您以前是否访问过此特定路径上的给定节点。无论有多少边可以连接两个顶点,这都有效。

因此,您要做的是,对于每条路径,保留已经访问过的顶点列表,并且永远不会前往已经访问过的顶点。因此,有些伪代码:

function DFSHelper(vertex v, array visited):
    for edge in v.edges:
        if edge.vertex_at_end not in visited:
            DFSHelper(edge.vertex_at_end, visited + [edge.vertex_at_end])
    for v in visited:
        print v + "->"

function DFS(vertex v):
    DFSHelper(v, [])

适当调整(例如,这当前打印给定路径的所有子路径,如“A”,“A-> B”,“A-> B-> C”等)。

另请注意,这将打印一些路径两次(如果同一对顶点之间有多条边)。您可以通过仅在给定函数中从顶点B移动到顶点A一次来调整以消除此行为(即,如果多个边连接两个边,仅在第一个边上递归,而忽略其余边)。

答案 1 :(得分:0)

这是在C中实现DFS搜索。 可以修改为使用MultiGraphs imo。

如果这是您正在寻找的,我可以修改它以使用'MultiGraphs'..

#include <stdio.h>
#include <malloc.h>
#include <conio.h>

typedef struct AdjacencyList
{
    char VertexID;
    int *IncidenceList;
}AdjList;

typedef struct Graph
{
    int VertexCount, Status;
    char VertexName;
    AdjList List;
    struct Graph *Next;
}Graph;

Graph* InitializeGraph();
Graph *InitGraphNode(int cnt);
void PerformDepthFirstSearch(Graph *graph);

int main()
{
    Graph *graph;
    graph = InitializeGraph();
    PerformDepthFirstSearch(graph);
    return 0;
}

Graph *InitGraphNode(int cnt)
{
    Graph *node = ((Graph*)malloc(sizeof(Graph)));
    node->List.IncidenceList = ((int*)malloc(sizeof(int)*cnt));
    node->Next = NULL;
    return node;
}

Graph* InitializeGraph()
{
    Graph *graphHead = NULL, *node, *tmp, *tmp2;
    char vname;
    int cnt, i, j, isIncident = 0;
    printf("Enter the number of vertices : ");
    scanf("%d", &cnt);
    if (cnt == 0)
    {
        printf("Number of vertices cannot be ZERO!!\n\n");
        return graphHead;
    }
    graphHead = InitGraphNode(1);
    graphHead->VertexCount = cnt;
    for(i = 0; i < cnt; i++)
    {
        printf("VertexName : ");
        vname = getche();
        printf("\n");
        node = InitGraphNode(cnt);
        node->VertexName = vname;
        node->Next = NULL;
        node->Status = 1;
        if (graphHead->Next == NULL)
        {
            graphHead->Next = node;
        }
        else
        {
            tmp = graphHead;
            while (tmp->Next != NULL)
            {
                tmp = tmp->Next;
            }
            tmp->Next = node;
        }
    }
    tmp = graphHead->Next;
    printf("Prepare to input the adjacent elements of corresponding vertices...\n\n");
    for(i = 0; i < cnt; i++)
    {
        vname = tmp->VertexName;
        tmp2 = graphHead->Next;
        for(j = 0; j < cnt; j++)
        {
        here :
            printf("%c incident on %c :: (1 for YES)(0 for NO) ::-> ",vname, tmp2->VertexName);
            scanf("%d", &isIncident);
            if ((isIncident < 0)||(isIncident > 1))
            {
                printf("Wrong Input!! Try again!!\n\n");
                goto here;
            }
            tmp->List.IncidenceList[j] = isIncident;
            tmp2 = tmp2->Next;
        }
        tmp = tmp->Next;
    }
    return graphHead;
}

void PerformDepthFirstSearch(Graph *graph)
{
    Graph *Stack[100], *Copy = graph->Next, *node, *tmp = graph->Next;
    int top = 0, i, cnt = 0;
    Stack[top++] = Copy;
    Copy->Status++;
    while(top != 0)
    {
        node = Stack[--top];
        node->Status++;
        printf("%c, ", node->VertexName);
        for(i = 0; i < graph->VertexCount; i++)
        {
            if(node->List.IncidenceList[i] == 1)
            {
                while (cnt < i)
                {
                    tmp = tmp->Next;
                    cnt++;
                }
                if (tmp->Status == 1)
                {
                    Stack[top++] = tmp;
                    tmp->Status++;
                }
            }
        }
    }
}