图方法:二分无向图的联通子图查找
生活随笔
收集整理的這篇文章主要介紹了
图方法:二分无向图的联通子图查找
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
連通域查找使用并行方法,需要對圖片接觸行列進行標簽合并,連通域標簽合并過程可以形式化為一個二分圖。
???????? 二分圖又稱作二部圖,是圖論中的一種特殊模型。 設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;}
總結
以上是生活随笔為你收集整理的图方法:二分无向图的联通子图查找的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 消息称拼多多旗下 TEMU 将在美国开放
- 下一篇: Morse理论:拓扑不变性特征匹配原理