GraphPreProcessor.cpp 46 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868
  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(size_t 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(size_t 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. size_t iNumEdges = boost::num_edges(gInputGraph);
  229. // XXX unused iNumEdges
  230. Q_UNUSED(iNumEdges);
  231. GraphPreProcessor::graph gLocalGraph(iNumVertices);
  232. std::vector< graph_traits< graph >::edge_descriptor > localCrossingEdgeList;
  233. //separate out the crossing edges from the graph
  234. this->findCrossingEdges(gInputGraph, gLocalGraph, localCrossingEdgeList);
  235. size_t iNumLocalEdges = boost::num_edges(gLocalGraph);
  236. // XXX unused
  237. Q_UNUSED(iNumLocalEdges);
  238. LAYOUT_ASSERT((localCrossingEdgeList.size() + iNumLocalEdges) == iNumEdges,
  239. LayoutException("toPlanar",
  240. LayoutExceptionEnum::INCONSISTENT_DATASTRUCTURE,
  241. "localCrossingEdgeList",
  242. "gLocalGraph"));
  243. //replace each crossing by a dummy vertex
  244. this->replaceCrossingsByDummyVertices(gInputGraph, gLocalGraph, localCrossingEdgeList,
  245. oDummyVertexList, correspondingCrossingEdgeList);
  246. LAYOUT_ASSERT(oDummyVertexList.size() == correspondingCrossingEdgeList.size(),
  247. LayoutException("toPlanar",
  248. LayoutExceptionEnum::INCONSISTENT_DATASTRUCTURE,
  249. "DummyVertices",
  250. "CorrespondingEdges"));
  251. }
  252. void GraphPreProcessor::findCrossingEdges(SubGraph & gInputGraph, GraphPreProcessor::graph & gLocalGraph,
  253. std::vector< graph_traits< graph >::edge_descriptor > & localCrossingEdgeList)
  254. {
  255. LayoutUtility layoutUtility;
  256. //for each edge in input graph
  257. EdgeIterator itrEdge, itrEdgeEnd;
  258. for(boost::tie(itrEdge, itrEdgeEnd) = edges(gInputGraph); itrEdge != itrEdgeEnd; ++itrEdge)
  259. {
  260. graph_traits<graph>::vertex_descriptor vLocalSource, vLocalTarget;
  261. vLocalSource = vertex(get(vertex_index, gInputGraph, source(*itrEdge, gInputGraph)),
  262. gLocalGraph);
  263. vLocalTarget = vertex(get(vertex_index, gInputGraph, target(*itrEdge, gInputGraph)),
  264. gLocalGraph);
  265. //add it to local graph
  266. add_edge(vLocalSource, vLocalTarget, gLocalGraph);
  267. //re-initialize edge indices
  268. layoutUtility.reinitializeEdgeIndices(gLocalGraph);
  269. //check planarity
  270. typedef std::vector< graph_traits<graph>::edge_descriptor > vec_t;
  271. std::vector<vec_t> embedding(num_vertices(gLocalGraph));
  272. bool bIsPlanar = boyer_myrvold_planarity_test(boyer_myrvold_params::graph = gLocalGraph,
  273. boyer_myrvold_params::embedding = &embedding[0]);
  274. if(!bIsPlanar) //if graph looses planarity due to added edge
  275. {
  276. LAYOUT_ASSERT(lookup_edge(vLocalSource, vLocalTarget, gLocalGraph).second,
  277. LayoutException("findCrossingEdges",
  278. LayoutExceptionEnum::NOT_FOUND_IN_CONTAINER,
  279. "LocalGraph",
  280. "crossing edge"));
  281. //remember it as crossing edge
  282. graph_traits<graph>::edge_descriptor eLocalCrossingEdge;
  283. eLocalCrossingEdge = lookup_edge(vLocalSource, vLocalTarget, gLocalGraph).first;
  284. localCrossingEdgeList.push_back(eLocalCrossingEdge);
  285. //remove it
  286. remove_edge(vLocalSource, vLocalTarget, gLocalGraph);
  287. //re-initialize edge indices
  288. layoutUtility.reinitializeEdgeIndices(gLocalGraph);
  289. }
  290. //else if planar, continue adding edges to local graph
  291. }
  292. }
  293. void GraphPreProcessor::replaceCrossingsByDummyVertices(SubGraph & gInputGraph, GraphPreProcessor::graph & gLocalGraph,
  294. std::vector< graph_traits< graph >::edge_descriptor > & localCrossingEdgeList,
  295. VertexOrderType &oDummyVertexList,
  296. std::vector<GraphPreProcessor::EdgePairType> & correspondingCrossingEdgeList)
  297. {
  298. LayoutUtility layoutUtility;
  299. //for each crossing edge
  300. for(size_t iCrossingEdgeIndex = 0; iCrossingEdgeIndex < localCrossingEdgeList.size(); ++iCrossingEdgeIndex)
  301. {
  302. //get its src and tgt and their indices in local graph
  303. graph_traits<SubGraph>::vertex_descriptor vSourceOfLocalCrossingEdge, vTargetOfLocalCrossingEdge;
  304. vSourceOfLocalCrossingEdge = source(localCrossingEdgeList[iCrossingEdgeIndex], gLocalGraph);
  305. vTargetOfLocalCrossingEdge = target(localCrossingEdgeList[iCrossingEdgeIndex], gLocalGraph);
  306. int iIndexOfSourceOfCrossingEdge = get(vertex_index, gLocalGraph, vSourceOfLocalCrossingEdge);
  307. int iIndexOfTargetOfCrossingEdge = get(vertex_index, gLocalGraph, vTargetOfLocalCrossingEdge);
  308. //get corresponding src and tgt in input graph
  309. VertexDescriptor vSourceOfCrossingEdge, vTargetOfCrossingEdge;
  310. vSourceOfCrossingEdge = vertex(iIndexOfSourceOfCrossingEdge, gInputGraph);
  311. vTargetOfCrossingEdge = vertex(iIndexOfTargetOfCrossingEdge, gInputGraph);
  312. //find augmented dual graph of local graph------------------------------------------------------------
  313. GraphPreProcessor::graph gDualGraph;
  314. UndirEdgeOrderType dualEdge(boost::num_edges(gLocalGraph));
  315. std::vector< graph_traits<GraphPreProcessor::graph>::vertex_descriptor > oAugmentedVertices(2);
  316. std::vector< int > oIndicesOfEndsOfCrossingEdge(2);
  317. oIndicesOfEndsOfCrossingEdge[0] = iIndexOfSourceOfCrossingEdge;
  318. oIndicesOfEndsOfCrossingEdge[1] = iIndexOfTargetOfCrossingEdge;
  319. this->createAugmentedDualGraph(gLocalGraph, gDualGraph, dualEdge,
  320. oIndicesOfEndsOfCrossingEdge,
  321. oAugmentedVertices);
  322. graph_traits<GraphPreProcessor::graph>::vertex_descriptor vAugmentedSource, vAugmentedTarget;
  323. vAugmentedSource = oAugmentedVertices[0];
  324. vAugmentedTarget = oAugmentedVertices[1];
  325. //----------------------------------------------------------------------------------------------------
  326. //find shortest path----------------------------------------------------------------------------------
  327. GraphPreProcessor::dijkstra_graph gDijkstraGraph(num_vertices(gDualGraph));
  328. std::vector<GraphPreProcessor::dijkstra_vertex_descriptor> path;
  329. this->findShortestPath(gDualGraph, gDijkstraGraph, vAugmentedSource, vAugmentedTarget, path);
  330. //---------------------------------------------------------------------------------------------------
  331. //Replace edge crossings along the shortest path by dummy vertices-----------------------------------
  332. graph_traits<graph>::vertex_descriptor vRecentlyAddedLocalVertex = vSourceOfLocalCrossingEdge;
  333. VertexDescriptor vRecentlyAddedVertex = vSourceOfCrossingEdge;
  334. LAYOUT_ASSERT(path.size() > 3,
  335. LayoutException("replaceCrossingsByDummyVertices",
  336. LayoutExceptionEnum::INCONSISTENT_DATASTRUCTURE,
  337. "shortest path",
  338. "in dual graph"));
  339. //for each dual edge in the shortest path
  340. for(size_t iPathIndex = 1; iPathIndex <= path.size() - 3; ++iPathIndex)
  341. {
  342. //this dual edge ( path[iPathIndex]-path[iPathIndex+1] ) represents a crossing
  343. //find edge in local graph corresponding to this dual edge (call it 'vertical edge')-------------
  344. graph_traits<graph>::vertex_descriptor vSourceOfDualEdge, vTargetOfDualEdge;
  345. //find vertices in (aug)dual draph, corresponding to path[i] and path[i+1] in gDijkstraGraph
  346. int iSourceIndexOfDualEdgeInPath = get(vertex_index, gDijkstraGraph, path[iPathIndex]);
  347. vSourceOfDualEdge = vertex(iSourceIndexOfDualEdgeInPath, gDualGraph);
  348. int iTargetIndexOfDualEdgeInPath = get(vertex_index, gDijkstraGraph, path[iPathIndex + 1]);
  349. vTargetOfDualEdge = vertex(iTargetIndexOfDualEdgeInPath, gDualGraph);
  350. //find edge between these vertices in (aug)dual graph
  351. graph_traits<graph>::edge_descriptor eDualEdge;
  352. if(lookup_edge(vSourceOfDualEdge, vTargetOfDualEdge, gDualGraph).second)
  353. eDualEdge = lookup_edge(vSourceOfDualEdge, vTargetOfDualEdge, gDualGraph).first;
  354. else if(lookup_edge(vTargetOfDualEdge, vSourceOfDualEdge, gDualGraph).second)
  355. eDualEdge = lookup_edge(vTargetOfDualEdge, vSourceOfDualEdge, gDualGraph).first;
  356. //find its corresponding edge in local graph
  357. graph_traits<graph>::edge_descriptor eLocalVerticalEdge;
  358. size_t iDualEdgeIndex = get(edge_index, gDualGraph, eDualEdge);
  359. LAYOUT_ASSERT(iDualEdgeIndex < dualEdge.size(),
  360. LayoutException("replaceCrossingsByDummyVertices",
  361. LayoutExceptionEnum::INCONSISTENT_DATASTRUCTURE,
  362. "dualEdge",
  363. "index out of bound"));
  364. eLocalVerticalEdge = dualEdge[iDualEdgeIndex];
  365. //find vertical edge's endpoints in local graph
  366. graph_traits<graph>::vertex_descriptor vSourceOfLocalVerticalEdge, vTargetOfLocalVerticalEdge;
  367. vSourceOfLocalVerticalEdge = source(eLocalVerticalEdge, gLocalGraph);
  368. vTargetOfLocalVerticalEdge = target(eLocalVerticalEdge, gLocalGraph);
  369. //find vertical edge's endpoints in input graph
  370. VertexDescriptor vSourceOfVerticalEdge, vTargetOfVerticalEdge;
  371. int iIndexOfSourceOfLocalVerticalEdge = get(vertex_index, gLocalGraph, vSourceOfLocalVerticalEdge);
  372. vSourceOfVerticalEdge = vertex(iIndexOfSourceOfLocalVerticalEdge, gInputGraph);
  373. int iIndexOfTargetOfLocalVerticalEdge = get(vertex_index, gLocalGraph, vTargetOfLocalVerticalEdge);
  374. vTargetOfVerticalEdge = vertex(iIndexOfTargetOfLocalVerticalEdge, gInputGraph);
  375. //-----------------------------------------------------------------------------------------------
  376. //Replace the crossing edges by dummy vertex-----------------------------------------------------
  377. //IN INPUT GRAPH:
  378. //add new (dummy) vertex
  379. VertexDescriptor vNewVertex = add_vertex(gInputGraph);
  380. oDummyVertexList.push_back(vNewVertex);
  381. //join new vertex to ends of vertical edge
  382. add_edge(vSourceOfVerticalEdge, vNewVertex, gInputGraph);
  383. add_edge(vNewVertex, vTargetOfVerticalEdge, gInputGraph);
  384. //remove vertical edge
  385. remove_edge(vSourceOfVerticalEdge, vTargetOfVerticalEdge, gInputGraph);
  386. remove_edge(vTargetOfVerticalEdge, vSourceOfVerticalEdge, gInputGraph);
  387. //join recent vertex to new vertex
  388. add_edge(vRecentlyAddedVertex, vNewVertex, gInputGraph);
  389. //remember crossing which is being replaced by vertex
  390. GraphPreProcessor::EdgePairType crossingEdgePair (2, std::vector<VertexDescriptor>(2));
  391. crossingEdgePair[0][0] = vSourceOfCrossingEdge;
  392. crossingEdgePair[0][1] = vTargetOfCrossingEdge;
  393. crossingEdgePair[1][0] = vSourceOfVerticalEdge;
  394. crossingEdgePair[1][1] = vTargetOfVerticalEdge;
  395. correspondingCrossingEdgeList.push_back(crossingEdgePair);
  396. //new vertex becomes recent vertex
  397. vRecentlyAddedVertex = vNewVertex;
  398. //IN LOCAL GRAPH:
  399. //add new vert
  400. graph_traits<graph>::vertex_descriptor vNewLocalVertex = add_vertex(gLocalGraph);
  401. //join new vertex to ends of vertical edge
  402. add_edge(vSourceOfLocalVerticalEdge, vNewLocalVertex, gLocalGraph);
  403. add_edge(vNewLocalVertex, vTargetOfLocalVerticalEdge, gLocalGraph);
  404. //remove vertical edge
  405. remove_edge(vSourceOfLocalVerticalEdge, vTargetOfLocalVerticalEdge, gLocalGraph);
  406. remove_edge(vTargetOfLocalVerticalEdge, vSourceOfLocalVerticalEdge, gLocalGraph);
  407. //join recent vertex to new vertex
  408. add_edge(vRecentlyAddedLocalVertex, vNewLocalVertex, gLocalGraph);
  409. //new vertex becomes recent vertex
  410. vRecentlyAddedLocalVertex = vNewLocalVertex;
  411. //-----------------------------------------------------------------------------------------------
  412. }
  413. //connect the last dummy vertex----------------------------------------------------------------------
  414. //IN INPUT GRAPH:
  415. //join recent and target of horizontal edge
  416. add_edge(vRecentlyAddedVertex, vTargetOfCrossingEdge, gInputGraph);
  417. //remove crossing (horizontal) edge
  418. remove_edge(vSourceOfCrossingEdge, vTargetOfCrossingEdge, gInputGraph);
  419. remove_edge(vTargetOfCrossingEdge, vSourceOfCrossingEdge, gInputGraph);
  420. //re-initiate edge indices
  421. layoutUtility.reinitializeEdgeIndices(gInputGraph);
  422. //IN LOCAL GRAPH:
  423. //join recent and target of horizontal edge
  424. add_edge(vRecentlyAddedLocalVertex, vTargetOfLocalCrossingEdge, gLocalGraph);
  425. //re-initialize edge indices
  426. layoutUtility.reinitializeEdgeIndices(gLocalGraph);
  427. //---------------------------------------------------------------------------------------------------
  428. //---------------------------------------------------------------------------------------------------
  429. }
  430. }
  431. void GraphPreProcessor::createAugmentedDualGraph(GraphPreProcessor::graph & gLocalGraph,
  432. GraphPreProcessor::graph & gDualGraph,
  433. UndirEdgeOrderType & dualEdge,
  434. std::vector< int > & oIndicesOfEndsOfCrossingEdge,
  435. std::vector< graph_traits<GraphPreProcessor::graph>::vertex_descriptor > & oAugmentedVertices)
  436. {
  437. LayoutUtility layoutUtility;
  438. //find dual graph of local graph-------------------------------------------------------------------
  439. std::vector< UndirVertexOrderType > adjecentFace(boost::num_vertices(gLocalGraph));
  440. // Compute the planar embedding - we know the input graph is planar,
  441. // so we're ignoring the return value of the test
  442. typedef std::vector< graph_traits<graph>::edge_descriptor > vec_t;
  443. std::vector<vec_t> embedding(num_vertices(gLocalGraph));
  444. boyer_myrvold_planarity_test(boyer_myrvold_params::graph = gLocalGraph,
  445. boyer_myrvold_params::embedding = &embedding[0]);
  446. create_dual_graph(gLocalGraph, gDualGraph, &embedding[0], adjecentFace, dualEdge);
  447. //-------------------------------------------------------------------------------------------------
  448. //find augmented dual graph------------------------------------------------------------------------
  449. //add source and target of the crossing-edge to dual graph
  450. oAugmentedVertices[0] = add_vertex(gDualGraph);
  451. oAugmentedVertices[1] = add_vertex(gDualGraph);
  452. //connect these src and tgt to their adjecent faces
  453. //for all of source's adjecent faces
  454. LAYOUT_ASSERT((size_t)oIndicesOfEndsOfCrossingEdge[0] < adjecentFace.size(),
  455. LayoutException("createAugmentedDualGraph",
  456. LayoutExceptionEnum::INVALID_ATTRIBUTE_VALUE,
  457. "adjecentFace",
  458. "index out of Bound")); //adjecentFace[oIndicesOfEndsOfCrossingEdge[0]] not Null
  459. LAYOUT_ASSERT(adjecentFace[oIndicesOfEndsOfCrossingEdge[0]].size() > 0,
  460. LayoutException("createAugmentedDualGraph",
  461. LayoutExceptionEnum::EMPTY_CONTAINER,
  462. "adjecentFace[source]",
  463. "adjecentFace of aug.source")); //adjecentFace[oIndicesOfEndsOfCrossingEdge[0]].size() > 0
  464. for(size_t iFaceIndex = 0; iFaceIndex < adjecentFace[oIndicesOfEndsOfCrossingEdge[0]].size(); ++iFaceIndex)
  465. {
  466. //if src not already connected to adjecent face
  467. if(!(lookup_edge(oAugmentedVertices[0], adjecentFace[oIndicesOfEndsOfCrossingEdge[0]][iFaceIndex], gDualGraph).second
  468. || lookup_edge(adjecentFace[oIndicesOfEndsOfCrossingEdge[0]][iFaceIndex], oAugmentedVertices[0], gDualGraph).second))
  469. {
  470. //add edge to dual graph
  471. add_edge(oAugmentedVertices[0], adjecentFace[oIndicesOfEndsOfCrossingEdge[0]][iFaceIndex], gDualGraph);
  472. }
  473. //else continue
  474. }
  475. //for all of target's adjecent faces
  476. LAYOUT_ASSERT((size_t)oIndicesOfEndsOfCrossingEdge[1] < adjecentFace.size(),
  477. LayoutException("createAugmentedDualGraph",
  478. LayoutExceptionEnum::INVALID_ATTRIBUTE_VALUE,
  479. "adjecentFace",
  480. "index out of Bound")); //adjecentFace[oIndicesOfEndsOfCrossingEdge[1]] not Null
  481. LAYOUT_ASSERT(adjecentFace[oIndicesOfEndsOfCrossingEdge[1]].size() > 0,
  482. LayoutException("createAugmentedDualGraph",
  483. LayoutExceptionEnum::EMPTY_CONTAINER,
  484. "adjecentFace[target]",
  485. "adjecentFace of aug.target")); //adjecentFace[oIndicesOfEndsOfCrossingEdge[1]].size() > 0
  486. for(size_t iFaceIndex = 0; iFaceIndex < adjecentFace[oIndicesOfEndsOfCrossingEdge[1]].size(); ++iFaceIndex)
  487. {
  488. //if tgt not already connected to adjecent face
  489. if(!(lookup_edge(oAugmentedVertices[1], adjecentFace[oIndicesOfEndsOfCrossingEdge[1]][iFaceIndex], gDualGraph).second
  490. || lookup_edge(adjecentFace[oIndicesOfEndsOfCrossingEdge[1]][iFaceIndex], oAugmentedVertices[1], gDualGraph).second))
  491. {
  492. //add edge to dual graph
  493. add_edge(oAugmentedVertices[1], adjecentFace[oIndicesOfEndsOfCrossingEdge[1]][iFaceIndex], gDualGraph);
  494. }
  495. //else continue
  496. }
  497. //re-initialize edge indices
  498. layoutUtility.reinitializeEdgeIndices(gDualGraph);
  499. //---------------------------------------------------------------------------------------------------
  500. }
  501. void GraphPreProcessor::findShortestPath(GraphPreProcessor::graph & gDualGraph,
  502. GraphPreProcessor::dijkstra_graph & gDijkstraGraph,
  503. graph_traits<GraphPreProcessor::graph>::vertex_descriptor & vAugmentedSource,
  504. graph_traits<GraphPreProcessor::graph>::vertex_descriptor & vAugmentedTarget,
  505. std::vector<GraphPreProcessor::dijkstra_vertex_descriptor> & path)
  506. {
  507. LayoutUtility layoutUtility;
  508. //create a copy of the augmented dual graph with edge weights set to '1'------------------------------------
  509. //for each edge in (augmented)dual graph
  510. graph_traits< GraphPreProcessor::graph >::edge_iterator itrDualGraphEdge, itrDualGraphEdgeEnd;
  511. for(boost::tie(itrDualGraphEdge, itrDualGraphEdgeEnd) = edges(gDualGraph); itrDualGraphEdge != itrDualGraphEdgeEnd; ++itrDualGraphEdge)
  512. {
  513. //get src and tgt of the edge
  514. graph_traits< GraphPreProcessor::graph >::vertex_descriptor vSourceOfDualEdge, vTargetOfDualEdge;
  515. vSourceOfDualEdge = source(*itrDualGraphEdge, gDualGraph);
  516. vTargetOfDualEdge = target(*itrDualGraphEdge, gDualGraph);
  517. int iIndexOfSourceOfDualEdge = get(vertex_index, gDualGraph, vSourceOfDualEdge);
  518. int iIndexOfTargetOfDualEdge = get(vertex_index, gDualGraph, vTargetOfDualEdge);
  519. //get corresponding src and tgt in dijkstra graph
  520. graph_traits< GraphPreProcessor::dijkstra_graph >::vertex_descriptor vSourceOfDualEdgeInDijkstra, vTargetOfDualEdgeInDijkstra;
  521. vSourceOfDualEdgeInDijkstra = vertex(iIndexOfSourceOfDualEdge, gDijkstraGraph);
  522. vTargetOfDualEdgeInDijkstra = vertex(iIndexOfTargetOfDualEdge, gDijkstraGraph);
  523. //add edge in dijkstra graph
  524. add_edge(vSourceOfDualEdgeInDijkstra, vTargetOfDualEdgeInDijkstra, 1, gDijkstraGraph);
  525. }
  526. //Initialize the interior edge index
  527. layoutUtility.reinitializeEdgeIndices(gDijkstraGraph);
  528. //----------------------------------------------------------------------------------------------------------
  529. //find vertices in gDijkstraGraph, corresponding to vAugmentedSource and vAugmentedTarget
  530. GraphPreProcessor::dijkstra_vertex_descriptor vDijkstraSource, vDijkstraTarget;
  531. int iIndexOfAugmentedSource = get(vertex_index, gDualGraph, vAugmentedSource);
  532. vDijkstraSource = vertex(iIndexOfAugmentedSource, gDijkstraGraph);
  533. int iIndexOfAugmentedTarget = get(vertex_index, gDualGraph, vAugmentedTarget);
  534. vDijkstraTarget = vertex(iIndexOfAugmentedTarget, gDijkstraGraph);
  535. //call Dijkstra's single source shortest path algorithm-----------------------------------------------------
  536. //it will calculate distances and preceding vertex of each vertex, in the shortest path from the source
  537. std::vector<GraphPreProcessor::dijkstra_vertex_descriptor> p(num_vertices(gDijkstraGraph)); //to maintatin parent of each vertex in Dijkstra traversal
  538. std::vector<int> d(num_vertices(gDijkstraGraph)); //to maintatin distance of each vertex from source in Dijkstra traversal
  539. dijkstra_shortest_paths(gDijkstraGraph,
  540. vDijkstraSource,
  541. predecessor_map(boost::make_iterator_property_map(p.begin(),
  542. get(boost::vertex_index,
  543. gDijkstraGraph))).distance_map(boost::make_iterator_property_map(d.begin(),
  544. get(boost::vertex_index,
  545. gDijkstraGraph))));
  546. //find path from src to tgt
  547. this->findPath(vDijkstraTarget, path, p); //finds path in reverse(target to source) in Dijkstra graph
  548. std::reverse(path.begin(), path.end());
  549. LAYOUT_ASSERT(((path[0] == vDijkstraSource) && (path[path.size() - 1] == vDijkstraTarget)),
  550. LayoutException("findShortestPath",
  551. LayoutExceptionEnum::NOT_FOUND_IN_CONTAINER,
  552. "shortest path",
  553. "aug. source/target")); //path is from source to target
  554. //----------------------------------------------------------------------------------------------------------
  555. }
  556. void GraphPreProcessor::findPath(GraphPreProcessor::dijkstra_vertex_descriptor &vTarget,
  557. std::vector<GraphPreProcessor::dijkstra_vertex_descriptor> &myPath,
  558. std::vector<GraphPreProcessor::dijkstra_vertex_descriptor> &parentVertex)
  559. {
  560. LAYOUT_ASSERT(vTarget < parentVertex.size(),
  561. LayoutException("findPath",
  562. LayoutExceptionEnum::INVALID_ATTRIBUTE_VALUE,
  563. "parentVertex",
  564. "index out of bound")); //parentVertex[vTarget] not NULL
  565. if(parentVertex[vTarget] == vTarget)
  566. {
  567. myPath.push_back(vTarget);
  568. return;
  569. }
  570. else
  571. {
  572. myPath.push_back(vTarget);
  573. findPath(parentVertex[vTarget], myPath, parentVertex);
  574. return;
  575. }
  576. }
  577. void GraphPreProcessor::addParallelEdges(SubGraph &gInputGraph, EdgeOrderType &oParallelEdgeList, std::vector<QString> & oParrallelEdgeIDs)
  578. {
  579. BoostGraphWrapper boostGraphWrapper;
  580. //for each parallel edge, add it to graph
  581. for(size_t iParallelEdgeIndex = 0; iParallelEdgeIndex < oParallelEdgeList.size(); ++iParallelEdgeIndex)
  582. {
  583. VertexDescriptor vSourceOfParallelEdge, vTargetOfParallelEdge;
  584. vSourceOfParallelEdge = source(oParallelEdgeList[iParallelEdgeIndex], gInputGraph);
  585. vTargetOfParallelEdge = target(oParallelEdgeList[iParallelEdgeIndex], gInputGraph);
  586. QString sEdgeID = oParrallelEdgeIDs[iParallelEdgeIndex];
  587. EdgeBoolPair pEdgeBool = add_edge(vSourceOfParallelEdge, vTargetOfParallelEdge, gInputGraph);
  588. LAYOUT_ASSERT(pEdgeBool.second,
  589. LayoutException("addParallelEdges",
  590. LayoutExceptionEnum::INVALID_OPERATION,
  591. "add_edge",
  592. "addParallelEdges"));
  593. boostGraphWrapper.setEdgeId(pEdgeBool.first, gInputGraph, sEdgeID);
  594. }
  595. //reinitialize edge index
  596. LayoutUtility layoutUtility;
  597. layoutUtility.reinitializeEdgeIndices(gInputGraph);
  598. }
  599. void GraphPreProcessor::removeDummyVertices(SubGraph & gInputGraph, VertexOrderType &oDummyVertices,
  600. std::vector<GraphPreProcessor::EdgePairType> & correspondingCrossingEdge)
  601. {
  602. //for each dummy vertex (in reverse order of insertion)
  603. // when size_t iDummyVertexIndex >= 0 is always true
  604. for(int iDummyVertexIndex = oDummyVertices.size() - 1; iDummyVertexIndex >= 0; --iDummyVertexIndex)
  605. {
  606. std::vector<EdgeDescriptor> oEdgesToBeRemoved;
  607. //remove all edges incident on current dummy vertex-----------------------------------------------------
  608. //for each edge in InputGraph
  609. EdgeIterator itrEdge, itrEdgeEnd;
  610. for(boost::tie(itrEdge, itrEdgeEnd)=edges(gInputGraph); itrEdge != itrEdgeEnd; ++itrEdge)
  611. {
  612. //if it has dummy vertex as end-point
  613. if(source(*itrEdge, gInputGraph) == oDummyVertices[iDummyVertexIndex]
  614. || target(*itrEdge, gInputGraph) == oDummyVertices[iDummyVertexIndex])
  615. {
  616. //remember it as ToBeRemoved
  617. oEdgesToBeRemoved.push_back(*itrEdge);
  618. }
  619. //else continue
  620. }
  621. //for each edge ToBeRemoved
  622. for(size_t iEdgeIndex = 0; iEdgeIndex < oEdgesToBeRemoved.size(); ++iEdgeIndex)
  623. {
  624. VertexDescriptor vSourceOfEdgeToBeRemoved, vTargetOfEdgeToBeRemoved;
  625. vSourceOfEdgeToBeRemoved = source(oEdgesToBeRemoved[iEdgeIndex], gInputGraph);
  626. vTargetOfEdgeToBeRemoved = target(oEdgesToBeRemoved[iEdgeIndex], gInputGraph);
  627. //remove edge
  628. remove_edge(vSourceOfEdgeToBeRemoved, vTargetOfEdgeToBeRemoved, gInputGraph);
  629. remove_edge(vTargetOfEdgeToBeRemoved, vSourceOfEdgeToBeRemoved, gInputGraph);
  630. }
  631. //------------------------------------------------------------------------------------------------------
  632. //add the corresponding crossing edges back-------------------------------------------------------------
  633. //for each crossing-edge corresponding to current dummy vrtex
  634. LAYOUT_ASSERT((size_t)iDummyVertexIndex < correspondingCrossingEdge.size(),
  635. LayoutException("removeDummyVertices",
  636. LayoutExceptionEnum::INCONSISTENT_DATASTRUCTURE,
  637. "correspondingCrossingEdge",
  638. "index out of bound"));
  639. LAYOUT_ASSERT(correspondingCrossingEdge[iDummyVertexIndex].size() == 2,
  640. LayoutException("removeDummyVertices",
  641. LayoutExceptionEnum::INCONSISTENT_DATASTRUCTURE,
  642. "correspondingCrossingEdges for dummyVertex",
  643. "index out of bound"));
  644. for(size_t iCrossingEdgeIndex = 0; iCrossingEdgeIndex < correspondingCrossingEdge[iDummyVertexIndex].size(); ++iCrossingEdgeIndex)
  645. {
  646. LAYOUT_ASSERT(correspondingCrossingEdge[iDummyVertexIndex][iCrossingEdgeIndex].size() == 2,
  647. LayoutException("removeDummyVertices",
  648. LayoutExceptionEnum::INCONSISTENT_DATASTRUCTURE,
  649. "endPoints of correspondingCrossingEdge for dummyVertex",
  650. "index out of bound"));
  651. //get its src and tgt
  652. VertexDescriptor vSourceOfCrossingEdge, vTargetOfCrossingEdge;
  653. vSourceOfCrossingEdge = correspondingCrossingEdge[iDummyVertexIndex][iCrossingEdgeIndex][0];
  654. vTargetOfCrossingEdge = correspondingCrossingEdge[iDummyVertexIndex][iCrossingEdgeIndex][1];
  655. //if not already added to InputGraph
  656. if(!(lookup_edge(vSourceOfCrossingEdge, vTargetOfCrossingEdge, gInputGraph).second
  657. || lookup_edge(vTargetOfCrossingEdge, vSourceOfCrossingEdge, gInputGraph).second))
  658. {
  659. //add edge
  660. LAYOUT_ASSERT(add_edge(vSourceOfCrossingEdge, vTargetOfCrossingEdge, gInputGraph).second,
  661. LayoutException("removeDummyVertices",
  662. LayoutExceptionEnum::INVALID_OPERATION,
  663. "add_edge",
  664. "removeDummyVertices"));
  665. }
  666. //else continue
  667. }
  668. //-----------------------------------------------------------------------------------------------------
  669. //reinitialize edge index
  670. LayoutUtility layoutUtility;
  671. layoutUtility.reinitializeEdgeIndices(gInputGraph);
  672. //set dummy vertex invisible
  673. BoostGraphWrapper boostGraphWrapper;
  674. boostGraphWrapper.setVertexIsInvisible(oDummyVertices[iDummyVertexIndex], gInputGraph, true);
  675. }
  676. }
  677. void GraphPreProcessor::toPlanarAlternate(SubGraph &gInputGraph, EdgeOrderType &oNonPlanarEdges)
  678. {
  679. VertexDescriptor descVertexSource;
  680. VertexDescriptor descVertexTarget;
  681. VertexDescriptor vNewInputGraphVertex;
  682. EdgeIterator itrEdge, itrEdgeEnd;
  683. EdgeDescriptor descEdge;
  684. int iVertexSource, iVertexTarget, iNumVertices;
  685. BoostGraphWrapper graphWrapper;
  686. iNumVertices = boost::num_vertices(gInputGraph);
  687. GraphPreProcessor::graph gLacalGraph(iNumVertices); //create a local undirected graph with same no. of vertices
  688. std::vector< graph_traits< graph >::edge_descriptor > nonPlanarUndirEdges;
  689. graph_traits< graph >::edge_descriptor eCurrentEdge, eTemporaryEdge1, eTemporaryEdge2, eTemporaryEdge3;
  690. bool bAdded;
  691. // XXX unused
  692. Q_UNUSED(vNewInputGraphVertex);
  693. //PLANARIZATION------------------------------------------------------------------------------------------
  694. // add each edge from gInputGraph to gLacalGraph one by one, until gLacalGraph is planar
  695. // if an edge makes gLacalGraph non-planar, remove and store it aside
  696. property_map<graph, edge_index_t>::type e_index = get(edge_index, gLacalGraph);
  697. graph_traits<graph>::edges_size_type edge_count;
  698. graph_traits<graph>::edge_iterator ei, ei_end;
  699. for(boost::tie(itrEdge, itrEdgeEnd) = edges(gInputGraph); itrEdge != itrEdgeEnd; itrEdge++)
  700. {
  701. descEdge = *itrEdge;
  702. descVertexSource = graphWrapper.getEdgeSource(descEdge, gInputGraph);
  703. descVertexTarget = graphWrapper.getEdgeTarget(descEdge, gInputGraph);
  704. iVertexSource = get(vertex_index, gInputGraph, descVertexSource);
  705. iVertexTarget = get(vertex_index, gInputGraph, descVertexTarget);
  706. boost::tie(eCurrentEdge, bAdded) = add_edge(iVertexSource, iVertexTarget, gLacalGraph);
  707. if(bAdded)
  708. {
  709. //Initialize the interior edge index
  710. edge_count = 0;
  711. for(boost::tie(ei, ei_end) = edges(gLacalGraph); ei != ei_end; ++ei)
  712. put(e_index, *ei, edge_count++);
  713. //Test for planarity; compute the planar embedding as a side-effect
  714. typedef std::vector< graph_traits<graph>::edge_descriptor > vec_t;
  715. std::vector<vec_t> embedding(num_vertices(gLacalGraph));
  716. if (boyer_myrvold_planarity_test(boyer_myrvold_params::graph = gLacalGraph,
  717. boyer_myrvold_params::embedding = &embedding[0]))
  718. {
  719. //std::cout << "Input graph is planar3" << std::endl;
  720. }
  721. else
  722. {
  723. //std::cout << "Input graph is not planar3" << std::endl;
  724. nonPlanarUndirEdges.push_back(eCurrentEdge);
  725. remove_edge(eCurrentEdge, gLacalGraph);
  726. //Re-initialize the interior edge index
  727. edge_count = 0;
  728. for(boost::tie(ei, ei_end) = edges(gLacalGraph); ei != ei_end; ++ei)
  729. put(e_index, *ei, edge_count++);
  730. }
  731. }
  732. }
  733. //END----------------------------------------------------------------------------------------------------
  734. //REMOVE NON-PLANAR EDGES FROM INPUT GRAPH---------------------------------------------------------------
  735. for(size_t iEdgeIndex = 0; iEdgeIndex < nonPlanarUndirEdges.size(); ++iEdgeIndex)
  736. {
  737. //find corresponding non-planar edge in gInputGraph
  738. VertexDescriptor vSourceInInputGraph, vTargetInInputGraph;
  739. vSourceInInputGraph = vertex(get(vertex_index,
  740. gInputGraph,
  741. source(nonPlanarUndirEdges[iEdgeIndex], gLacalGraph)),
  742. gInputGraph);
  743. vTargetInInputGraph = vertex(get(vertex_index,
  744. gInputGraph,
  745. target(nonPlanarUndirEdges[iEdgeIndex], gLacalGraph)),
  746. gInputGraph);
  747. EdgeDescriptor eNonPlanarEdgeInInputGraph;
  748. if(lookup_edge(vSourceInInputGraph, vTargetInInputGraph, gInputGraph).second)
  749. eNonPlanarEdgeInInputGraph = lookup_edge(vSourceInInputGraph, vTargetInInputGraph, gInputGraph).first;
  750. else if(lookup_edge(vTargetInInputGraph, vSourceInInputGraph, gInputGraph).second)
  751. eNonPlanarEdgeInInputGraph = lookup_edge(vTargetInInputGraph, vSourceInInputGraph, gInputGraph).first;
  752. else
  753. std::cout << "Error in finding non-planar edge" << std::endl;
  754. //remove that edge from gInputGraph and store it
  755. oNonPlanarEdges.push_back(eNonPlanarEdgeInInputGraph);
  756. remove_edge(eNonPlanarEdgeInInputGraph, gInputGraph);
  757. }
  758. //END----------------------------------------------------------------------------------------------------
  759. }
  760. void GraphPreProcessor::addNonPlanarEdges(SubGraph &gInputGraph, EdgeOrderType &oNonPlanarEdges)
  761. {
  762. for(size_t i = 0; i < oNonPlanarEdges.size(); ++i)
  763. {
  764. add_edge(source(oNonPlanarEdges[i], gInputGraph),
  765. target(oNonPlanarEdges[i], gInputGraph),
  766. gInputGraph);
  767. }
  768. //Initialize the interior edge index in input graph
  769. property_map<SubGraph, edge_index_t>::type in_e_index = get(edge_index, gInputGraph);
  770. graph_traits<SubGraph>::edges_size_type in_edge_count = 0;
  771. graph_traits<SubGraph>::edge_iterator in_ei, in_ei_end;
  772. for(boost::tie(in_ei, in_ei_end) = edges(gInputGraph); in_ei != in_ei_end; ++in_ei)
  773. put(in_e_index, *in_ei, in_edge_count++);
  774. }