在阅读并搜索了一段时间后,我仍然无法理解多重图的深度优先遍历(或搜索)(两个顶点可以有多个边缘)。 / 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
谢谢。
答案 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++;
}
}
}
}
}