简单的 bfs 示例...我不明白
Simple bfs example... I don't get it
我正在努力了解BFS如何使用队列来计算最短路径。假设我有一个网格:
1--2--3
| | |
4--5--6
| | |
7--8--9
|
0
起点为"9",目标为"0"。
所以。。。我推动开始。。。
push 9 {9}
pop 9 {}
push 6 {6}
push 8 {6,8}
pop 6 {8}
push 3 {8,3}
push 5 {8,3,5}
pop 8 {3,5}
push 7 {3,5,7}
pop 3 {5,7}
push 2 {5,7,2}
pop 5 {7,2}
push 4 {7,2,4}
pop 7 {2,5}
found 0
我怎样才能从这种混乱中提取最短的路径?我不明白这怎么会给我最短的路径。我想错了吗?
谢谢!
要找到最短路径,每个节点还应该"记住"在BFS期间是如何到达的[哪个顶点导致发现它]。
在cpp中,例如,您可以使用map<int,int>
。
简单示例:
map[9] = -1; //indicationg source
map[6] = 9;
map[8] = 9;
map[3] = 6;
map[7] = 8 ;
...
map[0] = 7;
要获得最短路径,只需沿着从0到源的路径[当值为-1]。
您需要做的是记住,对于每个节点,您是如何到达那里的。这涉及到向每个节点添加一个数据成员(如果您使用结构或类来表示节点),或者,在不太具侵入性的情况下,保留一个整数或节点指针的并行列表。既然你用C++标记了它,我认为你正在寻找一个C++解决方案。像这样的东西有效:
#include <iostream>
#include <queue>
#include <stdexcept>
#include <vector>
struct graph {
graph(size_t nodes)
: m_adjacency_list(nodes) {
}
size_t number_of_nodes() const {
return m_adjacency_list.size();
}
std::vector<size_t> const& neighbours_of(size_t node) const {
return m_adjacency_list.at(node);
}
void add_edge(size_t from, size_t to) {
std::vector<size_t>& al = m_adjacency_list.at(from);
if (to >= m_adjacency_list.size())
throw std::runtime_error("Tried to add edge to non-existant node");
for (size_t i = 0; i < al.size(); ++i) if (al[i] == to) return;
al.push_back(to);
}
private:
std::vector<std::vector<size_t>> m_adjacency_list;
};
int main() {
// generate your grid
graph g(10);
g.add_edge(1, 2);
g.add_edge(1, 4);
g.add_edge(2, 1);
g.add_edge(2, 3);
g.add_edge(2, 5);
g.add_edge(3, 2);
g.add_edge(3, 6);
g.add_edge(4, 1);
g.add_edge(4, 5);
g.add_edge(4, 7);
g.add_edge(5, 2);
g.add_edge(5, 4);
g.add_edge(5, 6);
g.add_edge(5, 8);
g.add_edge(6, 3);
g.add_edge(6, 5);
g.add_edge(6, 9);
g.add_edge(7, 4);
g.add_edge(7, 8);
g.add_edge(7, 0);
g.add_edge(8, 5);
g.add_edge(8, 7);
g.add_edge(8, 9);
g.add_edge(9, 6);
g.add_edge(9, 8);
g.add_edge(0, 7);
// do the bfs
std::vector<size_t> reached_by(g.number_of_nodes(), g.number_of_nodes());
std::queue<size_t> q;
size_t start = 9;
size_t target = 0;
reached_by[start] = start;
q.push(start);
while (!q.empty()) {
size_t node = q.front();
q.pop();
for (size_t i = 0; i < g.neighbours_of(node).size(); ++i) {
size_t candidate = g.neighbours_of(node)[i];
if (reached_by[candidate] == g.number_of_nodes()) {
reached_by[candidate] = node;
if (candidate == target) break;
q.push(candidate);
}
}
}
if (reached_by[target] == g.number_of_nodes())
std::cout<<"No path to "<<target<<" found!"<<std::endl;
else {
std::cout<<"Path to "<<target<<": ";
for (size_t node = target; node != start; node = reached_by[node])
std::cout<<node<<" <- ";
std::cout<<start<<std::endl;
}
}
在该代码中,向量reachd_by用于跟踪每个节点是从哪个节点到达的。一旦找到目标,您就可以使用该向量向后追踪到起点的路径。
运行此程序的输出是
Path to 0: 0 <- 7 <- 8 <- 9
相关文章:
- 激励'inline'说明符的真实世界示例?
- 为什么示例代码访问IUnknown中已删除的内存
- 我不明白为什么我声明一个空的内部结构并将其传递给构造函数
- 以下示例中如何避免代码复制?C++/库达
- "类模板示例<int>;"语句对 C++11 是什么意思?
- 我不明白这段代码是如何对这个pythonlist()进行排序的,也不明白如何用C++中的向量来重现它
- 示例C++项目编译中的警告
- 不明白迭代器,引用和指针失效,一个例子
- 示例外壳应用程序显示的 V8 "segmentation fault (core dumped)"错误
- 当Microsoft文档仅包含 C# 示例时,如何查找 C++ 包含文件名
- 在简单示例中,Python3 + ctypes 回调会导致内存泄漏
- 为什么理解这个递归示例如此难以转化为直觉?
- Eventloop 卡住:NAO C++ SDK OnFaceDetection 示例
- 如何替换此示例代码片段中已弃用的handler_type_t或 boost::asio::handler_type?
- 而循环:简单的除法程序输出零,不明白为什么
- 适用于 WebView2 旧版本的示例应用程序
- 即使直接从官方示例中复制,也找不到未知类型名称QML_ELEMENT和 QML 模块
- 不明白 istream::read cplusplus.com 示例
- 简单的 bfs 示例...我不明白
- 我不明白模板函数如何在 C++14 的 [namespace.memdef]/3 的示例中成为类 A::X::Y 的朋友