From fe093690c01b40310f04af522c9cf5ee047b6af9 Mon Sep 17 00:00:00 2001 From: Elijah Opoku-Nyarko Date: Tue, 26 Apr 2022 10:24:35 -0400 Subject: [PATCH 1/4] Indented code to match C++ style guide --- project5.cc | 66 ++++++------ province.cc | 296 ++++++++++++++++++++++++++-------------------------- province.h | 146 +++++++++++++------------- 3 files changed, 254 insertions(+), 254 deletions(-) diff --git a/project5.cc b/project5.cc index 611674a..53951cc 100644 --- a/project5.cc +++ b/project5.cc @@ -18,48 +18,48 @@ using namespace std; * check if we are at the end of the file */ bool eof() { - char c; - std::cin >> c; - // if the fie is ended, return true - if (std::cin.eof()) { - return true; - } else { - // if the file contains more data, return the previously gotten - // data to cin - std::cin.unget(); - return false; - } + char c; + std::cin >> c; + // if the fie is ended, return true + if (std::cin.eof()) { + return true; + } else { + // if the file contains more data, return the previously gotten + // data to cin + std::cin.unget(); + return false; + } } int main(int argc, char *argv[]) { - // Repeatedly read input from standard input - while (!eof()) { - // create a new graph for each loop, which will read all of the - // corresponding data per graph - Province theProvince(cin); + // Repeatedly read input from standard input + while (!eof()) { + // create a new graph for each loop, which will read all of the + // corresponding data per graph + Province theProvince(cin); - std::cout << std::endl; - std::cout << "------------------------------------------------" << std::endl; - std::cout << "---------------- New DataSet: ------------------" << std::endl; - std::cout << "------------------------------------------------" << std::endl; - std::cout << std::endl; + std::cout << std::endl; + std::cout << "------------------------------------------------" << std::endl; + std::cout << "---------------- New DataSet: ------------------" << std::endl; + std::cout << "------------------------------------------------" << std::endl; + std::cout << std::endl; - theProvince.printAll(0, cout); + theProvince.printAll(0, cout); - theProvince.printShortestPath(std::cout); + theProvince.printShortestPath(std::cout); - std::cout << std::endl; - std::cout << "------------------------------------------------" << std::endl; - std::cout << "------------------------------------------------" << std::endl; - std::cout << std::endl; + std::cout << std::endl; + std::cout << "------------------------------------------------" << std::endl; + std::cout << "------------------------------------------------" << std::endl; + std::cout << std::endl; - theProvince.minSpan(std::cout); + theProvince.minSpan(std::cout); - std::cout << std::endl; - std::cout << "------------------------------------------------" << std::endl; - std::cout << "------------------------------------------------" << std::endl; - std::cout << std::endl; + std::cout << std::endl; + std::cout << "------------------------------------------------" << std::endl; + std::cout << "------------------------------------------------" << std::endl; + std::cout << std::endl; - } + } } diff --git a/province.cc b/province.cc index b9c9e1d..eb09948 100644 --- a/province.cc +++ b/province.cc @@ -92,32 +92,32 @@ void Province::printAll(int start, std::ostream & output) { // Add current town's(vertex's) unscheduled neighbors to the queue for (Town::RoadList::iterator neighbor = _towns[current]._roads.begin(); neighbor != _towns[current]._roads.end(); neighbor++) { - std::string neighborName = _towns[neighbor->_head]._name; + std::string neighborName = _towns[neighbor->_head]._name; - output << " "; - output << neighborName << " " << neighbor->_length << " mi"; + output << " "; + output << neighborName << " " << neighbor->_length << " mi"; - // if the type is bridge, then add to output - if (neighbor ->_isBridge) { - output << " via bridge"; - } + // if the type is bridge, then add to output + if (neighbor ->_isBridge) { + output << " via bridge"; + } - output << endl; + output << endl; - int head = neighbor ->_head; + int head = neighbor ->_head; - // If neighbour is not scheduled, add neighbor to the queue - if (!scheduled[head]) { - toVisit.push(head); - scheduled[head] = true; - } + // If neighbour is not scheduled, add neighbor to the queue + if (!scheduled[head]) { + toVisit.push(head); + scheduled[head] = true; } + } } output << endl << endl; } int Province::smallest(double dist[], std::list toVisit, - int numTowns) const { + int numTowns) const { int smallest = toVisit.front(); if (toVisit.size() > 1) { @@ -140,85 +140,85 @@ int Province::smallest(double dist[], std::list toVisit, */ void Province::printShortestPath(std::ostream & output) const { - // if there is only one town only one town - if (_numberOfTowns == 1) { - output << "There is only one town, so the provincial " - << "officials have no need of efficient routes!"; - return; - } - - output << "The shortest routes from " + _towns[0]._name; - output << " are:" << std::endl << std::endl; - - // keeps track of the index of the predecessor to each - // town(vertex) n on the shortest path to n - int prev[_numberOfTowns]; - - // queue to keep track of which town(vertex) to visit next - list toVisit; + // if there is only one town only one town + if (_numberOfTowns == 1) { + output << "There is only one town, so the provincial " + << "officials have no need of efficient routes!"; + return; + } - // keeps track of the distance from the capital to each town - // following the shortest path - double dist[_numberOfTowns]; + output << "The shortest routes from " + _towns[0]._name; + output << " are:" << std::endl << std::endl; + // keeps track of the index of the predecessor to each + // town(vertex) n on the shortest path to n + int prev[_numberOfTowns]; - // set defaults for dist, prev, and add all vertices to toVisit - for (int i = 0; i < _numberOfTowns; i++) { - dist[i] = DBL_MAX; - toVisit.push_back(i); - } + // queue to keep track of which town(vertex) to visit next + list toVisit; - // distance from the capital to the capital is zero - dist[0] = 0.0; + // keeps track of the distance from the capital to each town + // following the shortest path + double dist[_numberOfTowns]; - while (!toVisit.empty()) { - int smallestIndex = smallest(dist, toVisit, _numberOfTowns); - toVisit.remove(smallestIndex); + // set defaults for dist, prev, and add all vertices to toVisit + for (int i = 0; i < _numberOfTowns; i++) { + dist[i] = DBL_MAX; + toVisit.push_back(i); + } - // Add current vertex's neighbors to the queue - for (Town::RoadList::iterator neighbor = - _towns[smallestIndex]._roads.begin(); - neighbor != _towns[smallestIndex]._roads.end(); neighbor++) { - // new distance needed for testing - double newDist = dist[smallestIndex] + neighbor->_length; + // distance from the capital to the capital is zero + dist[0] = 0.0; - // if new dist is smaller, replace the old one, and - // update the corresponding entry in prev - if (newDist < dist[neighbor->_head]) { - dist[neighbor->_head] = newDist; - prev[neighbor->_head] = smallestIndex; - } - } - } + while (!toVisit.empty()) { + int smallestIndex = smallest(dist, toVisit, _numberOfTowns); + + toVisit.remove(smallestIndex); + + // Add current vertex's neighbors to the queue + for (Town::RoadList::iterator neighbor = + _towns[smallestIndex]._roads.begin(); + neighbor != _towns[smallestIndex]._roads.end(); neighbor++) { + // new distance needed for testing + double newDist = dist[smallestIndex] + neighbor->_length; + + // if new dist is smaller, replace the old one, and + // update the corresponding entry in prev + if (newDist < dist[neighbor->_head]) { + dist[neighbor->_head] = newDist; + prev[neighbor->_head] = smallestIndex; + } + } + } - // print out the data for each non capital town - for (int i = 1; i < _numberOfTowns; i++) { - output << " " << "The shortest route from " + _towns[0]._name; - output << " to " + _towns[i]._name + " is " << dist[i]; - output << " mi:" << std::endl; + // print out the data for each non capital town + for (int i = 1; i < _numberOfTowns; i++) { + output << " " << "The shortest route from " + _towns[0]._name; + output << " to " + _towns[i]._name + " is " << dist[i]; + output << " mi:" << std::endl; - // stack to hold the path to the town at index i - std::stack predecessors; + // stack to hold the path to the town at index i + std::stack predecessors; - // add town at i to stack - int predecessor = i; - predecessors.push(i); + // add town at i to stack + int predecessor = i; + predecessors.push(i); - // follow the links in prev until we get to the capital, - // adding each town to the predecessor stack - while (predecessor != 0) { - predecessor = prev[predecessor]; - predecessors.push(predecessor); - } + // follow the links in prev until we get to the capital, + // adding each town to the predecessor stack + while (predecessor != 0) { + predecessor = prev[predecessor]; + predecessors.push(predecessor); + } - // print out the names for each entry in the stack - while (!predecessors.empty()) { - output << " " << _towns[predecessors.top()]._name; - output << std::endl; - predecessors.pop(); - } + // print out the names for each entry in the stack + while (!predecessors.empty()) { + output << " " << _towns[predecessors.top()]._name; + output << std::endl; + predecessors.pop(); } + } } /** @@ -227,7 +227,7 @@ void Province::printShortestPath(std::ostream & output) const { * @return True if road1 is shorter in length than road 2 */ bool Province::Road::operator < (Road road2) const { - return this->_length < road2._length; + return this->_length < road2._length; } /** @@ -235,64 +235,64 @@ bool Province::Road::operator < (Road road2) const { */ void Province::minSpan(std::ostream & output) const { - // if only one town - if (_numberOfTowns == 1) { - output << "There is only one town, so the province " - << "does not need to upgrade any roads!"; - return; - } + // if only one town + if (_numberOfTowns == 1) { + output << "There is only one town, so the province " + << "does not need to upgrade any roads!"; + return; + } - list roads; - vector minSpanTree; - vector higher; + list roads; + vector minSpanTree; + vector higher; - // Initialize a numComponent value for each town to 0 - int numComponent[_numberOfTowns]; - for (int i = 0; i < _numberOfTowns; i++) { - numComponent[i] = 0; - } + // Initialize a numComponent value for each town to 0 + int numComponent[_numberOfTowns]; + for (int i = 0; i < _numberOfTowns; i++) { + numComponent[i] = 0; + } - // Add all roads to list of roads - for (int i = 0; i < _numberOfRoads; i++) { - roads.push_back(_roads[i]); - } - - // Sort list of roads by length - roads.sort(); - - int compNum = 0; // Used to determine if edge forms a cycle - while (minSpanTree.size() < _numberOfTowns - 1) { - Road minRoad = roads.front(); - roads.pop_front(); - - // Both towns have component number 0 - if (numComponent[minRoad._head] == 0 && - numComponent[minRoad._tail] == 0) { - minSpanTree.push_back(minRoad); - compNum++; - numComponent[minRoad._head] = compNum; - numComponent[minRoad._tail] = compNum; - - // Only one town has component number 0 - } else if (numComponent[minRoad._head] == 0) { - minSpanTree.push_back(minRoad); - numComponent[minRoad._head] = numComponent[minRoad._tail]; - - // Other town has component number 0 - } else if (numComponent[minRoad._tail] == 0) { - minSpanTree.push_back(minRoad); - numComponent[minRoad._tail] = numComponent[minRoad._head]; - - // If component number of one town is less than other town - } else if (numComponent[minRoad._head] < - numComponent[minRoad._tail]) { - minSpanTree.push_back(minRoad); - higher.push_back(minRoad._tail); + // Add all roads to list of roads + for (int i = 0; i < _numberOfRoads; i++) { + roads.push_back(_roads[i]); + } - // Set all higher road components to value of lower - for (int i = 0; i < higher.size(); i++) { - higher[i] = numComponent[minRoad._head]; - } + // Sort list of roads by length + roads.sort(); + + int compNum = 0; // Used to determine if edge forms a cycle + while (minSpanTree.size() < _numberOfTowns - 1) { + Road minRoad = roads.front(); + roads.pop_front(); + + // Both towns have component number 0 + if (numComponent[minRoad._head] == 0 && + numComponent[minRoad._tail] == 0) { + minSpanTree.push_back(minRoad); + compNum++; + numComponent[minRoad._head] = compNum; + numComponent[minRoad._tail] = compNum; + + // Only one town has component number 0 + } else if (numComponent[minRoad._head] == 0) { + minSpanTree.push_back(minRoad); + numComponent[minRoad._head] = numComponent[minRoad._tail]; + + // Other town has component number 0 + } else if (numComponent[minRoad._tail] == 0) { + minSpanTree.push_back(minRoad); + numComponent[minRoad._tail] = numComponent[minRoad._head]; + + // If component number of one town is less than other town + } else if (numComponent[minRoad._head] < + numComponent[minRoad._tail]) { + minSpanTree.push_back(minRoad); + higher.push_back(minRoad._tail); + + // Set all higher road components to value of lower + for (int i = 0; i < higher.size(); i++) { + higher[i] = numComponent[minRoad._head]; + } // If component number of other town is less than other town } else if (numComponent[minRoad._head] > @@ -302,19 +302,19 @@ void Province::minSpan(std::ostream & output) const { // Set all higher road components to value of lower for (int i = 0; i < higher.size(); i++) { - higher[i] = numComponent[minRoad._tail]; + higher[i] = numComponent[minRoad._tail]; } - } - } + } + } - output << "The road upgrading goal can be achieved at minimal cost by upgrading:"; - output << std::endl << std::endl; - - // Print names of towns in minimum spanning tree of province - for (int i = 0; i < minSpanTree.size(); i++) { - output << " "; - output << _towns[minSpanTree[i]._head]._name; - output << " to "; - output << _towns[minSpanTree[i]._tail]._name << std::endl; - } + output << "The road upgrading goal can be achieved at minimal cost by upgrading:"; + output << std::endl << std::endl; + + // Print names of towns in minimum spanning tree of province + for (int i = 0; i < minSpanTree.size(); i++) { + output << " "; + output << _towns[minSpanTree[i]._head]._name; + output << " to "; + output << _towns[minSpanTree[i]._tail]._name << std::endl; + } } diff --git a/province.h b/province.h index 5b231ef..a5ce1c7 100644 --- a/province.h +++ b/province.h @@ -14,90 +14,90 @@ /** - * towns connected by roads - */ +* towns connected by roads +*/ class Province { public: - /** - * Constructor - * @param source Input data for province - */ - Province(std::istream & source); - - /** - * Print towns and roads in province in breadth-first search order - * @param output Stream to print data to - */ - void printAll(int start, std::ostream & output); - void printShortestPath(std::ostream & output) const; + /** + * Constructor + * @param source Input data for province + */ + Province(std::istream & source); + + /** + * Print towns and roads in province in breadth-first search order + * @param output Stream to print data to + */ + void printAll(int start, std::ostream & output); + void printShortestPath(std::ostream & output) const; - /** - * Find shortest path from one town to another - */ - void findShortestPath(); + /** + * Find shortest path from one town to another + */ + void findShortestPath(); - void minSpan(std::ostream & output) const; + void minSpan(std::ostream & output) const; - void removeBridges(std::ostream & output) const; + void removeBridges(std::ostream & output) const; - void articulationPoints(std::ostream & output) const; + void articulationPoints(std::ostream & output) const; - void dfs(std::vector & dfsTowns) const; + void dfs(std::vector & dfsTowns) const; - /** - * Destructor - */ - ~Province() {} + /** + * Destructor + */ + ~Province() {} private: - int smallest(double dist [], std::list toVisit, int numTowns) const; - std::vector bfs(int start) const; - void dfsAux(int current, std::vector & dfsTowns, bool visited []) const; - - /** - * Road - * Contains index of originating town, whether or not is bridge, - * and length - */ - class Road - { - public: - - /* - * Constructor - * @param head Index in vertex array of originating town - * @param isBridge Whether or not the road is a bridge - * @param length Length of the road in miles - */ - Road(int head, int tail, char isBridge, double length) - : _head(head), _tail(tail), _isBridge(isBridge), _length(length) - {} - - int _head; // Index of originating town in vertex array - int _tail; - char _isBridge; - double _length; - - bool operator < (Road road2) const; - }; - - /** - * Town - * Contains name and a list of roads that connect to it - */ - class Town - { - public: // consider making some of these private (RoadList) - std::string _name; - typedef std::list RoadList; - RoadList _roads; - }; - - int _numberOfTowns; - int _numberOfRoads; - Town *_towns; - std::vector _roads; + int smallest(double dist [], std::list toVisit, int numTowns) const; + std::vector bfs(int start) const; + void dfsAux(int current, std::vector & dfsTowns, bool visited []) const; + + /** + * Road + * Contains index of originating town, whether or not is bridge, + * and length + */ + class Road + { + public: + + /* + * Constructor + * @param head Index in vertex array of originating town + * @param isBridge Whether or not the road is a bridge + * @param length Length of the road in miles + */ + Road(int head, int tail, char isBridge, double length) + : _head(head), _tail(tail), _isBridge(isBridge), _length(length) + {} + + int _head; // Index of originating town in vertex array + int _tail; + char _isBridge; + double _length; + + bool operator < (Road road2) const; +}; + +/** +* Town +* Contains name and a list of roads that connect to it +*/ +class Town +{ +public: // consider making some of these private (RoadList) + std::string _name; + typedef std::list RoadList; + RoadList _roads; +}; + + int _numberOfTowns; + int _numberOfRoads; + Town *_towns; + std::vector _roads; }; From dbe3b0d89a6d8ea675779bfaa8cb49ce2683795d Mon Sep 17 00:00:00 2001 From: Elijah Opoku-Nyarko Date: Tue, 26 Apr 2022 12:37:55 -0400 Subject: [PATCH 2/4] BFS traversal on the province - Ignoring bridges --- province.cc | 41 +++++++++++++++++++++++++++++++++++++++++ province.h | 7 +++++++ 2 files changed, 48 insertions(+) diff --git a/province.cc b/province.cc index eb09948..793dcab 100644 --- a/province.cc +++ b/province.cc @@ -318,3 +318,44 @@ void Province::minSpan(std::ostream & output) const { output << _towns[minSpanTree[i]._tail]._name << std::endl; } } + +std::vector Province::bfs(int start) const { + // Initialize list of towns scheduled to visit + bool scheduled[_numberOfTowns]; + for (int i = 0; i < _numberOfTowns; i ++) { + scheduled[i] = false; + } + + // Initialize list of towns to visit with starting town + std::queue toVisit; + toVisit.push(start); + + scheduled[start] = true; + std::vector results; + + // While all towns have not been visited + while (!toVisit.empty()) { + + // Remove current town from queue, add to results + int current = toVisit.front(); + toVisit.pop(); + results.push_back(current); + + // Iterate over neighbors to current town + for (Town::RoadList::iterator neighbor = + _towns[current]._roads.begin(); + neighbor != _towns[current]._roads.end(); + neighbor ++) { + + // If neighbor is not bridge and is not scheduled, + // add to results and schedule + if (!neighbor->_isBridge && !scheduled[neighbor->_head]) { + toVisit.push(neighbor->_head); + scheduled[neighbor->_head] = true; + } + } + } + + return results; +} + diff --git a/province.h b/province.h index a5ce1c7..fcd773f 100644 --- a/province.h +++ b/province.h @@ -54,7 +54,14 @@ class Province private: int smallest(double dist [], std::list toVisit, int numTowns) const; + + /** + * Conduct a breadth-first traversal on the province, ignoring bridges + * @param start Index of town to start traversal at + * @return - List of indices of towns in order of traversal + */ std::vector bfs(int start) const; + void dfsAux(int current, std::vector & dfsTowns, bool visited []) const; /** From 1a5512deeb0f8677c7ab64fa2efda0b5c7c659b8 Mon Sep 17 00:00:00 2001 From: Elijah Opoku-Nyarko Date: Tue, 26 Apr 2022 12:40:11 -0400 Subject: [PATCH 3/4] Added a few comments --- province.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/province.cc b/province.cc index 793dcab..fd9c9de 100644 --- a/province.cc +++ b/province.cc @@ -336,7 +336,7 @@ std::vector Province::bfs(int start) const { // While all towns have not been visited while (!toVisit.empty()) { - // Remove current town from queue, add to results + // Remove current town from queue and add to results int current = toVisit.front(); toVisit.pop(); results.push_back(current); From 4ddd36a63abd60579080bd4a224f4d444c10e39a Mon Sep 17 00:00:00 2001 From: Elijah Opoku-Nyarko Date: Thu, 28 Apr 2022 09:11:57 -0400 Subject: [PATCH 4/4] Put something togeter for removeBridges function --- .DS_Store | Bin 6148 -> 6148 bytes province.cc | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+) diff --git a/.DS_Store b/.DS_Store index 6fc45215b53f821730c8bae577358abe8aa11f88..0f6eac7acd89355b7ea1090f7e074fb351ec77e3 100644 GIT binary patch delta 149 zcmZoMXfc@J&&ahgU^g=(*JK_RV?_>z0)`@ne1E(Vhk1TM301R? Province::bfs(int start) const { return results; } +/** + * Remove bridges and print the list of towns that remain connected + */ +void Province::removeBridges(ostream &output) const { + + // Look for a bridge + bool hasBridge = false; + for ( int roadNum = 0; roadNum < _roads.size(); roadNum++) { + if (_roads[roadNum]._isBridge) { + hasBridge = true; + break; + } + } + // If only one town + if (_numberOfTowns == 1) { + output << "There is only one town, so the province " + << "will not be affected by a major storm"; + return; + + // If province has no bridge + } else if (!hasBridge) { + output << "The province has no bridges, so it " + << "will not be affected by a major storm"; + return; + } + + // Mark all towns as unvisited + list toVisit; + for (int i = 0; i < _numberOfTowns; i++) { + toVisit.push_back(i); + } + output << "Connected components in event of a major storm are: "; + output << endl << endl; + + while (!toVisit.empty()) { + // Mark current town as visited + int curr = toVisit.back(); + toVisit.pop_back(); + + // Run BFS from current town + vector bfsResult = bfs(curr); + + // Mark all town in BFS result as visited + for (int i = 0; i < bfsResult.size(); i++) { + toVisit.remove(bfsResult[i]); + } + + output << " "; + output << "If all bridges fail, the following towns would form "; + output << "an isolated group:" << endl; + + // Print names of all towns in connected component + for (int i = 0; i < bfsResult.size(); i++) { + output << " "; + output << _towns[bfsResult[i]]._name << endl; + } + } + +} +