基础图算法:广度搜索优先(BFS)

什么是图?这里有对图的描述https://www.jianshu.com/p/bce71b2bdbc8

那么广度搜索优先算法与深度搜索优先算法的作用就是遍历整个图数据的两种算法,两种算法的核心都是对图的遍历,都属于对贪心算法的体现。

广度优先算法(BFS又称为宽度优先算法)

广度优先算法是遍历完整图的一种遍历算法,也是很多高级算法的基础,例如Dijkstra又称迪杰斯特拉算法(用来计算正向最短路径算法),Kruskal 又称克鲁斯卡尔算法(用来计算最小生成树)。BFS算法的核心类似于广播形式的由内到外一层一层进行搜索。直到遍历最外一层结构。通常我们需要依赖与队列(先进先出)数据结构完成整体的遍历。后面我会通过实际的栗子来介绍BFS的应用场景和实际用处。

如图所示为一个基本图

如何区遍历以上图结构.

第一步:准备创建一个空队列中,以及一个能保证数据唯一性的集合(我这里用set保存值为顶点id)来保存遍历过的点,我们假设以1顶点为(可以从任意顶点开始)开始,将其放入队列中。

第二步:从队列中获取1顶点,获取1顶点下连接的2,3点。判断是否在set中已存在该顶点,如果不存在写入到队列中。此时第一层已遍历完成。

第三步:从队列中取出2顶点,获取2顶点下连接4,5,6顶点,并判断是该顶点否在set中已存在,如果不存在则写入到队列中。再拿出3顶点获取5,7顶点,因为5顶点再set中已存在,不需要再写入队列.此时第二层已遍历完成

循环取出队列中的顶点,直到最后队

  • 5
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,下面是一个基本的C++代码实现,使用MPI+OpenMP并行化广度优先搜索算法,采用自底向上的方法。数据集从文件中读取,节点和边的数量比较小,适合做简单的演示。 ```c++ #include <iostream> #include <fstream> #include <queue> #include <vector> #include <mpi.h> #include <omp.h> using namespace std; const int MAX_NODE = 1000; const int INF = 0x3f3f3f3f; vector<int> adj[MAX_NODE]; int dist[MAX_NODE]; bool visited[MAX_NODE]; void bfs(int source, int num_nodes, int num_procs, int rank) { for (int i = 0; i < num_nodes; i++) { dist[i] = INF; visited[i] = false; } dist[source] = 0; visited[source] = true; queue<int> Q; Q.push(source); while (!Q.empty()) { int u = Q.front(); Q.pop(); if (rank == u % num_procs) { #pragma omp parallel for for (int i = 0; i < adj[u].size(); i++) { int v = adj[u][i]; if (!visited[v]) { visited[v] = true; dist[v] = dist[u] + 1; Q.push(v); } } } MPI_Barrier(MPI_COMM_WORLD); MPI_Bcast(&visited[0], num_nodes, MPI_C_BOOL, u % num_procs, MPI_COMM_WORLD); MPI_Bcast(&dist[0], num_nodes, MPI_INT, u % num_procs, MPI_COMM_WORLD); } } int main(int argc, char** argv) { int num_procs, rank; MPI_Init(&argc, &argv); MPI_Comm_size(MPI_COMM_WORLD, &num_procs); MPI_Comm_rank(MPI_COMM_WORLD, &rank); if (argc != 2) { if (rank == 0) { cout << "Usage: ./bfs <input_file>" << endl; } MPI_Finalize(); return 0; } // 读取数据集 ifstream fin(argv[1]); int num_nodes, num_edges, source; fin >> num_nodes >> num_edges >> source; for (int i = 0; i < num_edges; i++) { int u, v; fin >> u >> v; adj[u].push_back(v); adj[v].push_back(u); } fin.close(); double start_time = MPI_Wtime(); bfs(source, num_nodes, num_procs, rank); double end_time = MPI_Wtime(); if (rank == 0) { cout << "Distances from source " << source << ":" << endl; for (int i = 0; i < num_nodes; i++) { cout << i << " " << dist[i] << endl; } cout << "Elapsed time: " << end_time - start_time << " seconds" << endl; } MPI_Finalize(); return 0; } ``` 在这个代码中,我们首先读取一个包含节点和边的数量以及数据集的文件,然后使用MPI+BFS并行化广度优先搜索算法。在算法的主循环中,我们使用OpenMP并行化节点的遍历,使用MPI进行跨进程的数据同步。具体来说,每个进程只处理其余数等于自己rank的节点,遍历完后需要使用MPI_Bcast函数将visited和dist数组广播到其他进程,以保证所有进程都可以正确地更新它们自己的visited和dist数组。最后,我们在进程0中输出结果,并计算算法的运行时间。 需要注意的是,这个代码只是一个简单的示例,还有很多可以优化的地方,比如节点和边的分配、负载均衡、并行效率等等。在实际应用中,还需要针对具体的数据集和硬件环境进行适当的调整和优化。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值