Advertisement
Guest User

Untitled

a guest
Nov 21st, 2019
111
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.41 KB | None | 0 0
  1. // AlgoProject4.cpp : Defines the entry point for the console application.
  2. //
  3.  
  4. //#include "stdafx.h"
  5. #include <vector>
  6. #include <iostream>
  7. #include <string>
  8. #include <unordered_map>
  9. #include <queue>
  10. #include <limits>
  11.  
  12. using namespace std;
  13.  
  14.  
  15. struct Edge
  16. {
  17. int from, to, cost;
  18. Edge(int from, int to, int cost)
  19. {
  20. this->from = from;
  21. this->to = to;
  22. this->cost = cost;
  23. }
  24. };
  25.  
  26. struct Edge_Compare
  27. {
  28. bool operator() (Edge a, Edge b) const
  29. {
  30. return a.cost > b.cost;
  31. }
  32. };
  33.  
  34. void init(vector<vector<Edge>>& graph, int& node_degree,
  35. priority_queue<int, vector<Edge>, Edge_Compare>& next_to_connect)
  36. {
  37. int num_nodes;
  38. cout << "Enter the number of nodes in the graph: ";
  39. cin >> num_nodes;
  40. cin.ignore(numeric_limits<streamsize>::max(), '\n');
  41. graph.resize(num_nodes);
  42.  
  43. int num_edges, from, to, cost;
  44. cout << "Enter the number of distinct edges in your graph \n(Edges entered must be"
  45. << " distinct. i.e. no backwards edges): ";
  46. cin >> num_edges;
  47. cout << endl;
  48. cin.ignore(numeric_limits<streamsize>::max(), '\n');
  49.  
  50.  
  51.  
  52.  
  53.  
  54. for (int edge_itr = 0; edge_itr < num_edges; edge_itr++)
  55. {
  56. cout << "Enter a from_edge value followed by a to_edge value followed \nby an to edge_cost value: ";
  57. cin >> from;
  58. cin >> to;
  59. cin >> cost;
  60. Edge input = Edge(from, to, cost);
  61. graph[from].push_back(input);
  62. graph[to].push_back(input);
  63. next_to_connect.push(input);
  64. cout << endl;
  65. cin.ignore(numeric_limits<streamsize>::max(), '\n');
  66.  
  67. }
  68.  
  69.  
  70. }
  71.  
  72.  
  73.  
  74.  
  75.  
  76. int Kruskal(const vector<vector<Edge>>& graph, string& mst_nodes, int node_degree,
  77. priority_queue<int, vector<Edge>, Edge_Compare>& next_to_connect)
  78. {
  79. unordered_map<int, int> nodes_to_chain;
  80. vector<vector<int>> chains;
  81. int num_chains = 0, nodes_to_retain = next_to_connect.size() - node_degree, mst_cost = 0;
  82. for (int i = 0; i < graph.size(); i++)
  83. nodes_to_chain.insert(pair<int, int>(i, -1));
  84.  
  85. while (!next_to_connect.empty() /*&& next_to_connect.size() > nodes_to_retain*/)
  86. {
  87. Edge connect = next_to_connect.top();
  88.  
  89. if (nodes_to_chain.at(connect.from) == -1) //from node is unconnected
  90. {
  91. if (nodes_to_chain.at(connect.to) == -1) //to node is unconnected
  92. {
  93. chains.push_back(vector<int>());
  94. nodes_to_chain.at(connect.from) = chains.size() - 1;
  95. nodes_to_chain.at(connect.to) = chains.size() - 1;
  96. chains[chains.size() - 1].push_back(connect.from);
  97. chains[chains.size() - 1].push_back(connect.to);
  98. mst_nodes += to_string(connect.from) + "-" + to_string(connect.to) + ", ";
  99. mst_cost += connect.cost;
  100. }
  101. else //to node is connected
  102. {
  103. nodes_to_chain.at(connect.from) = nodes_to_chain.at(connect.to);
  104. chains[nodes_to_chain.at(connect.to)].push_back(connect.from);
  105. mst_nodes += to_string(connect.from) + "-" + to_string(connect.to) + ", ";
  106. mst_cost += connect.cost;
  107. }
  108. }
  109. else //from node is connected
  110. {
  111. if (nodes_to_chain.at(connect.to) == -1) //to node is unconnected
  112. {
  113. nodes_to_chain.at(connect.to) = nodes_to_chain.at(connect.from);
  114. chains[nodes_to_chain.at(connect.from)].push_back(connect.to);
  115. mst_nodes += to_string(connect.from) + "-" + to_string(connect.to) + ", ";
  116. mst_cost += connect.cost;
  117. }
  118. else if (nodes_to_chain.at(connect.from) != nodes_to_chain.at(connect.to)) //from node and to node
  119. //are connected but are also in different chains
  120. {
  121. chains.push_back(vector<int>());
  122. for (int node : chains[nodes_to_chain.at(connect.from)])
  123. {
  124. chains[chains.size() - 1].push_back(node);
  125. nodes_to_chain.at(node) = chains.size() - 1;
  126. }
  127. nodes_to_chain.at(connect.from) = chains.size() - 1;
  128. for (int node : chains[nodes_to_chain.at(connect.to)])
  129. {
  130. chains[chains.size() - 1].push_back(node);
  131. nodes_to_chain.at(node) = chains.size() - 1;
  132. }
  133. nodes_to_chain.at(connect.to) = chains.size() - 1;
  134.  
  135. mst_nodes += to_string(connect.from) + "-" + to_string(connect.to) + ", ";
  136. mst_cost += connect.cost;
  137. /*If the two connecting nodes are actually from different groups then we must
  138. place every node in each chain into the same chain.*/
  139. }
  140.  
  141. /*If connecting nodes are in the same chain, then that would form a cycle. Instead, we do not
  142. connect two nodes that are in the same chain.*/
  143. }
  144.  
  145. next_to_connect.pop();
  146. }
  147.  
  148. return mst_cost;
  149. }
  150.  
  151. int Prim(const vector<vector<Edge>>& graph, string& mst_nodes, int node_degree,
  152. priority_queue<int, vector<Edge>, Edge_Compare>& next_to_connect)
  153. {
  154. vector<bool> visited(graph.size());
  155. int mst_cost = 0;
  156. visited[0] = true;
  157. for (Edge e : graph[0])
  158. next_to_connect.push(e);
  159.  
  160. while (!next_to_connect.empty())
  161. {
  162. if (!visited[next_to_connect.top().to] ||
  163. visited[next_to_connect.top().to] && !visited[next_to_connect.top().from])
  164. {
  165.  
  166. int to = !visited[next_to_connect.top().to] ? next_to_connect.top().to :
  167. next_to_connect.top().from;
  168.  
  169. mst_cost += next_to_connect.top().cost;
  170. mst_nodes += to_string(next_to_connect.top().from)
  171. + "-" + to_string(next_to_connect.top().to) + ", ";
  172. visited[to] = true;
  173. next_to_connect.pop();
  174. for (Edge e : graph[to])
  175. next_to_connect.push(e);
  176.  
  177. }
  178. else
  179. next_to_connect.pop();
  180.  
  181.  
  182. }
  183.  
  184. return mst_cost;
  185. }
  186.  
  187.  
  188. int main()
  189. {
  190. vector<vector<Edge>> graph;
  191. priority_queue <int, vector<Edge>, Edge_Compare> next_to_connect;
  192. string mst_nodes = "{ ";
  193. int node_degree, mst_cost; //if a node_degree is supplied and it is less than the number of nodes in the graph,
  194. //then the path is not spanning. Only node_degree nodes are in the path. Otherwise, the path is spanning.
  195.  
  196. init(graph, node_degree, next_to_connect);
  197. node_degree = graph.size();
  198.  
  199. mst_cost = Kruskal(graph, mst_nodes, node_degree, next_to_connect);
  200. mst_nodes += "}";
  201.  
  202. cout << "The Minimum Spanning Tree path cost with Kruskal's is: " << mst_cost << endl;
  203. cout << "The edges in the Minimum Spanning Tree of degree " << node_degree << " are: " << mst_nodes << endl;
  204.  
  205. mst_nodes = "{ ";
  206.  
  207. mst_cost = Prim(graph, mst_nodes, node_degree, next_to_connect);
  208. mst_nodes += "}";
  209.  
  210. cout << "The Minimum Spanning Tree path cost with Prim's is: " << mst_cost << endl;
  211. cout << "The edges in the Minimum Spanning Tree of degree " << node_degree << " are: " << mst_nodes << endl;
  212.  
  213.  
  214.  
  215. return 0;
  216. }
  217. /*
  218. Sample Input:
  219. 6
  220. 9
  221. 0 1 7
  222. 0 2 8
  223. 1 2 3
  224. 1 3 6
  225. 2 3 4
  226. 2 4 3
  227. 3 4 2
  228. 3 5 5
  229. 4 5 2
  230.  
  231. 7
  232. 11
  233. 0 1 7
  234. 0 3 5
  235. 1 2 8
  236. 1 3 9
  237. 1 4 7
  238. 2 4 5
  239. 3 4 15
  240. 3 5 6
  241. 4 5 8
  242. 4 6 9
  243. 5 6 11
  244. */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement