GraphPreProcessor.cpp 46 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860
  1. #include "GraphPreProcessor.h"
  2. GraphPreProcessor::GraphPreProcessor()
  3. {
  4. }
  5. void GraphPreProcessor::toMaximalPlanar(SubGraph & gInputGraph, EdgeOrderType &oDummyEdges)
  6. {
  7. //CHANGE GRAPH FORMAT--------------------------------------------------------------------------------------
  8. //gInputGraph is a bidirectedS graph, whereas the algorithm to make it maximal planar accepts undirectedS graphs.
  9. //To map our graph to undirected one, we create a local undirected graph and copy the edges and vertices
  10. //in our graph to this local graph; and pass this to the algorithm.
  11. VertexDescriptor descVertexSource, descVertexTarget;
  12. EdgeIterator itrEdge, itrEdgeEnd;
  13. EdgeDescriptor descEdge;
  14. int iVertexSource, iVertexTarget, iNumVertices;
  15. BoostGraphWrapper graphWrapper;
  16. iNumVertices = boost::num_vertices(gInputGraph);
  17. GraphPreProcessor::graph g(iNumVertices); //create a local undirected graph with same no. of vertices
  18. LayoutUtility layoutUtility;
  19. // copy each edge one by one
  20. for(boost::tie(itrEdge, itrEdgeEnd) = edges(gInputGraph); itrEdge != itrEdgeEnd; itrEdge++)
  21. {
  22. descEdge = *itrEdge;
  23. descVertexSource = graphWrapper.getEdgeSource(descEdge, gInputGraph);
  24. descVertexTarget = graphWrapper.getEdgeTarget(descEdge, gInputGraph);
  25. iVertexSource = get(vertex_index, gInputGraph, descVertexSource);
  26. iVertexTarget = get(vertex_index, gInputGraph, descVertexTarget);
  27. add_edge(iVertexSource, iVertexTarget, g);
  28. }
  29. //Initialize the interior edge index
  30. layoutUtility.reinitializeEdgeIndices(g);
  31. //Test for planarity; compute the planar embedding as a side-effect
  32. typedef std::vector< graph_traits<graph>::edge_descriptor > vec_t;
  33. std::vector<vec_t> embedding(num_vertices(g));
  34. if (boyer_myrvold_planarity_test(boyer_myrvold_params::graph = g,
  35. boyer_myrvold_params::embedding = &embedding[0]))
  36. {
  37. //std::cout << "Input graph is planar1" << std::endl;
  38. }
  39. else
  40. {
  41. throw LayoutException("toMaximalPlanar",
  42. LayoutExceptionEnum::INVALID_GRAPH_TYPE,
  43. "inputGraph",
  44. "non-planar");
  45. //std::cout << "Input graph is not planar1" << std::endl;
  46. }
  47. //END------------------------------------------------------------------------------------------------------
  48. //MAKE MAXIMAL PLANAR--------------------------------------------------------------------------------------
  49. make_connected(g);
  50. // Re-initialize the edge index, since we just added a few edges
  51. layoutUtility.reinitializeEdgeIndices(g);
  52. //Test for planarity again; compute the planar embedding as a side-effect
  53. if (boyer_myrvold_planarity_test(boyer_myrvold_params::graph = g,
  54. boyer_myrvold_params::embedding = &embedding[0]))
  55. {
  56. //std::cout << "After calling make_connected, the graph is still planar" << std::endl;
  57. }
  58. else
  59. {
  60. throw LayoutException("toMaximalPlanar",
  61. LayoutExceptionEnum::INVALID_GRAPH_TYPE,
  62. "connectedGraph",
  63. "non-planar");
  64. //std::cout << "After calling make_connected, the graph is not planar" << std::endl;
  65. }
  66. make_biconnected_planar(g, &embedding[0]);
  67. // Re-initialize the edge index, since we just added a few edges
  68. layoutUtility.reinitializeEdgeIndices(g);
  69. //Test for planarity again; compute the planar embedding as a side-effect
  70. if (boyer_myrvold_planarity_test(boyer_myrvold_params::graph = g,
  71. boyer_myrvold_params::embedding = &embedding[0]))
  72. {
  73. //std::cout << "After calling make_biconnected, the graph is still planar" << std::endl;
  74. }
  75. else
  76. {
  77. throw LayoutException("toMaximalPlanar",
  78. LayoutExceptionEnum::INVALID_GRAPH_TYPE,
  79. "biconnectedGraph",
  80. "non-planar");
  81. //std::cout << "After calling make_biconnected, the graph is not planar" << std::endl;
  82. }
  83. make_maximal_planar(g, &embedding[0]);
  84. // Re-initialize the edge index, since we just added a few edges
  85. layoutUtility.reinitializeEdgeIndices(g);
  86. // Test for planarity one final time; compute the planar embedding as a side-effect
  87. if (boyer_myrvold_planarity_test(boyer_myrvold_params::graph = g,
  88. boyer_myrvold_params::embedding = &embedding[0]))
  89. {
  90. //std::cout << "After calling make_maximal_planar, the final graph is planar." << std::endl;
  91. }
  92. else
  93. {
  94. throw LayoutException("toMaximalPlanar",
  95. LayoutExceptionEnum::INVALID_GRAPH_TYPE,
  96. "maxPlanarGraph",
  97. "non-planar");
  98. //std::cout << "is not planar." << std::endl;
  99. }
  100. //END------------------------------------------------------------------------------------------------------
  101. //FIND EXTRA EDGES ADDED--------------------------------------------------------------------------------
  102. //add them to gInputGraph as well, and remember them as dummy edges
  103. graph_traits< graph >::edge_iterator itrUndirEdge, itrUndirEdgeEnd;
  104. graph_traits< graph >::edge_descriptor descUndirEdge;
  105. graph_traits< graph >::vertex_descriptor descUndirVertSource, descUndirVertTarget;
  106. bool bIsEdge;
  107. EdgeBoolPair pairEdgeBoolStoT, pairNewEdge;
  108. BoostGraphWrapper boostGraphWrapper;
  109. //for each edge in g:
  110. for(boost::tie(itrUndirEdge, itrUndirEdgeEnd) = edges(g); itrUndirEdge != itrUndirEdgeEnd; itrUndirEdge++)
  111. {
  112. //get edge descriptor for current edge (in g)
  113. descUndirEdge = *itrUndirEdge;
  114. //get its source and target vertices (in g)
  115. descUndirVertSource = source(descUndirEdge, g);
  116. descUndirVertTarget = target(descUndirEdge, g);
  117. //get indices of source and target (in g)
  118. iVertexSource = get(vertex_index, g, descUndirVertSource);
  119. iVertexTarget = get(vertex_index, g, descUndirVertTarget);
  120. //get corresponding vertices in gInputGraph
  121. descVertexSource = vertex(iVertexSource, gInputGraph);
  122. descVertexTarget = vertex(iVertexTarget, gInputGraph);
  123. //check if there's corresponding edge between these vertices in gInputGraph
  124. pairEdgeBoolStoT = lookup_edge(descVertexSource, descVertexTarget, gInputGraph);
  125. bIsEdge = pairEdgeBoolStoT.second;
  126. if(!bIsEdge)//if there isn't any edge, current edge is a dummy edge
  127. {
  128. //add an edge in gInputGraph
  129. pairNewEdge = boostGraphWrapper.addEdge(descVertexSource, descVertexTarget, gInputGraph);
  130. //remember the added edge
  131. LAYOUT_ASSERT(pairNewEdge.second,
  132. LayoutException("toMaximalPlanar",
  133. LayoutExceptionEnum::INVALID_OPERATION,
  134. "add_edge",
  135. "toMaximalPlanar"));
  136. oDummyEdges.push_back(pairNewEdge.first);
  137. }
  138. }
  139. //Initialize the interior edge index in input graph
  140. layoutUtility.reinitializeEdgeIndices(gInputGraph);
  141. //END------------------------------------------------------------------------------------------------------
  142. }
  143. void GraphPreProcessor::removeDummyEdges(SubGraph & gInputGraph, EdgeOrderType &oDummyEdges)
  144. {
  145. LayoutUtility layoutUtility;
  146. //for each DummyEdge
  147. for(int i = 0; i < oDummyEdges.size(); ++i)
  148. {
  149. //find corresponding edge in gInputGraph
  150. EdgeBoolPair dummyEdgeBool = lookup_edge(source(oDummyEdges[i], gInputGraph),
  151. target(oDummyEdges[i], gInputGraph),
  152. gInputGraph);
  153. //remove it from gInputGraph
  154. if(dummyEdgeBool.second)
  155. {
  156. remove_edge(source(dummyEdgeBool.first, gInputGraph),
  157. target(dummyEdgeBool.first, gInputGraph),
  158. gInputGraph);
  159. }
  160. else
  161. {
  162. throw LayoutException("removeDummyEdges",
  163. LayoutExceptionEnum::NOT_FOUND_IN_CONTAINER,
  164. "graph",
  165. "dummy edge");
  166. }
  167. }
  168. //Initialize the interior edge index in input graph
  169. layoutUtility.reinitializeEdgeIndices(gInputGraph);
  170. }
  171. void GraphPreProcessor::removeParallelEdges(SubGraph &gInputGraph, EdgeOrderType &oParallelEdgeList, std::vector<QString> & oParrallelEdgeIDs)
  172. {
  173. //std::vector<QString> oParrallelEdgeIDs;
  174. LayoutUtility layoutUtility;
  175. BoostGraphWrapper bGraphWrapper;
  176. int iNumVertices = boost::num_vertices(gInputGraph);
  177. GraphPreProcessor::graph gLocalGraph(iNumVertices);
  178. //for each edge in input graph
  179. EdgeIterator itrEdge, itrEdgeEnd;
  180. for(boost::tie(itrEdge, itrEdgeEnd) = edges(gInputGraph); itrEdge != itrEdgeEnd; ++itrEdge)
  181. {
  182. //get its endpoints in local graph
  183. graph_traits<graph>::vertex_descriptor vLocalSource, vLocalTarget;
  184. vLocalSource = vertex(get(vertex_index,
  185. gInputGraph,
  186. source(*itrEdge, gInputGraph)),
  187. gLocalGraph);
  188. vLocalTarget = vertex(get(vertex_index,
  189. gInputGraph,
  190. target(*itrEdge, gInputGraph)),
  191. gLocalGraph);
  192. //check if the edge already exists in local graph
  193. bool bIsInLocalG = (lookup_edge(vLocalSource, vLocalTarget, gLocalGraph).second
  194. || lookup_edge(vLocalTarget, vLocalSource, gLocalGraph).second);
  195. if(!bIsInLocalG) //if doesnot exist in local graph
  196. {
  197. //add it to local graph
  198. LAYOUT_ASSERT(add_edge(vLocalSource, vLocalTarget, gLocalGraph).second,
  199. LayoutException("removeParallelEdges",
  200. LayoutExceptionEnum::INVALID_OPERATION,
  201. "add_edge",
  202. "removeParallelEdges"));
  203. //re-initialize edge indices
  204. layoutUtility.reinitializeEdgeIndices(gLocalGraph);
  205. }
  206. else //if already exists in local graph
  207. {
  208. //remember it as a parallel edge
  209. EdgeDescriptor eParallelEdge = *itrEdge;
  210. oParallelEdgeList.push_back(eParallelEdge);
  211. QString sEdheID = bGraphWrapper.getEdgeId(eParallelEdge, gInputGraph);
  212. oParrallelEdgeIDs.push_back(sEdheID);
  213. }
  214. }
  215. //for each parallel edge
  216. for(int iEdgeIndex = 0; iEdgeIndex < oParallelEdgeList.size(); ++iEdgeIndex)
  217. {
  218. //remove it
  219. remove_edge(oParallelEdgeList[iEdgeIndex], gInputGraph);
  220. }
  221. //re-initiate edge indices
  222. layoutUtility.reinitializeEdgeIndices(gInputGraph);
  223. }
  224. void GraphPreProcessor::toPlanar(SubGraph & gInputGraph, VertexOrderType &oDummyVertexList,
  225. std::vector<GraphPreProcessor::EdgePairType> & correspondingCrossingEdgeList)
  226. {
  227. int iNumVertices = boost::num_vertices(gInputGraph);
  228. int iNumEdges = boost::num_edges(gInputGraph);
  229. GraphPreProcessor::graph gLocalGraph(iNumVertices);
  230. std::vector< graph_traits< graph >::edge_descriptor > localCrossingEdgeList;
  231. //separate out the crossing edges from the graph
  232. this->findCrossingEdges(gInputGraph, gLocalGraph, localCrossingEdgeList);
  233. int iNumLocalEdges = boost::num_edges(gLocalGraph);
  234. LAYOUT_ASSERT((localCrossingEdgeList.size() + iNumLocalEdges) == iNumEdges,
  235. LayoutException("toPlanar",
  236. LayoutExceptionEnum::INCONSISTENT_DATASTRUCTURE,
  237. "localCrossingEdgeList",
  238. "gLocalGraph"));
  239. //replace each crossing by a dummy vertex
  240. this->replaceCrossingsByDummyVertices(gInputGraph, gLocalGraph, localCrossingEdgeList,
  241. oDummyVertexList, correspondingCrossingEdgeList);
  242. LAYOUT_ASSERT(oDummyVertexList.size() == correspondingCrossingEdgeList.size(),
  243. LayoutException("toPlanar",
  244. LayoutExceptionEnum::INCONSISTENT_DATASTRUCTURE,
  245. "DummyVertices",
  246. "CorrespondingEdges"));
  247. }
  248. void GraphPreProcessor::findCrossingEdges(SubGraph & gInputGraph, GraphPreProcessor::graph & gLocalGraph,
  249. std::vector< graph_traits< graph >::edge_descriptor > & localCrossingEdgeList)
  250. {
  251. LayoutUtility layoutUtility;
  252. //for each edge in input graph
  253. EdgeIterator itrEdge, itrEdgeEnd;
  254. for(boost::tie(itrEdge, itrEdgeEnd) = edges(gInputGraph); itrEdge != itrEdgeEnd; ++itrEdge)
  255. {
  256. graph_traits<graph>::vertex_descriptor vLocalSource, vLocalTarget;
  257. vLocalSource = vertex(get(vertex_index, gInputGraph, source(*itrEdge, gInputGraph)),
  258. gLocalGraph);
  259. vLocalTarget = vertex(get(vertex_index, gInputGraph, target(*itrEdge, gInputGraph)),
  260. gLocalGraph);
  261. //add it to local graph
  262. add_edge(vLocalSource, vLocalTarget, gLocalGraph);
  263. //re-initialize edge indices
  264. layoutUtility.reinitializeEdgeIndices(gLocalGraph);
  265. //check planarity
  266. typedef std::vector< graph_traits<graph>::edge_descriptor > vec_t;
  267. std::vector<vec_t> embedding(num_vertices(gLocalGraph));
  268. bool bIsPlanar = boyer_myrvold_planarity_test(boyer_myrvold_params::graph = gLocalGraph,
  269. boyer_myrvold_params::embedding = &embedding[0]);
  270. if(!bIsPlanar) //if graph looses planarity due to added edge
  271. {
  272. LAYOUT_ASSERT(lookup_edge(vLocalSource, vLocalTarget, gLocalGraph).second,
  273. LayoutException("findCrossingEdges",
  274. LayoutExceptionEnum::NOT_FOUND_IN_CONTAINER,
  275. "LocalGraph",
  276. "crossing edge"));
  277. //remember it as crossing edge
  278. graph_traits<graph>::edge_descriptor eLocalCrossingEdge;
  279. eLocalCrossingEdge = lookup_edge(vLocalSource, vLocalTarget, gLocalGraph).first;
  280. localCrossingEdgeList.push_back(eLocalCrossingEdge);
  281. //remove it
  282. remove_edge(vLocalSource, vLocalTarget, gLocalGraph);
  283. //re-initialize edge indices
  284. layoutUtility.reinitializeEdgeIndices(gLocalGraph);
  285. }
  286. //else if planar, continue adding edges to local graph
  287. }
  288. }
  289. void GraphPreProcessor::replaceCrossingsByDummyVertices(SubGraph & gInputGraph, GraphPreProcessor::graph & gLocalGraph,
  290. std::vector< graph_traits< graph >::edge_descriptor > & localCrossingEdgeList,
  291. VertexOrderType &oDummyVertexList,
  292. std::vector<GraphPreProcessor::EdgePairType> & correspondingCrossingEdgeList)
  293. {
  294. LayoutUtility layoutUtility;
  295. //for each crossing edge
  296. for(int iCrossingEdgeIndex = 0; iCrossingEdgeIndex < localCrossingEdgeList.size(); ++iCrossingEdgeIndex)
  297. {
  298. //get its src and tgt and their indices in local graph
  299. graph_traits<SubGraph>::vertex_descriptor vSourceOfLocalCrossingEdge, vTargetOfLocalCrossingEdge;
  300. vSourceOfLocalCrossingEdge = source(localCrossingEdgeList[iCrossingEdgeIndex], gLocalGraph);
  301. vTargetOfLocalCrossingEdge = target(localCrossingEdgeList[iCrossingEdgeIndex], gLocalGraph);
  302. int iIndexOfSourceOfCrossingEdge = get(vertex_index, gLocalGraph, vSourceOfLocalCrossingEdge);
  303. int iIndexOfTargetOfCrossingEdge = get(vertex_index, gLocalGraph, vTargetOfLocalCrossingEdge);
  304. //get corresponding src and tgt in input graph
  305. VertexDescriptor vSourceOfCrossingEdge, vTargetOfCrossingEdge;
  306. vSourceOfCrossingEdge = vertex(iIndexOfSourceOfCrossingEdge, gInputGraph);
  307. vTargetOfCrossingEdge = vertex(iIndexOfTargetOfCrossingEdge, gInputGraph);
  308. //find augmented dual graph of local graph------------------------------------------------------------
  309. GraphPreProcessor::graph gDualGraph;
  310. UndirEdgeOrderType dualEdge(boost::num_edges(gLocalGraph));
  311. std::vector< graph_traits<GraphPreProcessor::graph>::vertex_descriptor > oAugmentedVertices(2);
  312. std::vector< int > oIndicesOfEndsOfCrossingEdge(2);
  313. oIndicesOfEndsOfCrossingEdge[0] = iIndexOfSourceOfCrossingEdge;
  314. oIndicesOfEndsOfCrossingEdge[1] = iIndexOfTargetOfCrossingEdge;
  315. this->createAugmentedDualGraph(gLocalGraph, gDualGraph, dualEdge,
  316. oIndicesOfEndsOfCrossingEdge,
  317. oAugmentedVertices);
  318. graph_traits<GraphPreProcessor::graph>::vertex_descriptor vAugmentedSource, vAugmentedTarget;
  319. vAugmentedSource = oAugmentedVertices[0];
  320. vAugmentedTarget = oAugmentedVertices[1];
  321. //----------------------------------------------------------------------------------------------------
  322. //find shortest path----------------------------------------------------------------------------------
  323. GraphPreProcessor::dijkstra_graph gDijkstraGraph(num_vertices(gDualGraph));
  324. std::vector<GraphPreProcessor::dijkstra_vertex_descriptor> path;
  325. this->findShortestPath(gDualGraph, gDijkstraGraph, vAugmentedSource, vAugmentedTarget, path);
  326. //---------------------------------------------------------------------------------------------------
  327. //Replace edge crossings along the shortest path by dummy vertices-----------------------------------
  328. graph_traits<graph>::vertex_descriptor vRecentlyAddedLocalVertex = vSourceOfLocalCrossingEdge;
  329. VertexDescriptor vRecentlyAddedVertex = vSourceOfCrossingEdge;
  330. LAYOUT_ASSERT(path.size() > 3,
  331. LayoutException("replaceCrossingsByDummyVertices",
  332. LayoutExceptionEnum::INCONSISTENT_DATASTRUCTURE,
  333. "shortest path",
  334. "in dual graph"));
  335. //for each dual edge in the shortest path
  336. for(int iPathIndex = 1; iPathIndex <= path.size() - 3; ++iPathIndex)
  337. {
  338. //this dual edge ( path[iPathIndex]-path[iPathIndex+1] ) represents a crossing
  339. //find edge in local graph corresponding to this dual edge (call it 'vertical edge')-------------
  340. graph_traits<graph>::vertex_descriptor vSourceOfDualEdge, vTargetOfDualEdge;
  341. //find vertices in (aug)dual draph, corresponding to path[i] and path[i+1] in gDijkstraGraph
  342. int iSourceIndexOfDualEdgeInPath = get(vertex_index, gDijkstraGraph, path[iPathIndex]);
  343. vSourceOfDualEdge = vertex(iSourceIndexOfDualEdgeInPath, gDualGraph);
  344. int iTargetIndexOfDualEdgeInPath = get(vertex_index, gDijkstraGraph, path[iPathIndex + 1]);
  345. vTargetOfDualEdge = vertex(iTargetIndexOfDualEdgeInPath, gDualGraph);
  346. //find edge between these vertices in (aug)dual graph
  347. graph_traits<graph>::edge_descriptor eDualEdge;
  348. if(lookup_edge(vSourceOfDualEdge, vTargetOfDualEdge, gDualGraph).second)
  349. eDualEdge = lookup_edge(vSourceOfDualEdge, vTargetOfDualEdge, gDualGraph).first;
  350. else if(lookup_edge(vTargetOfDualEdge, vSourceOfDualEdge, gDualGraph).second)
  351. eDualEdge = lookup_edge(vTargetOfDualEdge, vSourceOfDualEdge, gDualGraph).first;
  352. //find its corresponding edge in local graph
  353. graph_traits<graph>::edge_descriptor eLocalVerticalEdge;
  354. int iDualEdgeIndex = get(edge_index, gDualGraph, eDualEdge);
  355. LAYOUT_ASSERT(iDualEdgeIndex < dualEdge.size(),
  356. LayoutException("replaceCrossingsByDummyVertices",
  357. LayoutExceptionEnum::INCONSISTENT_DATASTRUCTURE,
  358. "dualEdge",
  359. "index out of bound"));
  360. eLocalVerticalEdge = dualEdge[iDualEdgeIndex];
  361. //find vertical edge's endpoints in local graph
  362. graph_traits<graph>::vertex_descriptor vSourceOfLocalVerticalEdge, vTargetOfLocalVerticalEdge;
  363. vSourceOfLocalVerticalEdge = source(eLocalVerticalEdge, gLocalGraph);
  364. vTargetOfLocalVerticalEdge = target(eLocalVerticalEdge, gLocalGraph);
  365. //find vertical edge's endpoints in input graph
  366. VertexDescriptor vSourceOfVerticalEdge, vTargetOfVerticalEdge;
  367. int iIndexOfSourceOfLocalVerticalEdge = get(vertex_index, gLocalGraph, vSourceOfLocalVerticalEdge);
  368. vSourceOfVerticalEdge = vertex(iIndexOfSourceOfLocalVerticalEdge, gInputGraph);
  369. int iIndexOfTargetOfLocalVerticalEdge = get(vertex_index, gLocalGraph, vTargetOfLocalVerticalEdge);
  370. vTargetOfVerticalEdge = vertex(iIndexOfTargetOfLocalVerticalEdge, gInputGraph);
  371. //-----------------------------------------------------------------------------------------------
  372. //Replace the crossing edges by dummy vertex-----------------------------------------------------
  373. //IN INPUT GRAPH:
  374. //add new (dummy) vertex
  375. VertexDescriptor vNewVertex = add_vertex(gInputGraph);
  376. oDummyVertexList.push_back(vNewVertex);
  377. //join new vertex to ends of vertical edge
  378. add_edge(vSourceOfVerticalEdge, vNewVertex, gInputGraph);
  379. add_edge(vNewVertex, vTargetOfVerticalEdge, gInputGraph);
  380. //remove vertical edge
  381. remove_edge(vSourceOfVerticalEdge, vTargetOfVerticalEdge, gInputGraph);
  382. remove_edge(vTargetOfVerticalEdge, vSourceOfVerticalEdge, gInputGraph);
  383. //join recent vertex to new vertex
  384. add_edge(vRecentlyAddedVertex, vNewVertex, gInputGraph);
  385. //remember crossing which is being replaced by vertex
  386. GraphPreProcessor::EdgePairType crossingEdgePair (2, std::vector<VertexDescriptor>(2));
  387. crossingEdgePair[0][0] = vSourceOfCrossingEdge;
  388. crossingEdgePair[0][1] = vTargetOfCrossingEdge;
  389. crossingEdgePair[1][0] = vSourceOfVerticalEdge;
  390. crossingEdgePair[1][1] = vTargetOfVerticalEdge;
  391. correspondingCrossingEdgeList.push_back(crossingEdgePair);
  392. //new vertex becomes recent vertex
  393. vRecentlyAddedVertex = vNewVertex;
  394. //IN LOCAL GRAPH:
  395. //add new vert
  396. graph_traits<graph>::vertex_descriptor vNewLocalVertex = add_vertex(gLocalGraph);
  397. //join new vertex to ends of vertical edge
  398. add_edge(vSourceOfLocalVerticalEdge, vNewLocalVertex, gLocalGraph);
  399. add_edge(vNewLocalVertex, vTargetOfLocalVerticalEdge, gLocalGraph);
  400. //remove vertical edge
  401. remove_edge(vSourceOfLocalVerticalEdge, vTargetOfLocalVerticalEdge, gLocalGraph);
  402. remove_edge(vTargetOfLocalVerticalEdge, vSourceOfLocalVerticalEdge, gLocalGraph);
  403. //join recent vertex to new vertex
  404. add_edge(vRecentlyAddedLocalVertex, vNewLocalVertex, gLocalGraph);
  405. //new vertex becomes recent vertex
  406. vRecentlyAddedLocalVertex = vNewLocalVertex;
  407. //-----------------------------------------------------------------------------------------------
  408. }
  409. //connect the last dummy vertex----------------------------------------------------------------------
  410. //IN INPUT GRAPH:
  411. //join recent and target of horizontal edge
  412. add_edge(vRecentlyAddedVertex, vTargetOfCrossingEdge, gInputGraph);
  413. //remove crossing (horizontal) edge
  414. remove_edge(vSourceOfCrossingEdge, vTargetOfCrossingEdge, gInputGraph);
  415. remove_edge(vTargetOfCrossingEdge, vSourceOfCrossingEdge, gInputGraph);
  416. //re-initiate edge indices
  417. layoutUtility.reinitializeEdgeIndices(gInputGraph);
  418. //IN LOCAL GRAPH:
  419. //join recent and target of horizontal edge
  420. add_edge(vRecentlyAddedLocalVertex, vTargetOfLocalCrossingEdge, gLocalGraph);
  421. //re-initialize edge indices
  422. layoutUtility.reinitializeEdgeIndices(gLocalGraph);
  423. //---------------------------------------------------------------------------------------------------
  424. //---------------------------------------------------------------------------------------------------
  425. }
  426. }
  427. void GraphPreProcessor::createAugmentedDualGraph(GraphPreProcessor::graph & gLocalGraph,
  428. GraphPreProcessor::graph & gDualGraph,
  429. UndirEdgeOrderType & dualEdge,
  430. std::vector< int > & oIndicesOfEndsOfCrossingEdge,
  431. std::vector< graph_traits<GraphPreProcessor::graph>::vertex_descriptor > & oAugmentedVertices)
  432. {
  433. LayoutUtility layoutUtility;
  434. //find dual graph of local graph-------------------------------------------------------------------
  435. std::vector< UndirVertexOrderType > adjecentFace(boost::num_vertices(gLocalGraph));
  436. // Compute the planar embedding - we know the input graph is planar,
  437. // so we're ignoring the return value of the test
  438. typedef std::vector< graph_traits<graph>::edge_descriptor > vec_t;
  439. std::vector<vec_t> embedding(num_vertices(gLocalGraph));
  440. boyer_myrvold_planarity_test(boyer_myrvold_params::graph = gLocalGraph,
  441. boyer_myrvold_params::embedding = &embedding[0]);
  442. create_dual_graph(gLocalGraph, gDualGraph, &embedding[0], adjecentFace, dualEdge);
  443. //-------------------------------------------------------------------------------------------------
  444. //find augmented dual graph------------------------------------------------------------------------
  445. //add source and target of the crossing-edge to dual graph
  446. oAugmentedVertices[0] = add_vertex(gDualGraph);
  447. oAugmentedVertices[1] = add_vertex(gDualGraph);
  448. //connect these src and tgt to their adjecent faces
  449. //for all of source's adjecent faces
  450. LAYOUT_ASSERT(oIndicesOfEndsOfCrossingEdge[0] < adjecentFace.size(),
  451. LayoutException("createAugmentedDualGraph",
  452. LayoutExceptionEnum::INVALID_ATTRIBUTE_VALUE,
  453. "adjecentFace",
  454. "index out of Bound")); //adjecentFace[oIndicesOfEndsOfCrossingEdge[0]] not Null
  455. LAYOUT_ASSERT(adjecentFace[oIndicesOfEndsOfCrossingEdge[0]].size() > 0,
  456. LayoutException("createAugmentedDualGraph",
  457. LayoutExceptionEnum::EMPTY_CONTAINER,
  458. "adjecentFace[source]",
  459. "adjecentFace of aug.source")); //adjecentFace[oIndicesOfEndsOfCrossingEdge[0]].size() > 0
  460. for(int iFaceIndex = 0; iFaceIndex < adjecentFace[oIndicesOfEndsOfCrossingEdge[0]].size(); ++iFaceIndex)
  461. {
  462. //if src not already connected to adjecent face
  463. if(!(lookup_edge(oAugmentedVertices[0], adjecentFace[oIndicesOfEndsOfCrossingEdge[0]][iFaceIndex], gDualGraph).second
  464. || lookup_edge(adjecentFace[oIndicesOfEndsOfCrossingEdge[0]][iFaceIndex], oAugmentedVertices[0], gDualGraph).second))
  465. {
  466. //add edge to dual graph
  467. add_edge(oAugmentedVertices[0], adjecentFace[oIndicesOfEndsOfCrossingEdge[0]][iFaceIndex], gDualGraph);
  468. }
  469. //else continue
  470. }
  471. //for all of target's adjecent faces
  472. LAYOUT_ASSERT(oIndicesOfEndsOfCrossingEdge[1] < adjecentFace.size(),
  473. LayoutException("createAugmentedDualGraph",
  474. LayoutExceptionEnum::INVALID_ATTRIBUTE_VALUE,
  475. "adjecentFace",
  476. "index out of Bound")); //adjecentFace[oIndicesOfEndsOfCrossingEdge[1]] not Null
  477. LAYOUT_ASSERT(adjecentFace[oIndicesOfEndsOfCrossingEdge[1]].size() > 0,
  478. LayoutException("createAugmentedDualGraph",
  479. LayoutExceptionEnum::EMPTY_CONTAINER,
  480. "adjecentFace[target]",
  481. "adjecentFace of aug.target")); //adjecentFace[oIndicesOfEndsOfCrossingEdge[1]].size() > 0
  482. for(int iFaceIndex = 0; iFaceIndex < adjecentFace[oIndicesOfEndsOfCrossingEdge[1]].size(); ++iFaceIndex)
  483. {
  484. //if tgt not already connected to adjecent face
  485. if(!(lookup_edge(oAugmentedVertices[1], adjecentFace[oIndicesOfEndsOfCrossingEdge[1]][iFaceIndex], gDualGraph).second
  486. || lookup_edge(adjecentFace[oIndicesOfEndsOfCrossingEdge[1]][iFaceIndex], oAugmentedVertices[1], gDualGraph).second))
  487. {
  488. //add edge to dual graph
  489. add_edge(oAugmentedVertices[1], adjecentFace[oIndicesOfEndsOfCrossingEdge[1]][iFaceIndex], gDualGraph);
  490. }
  491. //else continue
  492. }
  493. //re-initialize edge indices
  494. layoutUtility.reinitializeEdgeIndices(gDualGraph);
  495. //---------------------------------------------------------------------------------------------------
  496. }
  497. void GraphPreProcessor::findShortestPath(GraphPreProcessor::graph & gDualGraph,
  498. GraphPreProcessor::dijkstra_graph & gDijkstraGraph,
  499. graph_traits<GraphPreProcessor::graph>::vertex_descriptor & vAugmentedSource,
  500. graph_traits<GraphPreProcessor::graph>::vertex_descriptor & vAugmentedTarget,
  501. std::vector<GraphPreProcessor::dijkstra_vertex_descriptor> & path)
  502. {
  503. LayoutUtility layoutUtility;
  504. //create a copy of the augmented dual graph with edge weights set to '1'------------------------------------
  505. //for each edge in (augmented)dual graph
  506. graph_traits< GraphPreProcessor::graph >::edge_iterator itrDualGraphEdge, itrDualGraphEdgeEnd;
  507. for(boost::tie(itrDualGraphEdge, itrDualGraphEdgeEnd) = edges(gDualGraph); itrDualGraphEdge != itrDualGraphEdgeEnd; ++itrDualGraphEdge)
  508. {
  509. //get src and tgt of the edge
  510. graph_traits< GraphPreProcessor::graph >::vertex_descriptor vSourceOfDualEdge, vTargetOfDualEdge;
  511. vSourceOfDualEdge = source(*itrDualGraphEdge, gDualGraph);
  512. vTargetOfDualEdge = target(*itrDualGraphEdge, gDualGraph);
  513. int iIndexOfSourceOfDualEdge = get(vertex_index, gDualGraph, vSourceOfDualEdge);
  514. int iIndexOfTargetOfDualEdge = get(vertex_index, gDualGraph, vTargetOfDualEdge);
  515. //get corresponding src and tgt in dijkstra graph
  516. graph_traits< GraphPreProcessor::dijkstra_graph >::vertex_descriptor vSourceOfDualEdgeInDijkstra, vTargetOfDualEdgeInDijkstra;
  517. vSourceOfDualEdgeInDijkstra = vertex(iIndexOfSourceOfDualEdge, gDijkstraGraph);
  518. vTargetOfDualEdgeInDijkstra = vertex(iIndexOfTargetOfDualEdge, gDijkstraGraph);
  519. //add edge in dijkstra graph
  520. add_edge(vSourceOfDualEdgeInDijkstra, vTargetOfDualEdgeInDijkstra, 1, gDijkstraGraph);
  521. }
  522. //Initialize the interior edge index
  523. layoutUtility.reinitializeEdgeIndices(gDijkstraGraph);
  524. //----------------------------------------------------------------------------------------------------------
  525. //find vertices in gDijkstraGraph, corresponding to vAugmentedSource and vAugmentedTarget
  526. GraphPreProcessor::dijkstra_vertex_descriptor vDijkstraSource, vDijkstraTarget;
  527. int iIndexOfAugmentedSource = get(vertex_index, gDualGraph, vAugmentedSource);
  528. vDijkstraSource = vertex(iIndexOfAugmentedSource, gDijkstraGraph);
  529. int iIndexOfAugmentedTarget = get(vertex_index, gDualGraph, vAugmentedTarget);
  530. vDijkstraTarget = vertex(iIndexOfAugmentedTarget, gDijkstraGraph);
  531. //call Dijkstra's single source shortest path algorithm-----------------------------------------------------
  532. //it will calculate distances and preceding vertex of each vertex, in the shortest path from the source
  533. std::vector<GraphPreProcessor::dijkstra_vertex_descriptor> p(num_vertices(gDijkstraGraph)); //to maintatin parent of each vertex in Dijkstra traversal
  534. std::vector<int> d(num_vertices(gDijkstraGraph)); //to maintatin distance of each vertex from source in Dijkstra traversal
  535. dijkstra_shortest_paths(gDijkstraGraph,
  536. vDijkstraSource,
  537. predecessor_map(boost::make_iterator_property_map(p.begin(),
  538. get(boost::vertex_index,
  539. gDijkstraGraph))).distance_map(boost::make_iterator_property_map(d.begin(),
  540. get(boost::vertex_index,
  541. gDijkstraGraph))));
  542. //find path from src to tgt
  543. this->findPath(vDijkstraTarget, path, p); //finds path in reverse(target to source) in Dijkstra graph
  544. std::reverse(path.begin(), path.end());
  545. LAYOUT_ASSERT(path[0] == vDijkstraSource & path[path.size() - 1] == vDijkstraTarget,
  546. LayoutException("findShortestPath",
  547. LayoutExceptionEnum::NOT_FOUND_IN_CONTAINER,
  548. "shortest path",
  549. "aug. source/target")); //path is from source to target
  550. //----------------------------------------------------------------------------------------------------------
  551. }
  552. void GraphPreProcessor::findPath(GraphPreProcessor::dijkstra_vertex_descriptor &vTarget,
  553. std::vector<GraphPreProcessor::dijkstra_vertex_descriptor> &myPath,
  554. std::vector<GraphPreProcessor::dijkstra_vertex_descriptor> &parentVertex)
  555. {
  556. LAYOUT_ASSERT(vTarget < parentVertex.size(),
  557. LayoutException("findPath",
  558. LayoutExceptionEnum::INVALID_ATTRIBUTE_VALUE,
  559. "parentVertex",
  560. "index out of bound")); //parentVertex[vTarget] not NULL
  561. if(parentVertex[vTarget] == vTarget)
  562. {
  563. myPath.push_back(vTarget);
  564. return;
  565. }
  566. else
  567. {
  568. myPath.push_back(vTarget);
  569. findPath(parentVertex[vTarget], myPath, parentVertex);
  570. return;
  571. }
  572. }
  573. void GraphPreProcessor::addParallelEdges(SubGraph &gInputGraph, EdgeOrderType &oParallelEdgeList, std::vector<QString> & oParrallelEdgeIDs)
  574. {
  575. BoostGraphWrapper boostGraphWrapper;
  576. //for each parallel edge, add it to graph
  577. for(int iParallelEdgeIndex = 0; iParallelEdgeIndex < oParallelEdgeList.size(); ++iParallelEdgeIndex)
  578. {
  579. VertexDescriptor vSourceOfParallelEdge, vTargetOfParallelEdge;
  580. vSourceOfParallelEdge = source(oParallelEdgeList[iParallelEdgeIndex], gInputGraph);
  581. vTargetOfParallelEdge = target(oParallelEdgeList[iParallelEdgeIndex], gInputGraph);
  582. QString sEdgeID = oParrallelEdgeIDs[iParallelEdgeIndex];
  583. EdgeBoolPair pEdgeBool = add_edge(vSourceOfParallelEdge, vTargetOfParallelEdge, gInputGraph);
  584. LAYOUT_ASSERT(pEdgeBool.second,
  585. LayoutException("addParallelEdges",
  586. LayoutExceptionEnum::INVALID_OPERATION,
  587. "add_edge",
  588. "addParallelEdges"));
  589. boostGraphWrapper.setEdgeId(pEdgeBool.first, gInputGraph, sEdgeID);
  590. }
  591. //reinitialize edge index
  592. LayoutUtility layoutUtility;
  593. layoutUtility.reinitializeEdgeIndices(gInputGraph);
  594. }
  595. void GraphPreProcessor::removeDummyVertices(SubGraph & gInputGraph, VertexOrderType &oDummyVertices,
  596. std::vector<GraphPreProcessor::EdgePairType> & correspondingCrossingEdge)
  597. {
  598. //for each dummy vertex (in reverse order of insertion)
  599. for(int iDummyVertexIndex = oDummyVertices.size() - 1; iDummyVertexIndex >= 0; --iDummyVertexIndex)
  600. {
  601. std::vector<EdgeDescriptor> oEdgesToBeRemoved;
  602. //remove all edges incident on current dummy vertex-----------------------------------------------------
  603. //for each edge in InputGraph
  604. EdgeIterator itrEdge, itrEdgeEnd;
  605. for(boost::tie(itrEdge, itrEdgeEnd)=edges(gInputGraph); itrEdge != itrEdgeEnd; ++itrEdge)
  606. {
  607. //if it has dummy vertex as end-point
  608. if(source(*itrEdge, gInputGraph) == oDummyVertices[iDummyVertexIndex]
  609. || target(*itrEdge, gInputGraph) == oDummyVertices[iDummyVertexIndex])
  610. {
  611. //remember it as ToBeRemoved
  612. oEdgesToBeRemoved.push_back(*itrEdge);
  613. }
  614. //else continue
  615. }
  616. //for each edge ToBeRemoved
  617. for(int iEdgeIndex = 0; iEdgeIndex < oEdgesToBeRemoved.size(); ++iEdgeIndex)
  618. {
  619. VertexDescriptor vSourceOfEdgeToBeRemoved, vTargetOfEdgeToBeRemoved;
  620. vSourceOfEdgeToBeRemoved = source(oEdgesToBeRemoved[iEdgeIndex], gInputGraph);
  621. vTargetOfEdgeToBeRemoved = target(oEdgesToBeRemoved[iEdgeIndex], gInputGraph);
  622. //remove edge
  623. remove_edge(vSourceOfEdgeToBeRemoved, vTargetOfEdgeToBeRemoved, gInputGraph);
  624. remove_edge(vTargetOfEdgeToBeRemoved, vSourceOfEdgeToBeRemoved, gInputGraph);
  625. }
  626. //------------------------------------------------------------------------------------------------------
  627. //add the corresponding crossing edges back-------------------------------------------------------------
  628. //for each crossing-edge corresponding to current dummy vrtex
  629. LAYOUT_ASSERT(iDummyVertexIndex < correspondingCrossingEdge.size(),
  630. LayoutException("removeDummyVertices",
  631. LayoutExceptionEnum::INCONSISTENT_DATASTRUCTURE,
  632. "correspondingCrossingEdge",
  633. "index out of bound"));
  634. LAYOUT_ASSERT(correspondingCrossingEdge[iDummyVertexIndex].size() == 2,
  635. LayoutException("removeDummyVertices",
  636. LayoutExceptionEnum::INCONSISTENT_DATASTRUCTURE,
  637. "correspondingCrossingEdges for dummyVertex",
  638. "index out of bound"));
  639. for(int iCrossingEdgeIndex = 0; iCrossingEdgeIndex < correspondingCrossingEdge[iDummyVertexIndex].size(); ++iCrossingEdgeIndex)
  640. {
  641. LAYOUT_ASSERT(correspondingCrossingEdge[iDummyVertexIndex][iCrossingEdgeIndex].size() == 2,
  642. LayoutException("removeDummyVertices",
  643. LayoutExceptionEnum::INCONSISTENT_DATASTRUCTURE,
  644. "endPoints of correspondingCrossingEdge for dummyVertex",
  645. "index out of bound"));
  646. //get its src and tgt
  647. VertexDescriptor vSourceOfCrossingEdge, vTargetOfCrossingEdge;
  648. vSourceOfCrossingEdge = correspondingCrossingEdge[iDummyVertexIndex][iCrossingEdgeIndex][0];
  649. vTargetOfCrossingEdge = correspondingCrossingEdge[iDummyVertexIndex][iCrossingEdgeIndex][1];
  650. //if not already added to InputGraph
  651. if(!(lookup_edge(vSourceOfCrossingEdge, vTargetOfCrossingEdge, gInputGraph).second
  652. || lookup_edge(vTargetOfCrossingEdge, vSourceOfCrossingEdge, gInputGraph).second))
  653. {
  654. //add edge
  655. LAYOUT_ASSERT(add_edge(vSourceOfCrossingEdge, vTargetOfCrossingEdge, gInputGraph).second,
  656. LayoutException("removeDummyVertices",
  657. LayoutExceptionEnum::INVALID_OPERATION,
  658. "add_edge",
  659. "removeDummyVertices"));
  660. }
  661. //else continue
  662. }
  663. //-----------------------------------------------------------------------------------------------------
  664. //reinitialize edge index
  665. LayoutUtility layoutUtility;
  666. layoutUtility.reinitializeEdgeIndices(gInputGraph);
  667. //set dummy vertex invisible
  668. BoostGraphWrapper boostGraphWrapper;
  669. boostGraphWrapper.setVertexIsInvisible(oDummyVertices[iDummyVertexIndex], gInputGraph, true);
  670. }
  671. }
  672. void GraphPreProcessor::toPlanarAlternate(SubGraph &gInputGraph, EdgeOrderType &oNonPlanarEdges)
  673. {
  674. VertexDescriptor descVertexSource, descVertexTarget, vNewInputGraphVertex;
  675. EdgeIterator itrEdge, itrEdgeEnd;
  676. EdgeDescriptor descEdge;
  677. int iVertexSource, iVertexTarget, iNumVertices;
  678. BoostGraphWrapper graphWrapper;
  679. iNumVertices = boost::num_vertices(gInputGraph);
  680. GraphPreProcessor::graph gLacalGraph(iNumVertices); //create a local undirected graph with same no. of vertices
  681. std::vector< graph_traits< graph >::edge_descriptor > nonPlanarUndirEdges;
  682. graph_traits< graph >::edge_descriptor eCurrentEdge, eTemporaryEdge1, eTemporaryEdge2, eTemporaryEdge3;
  683. bool bAdded;
  684. //PLANARIZATION------------------------------------------------------------------------------------------
  685. // add each edge from gInputGraph to gLacalGraph one by one, until gLacalGraph is planar
  686. // if an edge makes gLacalGraph non-planar, remove and store it aside
  687. property_map<graph, edge_index_t>::type e_index = get(edge_index, gLacalGraph);
  688. graph_traits<graph>::edges_size_type edge_count;
  689. graph_traits<graph>::edge_iterator ei, ei_end;
  690. for(boost::tie(itrEdge, itrEdgeEnd) = edges(gInputGraph); itrEdge != itrEdgeEnd; itrEdge++)
  691. {
  692. descEdge = *itrEdge;
  693. descVertexSource = graphWrapper.getEdgeSource(descEdge, gInputGraph);
  694. descVertexTarget = graphWrapper.getEdgeTarget(descEdge, gInputGraph);
  695. iVertexSource = get(vertex_index, gInputGraph, descVertexSource);
  696. iVertexTarget = get(vertex_index, gInputGraph, descVertexTarget);
  697. boost::tie(eCurrentEdge, bAdded) = add_edge(iVertexSource, iVertexTarget, gLacalGraph);
  698. if(bAdded)
  699. {
  700. //Initialize the interior edge index
  701. edge_count = 0;
  702. for(boost::tie(ei, ei_end) = edges(gLacalGraph); ei != ei_end; ++ei)
  703. put(e_index, *ei, edge_count++);
  704. //Test for planarity; compute the planar embedding as a side-effect
  705. typedef std::vector< graph_traits<graph>::edge_descriptor > vec_t;
  706. std::vector<vec_t> embedding(num_vertices(gLacalGraph));
  707. if (boyer_myrvold_planarity_test(boyer_myrvold_params::graph = gLacalGraph,
  708. boyer_myrvold_params::embedding = &embedding[0]))
  709. {
  710. //std::cout << "Input graph is planar3" << std::endl;
  711. }
  712. else
  713. {
  714. //std::cout << "Input graph is not planar3" << std::endl;
  715. nonPlanarUndirEdges.push_back(eCurrentEdge);
  716. remove_edge(eCurrentEdge, gLacalGraph);
  717. //Re-initialize the interior edge index
  718. edge_count = 0;
  719. for(boost::tie(ei, ei_end) = edges(gLacalGraph); ei != ei_end; ++ei)
  720. put(e_index, *ei, edge_count++);
  721. }
  722. }
  723. }
  724. //END----------------------------------------------------------------------------------------------------
  725. //REMOVE NON-PLANAR EDGES FROM INPUT GRAPH---------------------------------------------------------------
  726. for(int iEdgeIndex = 0; iEdgeIndex < nonPlanarUndirEdges.size(); ++iEdgeIndex)
  727. {
  728. //find corresponding non-planar edge in gInputGraph
  729. VertexDescriptor vSourceInInputGraph, vTargetInInputGraph;
  730. vSourceInInputGraph = vertex(get(vertex_index,
  731. gInputGraph,
  732. source(nonPlanarUndirEdges[iEdgeIndex], gLacalGraph)),
  733. gInputGraph);
  734. vTargetInInputGraph = vertex(get(vertex_index,
  735. gInputGraph,
  736. target(nonPlanarUndirEdges[iEdgeIndex], gLacalGraph)),
  737. gInputGraph);
  738. EdgeDescriptor eNonPlanarEdgeInInputGraph;
  739. if(lookup_edge(vSourceInInputGraph, vTargetInInputGraph, gInputGraph).second)
  740. eNonPlanarEdgeInInputGraph = lookup_edge(vSourceInInputGraph, vTargetInInputGraph, gInputGraph).first;
  741. else if(lookup_edge(vTargetInInputGraph, vSourceInInputGraph, gInputGraph).second)
  742. eNonPlanarEdgeInInputGraph = lookup_edge(vTargetInInputGraph, vSourceInInputGraph, gInputGraph).first;
  743. else
  744. std::cout << "Error in finding non-planar edge" << std::endl;
  745. //remove that edge from gInputGraph and store it
  746. oNonPlanarEdges.push_back(eNonPlanarEdgeInInputGraph);
  747. remove_edge(eNonPlanarEdgeInInputGraph, gInputGraph);
  748. }
  749. //END----------------------------------------------------------------------------------------------------
  750. }
  751. void GraphPreProcessor::addNonPlanarEdges(SubGraph &gInputGraph, EdgeOrderType &oNonPlanarEdges)
  752. {
  753. for(int i = 0; i < oNonPlanarEdges.size(); ++i)
  754. {
  755. add_edge(source(oNonPlanarEdges[i], gInputGraph),
  756. target(oNonPlanarEdges[i], gInputGraph),
  757. gInputGraph);
  758. }
  759. //Initialize the interior edge index in input graph
  760. property_map<SubGraph, edge_index_t>::type in_e_index = get(edge_index, gInputGraph);
  761. graph_traits<SubGraph>::edges_size_type in_edge_count = 0;
  762. graph_traits<SubGraph>::edge_iterator in_ei, in_ei_end;
  763. for(boost::tie(in_ei, in_ei_end) = edges(gInputGraph); in_ei != in_ei_end; ++in_ei)
  764. put(in_e_index, *in_ei, in_edge_count++);
  765. }