在无向图中查找最小环,就像需要查找一个蜂窝中所有孔洞,如果只查找数目,可以利用欧拉公式,若查找到所有环,需要更进一步的搜索。

方法:寻找到所有顶点的最短路径,对每一个顶点,取出环,循环删除顶点,输出所有最小环。

注意:拓扑图具有位置可变性,不影响图结构的拓扑变化。所以此方法,只能找到拓扑最小环,若想找到距离最小环,需要对边进行加权。

 

原文:找出无向图中所有环的算法。代码也转自于作者。

图片实例:

code:

bool findAllLoop(int argc, char* argv[]);//查找所有路径的算法是成功的;但最短路径不能保证找到最小环
int main(int argc, char* argv[])
{findAllLoop(argc, argv);return 0;
}bool findAllLoop(int argc, char* argv[]){//if (argc != 5){printf("\tThis algorithm require 3 parameters""\n\t\t1:the size of eage""\n\t\t2:the filename contain eage-data""\n\t\t3:the size of vertax""\n\t\t4:the filename contain vertax-data\n");//exit(0);}//eage_size = atoi(argv[1]);//strcat(filename_eage, argv[2]);//vertax_size = atoi(argv[3]);//strcat(filename_vertax, argv[4]);wishchin::eage_size = 22;//边的个数//strcat(filename_eage, argv[2]);std::string filename_eages("D:/DataSet/RsData/loopFind/houseAdj.txt");wishchin::vertax_size = 17;//顶点个数//strcat(filename_vertax, argv[4]);std::string filename_vertaxs("D:/DataSet/RsData/loopFind/houseVotex.txt");//printf("eage_size : %d, vertax_size : %d, filename-eage : %s, filename-vertax : %s\n",\wishchin::eage_size, wishchin::vertax_size, filename_eages, wishchin::filename_vertax);wishchin::readEageDataFromFile(filename_eages);wishchin::readVertaxDataFromFile(filename_vertaxs);wishchin::createAdjacentMatrix();wishchin::DFSTraverse();//test_stack();  return true;
}namespace wishchin{void readEageDataFromFile( std::string filename_eages){FILE* f_read;if (NULL == (f_read = fopen(filename_eages.c_str(), "r"))){printf("open file(%s) error!\n", filename_eages.c_str());exit(0);}//create dynamic array for storing original data form file @filename  eage_set = (int**)malloc(sizeof(int*) * (eage_size + 1));if (!eage_set){printf("malloc error: eage_set**\n");exit(0);}int i;for (i = 1; i <= eage_size; i++){eage_set[i] = (int*)malloc(sizeof(int) * (2 + 1));if (!eage_set[i]){printf("eage_set[%d] malloc error", i);exit(0);}}//read original data from file  //直接读入边的集合for (i = 1; i <= eage_size; i++){if (2 != fscanf(f_read, "%d %d", &eage_set[i][1], &eage_set[i][2])){printf("fscanf error: %d\n", i);exit(0);}printf("%d\t%d\n", eage_set[i][1], eage_set[i][2]);}//test  printf("\n show the origin data from file\n");for (i = 1; i <= eage_size; i++){printf("%d\t%d\n", eage_set[i][1], eage_set[i][2]);}printf("\n");//test END  }void readEageDataFromFile(){FILE* f_read;if (NULL == (f_read = fopen(filename_eage, "r"))){printf("open file(%s) error!\n", filename_eage);exit(0);}//create dynamic array for storing original data form file @filename  eage_set = (int**)malloc(sizeof(int*) * (eage_size + 1));if (!eage_set){printf("malloc error: eage_set**\n");exit(0);}int i;for (i = 1; i <= eage_size; i++){eage_set[i] = (int*)malloc(sizeof(int) * (2 + 1));if (!eage_set[i]){printf("eage_set[%d] malloc error", i);exit(0);}}//read original data from file  //直接读入边的集合for (i = 1; i <= eage_size; i++){if (2 != fscanf(f_read, "%d %d", &eage_set[i][1], &eage_set[i][2])){printf("fscanf error: %d\n", i);exit(0);}}//test  printf("\n show the origin data from file\n");for (i = 1; i <= eage_size; i++){printf("%d\t%d\n", eage_set[i][1], eage_set[i][2]);}printf("\n");//test END  }void readVertaxDataFromFile(){//create the dynamic array for saving vertax-set information  vertax_set = (char**)malloc(sizeof(char*) * (vertax_size + 1));if (!vertax_set){printf("vertax_set malloc error");exit(0);}int i;for (i = 1; i <= vertax_size; i++){vertax_set[i] = (char*)malloc(sizeof(char) * (20 + 1));if (!vertax_set[i]){printf("vertax_set[%d] malloc error");exit(0);}}//open file  FILE* f_read;if (NULL == (f_read = fopen(filename_vertax, "r"))){printf("open file(%s) error", filename_vertax);exit(0);}//read vertax-set information  for (i = 1; i <= vertax_size; i++){if (1 != fscanf(f_read, "%s ", vertax_set[i])){printf("fscanf vertax_set[%d] error", i);exit(0);}}//test  for (i = 1; i <= vertax_size; i++){printf("%s\n", vertax_set[i]);}printf("\n");//test END  }void readVertaxDataFromFile( std::string filename_vertaxs ){//create the dynamic array for saving vertax-set information  vertax_set = (char**)malloc(sizeof(char*) * (vertax_size + 1));if (!vertax_set){printf("vertax_set malloc error");exit(0);}int i;for (i = 1; i <= vertax_size; i++){vertax_set[i] = (char*)malloc(sizeof(char) * (20 + 1));if (!vertax_set[i]){printf("vertax_set[%d] malloc error");exit(0);}}//open file  FILE* f_read;if (NULL == (f_read = fopen(filename_vertaxs.c_str(), "r"))){printf("open file(%s) error", filename_vertaxs.c_str());exit(0);}//read vertax-set information  for (i = 1; i <= vertax_size; i++){if (1 != fscanf(f_read, "%s ", vertax_set[i])){printf("fscanf vertax_set[%d] error", i);exit(0);}}//test  for (i = 1; i <= vertax_size; i++){printf("%s\n", vertax_set[i]);}printf("\n");//test END  }void createAdjacentMatrix(){//create the dynamic array for saving adjcaent matrix  adjacentMatrix = (int**)malloc(sizeof(int*) * (vertax_size + 1));if (!adjacentMatrix){printf("adjacentMatrix** malloc error");exit(0);}int i;for (i = 1; i <= vertax_size; i++){adjacentMatrix[i] = (int*)malloc(sizeof(int) * (vertax_size + 1));if (!adjacentMatrix[i]){printf("adjacentMatrix[%d] malloc error");exit(0);}}//initial the value of adjacentMatrix  int j;for (i = 1; i <= vertax_size; i++){for (j = 1; j <= vertax_size; j++){adjacentMatrix[i][j] = 0;}}//set the value for adjacentMatrix   for (i = 1; i <= eage_size; i++){adjacentMatrix[eage_set[i][1]][eage_set[i][2]] = 1;adjacentMatrix[eage_set[i][2]][eage_set[i][1]] = 1;}//test  printf("\n show the information about adjacent matrix: \n");for (i = 1; i <= vertax_size; i++){for (j = 1; j <= vertax_size; j++){printf("%d ", adjacentMatrix[i][j]);}printf("\n");}//test END  }
}namespace wishchin{int loop_count;int heap;int innerStep = 0;int temp;int isRecall;SequenceStack loop_stack;int pop_value;void DFS(int startVertax){setVisitedFlag(startVertax, 1);int nextVertax;push_stack(&loop_stack, startVertax);nextVertax = firstAdjacentVertax(startVertax);innerStep++;for (;;){if (nextVertax != -1){if (visitedFlag[nextVertax] == 1 && nextVertax == heap && innerStep == 2){nextVertax = nextAdjacentVertax(startVertax, nextVertax);continue;}else if (visitedFlag[nextVertax] == 1 && nextVertax == heap && innerStep != 2){print_stack(loop_stack);nextVertax = nextAdjacentVertax(startVertax, nextVertax);continue;}else if (visitedFlag[nextVertax] == 0){DFS(nextVertax);}if (isRecall == 1){innerStep--;temp = nextVertax;nextVertax = nextAdjacentVertax(startVertax, nextVertax);pop_stack(&loop_stack, &pop_value);setVisitedFlag(temp, 0);isRecall = 0;continue;}nextVertax = nextAdjacentVertax(startVertax, nextVertax);}else if (nextVertax == -1){isRecall = 1;break;}}}void DFSTraverse(){initialVisitedFlagArray();initializeSequenceStack(&loop_stack);int i;for (heap = 1; heap <= vertax_size; heap++){for (i = 1; i <= vertax_size; i++){visitedFlag[i] = 0;}/*printf("print the visitedFlag array: ");for( i = 1; i <= vertax_size; i++ ){printf("%d ", visitedFlag[i]);}printf("\n");*/if (visitedFlag[heap] == 0){printf("\n-------------------the loop start and end with %d----------------\n", heap);clear_stack(&loop_stack);innerStep = 0;//printf("isRecall : %d, findLoop : %d, hasOthers : %d\n", isRecall, findLoop, hasOthers);  isRecall = 0;DFS(heap);}}}void initialVisitedFlagArray(){visitedFlag = (int*)malloc(sizeof(int) * (vertax_size + 1));if (!visitedFlag){printf("visitedFlag* malloc error");exit(0);}int i;for (i = 1; i <= vertax_size; i++)visitedFlag[i] = 0;}void printVisitedVertax(int vertaxID){printf("visited: %d \n", vertaxID);}void setVisitedFlag(int vertaxID, int value){visitedFlag[vertaxID] = value;}int firstAdjacentVertax(int vertaxID){int i;for (i = 1; i <= vertax_size; i++){if (adjacentMatrix[vertaxID][i] == 1)return i;}return -1;}int nextAdjacentVertax(int vertaxID, int nextVertaxID){int i;for (i = nextVertaxID + 1; i <= vertax_size; i++){if (adjacentMatrix[vertaxID][i] == 1)return i;}return -1;}void initializeSequenceStack(SequenceStack* stack){stack->base = (int*)malloc(sizeof(int) * (vertax_size + 1));if (!stack->base){printf("Sequence stack malloc error!\n");exit(0);}stack->top = stack->base;stack->stackSize = vertax_size;}void pop_stack(SequenceStack* stack, int* value){if (empty_stack(*stack) == 1){printf("stack is empty , can not to pop!\n");exit(0);}*value = *(--(stack->top));}void push_stack(SequenceStack* stack, int value){*(stack->top) = value;(stack->top)++;}int empty_stack(SequenceStack stack){return stack.top == stack.base ? 1 : 0;}void print_stack(SequenceStack stack){int temp = *(stack.base);while (stack.top != stack.base){printf("%d->", *((stack.base)++));}printf("%d\n", temp);}void clear_stack(SequenceStack* stack){stack->top = stack->base;}
}

测试数据:

houseAdj.txt:

1 2
2 3
3 4
1 5
2 6
3 7
4 8
5 6
5 9
7 8
7 12
9 10
10 11
11 12
12 17
9 13
10 14
11 15
17 16
13 14
14 15
15 16

housevotex.txt

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

程序输出:

无向图:查找最小环集合(最短路径回溯算法)相关推荐

  1. 常用十大算法 非递归二分查找、分治法、动态规划、贪心算法、回溯算法(骑士周游为例)、KMP、最小生成树算法:Prim、Kruskal、最短路径算法:Dijkstra、Floyd。

    十大算法 学完数据结构该学什么?当然是来巩固算法,下面介绍了十中比较常用的算法,希望能帮到大家. 包括:非递归二分查找.分治法.动态规划.贪心算法.回溯算法(骑士周游为例).KMP.最小生成树算法:P ...

  2. 无向图的最短路径求解算法之——Dijkstra算法

    在准备ACM比赛的过程中,研究了图论中一些算法.首先研究的便是最短路的问题.<离散数学>第四版(清华大学出版社)一书中讲解的Dijkstra算法是我首先研究的源材料. 如何求图中V0到V5 ...

  3. JavaScript实现使用 BACKTRACKING 方法查找集合的幂集算法

    JavaScript实现使用 BACKTRACKING 方法查找集合的幂集算法(附完整源码) btPowerSet.js完整源代码 btPowerSet.test.js完整源代码 btPowerSet ...

  4. JavaScript实现使用 BITWISE 方法查找集合的幂集算法(附完整源码)

    JavaScript实现使用 BITWISE 方法查找集合的幂集算法(附完整源码) bwPowerSet.js完整源代码 bwPowerSet.test.js完整源代码 bwPowerSet.js完整 ...

  5. 最短路径-Dijkstra算法与Floyd算法

    最短路径-Dijkstra算法与Floyd算法 原文:https://www.cnblogs.com/smile233/p/8303673.html 一.最短路径 ①在非网图中,最短路径是指两顶点之间 ...

  6. 常用算法总结(穷举法、贪心算法、递归与分治算法、回溯算法、数值概率算法)

    博主联系方式: QQ:1540984562 微信:wxid_nz49532kbh9u22 QQ交流群:892023501 目录 1.穷举法 2.贪心算法 3.递归与分治算法 4.回溯算法 5.数值概率 ...

  7. 【最短路径Floyd算法详解推导过程】看完这篇,你还能不懂Floyd算法?还不会?...

    简介 Floyd-Warshall算法(Floyd-Warshall algorithm),是一种利用动态规划的思想寻找给定的加权图中多源点之间最短路径的算法,与Dijkstra算法类似.该算法名称以 ...

  8. 回溯 皇后 算法笔记_什么叫回溯算法,一看就会,一写就废

    什么叫回溯算法 对于回溯算法的定义,百度百科上是这样描述的:回溯算法实际上一个类似枚举的搜索尝试过程,主要是在搜索尝试过程中寻找问题的解,当发现已不满足求解条件时,就"回溯"返回, ...

  9. python中判断无向图是否有环_数据结构与算法:17 图

    17 图 知识结构: 图1 知识结构 1. 图的基本概念与术语 1.1 图的定义 图由顶点集和边集组成,记为 . 顶点集:顶点的有穷非空集合,记为. 边集:顶点偶对的有穷集合,记为 . 边: 无向边: ...

最新文章

  1. c++ 函数指针_开发经验分享(5) 修改Makefile实现C/C++混合编程
  2. 草履虫纳米机器人_Nature:看不见的外科医生——比头发丝还小的微型“机器人大军”正在走来...
  3. Seata RPC 模块的重构之路
  4. 网站SEO优化的方法
  5. .net 连接php,NetBeans平台如何连接到PHP解析器?
  6. postgis启动_PostgreSQL的安装和启动方法大全
  7. .NET Core加解密实战系列之——使用BouncyCastle制作p12(.pfx)数字证书
  8. dotnet pack 打包文件版本号引起 Could not load file or assembly 问题
  9. AtCoder 4169 [ARC100D] Colorful Sequences(dp)
  10. unity2d随机生成物体_2020 年最好用的一键生成设计神器,全在这里了!
  11. linux /etc/group文件详解
  12. 插入移动硬盘_Win10插入移动硬盘或U盘有提示声但电脑中不显示的解决方法
  13. 云搜索服务在APP搜索场景的应用
  14. 版本控制工具(svn)
  15. PSD模版如何变成网页模版 (转载)
  16. oracle12兼容ojdbc6,oracle ojdbc6 使用 报错
  17. 常见计算机英语词汇翻译,常见计算机英语词汇翻译_0.doc
  18. 前端必读:浏览器工作原理
  19. ios13 微信提示音插件_教大家苹果ios13系统怎么改微信提示音的方法
  20. CodeForces - 497D Gears

热门文章

  1. AMD cpu 下 Pytorch 多卡并行卡死问题解决
  2. 基于syslog+logstash+elasticSearch+redis日志分析系统实现
  3. pip install cryptography error
  4. 基础才是重中之重~再说面向接口的编程
  5. PartialView 加载Js
  6. 简单的WINFORM窗体,体验WINFORM带来的快感
  7. Linux安装Nginx使用负载均衡
  8. 【Yaml】Yaml学习笔记
  9. Linux下 Nginx 启动 重启 关闭
  10. UVA - 1587 Box