Advertisement
Guest User

Untitled

a guest
Nov 30th, 2015
74
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.27 KB | None | 0 0
  1. /****************************************************
  2. File Name: prog08_DAC183.cpp
  3.  
  4. Author: David Crowe
  5. Date: 11/18/2015
  6. Problem Number: 8
  7. CS 1428 Fall 2015
  8. Instructor: Priebe
  9.  
  10. Pulls locations of several cities and optimizes the route between them.
  11. *****************************************************/
  12.  
  13. #include <iostream>
  14. #include <fstream>
  15. #include <cmath>
  16. #include <iomanip>
  17.  
  18. using namespace std;
  19.  
  20. struct City
  21. {
  22. string name;
  23. double x;
  24. double y;
  25. };
  26.  
  27. bool getData(string inputFile, City cities[], int &numCities);//checks to see if text file is readable and populates City array
  28. double getDistance(City city1, City city2);//finds distance between two cities
  29. double totalDistance(City cities[], int numCities);//finds total distance between all cities in a certain route
  30. void greedyRouteImprove(City cities[], int numCities, const int MAX_CITIES);//finds an improved route based on getting nearest city
  31. void hungarianMethodRouteImprove(City cities[], int numCities);//uses the hungarian method to find THE most optimal route
  32.  
  33. int main()
  34. {
  35. const int MAX_CITIES = 99;
  36. int numCities = 0;
  37. City cities[MAX_CITIES];
  38.  
  39. string inputFile = "route_data.txt";
  40.  
  41. if (getData(inputFile, cities, numCities))
  42. {
  43. cout << "Current Route: \n";
  44. for (int i = 0; i < numCities; i++)
  45. cout << cities[i].name << endl;
  46. //setw(5) << " " << setw(4) << cities[i].x << ", " << cities[i].y << endl;
  47.  
  48. cout << "\nDistance between cities: \n";
  49. for (int d = 0; d < numCities - 1; d++)
  50. cout << setw(10) << cities[d].name << setw(4) << " -> " << left << setw(8) << cities[d+1].name << ": "
  51. << setprecision(2) << fixed << setw(9) << getDistance(cities[d], cities[d+1]) << endl;
  52.  
  53. cout << "\nTotal distance: " << totalDistance(cities, numCities) << endl;
  54.  
  55. //greedyRouteImprove(cities, numCities, MAX_CITIES);
  56. hungarianMethodRouteImprove(cities, numCities);
  57. }
  58. return 0;
  59. }
  60.  
  61. bool getData(string inputFile, City cities[], int &numCities)
  62. {
  63. ifstream inFile;
  64. inFile.open("route_data.txt");
  65. if (inFile)
  66. {
  67. string name;
  68. while (inFile >> name)
  69. {
  70. cities[numCities].name = name;
  71. inFile >> cities[numCities].x;
  72. inFile >> cities[numCities].y;
  73.  
  74. numCities++;
  75. }
  76. return true;
  77. }
  78. else
  79. return false;
  80. }
  81.  
  82. double getDistance(City city1, City city2)
  83. {
  84. return (sqrt(pow((city2.y - city1.y),2) + pow((city2.x - city1.x),2)));
  85. }
  86.  
  87. double totalDistance(City cities[], int numCities)
  88. {
  89. double distance = 0;
  90.  
  91. for (int t = 0; t < numCities-1; t++)
  92. distance += getDistance(cities[t],cities[t+1]);
  93.  
  94. return distance;
  95. }
  96.  
  97. void greedyRouteImprove(City cities[], int numCities, const int MAX_CITIES)
  98. {
  99. cout << "\n[----------------------]\n";
  100. cout << "\nImproved Route:\n";
  101.  
  102. bool valid;
  103.  
  104. City betterCities[MAX_CITIES];
  105.  
  106. betterCities[0] = cities[0];
  107. double smallestDistance = 99;
  108.  
  109. for (int a = 0; a < numCities; a++)//iterates through betterCities array
  110. {
  111. for (int b = 1; b < numCities; b++)//iterates through cities array
  112. {
  113. if (getDistance(betterCities[a], cities[b]) < smallestDistance)
  114. {
  115. valid = true;//determines if a city is valid based if it's already used
  116. for (int w = 0; w < numCities; w++)
  117. {
  118. if (betterCities[w].name == cities[b].name)
  119. valid = false;
  120. }
  121. if(valid)
  122. {
  123. betterCities[a+1] = cities[b];
  124. smallestDistance = getDistance(betterCities[a], cities[b]);
  125. }
  126. }
  127. }
  128. smallestDistance = 99;
  129. }
  130.  
  131. for (int p = 0; p < numCities; p++)
  132. cout << betterCities[p].name << endl;
  133.  
  134. cout << "\nDistance between cities: \n";
  135. for (int d = 0; d < numCities - 1; d++)
  136. cout << setw(10) << betterCities[d].name << setw(4) << " -> " << left << setw(8) << betterCities[d+1].name << ": "
  137. << setprecision(2) << fixed << setw(9) << getDistance(betterCities[d], betterCities[d+1]) << endl;
  138.  
  139. cout << "\nTotal distance: " << totalDistance(betterCities, numCities) << endl << endl;
  140.  
  141. cout << "\n\t\t >>> " << totalDistance(cities, numCities) / totalDistance(betterCities, numCities) << "x better <<<\n\n\n";
  142. }
  143.  
  144. void hungarianMethodRouteImprove(City cities[], int numCities)
  145. {
  146. double distancesArray[numCities][numCities];
  147. double cleanDistancesArray[numCities][numCities];
  148.  
  149. for (int a = 0; a < numCities; a++)
  150. for (int b = 0; b < numCities; b++)
  151. distancesArray[a][b] = (getDistance(cities[a], cities[b]));
  152.  
  153. for (int r = 0; r < numCities; r++)
  154. {
  155. for (int c = 0; c < numCities; c++)
  156. {
  157. if (distancesArray[r][c] == 0.00)
  158. {
  159. distancesArray[r][c] = -1.00;
  160. }
  161. //cout << distancesArray[r][c] << ", ";
  162. }
  163. //cout << endl;
  164. }
  165.  
  166. std::copy(&distancesArray[0][0], &distancesArray[0][0]+numCities*numCities,&cleanDistancesArray[0][0]);//copies arrays to be used later
  167.  
  168. const int BY = numCities;
  169.  
  170. int round = 0;
  171. double totalDistance = 0;
  172. int pathArray [BY];
  173.  
  174. while(round < BY)
  175. {
  176. cout << "Matrix: " << endl;
  177. for (int a = 0; a < BY; a++)
  178. {
  179. cout << setw(5);
  180. for (int b = 0; b < BY; b++)
  181. {
  182. cout << setw(5) << distancesArray[a][b] << " | ";
  183. }
  184. cout << endl;
  185. }
  186. cout << endl;
  187.  
  188.  
  189. double minR = 99.0;
  190. double minC = 99.0;
  191.  
  192. for (int r = 0; r < BY; r++) //row minimization
  193. {
  194. for (int c = 0; c < BY; c++)
  195. if (distancesArray[r][c] < minR && distancesArray[r][c] != -1)
  196. minR = distancesArray[r][c];
  197.  
  198. for (int iC = 0; iC < BY; iC++)
  199. if (distancesArray[r][iC] != -1)
  200. distancesArray[r][iC] = (distancesArray[r][iC] - minR);
  201. minR = 99;
  202. }
  203.  
  204. cout << "Row Reduced Matrix: " << endl;
  205. for (int a = 0; a < 5; a++)
  206. {
  207. cout << setw(5);
  208. for (int b = 0; b < BY; b++)
  209. cout << setw(5) << distancesArray[a][b] << " | ";
  210. cout << endl;
  211. }
  212. cout << endl;
  213.  
  214. for (int c = 0; c < BY; c++) //column minimization
  215. {
  216. for (int r = 0; r < BY; r++)
  217. if (distancesArray[r][c] < minC && distancesArray[r][c] != -1)
  218. minC = distancesArray[r][c];
  219.  
  220. for (int iR = 0; iR < BY; iR++)
  221. if (distancesArray[iR][c] != -1)
  222. distancesArray[iR][c] = (distancesArray[iR][c] - minC);
  223. minC = 99;
  224. }
  225.  
  226. cout << "Column Reduced Matrix: " << endl;
  227. for (int a = 0; a < BY; a++)
  228. {
  229. cout << setw(5);
  230. for (int b = 0; b < BY; b++)
  231. cout << setw(5) << distancesArray[a][b] << " | ";
  232. cout << endl;
  233. }
  234. cout << endl;
  235.  
  236. double penalty = 0;
  237. double penaltyArray[BY][BY];
  238. double minRow = 99.0;
  239. double minCol = 99.0;
  240.  
  241. for (int x = 0; x < BY; x++)
  242. for (int y = 0; y < BY; y++)
  243. penaltyArray[y][x] = 0.00;
  244.  
  245. for (int a = 0; a < BY; a++)//row
  246. {
  247. for (int b = 0; b < BY; b++)//column
  248. {
  249. if (distancesArray[a][b] == 0)
  250. {
  251. distancesArray[a][b] = 100.0;
  252. for (int c = 0; c < BY; c++)
  253. {
  254. if (distancesArray[a][c] < minRow && distancesArray[a][c] != -1)
  255. minRow = distancesArray[a][c];
  256. }
  257. for (int r = 0; r < BY; r++)
  258. {
  259. if (distancesArray[r][b] < minCol && distancesArray[r][b] != -1)
  260. minCol = distancesArray[r][b];
  261. }
  262. penaltyArray[a][b] = (minRow + minCol);
  263. minRow = 99.0;
  264. minCol = 99.0;
  265. distancesArray[a][b] = 0;
  266. }
  267. }
  268. }
  269.  
  270. double greatestPenalty = 0.0;
  271.  
  272. cout << "Penalty Matrix: " << endl;
  273. for (int a = 0; a < BY; a++)
  274. {
  275. cout << setw(5);
  276. for (int b = 0; b < BY; b++)
  277. {
  278. cout << setw(5) << penaltyArray[a][b] << " | ";
  279. if (penaltyArray[a][b] > greatestPenalty)
  280. greatestPenalty = penaltyArray[a][b];
  281. }
  282. cout << endl;
  283. }
  284.  
  285. int oneCount = 0;
  286. int scratchR = 0;
  287. int scratchC = 0;
  288.  
  289. for (int a = 0; a < BY; a++)
  290. for (int b = 0; b < BY; b++)
  291. if (penaltyArray[a][b] == greatestPenalty)
  292. while (oneCount < 1)
  293. {
  294. cout << "\t\t\tLocation: " << a << " -> " << b << endl;
  295. pathArray[a] = b;
  296. totalDistance += cleanDistancesArray[a][b];
  297. scratchR = a;
  298. scratchC = b;
  299. oneCount++;
  300. }
  301. distancesArray[scratchC][scratchR] = -1;
  302.  
  303. for (int r = 0; r < BY; r++)
  304. distancesArray[r][scratchC] = -1;
  305. for (int c = 0; c < BY; c++)
  306. distancesArray[scratchR][c] = -1;
  307.  
  308. //cout << "\nReduced Matrix: " << endl;
  309. for (int a = 0; a < BY; a++)
  310. {
  311. for (int b = 0; b < BY; b++)
  312. {
  313. //cout << distancesArray[a][b] << " ";
  314. if (penaltyArray[a][b] > greatestPenalty)
  315. greatestPenalty = penaltyArray[a][b];
  316. }
  317. //cout << endl;
  318. }
  319. round++;
  320. }
  321.  
  322. int stop = 0;
  323. int city = 0;
  324. cout << "\nRoute: ";
  325. while (stop < BY -1)
  326. {
  327. //cout << city << " -> " << pathArray[city] << ", ";
  328. city = pathArray[city];
  329. stop++;
  330. }
  331.  
  332. for (int i = 0; i < BY; i++)
  333. cout << i << "->" << pathArray[i] << ", ";
  334. cout << "\nTotal distance: " << totalDistance << endl;
  335. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement