快速寻找无向图中两点间的所有路径

xie68xuanzwa 2014-09-27 03:31:54
背景:
点自身无环,是无向图,大概有70个点。
之前在网上找到了一些程序,基于C++ 6.0,用的是深度搜索递归算法,在计算小规模图时候(例如10个节点)时候可以采用,但是一旦达到30节点及以上时候,内存就爆掉了。
求问:有没有大神指点一下该如何编程?
若干年前有这样一篇帖子http://bbs.csdn.net/topics/269748,背景和我很像,都是搞电网络的,但是starfish网友给的那个连接已经进不去了,所以才在这里发帖子。
多谢!
...全文
5844 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
FancyMouse 2014-09-28
  • 打赏
  • 举报
回复 1
for(i=0;i<n;i++) { for(j=0;j<n;j++) { if(i!=j) map[i][j]=1; } } 你不是说没环么?是说没有自环但是图有可能有环? 那你想想,你这个图的话至少有(n-2)!个路径,你要是想要全部输出,那不爆就奇怪了。 不过我之前也理解错了。已经说了无向图,那么必定是有环的。我本来说的是有向图没环我能构造出个爆掉的数据。现在是无向图,那更不可能存的下所有解了。 所以还是回到我1L说过的。要求所有路径本来就是流氓行为,你需要复查的是需求而不是算法。
xie68xuanzwa 2014-09-27
  • 打赏
  • 举报
回复
引用 3 楼 FancyMouse 的回复:
我构造个数据,70个顶点就能让它死掉。5000个点胡扯呢,他测的时候数据太弱而已。 但是方法还是同一个。 至于你说DFS内存爆掉,那一般都是程序写扯了。DFS本身从来都是只要O(V)额外内存的。DFS本身肯定不应该是爆内存的原因。
/* 深度优先搜索算法。 */ #include <stdio.h> #include <stdlib.h> #include <assert.h> #include <iostream.h> // 图中最多的点数 #define MAX_NODES_NUM 100 // 图中两点最多的路径数 #define MAX_PATHS_BETWEEN_TWO_NODES_NUM 98//(1<<(MAX_NODES_NUM-2)) // 标记无穷远的路径长度 #define INFINTITY (1<<30) // 标记可以到达的路径长度 #define REACHABLE 1 #define TRUE 1 #define FALSE 0 struct Path { int size; int nodes[MAX_NODES_NUM]; }; /* 获取地图 map 中 点 start 到 点 end 的所有路径 map : 地图 n : 地图的点数 start : 起点 end : 终点 paths : 保存找到的所有从 start 到 end 路径 paths : 保存找到的所有从 start 到 end 路径数目 */ void getPaths(int map[][MAX_NODES_NUM],int n ,int start,int end,int isNodeUsed[],struct Path paths[],int * pathsNum) { int i,j; struct Path * tempPaths=(struct Path*) calloc(100000,sizeof(struct Path)); // struct Path tempPaths[MAX_PATHS_BETWEEN_TWO_NODES_NUM]; int tempPathsNum ; // 标记当前起点不可用 isNodeUsed[start] = TRUE; for(i=0;i<n;i++) { // 节点不在路径中,且可以到达// isNodeUsed数组初始值都为0 if(isNodeUsed[i] == FALSE && map[start][i]== REACHABLE) //start与i相连 { // 当前起点能直接到达终点 if(i == end) { paths[(*pathsNum)].size = 2; paths[(*pathsNum)].nodes[0] = end; paths[(*pathsNum)].nodes[1] = start; (*pathsNum)++; } // 当前起点能不能直接到达终点,尝试当前节点通过其他节点达到终点 else { // 递归计算从当前起点到达终点的所有路径 tempPathsNum = 0; getPaths(map,n,i,end,isNodeUsed,tempPaths,&tempPathsNum); // 处理找到的,从当前起点到达终点的所有路径 for(j=0;j<tempPathsNum;j++) { // 在当前起点到达终点的所有路径中,添加当前起点 tempPaths[j].nodes[tempPaths[j].size] = start; tempPaths[j].size ++; // 合并到最终的路径中 paths[(*pathsNum)] = tempPaths[j]; (*pathsNum)++; } } } } isNodeUsed[start] = FALSE; delete []tempPaths; } //int argc, char *argv[] int main() { int map[MAX_NODES_NUM][MAX_NODES_NUM]; int isNodeUsed[MAX_NODES_NUM]; struct Path * paths=(struct Path*) calloc(10000,sizeof(struct Path)); // struct Path paths[MAX_PATHS_BETWEEN_TWO_NODES_NUM]; int pathsNum; int i,j,k ; int start,end; int a,b; int n,m; int x,y,z; n=7; m=21; // 读取点数,路径数 // while(scanf("%d%d",&n,&m)!=EOF) // { // 初始化图 for(i=0;i<n;i++) { isNodeUsed[i] = FALSE; for(j=0;j<n;j++) { map[i][j] = INFINTITY; } } // 读入路径 // for(i=0;i<m;i++) // { // scanf("%d%d",&a,&b); // 标记 a b 间有路径,注意是无向图,标记两次 // map[a][b] = REACHABLE; // map[b][a] = REACHABLE; // } for(i=0;i<n;i++) { for(j=0;j<n;j++) { if(i!=j) map[i][j]=1; } } // 要连接的两个点 // scanf("%d%d",&start,&end); // 查找点 start 到点 end 的所有路径 // start=0; // end=3; pathsNum = 0; // for(i=0;i<n;i++) // { //初始化 // for(j=i+1;j<n;j++) // { i=1; j=3; for(k=0;k<MAX_NODES_NUM;k++) isNodeUsed[k]=0; for(k=0;k<MAX_PATHS_BETWEEN_TWO_NODES_NUM;k++) { paths[k].size=0; for(z=0;z<MAX_NODES_NUM;z++) { paths[k].nodes[z]=0; } } pathsNum=0; getPaths(map,n,i,j,isNodeUsed,paths,&pathsNum); cout<<"起点为 "<<i<<" 终点为 "<<j<<" 共有路径 "<<pathsNum<<" 条 "<<endl; for(x=0;x<pathsNum;x++) { for(y=paths[x].size-1;y>=1;y--) { cout<<paths[x].nodes[y]<<" -> "; // cout<<paths[i].nodes[j]<<" -> "; } cout<<(paths[x].nodes[y])<<endl; } cout<<"****************************************************"<<endl; // } // } delete []paths; return 0; } /* 测试用数据: 1)首先输入点数 n,路径条数 m, 2)接下来输入 m 对点的编号,每对点 a,b 表示点 a 和 点 b 之间有一条路 点的编号从 0 开始到 n-1. 3)最后输入要连接的两个点 输入: 6 14 0 1 0 2 1 0 1 3 2 0 2 4 2 5 3 1 3 5 4 2 4 5 5 2 5 3 5 4 0 5 输出: 0 -> 1 -> 3 -> 5 0 -> 2 -> 4 -> 5 0 -> 2 -> 5 */
xie68xuanzwa 2014-09-27
  • 打赏
  • 举报
回复
引用 3 楼 FancyMouse 的回复:
我构造个数据,70个顶点就能让它死掉。5000个点胡扯呢,他测的时候数据太弱而已。 但是方法还是同一个。 至于你说DFS内存爆掉,那一般都是程序写扯了。DFS本身从来都是只要O(V)额外内存的。DFS本身肯定不应该是爆内存的原因。
那啥,我把代码给您发来看看,您看行吗?现在用的是递归来做的,不知道错误在哪里。。。
FancyMouse 2014-09-27
  • 打赏
  • 举报
回复
我构造个数据,70个顶点就能让它死掉。5000个点胡扯呢,他测的时候数据太弱而已。 但是方法还是同一个。 至于你说DFS内存爆掉,那一般都是程序写扯了。DFS本身从来都是只要O(V)额外内存的。DFS本身肯定不应该是爆内存的原因。
xie68xuanzwa 2014-09-27
  • 打赏
  • 举报
回复
引用 1 楼 FancyMouse 的回复:
没环那当然暴做咯还有什么办法。答案个数本身就是最坏指数的。要求所有路径本来就是流氓行为,你需要复查的是需求而不是算法。
但是之前有人能够处理5000多节点的,我这70个节点应该松松的吧
FancyMouse 2014-09-27
  • 打赏
  • 举报
回复
没环那当然暴做咯还有什么办法。答案个数本身就是最坏指数的。要求所有路径本来就是流氓行为,你需要复查的是需求而不是算法。

33,010

社区成员

发帖
与我相关
我的任务
社区描述
数据结构与算法相关内容讨论专区
社区管理员
  • 数据结构与算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧