Advertisement
Guest User

Untitled

a guest
Nov 24th, 2014
132
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.63 KB | None | 0 0
  1. class Vertex {
  2. public:
  3. Vertex() {
  4. bVisited = false;
  5. }
  6. int data = 0;
  7. EdgeList edgeList;
  8. bool bVisited = false;
  9. };
  10.  
  11. struct Edge {
  12. int cost;
  13. boost::weak_ptr<Vertex> srcVertex;
  14. boost::weak_ptr<Vertex> dstVertex;
  15. };
  16.  
  17. typedef std::list<boost::shared_ptr<Vertex>> VerticesList;
  18. typedef std::map<int, VerticesList::const_iterator> DataVertexMap;
  19. class Graph {
  20.  
  21. VerticesList _verticesList;
  22. DataVertexMap _dataVertexMap;
  23.  
  24. //TODO: Need some design to have this function internal only and not exposed to client
  25. boost::shared_ptr<Vertex> addAndGetVertex(int data);
  26. public:
  27. Graph();
  28. ~Graph();
  29.  
  30. bool isEmpty() const;
  31. //We don't check for duplicate vertex
  32. void addVertex(int data);
  33. void addEdge(int srcData, int dstData, int cost);
  34. int getCostForEdge(int srcData, int dstData);
  35. void displayGraph();
  36. void dfsTraversal();
  37. void bfsTraversal();
  38.  
  39. void findShortestPath(int srcData, int dstData);
  40. void kruskalMST();
  41. void primMST();
  42. };
  43.  
  44. void Graph::findShortestPath(int srcData, int dstData) {
  45. DataVertexMap::const_iterator srcIter = _dataVertexMap.find(srcData);
  46. DataVertexMap::const_iterator dstIter = _dataVertexMap.find(dstData);
  47. if(srcIter == _dataVertexMap.end() || dstIter == _dataVertexMap.end())
  48. assert(false);
  49.  
  50. boost::shared_ptr<Vertex> srcVertex(*(srcIter->second));
  51. boost::shared_ptr<Vertex> dstVertex(*(dstIter->second));
  52.  
  53. struct VertexInfo {
  54. bool bGotMinDistance = false;
  55. boost::weak_ptr<Vertex> precedingVertex;
  56. int distanceFromSource = INFINITY;
  57. };
  58.  
  59. boost::shared_ptr<Vertex> currentVertex = srcVertex;
  60.  
  61. typedef std::map<boost::shared_ptr<Vertex>, VertexInfo> VertexInfoMap;
  62. VertexInfoMap vertexInfoMap;
  63. for(boost::shared_ptr<Vertex> vertex : _verticesList) {
  64. VertexInfo info;
  65. if(vertex.get() == srcVertex.get()) {
  66. info.bGotMinDistance = true;
  67. info.distanceFromSource = 0;
  68. info.precedingVertex = boost::weak_ptr<Vertex> ();
  69. }
  70. vertexInfoMap.insert(std::make_pair(vertex, info));
  71. }
  72.  
  73.  
  74. while(currentVertex.get() != dstVertex.get()) {
  75. VertexInfo& curVertexInfo = vertexInfoMap[currentVertex];
  76. curVertexInfo.bGotMinDistance = true;
  77. boost::shared_ptr<Vertex> minDistVertex = currentVertex;
  78. int curMinDist = INFINITY;
  79. for(auto iter = vertexInfoMap.begin(); iter != vertexInfoMap.end(); ++iter) {
  80. boost::shared_ptr<Vertex> vertex = iter->first;
  81. VertexInfo& vertexInfo = iter->second;
  82. if(!vertexInfo.bGotMinDistance) {
  83. int distFromCurToVertex = getCostForEdge(currentVertex->data, vertex->data);
  84. if(vertexInfo.distanceFromSource > distFromCurToVertex + curVertexInfo.distanceFromSource) {
  85. vertexInfo.distanceFromSource = distFromCurToVertex + curVertexInfo.distanceFromSource;
  86. vertexInfo.precedingVertex = currentVertex;
  87. }
  88.  
  89. if(vertexInfo.distanceFromSource < curMinDist) {
  90. curMinDist = vertexInfo.distanceFromSource;
  91. minDistVertex = vertex;
  92. }
  93. }
  94. }
  95. currentVertex = minDistVertex;
  96. }
  97.  
  98. class CompareEdge {
  99. public:
  100. bool operator() (const boost::shared_ptr<Edge> & e1, const boost::shared_ptr<Edge> & e2) const{
  101. if(e1->cost == e2->cost)
  102. return e1.get() < e2.get(); //similar to default comparator less<T>
  103.  
  104. return e1->cost < e2->cost;
  105. }
  106. };
  107.  
  108. typedef std::map<boost::shared_ptr<Vertex>, boost::shared_ptr<Vertex>> ParentMap;
  109.  
  110. // A utility function to find the subset of an element i
  111. boost::shared_ptr<Vertex> find(const ParentMap& parentMap, const boost::shared_ptr<Vertex>& vertex)
  112. {
  113. ParentMap::const_iterator iter = parentMap.find(vertex);
  114. if (!(iter->second).get())
  115. return vertex;
  116. return find(parentMap, iter->second);
  117. }
  118.  
  119. // A utility function to do union of two subsets
  120. void Union(ParentMap& parentMap, const boost::shared_ptr<Vertex>& x, const boost::shared_ptr<Vertex>& y)
  121. {
  122. const boost::shared_ptr<Vertex> xset = find(parentMap, x);
  123. const boost::shared_ptr<Vertex> yset = find(parentMap, y);
  124. parentMap[x] = y;
  125. }
  126.  
  127.  
  128. // The main function to check whether a given graph contains cycle or not
  129. bool isCycle(const VerticesList& verticesList, const EdgeList& allEdgeList)
  130. {
  131. // Allocate memory for creating V subsets
  132. ParentMap parent;
  133.  
  134. for(boost::shared_ptr<Vertex> vertex : verticesList) {
  135. parent.insert(std::make_pair(vertex, nullptr));
  136. }
  137.  
  138. // Iterate through all edges of graph, find subset of both
  139. // vertices of every edge, if both subsets are same, then there is
  140. // cycle in graph.
  141. for(boost::shared_ptr<Edge> edge : allEdgeList)
  142. {
  143. boost::shared_ptr<Vertex> x = find(parent, (edge->srcVertex).lock());
  144. boost::shared_ptr<Vertex> y = find(parent, (edge->dstVertex).lock());
  145.  
  146. if (x.get() == y.get())
  147. return true;
  148.  
  149. Union(parent, x, y);
  150. }
  151. return false;
  152. }
  153.  
  154. void Graph::kruskalMST() {
  155. //set to hold all edges in increasing order of edge cost
  156. std::set<boost::shared_ptr<Edge>, CompareEdge> allEdgeList;
  157. for(boost::shared_ptr<Vertex> vertex : _verticesList) {
  158. EdgeList& vertexEdgeList = vertex->edgeList;
  159. allEdgeList.insert(vertexEdgeList.begin(), vertexEdgeList.end());
  160. }
  161.  
  162. EdgeList mstEdgeList;
  163. for(boost::shared_ptr<Edge> edge : allEdgeList) {
  164. if(mstEdgeList.size() == _verticesList.size() - 1) break;
  165. mstEdgeList.push_front(edge);
  166. if(isCycle(_verticesList, mstEdgeList)) {
  167. //Remove the edge from MST
  168. mstEdgeList.pop_front();
  169. }
  170. }
  171.  
  172. // print the contents of result[] to display the built MST
  173. printf("Following are the edges in the constructed MSTn");
  174. for (boost::shared_ptr<Edge> edge : mstEdgeList)
  175. printf("%d -- %d == %dn", (edge->srcVertex).lock()->data, (edge->dstVertex).lock()->data,
  176. edge->cost);
  177. return;
  178. }
  179.  
  180. //return min cost edge
  181. boost::shared_ptr<Edge> getMinEdge(const EdgeList& edgeList) {
  182. int min = INFINITY;
  183. boost::shared_ptr<Edge> minEdge;
  184. for(boost::shared_ptr<Edge> edge : edgeList) {
  185. if(edge->cost < min) {
  186. min = edge->cost;
  187. minEdge = edge;
  188. }
  189. }
  190.  
  191. return minEdge;
  192. }
  193.  
  194. void Graph::primMST() {
  195. EdgeList mstEdgeList;
  196. EdgeList potentialEdgeList;
  197.  
  198. //insert edges for first vertex
  199. boost::shared_ptr<Vertex> firstVertex = _verticesList.front();
  200. potentialEdgeList.insert(potentialEdgeList.begin(), firstVertex->edgeList.begin(), firstVertex->edgeList.end());
  201.  
  202. while(mstEdgeList.size() < _verticesList.size() - 1) {
  203. boost::shared_ptr<Edge> minEdge = getMinEdge(potentialEdgeList);
  204. mstEdgeList.push_front(minEdge);
  205. potentialEdgeList.remove(minEdge);
  206. //Mark the vertices visited so that edge having them as destination are not again included
  207. (minEdge->srcVertex).lock()->bVisited = true;
  208. (minEdge->dstVertex).lock()->bVisited = true;
  209. EdgeList& dstVertexEdgeList = (minEdge->dstVertex).lock()->edgeList;
  210. for(boost::shared_ptr<Edge> edge : dstVertexEdgeList) {
  211. if(!(edge->dstVertex).lock()->bVisited)
  212. potentialEdgeList.push_front(edge);
  213. }
  214. }
  215.  
  216. //TODO: set all bVisited false
  217.  
  218. // print the contents of result[] to display the built MST
  219. printf("Following are the edges in the constructed MSTn");
  220. for (boost::shared_ptr<Edge> edge : mstEdgeList)
  221. printf("%d -- %d == %dn", (edge->srcVertex).lock()->data, (edge->dstVertex).lock()->data,
  222. edge->cost);
  223. return;
  224. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement