Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- * Graph.cpp
- * InlΓ€mning 3B
- *
- * Created by Sebastian Norling on 2011-04-26.
- * Copyright 2011 Sebastian Norling. All rights reserved.
- *
- */
- #include "Graph.h"
- #include <iostream>
- #include <fstream>
- #include <sstream>
- #define INFINITY 99999999
- Graph::Graph() {
- this->cities = NULL;
- this->relations = NULL;
- }
- Graph::Graph(string cities[], int n) {
- this->nrOfNodes = n;
- this->cities = new string[n];
- for (int i = 0; i < n; i++) {
- this->cities[i] = cities[i];
- }
- this->initRelations(n);
- }
- Graph::Graph(const Graph& g) {
- this->copy(g);
- }
- Graph::~Graph() {
- this->clear();
- }
- Graph &Graph::operator=(const Graph& g) {
- this->clear();
- this->copy(g);
- return *this;
- }
- void Graph::clear() {
- for (int i = 0; i < this->nrOfNodes; i++) {
- delete[] this->relations[i];
- }
- delete[] this->relations;
- delete[] this->cities;
- this->nrOfNodes = 0;
- }
- void Graph::copy(const Graph& g) {
- this->nrOfNodes = g.nrOfNodes;
- this->cities = new string[g.nrOfNodes];
- for (int i = 0; i < g.nrOfNodes; i++) {
- this->cities[i] = g.cities[i];
- }
- this->relations = new int*[g.nrOfNodes];
- for (int i = 0; i < g.nrOfNodes; i++) {
- this->relations[i] = new int[g.nrOfNodes];
- for (int k = 0; k < g.nrOfNodes; k++) {
- this->relations[i][k] = g.relations[i][k];
- }
- }
- }
- void Graph::initRelations(int n) {
- this->relations = new int*[n];
- for (int i = 0; i < n; i++) {
- this->relations[i] = new int[n];
- for (int k = 0; k < n; k++) {
- if (i == k) {
- this->relations[i][k] = 0;
- } else {
- this->relations[i][k] = INFINITY;
- }
- }
- }
- }
- int Graph::getCityPos(string city) const {
- for (int i = 0; i < this->nrOfNodes; i++) {
- if (this->cities[i] == city) {
- return i;
- }
- }
- return -1;
- }
- int Graph::getNextNodeToVisit(int distance[], bool visited[]) const {
- int min = INFINITY, next = -1;
- for (int i = 0; i < this->nrOfNodes; i++) {
- if (!visited[i] && (min >= distance[i] || min == INFINITY)) {
- min = distance[i];
- next = i;
- }
- }
- return next;
- }
- void Graph::addEdge(string from, string to, int distance) {
- int fromPos = this->getCityPos(from),
- toPos = this->getCityPos(to);
- if (fromPos != -1 && toPos != -1) {
- this->relations[fromPos][toPos] = this->relations[toPos][fromPos] = distance;
- } else {
- throw "One or both of the cities don't exist.";
- }
- }
- bool Graph::removeEdge(string from, string to) {
- bool removed = false;
- int fromPos = this->getCityPos(from),
- toPos = this->getCityPos(to);
- if (fromPos != -1 && toPos != -1) {
- this->relations[fromPos][toPos] = this->relations[toPos][fromPos] = INFINITY;
- removed = true;
- }
- return removed;
- }
- bool Graph::hasEdge(string from, string to) const {
- bool hasEdge = false;
- int fromPos = this->getCityPos(from),
- toPos = this->getCityPos(to);
- if (fromPos != -1 && toPos != -1) {
- if (this->relations[fromPos][toPos] != INFINITY) {
- hasEdge = true;
- }
- }
- return hasEdge;
- }
- int Graph::shortestPath(string from, string to) const {
- bool visited[this->nrOfNodes];
- int fromPos = this->getCityPos(from),
- toPos = this->getCityPos(to);
- int predecessor[this->nrOfNodes],
- distance[this->nrOfNodes];
- if (fromPos != -1 && toPos != -1) {
- for (int i = 0; i < this->nrOfNodes; i++) {
- predecessor[i] = -1;
- if (this->relations[fromPos][i] > 0) {
- distance[i] = this->relations[fromPos][i];
- } else {
- distance[i] = INFINITY;
- }
- visited[i] = false;
- }
- distance[fromPos] = 0;
- visited[fromPos] = true;
- int next;
- for (int c = 0; c < this->nrOfNodes; c++) {
- next = this->getNextNodeToVisit(distance, visited);
- visited[next] = true;
- for(int i = 0; i < this->nrOfNodes; i++) {
- if(!visited[i] && this->relations[next][i] > 0 && distance[next] > 0) {
- if (distance[i] > (distance[next] + this->relations[next][i])) {
- predecessor[i] = next;
- distance[i] = distance[next] + this->relations[next][i];
- }
- }
- }
- }
- return distance[toPos];
- } else {
- throw "One or both cities was not recognized.";
- }
- }
- void Graph::printShortestPath(string from, string to) const {
- bool visited[this->nrOfNodes];
- int fromPos = this->getCityPos(from),
- toPos = this->getCityPos(to);
- int predecessor[this->nrOfNodes],
- distance[this->nrOfNodes];
- if (fromPos != -1 && toPos != -1) {
- for (int i = 0; i < this->nrOfNodes; i++) {
- predecessor[i] = -1;
- if (this->relations[fromPos][i] > 0) {
- distance[i] = this->relations[fromPos][i];
- } else {
- distance[i] = INFINITY;
- }
- visited[i] = false;
- }
- distance[fromPos] = 0;
- visited[fromPos] = true;
- int next;
- for (int c = 0; c < this->nrOfNodes; c++) {
- next = this->getNextNodeToVisit(distance, visited);
- visited[next] = true;
- for(int i = 0; i < this->nrOfNodes; i++) {
- if(!visited[i] && this->relations[next][i] > 0 && distance[next] > 0) {
- if (distance[i] > (distance[next] + this->relations[next][i])) {
- predecessor[i] = next;
- distance[i] = distance[next] + this->relations[next][i];
- }
- }
- }
- }
- int pos = toPos;
- string path = "";
- while (pos != -1) {
- path = " -> " + this->cities[pos] + path;
- pos = predecessor[pos];
- }
- cout << this->cities[fromPos] << path << endl;
- } else {
- throw "One or both cities was not recognized.";
- }
- }
- int Graph::getNumberOfNodes() const {
- return this->nrOfNodes;
- }
- void Graph::printAllRelations() const {
- for (int i = 0; i < this->nrOfNodes; i++) {
- for (int k = 0; k < this->nrOfNodes; k++) {
- cout << this->relations[i][k] << "\t";
- }
- cout << endl;
- }
- }
- void Graph::readFromFile(string citiesFile, string relationsFile) {
- this->clear();
- this->readCitiesFromFile(citiesFile);
- this->readRelationsFromFile(relationsFile);
- }
- void Graph::readCitiesFromFile(string filename) {
- ifstream inputFile(filename.c_str());
- if (inputFile.is_open()) {
- inputFile >> this->nrOfNodes;
- this->cities = new string[this->nrOfNodes];
- for (int i = 0; i < this->nrOfNodes; i++) {
- inputFile >> this->cities[i];
- }
- this->initRelations(this->nrOfNodes);
- }
- inputFile.close();
- }
- void Graph::readRelationsFromFile(string filename) {
- ifstream inputFile(filename.c_str());
- if (inputFile.is_open()) {
- if (this->nrOfNodes > 0) {
- string from, to, distString;
- int dist = 0;
- while (inputFile.good()) {
- getline(inputFile, from, ' ');
- getline(inputFile, to, ' ');
- getline(inputFile, distString, '\n');
- stringstream distStream(distString);
- distStream >> dist;
- this->addEdge(from, to, dist);
- }
- }
- }
- inputFile.close();
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement