假设您有一个图表G
,您需要做的是从start_node
到finish_node
找到所有可能的路线。此外,您需要以正确的顺序打印所有路线。你会怎么做?发现节点并不困难,它以正确的顺序打印它们并获得距离。
template <class VertexType>
void DepthFirstSearch(Graph<VertexType> routes, VertexType from_vertex, VertexType to_vertex)
{
stack<VertexType> mystack;
queue<VertexType> vertexQ;
int total_weight = 0;
int found_count = 0;
/*stringstream ss;*/
bool found = false;
VertexType vertex;
VertexType item;
routes.clearMarks();
// size_t i = 0;
// size_t j = 0;
mystack.push(from_vertex); // Adding Location to stack
do
{
vertex = mystack.top(); // Get top location
mystack.pop(); // Getting rid of top location
if (vertex == to_vertex) // If location == destination, then stop;
{
found = true;
found_count++;
} else {
if (!routes.isMarked(vertex)) // If route has not been traveled to
{
routes.markVertex(vertex); // Mark place
routes.goToVertices(vertex, vertexQ); // Add adjacent positions
while (!vertexQ.empty()) // While there are still positions left to test
{
item = vertexQ.front(); // Get top position
vertexQ.pop(); // Get rid of top position from stack
if (!routes.isMarked(item)) // If top position is not marked,
mystack.push(item); // Add to-visit stack
}
}
}
} while (!mystack.empty());
if(!found)
{
std::cout << "Distance: infinity" << std::endl;
std::cout << "Rout:" << std::endl;
std::cout << "None" << std::endl;
} else {
std::cout << "Found this many times: " << found_count << std::endl;
}
}
理想情况下,如果有人输入A B
,那么输出的示例将为:
distance: 100
A to C, 50
C to D, 40
D to B, 10
distance: 10
A to B, 10
请注意,C
和D
都有其他可以访问的节点,但即使深度优先算法会探索它们,也不会考虑它们的距离。这是一个单向图,输入来自文本文件。
答案 0 :(得分:0)
您需要跟踪您经历过的顶点,并将该列表用作路径。
然后你有两个选择:
这两种方法都是正确的,具体取决于您希望在路径上进行哪种处理。
为了能够正确回溯,您需要知道当前路径上每个顶点仍有哪些相邻顶点要访问。您当前的算法通过推送mystack
中的所有顶点来忘记该信息。我建议在mystack
中使用迭代器而不是顶点,让你的图形对象从goToVertices
方法返回这样的迭代器。
由于我不知道你的图表是否有可用的类,我将使用堆栈代替在mystack
中按级别对顶点进行分组。每个队列代表覆盖dfs的树的级别。
deque<queue<VertexType> > mystack;
queue<VertexType> vertexQ;
int total_weight = 0;
int found_count = 0;
VertexType vertex;
routes.clearMarks();
// size_t i = 0;
// size_t j = 0;
vertexQ.push(from_vertex);
mystack.push_front(vertexQ); // Adding Location to stack
do
{
vertexQ = mystack.front(); // Get top location
if (vertexQ.empty()) {
mystack.pop_front();
mystack.front().pop();
continue;
}
if (vertexQ.front() == to_vertex) // If location == destination, then stop;
{
// save path: loop on all the queues from mystack and print front.
for (stack<queue<VertexType>>::const_reverse_iterator it = mystack.rbegin();
it != mystack.rend(); ++it){
// save or process path vertices
cout << it->front() << endl;
}
// backtrack
mystack.pop_front();
mystack.front().pop();
} else {
if (!routes.isMarked(vertexQ.front())) // If route has not been traveled to
{
routes.markVertex(vertexQ.front()); // Mark place
mystack.push_front(
routes.goToVertices(vertexQ.front())); // Get adjacent vertices
}
}
} while (!mystack.empty());