#include "extendedgraph.h" #include ExtendedGraph::ExtendedGraph() { // Default Constructor this->vertices = std::vector(0); // Empty Vector for this->vertices this->adjacencyMatrix.resize( 0, std::vector(0)); // 0x0 Matrix for this->adjacencyMatrix } /* -- Constructor with params -- */ ExtendedGraph::ExtendedGraph(const std::vector &vertices, const std::vector &edges) { this->vertices = vertices; // definition of this->vertex through parameter // vertices (type: std::vector) this->adjacencyMatrix.resize( vertices.size(), std::vector( this->vertices.size())); // creation of an NxN Matrix, based on the // size of vertices for (int i = 0; i < edges.size(); i++) { insertEdge(edges[i]); // edges are added one by one, utilizing the // insertEdge()-Function } } /* -- / Function to insert a vertex into the Graph; - takes one argument of type std::string that represents a vertex - returns void / -- */ void ExtendedGraph::insertVertex(const std::string &vertex) { if (this->resolveVertex(vertex) != -1) { /* -- */ std::cerr << "Vertex already in Graph!\n"; /* Calls this->resolveVertex to check if a given vertex is already in the Graph. Returns with an error, if this is the case. */ return; /* -- */ } this->vertices.push_back(vertex); // adds a vertetx via the push_back // function provided by std::vector this->adjacencyMatrix.resize( this->vertices.size(), std::vector(this->vertices.size())); // resizes the adjacencyMatrix // to the new size for (int i = 0; i < this->vertices.size(); i++) { /* -- */ adjacencyMatrix[i].resize( this->vertices.size()); /* resizes every "sub" vector of the matrix to the new size */ } /* -- */ } /* -- / Function to delete a vertex from the Graph; - takes one argument of type std::string that represents a vertex - returns void / -- */ void ExtendedGraph::deleteVertex(const std::string &vertex) { int index = this->resolveVertex(vertex); if (index == -1) { /* -- */ std::cerr << "Vertex not found\n"; /* Calls this->resolveVertex to check if a given vertex is already in the Graph. Returns with an error, if this is the case. */ return; /* -- */ } this->vertices.erase( this->vertices.begin() + index); // erases the vertex at position "index" from this->vertices this->adjacencyMatrix.erase( this->adjacencyMatrix.begin() + index); // erases the entries from the adjacencyMatrix at "column" // position "index" for (int i = 0; i < this->adjacencyMatrix[0].size(); i++) { /* -- */ this->adjacencyMatrix[i].erase(this->adjacencyMatrix[i].begin() + index); /* erases the entries from the adjacencyMatrix in every "row" */ } /* -- */ } /* -- / Function to insert an Edge - takes one argument of type Edge that represents an edge - returns void / -- */ void ExtendedGraph::insertEdge(const Edge &edge) { int col = this->resolveVertex( edge.getSrc()); // resolves the src of the edge to the index within the // adjacencyMatrix int row = this->resolveVertex( edge.getDest()); // resolves the dest of the edge to the index within the // adjacencyMatrix if (col == -1 || row == -1) { /* -- */ std::cerr << "Vertex not found!\n"; /* Calls this->resolveVertex to check if a given vertex is already in the Graph. Returns with an error, if this is the case. */ return; /* -- */ } this->adjacencyMatrix[col][row] = edge.getWeight(); // sets the value of the adjacencyMatrix at position // [col][row] to the weight of the edge } /* -- / Function to delete an Edge - takes one argument of type Edge that represents an edge - returns void / -- */ void ExtendedGraph::deleteEdge(const Edge &edge) { int col = this->resolveVertex( edge.getSrc()); // resolves the src of the edge to the index within the // adjacencyMatrix int row = this->resolveVertex( edge.getDest()); // resolves the dest of the edge to the index within the // adjacencyMatrix if (col == -1 || row == -1) { /* -- */ std::cerr << "Vertex not found!\n"; /* Calls this->resolveVertex to check if a given vertex is already in the Graph. Returns with an error, if this is the case. */ return; /* -- */ } this->adjacencyMatrix[col][row] = 0; // sets the value of the adjacencyMatrix at position [col][row] to 0 } /* -- / Function to check whether vertex v2 is adjacent to vertex v1 - takes one argument of type Edge that represents an edge - returns void / -- */ bool ExtendedGraph::adjacent(const std::string &vertex1, const std::string &vertex2) { int indexVertex1 = this->resolveVertex(vertex1); int indexVertex2 = this->resolveVertex(vertex2); if (indexVertex1 == -1 || indexVertex2 == -1) { std::cerr << "Vertex not found!\n"; return false; } // As adjacency is an equivalency relation, we need to check for a possible // relation in both direction. This can be achieved by swapping the the // position specifications of the adjacencyMatrix (from // [indexVertex1][indexVertex2] to [indexVertex2][indexVertex1]). if (this->adjacencyMatrix[indexVertex1][indexVertex2] != 0 || this->adjacencyMatrix[indexVertex2][indexVertex1] != 0) { return true; // if a connection (in any direction) is found, return true } else { return false; // else, return false } } /* -- / Function that returns an std::vector of std::string representing the neighbouring vertices of the parameter std::string vertex. Other than adjacent, neighbourhood is a directed relationship, which means that a vertex "A" can be the neighbour of "B", but this does not automatically imply that "B" is the neighbour of "A". - takes one argument of type std::string that represents a vertex - returns a std::vector of std::string / -- */ std::vector ExtendedGraph::neighbours(const std::string &vertex) { int indexVertex = this->resolveVertex( vertex); // resolves the vertex to the index within the adjacencyMatrix std::vector resVector = {}; // initializes an empty std::vetor of std::string for (int i = 0; i < this->adjacencyMatrix[indexVertex].size(); i++) { /* Loops through all entries of the subvector of adjacencyMatrix[indexVertex] */ if (this->adjacencyMatrix[indexVertex][i] != 0) { /* and checks if the entry at position [indexVertex][i] is not 0. */ resVector.push_back( this->vertices[i]); /* If the condition is fulfilled, add the vertex (name) to the result vector resVector */ } } return resVector; } /* -- / Function that prints the current Graph's adjacencyMatrix. - prints the Graph by utilizing std::cout - returns void / -- */ void ExtendedGraph::printGraph() { std::cout << "--------------------------------------------\n"; std::cout << "\t\t\t"; for (int i = 0; i < this->vertices.size(); i++) { std::cout << this->vertices[i] << "\t"; } std::cout << "\n"; for (int i = 0; i < this->vertices.size(); i++) { std::cout << " " << this->vertices[i] << "\t\t-->\t"; for (int j = 0; j < this->vertices.size(); j++) { std::cout << this->adjacencyMatrix[i][j] << "\t"; } std::cout << "\n"; } std::cout << "--------------------------------------------\n"; }; /* -- / Function that resolves a parameter std::string name and returns it's index within the this->vertices vector; between vertices of type std::string and the corresponding index (in the adjacencyMatrix) of type int. - takes one argument of type std::string that represents a vertex - returns an int representing the vertex's index in the adjacencyMatrix; - function returns -1 in case the resolution of the name is unsuccessful / -- */ int ExtendedGraph::resolveVertex(const std::string &vertexName) { for (int i = 0; i < this->vertices.size(); i++) { if (this->vertices[i] == vertexName) { return i; } } return -1; } int ExtendedGraph::minDistance(int dist[], bool sptSet[]) { int min = INT_MAX, min_index; for (int v = 0; v < this->vertices.size(); v++) if (sptSet[v] == false && dist[v] <= min) min = dist[v], min_index = v; return min_index; } void ExtendedGraph::performDijkstraPath(std::string sourceVertex, std::string targetVertex) { int dist[this->vertices.size()]; bool sptSet[vertices.size()]; int parent[vertices.size()]; for (int i = 0; i < vertices.size(); i++) { parent[i] = -1; } for (int i = 0; i < this->vertices.size(); i++) { dist[i] = INT_MAX; sptSet[i] = false; } dist[resolveVertex(sourceVertex)] = 0; for (int count = 0; count < this->vertices.size() - 1; count++) { int m = minDistance(dist, sptSet); sptSet[m] = true; for (int v = 0; v < vertices.size(); v++) { if (!sptSet[v] && this->adjacencyMatrix[m][v] && dist[m] != INT_MAX && dist[m] + this->adjacencyMatrix[m][v] < dist[v]) { dist[v] = dist[m] + this->adjacencyMatrix[m][v]; parent[v] = m; } } if (sptSet[resolveVertex(targetVertex)]) { break; } } // int src = 0; // std::cout << "Vertex\t Distance\tPath"; /* for (int i = 1; i < this->vertices.size(); i++) { printf("\n%d -> %d \t\t %d\t\t%d ", src, i, dist[i], src); printPath(parent, i); } */ /* printf("\n%d -> %d \t\t %d\t\t%d ", resolveVertex(sourceVertex), resolveVertex(targetVertex), dist[resolveVertex(targetVertex)], resolveVertex(sourceVertex)); */ std::cout << sourceVertex << " "; int sumPath = 0; printPath(parent, resolveVertex(targetVertex), dist, sumPath); std::cout << "; Gesamter Zollbetrag: " << sumPath << std::endl; } void ExtendedGraph::printPath(int parent[], int j, int dist[], int &sum) { // Base Case : If j is source if (parent[j] == -1) return; printPath(parent, parent[j], dist, sum); std::cout << " -(" << this->adjacencyMatrix[parent[j]][j] << ")-> " << this->vertices[j] << std::flush; sum += adjacencyMatrix[parent[j]][j]; }