RandomLayoutGenerator.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. #include "RandomLayoutGenerator.h"
  2. RandomLayoutGenerator::RandomLayoutGenerator()
  3. {
  4. }
  5. void RandomLayoutGenerator::applyRandomLayout(SubGraph &gMainGraph)
  6. {
  7. //Calculate compartment size according to number of nodes in graph
  8. int iNumVertices;
  9. iNumVertices = m_boostGraphWrapper.numVertices(gMainGraph);
  10. int iSideLength = iNumVertices * 30 ;
  11. // int iSideLength = 10000;
  12. if(iSideLength > 10000)
  13. {
  14. iSideLength = 10000;
  15. }
  16. m_mainCompartment.width = iSideLength;
  17. m_mainCompartment.height = iSideLength;
  18. m_mainCompartment.x = iSideLength/-2;
  19. m_mainCompartment.y = iSideLength/-2;
  20. //Create topology of compartment size
  21. boost::minstd_rand randGenerator;
  22. rectangle_topology<> rectTopology(randGenerator,
  23. m_mainCompartment.x,
  24. m_mainCompartment.y,
  25. m_mainCompartment.x + iSideLength,
  26. m_mainCompartment.x + iSideLength);
  27. //Apply boost random layout
  28. random_graph_layout(gMainGraph
  29. , get(vertex_position , gMainGraph)
  30. , rectTopology);
  31. /*Set x,y properties in graph iCoordx and iCoordY
  32. TODO: Later change this if coordinate representation changed */
  33. int iCoordX , iCoordY;
  34. BGL_FORALL_VERTICES(vVertex , gMainGraph , SubGraph)
  35. {
  36. iCoordX = (int)get(vertex_position, gMainGraph)[vVertex][0];
  37. iCoordY = (int)get(vertex_position, gMainGraph)[vVertex][1];
  38. m_boostGraphWrapper.setVertexCenterCoordX(vVertex , gMainGraph , iCoordX);
  39. m_boostGraphWrapper.setVertexCenterCoordY(vVertex , gMainGraph , iCoordY);
  40. }
  41. }
  42. void RandomLayoutGenerator::applyRandomLayoutForClusteredGraph(SubGraph & gInputGraph, SubGraph & gRootGraph)
  43. {
  44. BoostGraphWrapper boostGraphWrapper;
  45. std::vector<int> oHeightOfChild;
  46. std::vector<int> oWidthOfChild;
  47. int iChildCount = 0;
  48. int iBlockCount = 0;
  49. //Get the partitions of input graph-------------------------------------------------------------------------
  50. //partitions are made up of children and remaining vertices
  51. //apply random layout on these partitions recursively
  52. //for each child
  53. ChildrenIterator itrChild, itrChildEnd;
  54. for(boost::tie(itrChild, itrChildEnd)=gInputGraph.children(); itrChild != itrChildEnd; ++itrChild)
  55. {
  56. //recursively apply random layout to child
  57. this->applyRandomLayoutForClusteredGraph(*itrChild, gRootGraph);
  58. //read and save height and width of child
  59. oHeightOfChild.push_back(boostGraphWrapper.getGraphHeight(*itrChild));
  60. oWidthOfChild.push_back(boostGraphWrapper.getGraphWidth(*itrChild));
  61. //maintain count of children (say N)
  62. iChildCount++;
  63. }
  64. iBlockCount = iChildCount;
  65. //for remaining vertices
  66. //create a dummy graph
  67. std::vector<VertexIterator> oRemainingVertices;
  68. SubGraph gDummyGraph;
  69. int iInputGraphID = boostGraphWrapper.getGraphClusterID(gInputGraph);
  70. //for each vertex in input graph
  71. VertexIterator itrVert, itrVertEnd;
  72. for(boost::tie(itrVert, itrVertEnd)=vertices(gInputGraph); itrVert != itrVertEnd; ++itrVert)
  73. {
  74. int iVertexID = boostGraphWrapper.getVertexClusterID(*itrVert, gInputGraph);
  75. if(iInputGraphID == iVertexID) //if remaining vertex
  76. {
  77. add_vertex(gDummyGraph);
  78. oRemainingVertices.push_back(itrVert);
  79. }
  80. }
  81. //applyRandomLayout on these remaining vertices
  82. if(num_vertices(gDummyGraph) > 0)
  83. {
  84. this->applyRandomLayout(gDummyGraph);
  85. Reingold reingold;
  86. reingold.setCompartMentProps(gDummyGraph, 10);
  87. iBlockCount++;
  88. }
  89. //-----------------------------------------------------------------------------------------------------------
  90. if(iBlockCount == 0) //if input graph is empty
  91. {
  92. //add dummy vertex to input graph
  93. VertexDescriptor vDummyVertex = add_vertex(gInputGraph);
  94. boostGraphWrapper.setVertexCenterCoordX(vDummyVertex, gInputGraph, 0);
  95. boostGraphWrapper.setVertexCenterCoordY(vDummyVertex, gInputGraph, 0);
  96. boostGraphWrapper.setVertexHeight(vDummyVertex, gInputGraph, 25);
  97. boostGraphWrapper.setVertexWidth(vDummyVertex, gInputGraph, 25);
  98. boostGraphWrapper.setVertexIsInvisible(vDummyVertex, gInputGraph, true);
  99. //goto setArea;
  100. Reingold reingold;
  101. reingold.setCompartMentProps(gInputGraph, 10);
  102. return;
  103. }
  104. //Divide area of input graph into blocks---------------------------------------------------------------------
  105. //find max height and width among these areas
  106. int iMaxHeight = 0, iMaxWidth = 0;
  107. //max height and width among children
  108. for(int iChildIndex = 0; iChildIndex < iChildCount; iChildIndex++)
  109. {
  110. if(iMaxHeight < oHeightOfChild[iChildIndex])
  111. {
  112. iMaxHeight = oHeightOfChild[iChildIndex];
  113. }
  114. if(iMaxWidth < oWidthOfChild[iChildIndex])
  115. {
  116. iMaxWidth = oWidthOfChild[iChildIndex];
  117. }
  118. }
  119. //max height and width among all blocks
  120. if(num_vertices(gDummyGraph) > 0)
  121. {
  122. if(iMaxHeight < boostGraphWrapper.getGraphHeight(gDummyGraph))
  123. {
  124. iMaxHeight = boostGraphWrapper.getGraphHeight(gDummyGraph);
  125. }
  126. if(iMaxWidth < boostGraphWrapper.getGraphWidth(gDummyGraph))
  127. {
  128. iMaxWidth = boostGraphWrapper.getGraphWidth(gDummyGraph);
  129. }
  130. }
  131. //define area consisting of minimum (N+1) blocks, find offset of each block
  132. std::vector<Point> oOffsetOfBlock;
  133. this->calculateBlockOffsets(iBlockCount, iMaxHeight, iMaxWidth, oOffsetOfBlock);
  134. //-----------------------------------------------------------------------------------------------------------
  135. //Assign random block to each partition----------------------------------------------------------------------
  136. #warning "RandomLayout/RandomLayoutGenerator.cpp:155:34: warning: ISO C++ forbids variable length array ‘oIsBlockUsed’ [-Wvla]"
  137. bool oIsBlockUsed[iBlockCount]; //flag to check if the block is used already
  138. //int iUsedBlockCount = 0;
  139. for(int iBlockIndex = 0; iBlockIndex < iBlockCount; ++iBlockIndex)
  140. {
  141. oIsBlockUsed[iBlockIndex] = false;
  142. }
  143. //for each child graph
  144. for(boost::tie(itrChild, itrChildEnd)=gInputGraph.children(); itrChild != itrChildEnd; ++itrChild)
  145. {
  146. //generate unique-random block number
  147. int iRandomBlockNumber;
  148. do
  149. {
  150. iRandomBlockNumber = 0 + (std::rand() * (iBlockCount-1))/RAND_MAX;
  151. }while(oIsBlockUsed[iRandomBlockNumber]);
  152. // //calculate its location(row, column) in the area
  153. // int iBlockRowIndex = iRandomBlockNumber / (int)std::sqrt(iBlockCount);
  154. // int iBlockColIndex = iRandomBlockNumber % (int)std::sqrt(iBlockCount);
  155. //for each vertex in the child graph
  156. for(boost::tie(itrVert, itrVertEnd)=vertices(*itrChild); itrVert != itrVertEnd; ++itrVert)
  157. {
  158. //get corres global vertex
  159. VertexDescriptor vGlobalOfCurrentVertex = (*itrChild).local_to_global(*itrVert);
  160. //read current coords
  161. int iCurrentX = boostGraphWrapper.getVertexCenterCoordX(vGlobalOfCurrentVertex, gRootGraph);
  162. int iCurrentY = boostGraphWrapper.getVertexCenterCoordY(vGlobalOfCurrentVertex, gRootGraph);
  163. //update coords by putting them at offset of current block
  164. boostGraphWrapper.setVertexCenterCoordX(vGlobalOfCurrentVertex, gRootGraph,
  165. oOffsetOfBlock[iRandomBlockNumber].iXCoord + iCurrentX + 25);
  166. boostGraphWrapper.setVertexCenterCoordY(vGlobalOfCurrentVertex, gRootGraph,
  167. oOffsetOfBlock[iRandomBlockNumber].iYCoord + iCurrentY + 25);
  168. }
  169. oIsBlockUsed[iRandomBlockNumber] = true; //mark as used
  170. //iUsedBlockCount++;
  171. }
  172. //for remaining vertices
  173. if(num_vertices(gDummyGraph) > 0)
  174. {
  175. //generate unique-random block number
  176. int iRandomBlockNumber;
  177. do
  178. {
  179. iRandomBlockNumber = 0 + (std::rand() * (iBlockCount-1))/RAND_MAX;
  180. }while(oIsBlockUsed[iRandomBlockNumber]);
  181. // //calculate its location(row, column) in the area
  182. // int iBlockRowIndex = iRandomBlockNumber / (int)std::sqrt(iBlockCount);
  183. // int iBlockColIndex = iRandomBlockNumber % (int)std::sqrt(iBlockCount);
  184. //for each vertex in the dummy graph
  185. for(boost::tie(itrVert, itrVertEnd)=vertices(gDummyGraph); itrVert != itrVertEnd; ++itrVert)
  186. {
  187. //get corresponding remaining vertex
  188. int iDummyVertIndex = get(vertex_index, gDummyGraph, *itrVert);
  189. *oRemainingVertices[iDummyVertIndex];
  190. //read current coords
  191. VertexDescriptor vCurrentVertexInDummuGraph = *itrVert;
  192. int iCurrentX = boostGraphWrapper.getVertexCenterCoordX(vCurrentVertexInDummuGraph, gDummyGraph);
  193. int iCurrentY = boostGraphWrapper.getVertexCenterCoordY(vCurrentVertexInDummuGraph, gDummyGraph);
  194. //get corres global vertex
  195. VertexDescriptor vGlobalOfCurrentVertex = (gInputGraph).local_to_global(*oRemainingVertices[iDummyVertIndex]);
  196. //update coords of the remaining vertex by putting it at offset of current block
  197. boostGraphWrapper.setVertexCenterCoordX(vGlobalOfCurrentVertex, gRootGraph,
  198. oOffsetOfBlock[iRandomBlockNumber].iXCoord + iCurrentX + 25);
  199. boostGraphWrapper.setVertexCenterCoordY(vGlobalOfCurrentVertex, gRootGraph,
  200. oOffsetOfBlock[iRandomBlockNumber].iYCoord + iCurrentY + 25);
  201. }
  202. oIsBlockUsed[iRandomBlockNumber] = true; //mark as used
  203. }
  204. //-----------------------------------------------------------------------------------------------------------
  205. //set area of graph------------------------------------------------------------------------------------------
  206. //setArea:
  207. Reingold reingold;
  208. reingold.setCompartMentProps(gInputGraph, 10);
  209. //-----------------------------------------------------------------------------------------------------------
  210. }
  211. void RandomLayoutGenerator::calculateBlockOffsets(int & iBlockCount, int iMaxHeight, int iMaxWidth,
  212. std::vector<Point> & oOffsetOfBlock)
  213. {
  214. int iRowsCols = ceil(sqrt(iBlockCount));
  215. for(int iRowIndex = 0; iRowIndex < iRowsCols; ++iRowIndex)
  216. {
  217. for(int iColIndex = 0; iColIndex < iRowsCols; ++iColIndex)
  218. {
  219. // oOffsetOfBlock[iRowIndex][iColIndex].iXCoord = iColIndex*iMaxWidth;
  220. // oOffsetOfBlock[iRowIndex][iColIndex].iYCoord = iRowIndex*iMaxHeight;
  221. Point offsetPoint;
  222. offsetPoint.iXCoord = iColIndex*iMaxWidth;
  223. offsetPoint.iYCoord = iRowIndex*iMaxHeight;
  224. oOffsetOfBlock.push_back(offsetPoint);
  225. }
  226. }
  227. iBlockCount = iRowsCols*iRowsCols;
  228. }