这是我的问题。
我正在尝试解决此问题。
给定起点和终点,从开始查找所有路径 角落到角落的角落。仅包括未通过的路线 通过任何角落不止一次。
例如: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)
。
答案 0 :(得分:0)
问题是您在触摸节点后将其标记为已访问,并且仅在算法结束时取消设置标记。这意味着节点永远不会出现在不同的路径中,并且您的搜索结束非常快。我建议您不要将此信息存储在节点本身中,而是检查节点是否已经是当前路径中节点堆栈的一部分。我认为这就是你想要做的:你想要防止一个节点在路径中出现两次(避免循环),而不是在搜索过程中只将节点添加到任何路径一次。
此外,我没有看到你的DFS函数如何返回任何东西。它只是在选择节点时输出节点,但您从不检查是否到达目标节点。
如果不再使用isVisited标志,还必须更改选择新节点的方式。我建议为您的DFS提供递归解决方案。编写一个函数,将当前路径(Stack)作为参数,然后确定所有相邻节点不是堆栈的一部分,然后通过递归调用每个这样的节点(相应的节点添加到堆栈)来迭代它们