Advertisement
Bazze

Graph.cpp

May 10th, 2011
132
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.54 KB | None | 0 0
  1. /*
  2.  *  Graph.cpp
  3.  *  InlΓ€mning 3B
  4.  *
  5.  *  Created by Sebastian Norling on 2011-04-26.
  6.  *  Copyright 2011 Sebastian Norling. All rights reserved.
  7.  *
  8.  */
  9.  
  10. #include "Graph.h"
  11.  
  12. #include <iostream>
  13. #include <fstream>
  14. #include <sstream>
  15.  
  16. #define INFINITY 99999999
  17.  
  18. Graph::Graph() {
  19.     this->cities = NULL;
  20.     this->relations = NULL;
  21. }
  22. Graph::Graph(string cities[], int n) {
  23.     this->nrOfNodes = n;
  24.     this->cities = new string[n];
  25.     for (int i = 0; i < n; i++) {
  26.         this->cities[i] = cities[i];
  27.     }
  28.     this->initRelations(n);
  29. }
  30. Graph::Graph(const Graph& g) {
  31.     this->copy(g);
  32. }
  33. Graph::~Graph() {
  34.     this->clear();
  35. }
  36.  
  37. Graph &Graph::operator=(const Graph& g) {
  38.     this->clear();
  39.     this->copy(g);
  40.     return *this;
  41. }
  42.  
  43. void Graph::clear() {
  44.     for (int i = 0; i < this->nrOfNodes; i++) {
  45.         delete[] this->relations[i];
  46.     }
  47.     delete[] this->relations;
  48.     delete[] this->cities;
  49.     this->nrOfNodes = 0;
  50. }
  51. void Graph::copy(const Graph& g) {
  52.     this->nrOfNodes = g.nrOfNodes;
  53.     this->cities = new string[g.nrOfNodes];
  54.     for (int i = 0; i < g.nrOfNodes; i++) {
  55.         this->cities[i] = g.cities[i];
  56.     }
  57.     this->relations = new int*[g.nrOfNodes];
  58.     for (int i = 0; i < g.nrOfNodes; i++) {
  59.         this->relations[i] = new int[g.nrOfNodes];
  60.         for (int k = 0; k < g.nrOfNodes; k++) {
  61.             this->relations[i][k] = g.relations[i][k];
  62.         }
  63.     }
  64. }
  65. void Graph::initRelations(int n) {
  66.     this->relations = new int*[n];
  67.     for (int i = 0; i < n; i++) {
  68.         this->relations[i] = new int[n];
  69.         for (int k = 0; k < n; k++) {
  70.             if (i == k) {
  71.                 this->relations[i][k] = 0;
  72.             } else {
  73.                 this->relations[i][k] = INFINITY;
  74.             }
  75.         }
  76.     }
  77. }
  78.  
  79. int Graph::getCityPos(string city) const {
  80.     for (int i = 0; i < this->nrOfNodes; i++) {
  81.         if (this->cities[i] == city) {
  82.             return i;
  83.         }
  84.     }
  85.     return -1;
  86. }
  87.  
  88. int Graph::getNextNodeToVisit(int distance[], bool visited[]) const {
  89.     int min = INFINITY, next = -1;
  90.     for (int i = 0; i < this->nrOfNodes; i++) {
  91.         if (!visited[i] && (min >= distance[i] || min == INFINITY)) {
  92.             min = distance[i];
  93.             next = i;
  94.         }
  95.     }
  96.     return next;
  97. }
  98.  
  99. void Graph::addEdge(string from, string to, int distance) {
  100.     int fromPos = this->getCityPos(from),
  101.         toPos = this->getCityPos(to);
  102.     if (fromPos != -1 && toPos != -1) {
  103.         this->relations[fromPos][toPos] = this->relations[toPos][fromPos] = distance;
  104.     } else {
  105.         throw "One or both of the cities don't exist.";
  106.     }
  107. }
  108. bool Graph::removeEdge(string from, string to) {
  109.     bool removed = false;
  110.     int fromPos = this->getCityPos(from),
  111.         toPos = this->getCityPos(to);
  112.     if (fromPos != -1 && toPos != -1) {
  113.         this->relations[fromPos][toPos] = this->relations[toPos][fromPos] = INFINITY;
  114.         removed = true;
  115.     }
  116.     return removed;
  117. }
  118. bool Graph::hasEdge(string from, string to) const {
  119.     bool hasEdge = false;
  120.     int fromPos = this->getCityPos(from),
  121.         toPos = this->getCityPos(to);
  122.     if (fromPos != -1 && toPos != -1) {
  123.         if (this->relations[fromPos][toPos] != INFINITY) {
  124.             hasEdge = true;
  125.         }
  126.     }
  127.     return hasEdge;
  128. }
  129.  
  130. int Graph::shortestPath(string from, string to) const {
  131.     bool visited[this->nrOfNodes];
  132.     int fromPos = this->getCityPos(from),
  133.         toPos = this->getCityPos(to);
  134.     int predecessor[this->nrOfNodes],
  135.         distance[this->nrOfNodes];
  136.     if (fromPos != -1 && toPos != -1) {
  137.         for (int i = 0; i < this->nrOfNodes; i++) {
  138.             predecessor[i] = -1;
  139.             if (this->relations[fromPos][i] > 0) {
  140.                 distance[i] = this->relations[fromPos][i];
  141.             } else {
  142.                 distance[i] = INFINITY;
  143.             }
  144.             visited[i] = false;
  145.         }
  146.         distance[fromPos] = 0;
  147.         visited[fromPos] = true;
  148.         int next;
  149.         for (int c = 0; c < this->nrOfNodes; c++) {
  150.             next = this->getNextNodeToVisit(distance, visited);
  151.             visited[next] = true;
  152.             for(int i = 0; i < this->nrOfNodes; i++) {
  153.                 if(!visited[i] && this->relations[next][i] > 0 && distance[next] > 0) {
  154.                     if (distance[i] > (distance[next] + this->relations[next][i])) {
  155.                         predecessor[i] = next;
  156.                         distance[i] = distance[next] + this->relations[next][i];
  157.                     }
  158.                 }
  159.             }
  160.         }
  161.         return distance[toPos];
  162.     } else {
  163.         throw "One or both cities was not recognized.";
  164.     }
  165. }
  166. void Graph::printShortestPath(string from, string to) const {
  167.     bool visited[this->nrOfNodes];
  168.     int fromPos = this->getCityPos(from),
  169.     toPos = this->getCityPos(to);
  170.     int predecessor[this->nrOfNodes],
  171.     distance[this->nrOfNodes];
  172.     if (fromPos != -1 && toPos != -1) {
  173.         for (int i = 0; i < this->nrOfNodes; i++) {
  174.             predecessor[i] = -1;
  175.             if (this->relations[fromPos][i] > 0) {
  176.                 distance[i] = this->relations[fromPos][i];
  177.             } else {
  178.                 distance[i] = INFINITY;
  179.             }
  180.             visited[i] = false;
  181.         }
  182.         distance[fromPos] = 0;
  183.         visited[fromPos] = true;
  184.         int next;
  185.         for (int c = 0; c < this->nrOfNodes; c++) {
  186.             next = this->getNextNodeToVisit(distance, visited);
  187.             visited[next] = true;
  188.             for(int i = 0; i < this->nrOfNodes; i++) {
  189.                 if(!visited[i] && this->relations[next][i] > 0 && distance[next] > 0) {
  190.                     if (distance[i] > (distance[next] + this->relations[next][i])) {
  191.                         predecessor[i] = next;
  192.                         distance[i] = distance[next] + this->relations[next][i];
  193.                     }
  194.                 }
  195.             }
  196.         }
  197.         int pos = toPos;
  198.         string path = "";
  199.         while (pos != -1) {
  200.             path = " -> " + this->cities[pos] + path;
  201.             pos = predecessor[pos];
  202.         }
  203.         cout << this->cities[fromPos] << path << endl;
  204.     } else {
  205.         throw "One or both cities was not recognized.";
  206.     }
  207. }
  208.  
  209. int Graph::getNumberOfNodes() const {
  210.     return this->nrOfNodes;
  211. }
  212.  
  213. void Graph::printAllRelations() const {
  214.     for (int i = 0; i < this->nrOfNodes; i++) {
  215.         for (int k = 0; k < this->nrOfNodes; k++) {
  216.             cout << this->relations[i][k] << "\t";
  217.         }
  218.         cout << endl;
  219.     }
  220. }
  221.  
  222. void Graph::readFromFile(string citiesFile, string relationsFile) {
  223.     this->clear();
  224.     this->readCitiesFromFile(citiesFile);
  225.     this->readRelationsFromFile(relationsFile);
  226. }
  227. void Graph::readCitiesFromFile(string filename) {
  228.     ifstream inputFile(filename.c_str());
  229.     if (inputFile.is_open()) {
  230.         inputFile >> this->nrOfNodes;
  231.         this->cities = new string[this->nrOfNodes];
  232.         for (int i = 0; i < this->nrOfNodes; i++) {
  233.             inputFile >> this->cities[i];
  234.         }
  235.         this->initRelations(this->nrOfNodes);
  236.     }
  237.     inputFile.close();
  238. }
  239. void Graph::readRelationsFromFile(string filename) {
  240.     ifstream inputFile(filename.c_str());
  241.     if (inputFile.is_open()) {
  242.         if (this->nrOfNodes > 0) {
  243.             string from, to, distString;
  244.             int dist = 0;
  245.             while (inputFile.good()) {
  246.                 getline(inputFile, from, ' ');
  247.                 getline(inputFile, to, ' ');
  248.                 getline(inputFile, distString, '\n');
  249.                 stringstream distStream(distString);
  250.                 distStream >> dist;
  251.                 this->addEdge(from, to, dist);
  252.             }
  253.         }
  254.     }
  255.     inputFile.close();
  256. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement