连通域查找使用并行方法,需要对图片接触行列进行标签合并,连通域标签合并过程可以形式化为一个二分图。

二分图又称作二部图,是图论中的一种特殊模型。 设G=(V,E)是一个无向图,如果顶点V可分割为两个互不相交的子集(A,B),并且图中的每条边(i,j)所关联的两个顶点i和j分别属于这两个不同的顶点集(i in A,j in B),则称图G为一个二分图。

寻找二分图的连通子图,用于解决传导等价类问题。

图1  中有两个连通子图

C++代码:

 //输入为二部图的边集合,无重复int findEqualSetBinGraph(std::hash_multimap<int,int>  &equelHashL,std::hash_multimap<int,int>  &equelHashR,std::vector<int>  &vetexL,std::vector<int>  &vetexR,std::vector< std::pair<std::vector<int>,std::vector<int> > >  &equelSet,bool bStack ){//使用堆栈,删除遍历过的边if ( equelHashL.size() >0 ){std::stack<std::pair< int, int > > edgeEs;//使用边堆栈std::stack< int >  pSL,pSR;//左边堆栈std::vector< int >  pVL,pVR;//左右等价集合for ( int i=0; i< vetexL.size();++i){//从左侧开始//遍历过的顶点边的个数为0pVL.resize(0);pVR.resize(0);int VL = vetexL[i];pSL.push(vetexL[i]);pVL.push_back(VL);while ( !pSL.empty() ){VL = pSL.top();auto ptr =equelHashR.find(VL);int C = equelHashR.count(VL);if ( C> 0){auto ptr1 =equelHashR.lower_bound(VL);auto ptr2 =equelHashR.upper_bound(VL);for (int i=0;i<C;++i){pSR.push(ptr1->second);pVR.push_back(ptr1->second);++ptr1;}pSL.pop();//去除掉相连的边equelHashR.erase( VL );//遍历对方的边while ( !pSR.empty() ){int VR = pSR.top();auto ptr =equelHashL.find(VR);int C = equelHashL.count(VR);if ( C > 1 ){auto ptr1 =equelHashL.lower_bound(VR);auto ptr2 =equelHashL.upper_bound(VR);for (int i=0;i<C;++i)//绕过第一个,必须要顺序排列才能使用{if ( ptr1->second != VL ){pSL.push(ptr1->second);pVL.push_back( ptr1->second );//删除右边元素auto ptrR =equelHashR.lower_bound( ptr1->second );for ( int i =0; i< equelHashR.count( ptr1->second ); ++i ){if ( ptrR->second == VR){equelHashR.erase(ptrR);break;}else{++ptrR;}}}++ptr1;}pSR.pop();equelHashL.erase( VR );}else{//删除右边元素int VR = pSR.top();auto ptrR = equelHashL.lower_bound( VR );for ( int i =0; i< equelHashL.count( VR ); ++i ){if ( ptrR->second == VL){equelHashL.erase(ptrR);break;}else{++ptrR;}}pSR.pop();}}} else{pSL.pop();}}if ( pVL.size()>0 && pVR.size()>0 ){equelSet.push_back( std::make_pair( pVL,pVR ) );}}}return 1;}//输入为二部图的边集合,有重复int findEqualSetBinGraph(std::vector< std::pair<int,int>  >  &edgeSet,std::vector< std::pair<std::vector<int>,std::vector<int> > > &equelSet,bool bStack ){//4.2筛选集合//划分等价类//使用查找划分等价类std::vector< std::pair<int,int> > equelLabelL,equelLabelR,equelLabelMin,equelLabelMinMirro;equelLabelL.reserve(edgeSet.size() );//等价集合std::vector< std::pair<std::vector<int>,std::vector<int> > > equelSetL,equelSetR;//,equelSet,;std::map<int,int>  equelMapL,equelMapR;//使用多值哈希//设置重复集合//用于最后合并连通域std::hash_multimap<int,int>  equelHashL,equelHashR;std::vector<int>  vetexL,vetexR;//顶点集合if ( edgeSet.size()>0 ){std::qsort(&edgeSet[0],edgeSet.size(),sizeof(edgeSet[0]) ,cvWish::Operater::cmpPairIntFirst);//使用基数排序//一次合并完成{int idxS =0;int idxE =0;int vL;vL = edgeSet[0].first;for ( idxE ; idxE< edgeSet.size();  ++idxE ){if ( idxE == 0 ){continue;}if ( vL == edgeSet[idxE].first ){}else{vL = edgeSet[idxE].first;std::qsort(&edgeSet[idxS],idxE-idxS,sizeof(edgeSet[0]) ,cvWish::Operater::cmpPairIntSecond );idxS = idxE;}}std::qsort(&edgeSet[idxS],idxE-idxS,sizeof(edgeSet[0]) ,cvWish::Operater::cmpPairIntSecond );}equelLabelMin.reserve( edgeSet.size() );//equelLabelMin.reserve( equelLabelR.size() );{int vL,vR;vL = edgeSet.begin()->first;vR = edgeSet.begin()->second;equelLabelMin.push_back( std::make_pair(vL,vR) );for ( auto ptr = edgeSet.begin(); ptr!= edgeSet.end();  ++ptr){if (ptr == edgeSet.begin()){//跳过第一个continue;}if ( vL == ptr->first && vR == ptr->second){}else{vL = ptr->first;vR = ptr->second;equelLabelMin.push_back(  std::make_pair(vL,vR) );}//vL = ptr->first;//vR = ptr->second;}}for ( auto ptr = equelLabelMin.begin(); ptr!= equelLabelMin.end();  ++ptr){equelHashR.insert( *ptr );equelLabelMinMirro.push_back( std::make_pair( ptr->second,ptr->first ) );}std::qsort(&equelLabelMinMirro[0],equelLabelMinMirro.size(),sizeof(equelLabelMinMirro[0]) ,cvWish::Operater::cmpPairIntFirst );{int idxS =0;int idxE =0;int vL   = equelLabelMinMirro[0].first;for ( idxE ; idxE< equelLabelMinMirro.size();  ++idxE ){if ( idxE == 0 ){continue;}if ( vL == equelLabelMinMirro[idxE].first ){}else{vL = equelLabelMinMirro[idxE].first;std::qsort(&equelLabelMinMirro[idxS],idxE-idxS,sizeof(equelLabelMinMirro[0]) ,cvWish::Operater::cmpPairIntSecond );idxS = idxE;}}std::qsort(&equelLabelMinMirro[idxS],idxE-idxS,sizeof(equelLabelMinMirro[0]) ,cvWish::Operater::cmpPairIntSecond );}for ( auto ptr = equelLabelMinMirro.begin(); ptr!= equelLabelMinMirro.end();  ++ptr){equelHashL.insert(*ptr );//多值hash和多值map都不能剔除重复条目,不应该啊!}bool bStack = true;//4.3 找出顶点集合//暂时不需要,根据所有的边找出顶点vetexL.reserve(equelLabelMin.size());{int vL,vR;vL = equelLabelMin.begin()->first;vetexL.push_back(vL);for (auto ptr = equelLabelMin.begin(); ptr!= equelLabelMin.end();++ptr){if (ptr == equelLabelMin.begin()){//跳过第一个continue;}if ( vL == ptr->first ){}else{vL = ptr->first;vetexL.push_back(vL);}}}vetexR.reserve( equelLabelMinMirro.size() );{int vL,vR;vR = equelLabelMinMirro.begin()->first;vetexR.push_back(vR);for (auto ptr = equelLabelMinMirro.begin(); ptr!= equelLabelMinMirro.end();++ptr){if ( ptr == equelLabelMinMirro.begin()){//跳过第一个continue;}if ( vR == ptr->first ){}else{vR = ptr->first;vetexR.push_back(vR);}}}}//使用堆栈法寻找连通子图//边集合: equelLabelMin,equelLabelMinMirros,但使用equelHashL equelHashR 顶点集合: vetexL,vetexRfindEqualSetBinGraph(equelHashL,equelHashR,vetexL,vetexR,equelSet,bStack );return 1;}

图方法:二分无向图的联通子图查找相关推荐

  1. python 子图_python 实现在一张图中绘制一个小的子图方法

    有时候为了直观展现图的信息,可以在大图中添加小子图的方式进行数据分析,如下图所示: 具体的代码如下:该图连接了数据库,当然重要的不是数据展示,而是添加子图的方法. import matplotlib. ...

  2. python画50个图-python 实现在一张图中绘制一个小的子图方法

    有时候为了直观展现图的信息,可以在大图中添加小子图的方式进行数据分析,如下图所示: 具体的代码如下:该图连接了数据库,当然重要的不是数据展示,而是添加子图的方法. import matplotlib. ...

  3. python画简便的图-python 实现在一张图中绘制一个小的子图方法

    有时候为了直观展现图的信息,可以在大图中添加小子图的方式进行数据分析,如下图所示: 具体的代码如下:该图连接了数据库,当然重要的不是数据展示,而是添加子图的方法. import matplotlib. ...

  4. 查找方法----二分查找

    二分查找又称折半查找,它是一种效率较高的查找方法. [二分查找要求]:1.必须采用顺序存储结构 2.必须按关键字大小有序排列. [优缺点]折半查找法的优点是比较次数少,查找速度快,平均性能好;其缺点是 ...

  5. python一张图-python 实现在一张图中绘制一个小的子图方法

    有时候为了直观展现图的信息,可以在大图中添加小子图的方式进行数据分析,如下图所示: 具体的代码如下:该图连接了数据库,当然重要的不是数据展示,而是添加子图的方法. import matplotlib. ...

  6. 0102数据结构和图处理算法-无向图-数据结构和算法(Java)

    文章目录 1 数据类型 2 图的表示方法 3 无向图的实现 4 图处理算法的设计模式 后记 1 数据类型 要处理各种图的算法,我们首先看一份定义了图的基本操作的API,如下表1-1所示: public ...

  7. 二分图常用建图方法及其性质

    建图方法 https://wenku.baidu.com/view/63c1a01655270722192ef7c3.html 性质 http://dsqiu.iteye.com/blog/16895 ...

  8. java怎么判断mysql中是否存在我们查找的索引_10张图告诉你,MySQL 是如何查找数据的?...

    在我们日常生活中经常会涉及到查找某个东西的场景,就比如说在一个学校里吧,我们想找出个子"最高的10个"同学,或者想查找姓名是"张三"的同学,又或者是查找学号是& ...

  9. 数独游戏技巧从入门到精通_工程施工图识图方法和技巧,使你从建筑施工入门到精通!...

    工程施工图识图方法和技巧,使你从建筑施工入门到精通! 施工图纸是施工和验收的主要依据之一.在项目开工前要求施工人员必须充分领会设计意图.熟悉设计内容.正确施工,确保施工质量, 必须在开工前进行图纸会检 ...

最新文章

  1. 计算机英语缩写AGP,IT行业常用计算机缩略语
  2. 测试ESP32S基本模块的功能,并验证是否可以应用在AI智能车竞赛检测激光信号中
  3. centos6 升级gcc / 无法识别的命令行选项“-std=gnu++1y”的解决办法
  4. Spring @ConfigurationProperties注解使用示例
  5. CodeForces - 1058A. In Search of an Easy Problem
  6. 当HTTP状态代码不足时:处理Web API错误报告
  7. mfc使用cef源代码实现_如何获得微信小游戏跳一跳源码以及源代码组合包括哪些...
  8. Redis 核心技术与实战
  9. 保持稳定迭代的秘密:基于Spinnaker的全自动渐进式交付
  10. Pycharm安装完出现interpreter field is empty
  11. hadoop2.6---常用命令
  12. 《SQL必知必会》附录
  13. Logisim新手入门实验
  14. CS61A 2021Spring Lab: Cats
  15. php px与rem转换,pt 与 px、em、rem 的区别与换算
  16. 关于2022年电改政策的解读
  17. MATLAB2014b安装(Ubuntu 14.10)
  18. 如何将静图制作成动图?教你一招快速合成GIF动图的方法
  19. R语言绘图基础篇-柱状图加误差棒
  20. STM32F4系列定时器简介

热门文章

  1. php课程 6-20 字符串基础和去除空格和字符串填补函数
  2. CentOS 6.9配置网卡IP/网关/DNS命令详细介绍及一些常用网络配置命令(转)
  3. 两种驱动系统运行的方式--分时的方式
  4. 微博预计要火一阵的SleepSort之Shell及C实现
  5. JSP 中EL表达式用法详解
  6. 6.22软件工程总结
  7. struts2的action从request获取参数值的几种方式
  8. android软件中加入广告实现方法
  9. Windows Phone开发(4):框架和页
  10. Oracle索引----位图索引