查找图中从起始节点到结束节点的所有路径

时间:2016-01-11 14:08:08

标签: algorithm graph

这是我的问题。

我正在尝试解决此问题。

  

给定起点和终点,从开始查找所有路径   角落到角落的角落。仅包括未通过的路线   通过任何角落不止一次。

例如:1是起始节点,6是终点。我有数据

1 2
1 3
3 4
3 5
4 6
5 6
2 3
2 4

由连接的空白分隔的正整数对。 所以输出应该是。

1 2 3 4 6
1 2 3 5 6
1 2 4 3 5 6
1 2 4 6
1 3 2 4 6
1 3 4 6
1 3 5 6

从1到6有7条路线。

现在我使用图搜索算法,我只能找到一个。而且我也找不到给定最终目的地的那个。我的意思是我只能遍历图表。

我所做的是我创建了图形的邻接矩阵,然后进行了深度优先搜索。

首先我定义了一个班级Node

public class Node
{
    public string NodeId;
    public bool IsVisited;
    public Node(string nodeId)
    {
        NodeId = nodeId;
    }
}

然后是Graph类,

 public class Graph
{
    private Node[] _nodes;
    private int[][] _adjacencyMatrix;
    public int _numberOfTotalNodes;
    public Graph(int[][] adjacencyMatrix, int numberOfTotalNodes)
    {
        _adjacencyMatrix = adjacencyMatrix;
        _numberOfTotalNodes = numberOfTotalNodes;
        _nodes = new Node[_numberOfTotalNodes];
        for (int i = 0; i < _numberOfTotalNodes; i++)
        {
            _nodes[i] = new Node((i + 1).ToString());
        }
    }

    public void DepthFirstSearch()
    {
        Stack s = new Stack();
        _nodes[0].IsVisited = true;
        DisplayNodeId(0);
        s.Push(0);
        int v;
        while (s.Count > 0)
        {
            v = GetAdjUnvisitedNode((int)s.Peek());
            if (v == -1 || _nodes[v].IsVisited)
            {
                s.Pop();
            }
            else
            {
                _nodes[v].IsVisited = true;
                DisplayNodeId(v);
                s.Push(v);
            }
        }
        for (int u = 0; u < _numberOfTotalNodes; u++)
        {
            _nodes[u].IsVisited = false;
        }
    }

    public void DisplayNodeId(int nodePosition)
    {
        Console.Write(_nodes[nodePosition].NodeId + " ");
    }

    public int GetAdjUnvisitedNode(int v)
    {
        for (int j = 0; j < _numberOfTotalNodes; j++)
        {
            if (_adjacencyMatrix[v][j] == 1 && _nodes[j].IsVisited == false)
            {
                return j;
            }
        }
        return -1;
    }
}

要调用它,只需使用代码即可。

var graph = new Graph(adjacenyMatrix, adjacenyMatrix.GetLength(0));
graph.DepthFirstSearch();

请指出我算法的缺陷。

根据评论,那里有一个solution,我想要C#代码。但是没有完成。它缺少方法AdjacentNodes(T current)

1 个答案:

答案 0 :(得分:0)

问题是您在触摸节点后将其标记为已访问,并且仅在算法结束时取消设置标记。这意味着节点永远不会出现在不同的路径中,并且您的搜索结束非常快。我建议您不要将此信息存储在节点本身中,而是检查节点是否已经是当前路径中节点堆栈的一部分。我认为这就是你想要做的:你想要防止一个节点在路径中出现两次(避免循环),而不是在搜索过程中只将节点添加到任何路径一次。

此外,我没有看到你的DFS函数如何返回任何东西。它只是在选择节点时输出节点,但您从不检查是否到达目标节点。

如果不再使用isVisited标志,还必须更改选择新节点的方式。我建议为您的DFS提供递归解决方案。编写一个函数,将当前路径(Stack)作为参数,然后确定所有相邻节点不是堆栈的一部分,然后通过递归调用每个这样的节点(相应的节点添加到堆栈)来迭代它们