-
Notifications
You must be signed in to change notification settings - Fork 0
/
WeightedGraph.h
122 lines (112 loc) · 3.59 KB
/
WeightedGraph.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
#ifndef WEIGHTEDGRAPH_H
#define WEIGHTEDGRAPH_H
#include <cctype>
#include <fstream>
#include <iomanip>
#include "MinHeap.h"
class WeightedGraph
{
int** g;
int nVertices;
//used to get convert from char to corrisponding index
int toIndex(char c){
c=tolower(c);
return static_cast<int>(c)-static_cast<int>('a');
}
//used to convert index to corrisponding char
char toChar(int index){
return 'a'+index;
}
public:
//returns the number of vertices
int getNVertices(){return nVertices;};
//returns weight of the edge connecting the given vertices
int getWeight(char ch1,char ch2){
int i=toIndex(ch1);
int j=toIndex(ch2);
return g[i][j];
};
// returns the indices of the neighbors of the vertex v as an int array
int* returnNeighbors(int v){
int* arr=new int[numNeighbors(v)];
for(int i=0,k=0;i<nVertices;i++){
if(g[v][i]!=0){
arr[k++]=i;
}
}
return arr;
};
//returns the number of neighbors of the vertex v
int numNeighbors(int v){
int count=0;
for(int i=0;i<nVertices;i++){
if(g[v][i]!=0)
count++;
}
return count;
};
//allocates the adjacency matrix & initializes edge weights from the specified file
void loadGraphFromFile(std::ifstream& obj){
obj>>nVertices;
g=new int*[nVertices];
for(int i=0 ; i<nVertices ; i++){
g[i]=new int[nVertices]{0};
}
int NOE;
obj>>NOE;
for(int i=0 ; i<NOE ; i++){
int x,y,weight;
char temp;
obj>>temp;
x=toIndex(temp);
obj>>temp;
y=toIndex(temp);
obj>>weight;
g[x][y]=weight;
//for undirected graph
//g[y][x]=weight;
}
};
//find the shortest path from the start vertex to all other vertices,
//by filling the prev array and the distances array
void dijkstra(char startVertex, char* prev, Node distances[]){
MinHeap m;
//~=infinity
int x=98765;
//initialize the distances array with labels and costs(infinity)
for(int i=0 ; i<nVertices ; i++){
distances[i].cost=x;
distances[i].label=toChar(i);
};
//sets start vertex cost to 0 and builds heap
distances[toIndex(startVertex)].cost=0;
prev[toIndex(startVertex)]=startVertex;
m.buildMinHeap(distances,nVertices);
while(m.getSize()>0){
//the min node in heap
Node minNode = m.extractMin();
//number of neighbours and neighbours array of min node
int NON=numNeighbors(toIndex(minNode.label));
int*nNodes=returnNeighbors(toIndex(minNode.label));
for(int i=0;i<NON;i++){
//new weight (accumilated)
int weight=getWeight(minNode.label,toChar(nNodes[i]))+minNode.cost;
//if in heap and weight in heap is > new weight
if(m.inHeap(toChar(nNodes[i])) && weight<distances[nNodes[i]].cost){
m.decreaseKey(toChar(nNodes[i]),weight);
distances[nNodes[i]].cost=weight;
prev[nNodes[i]]=minNode.label;
}
}
}
};
//just prints the 2d array / matrix for testing
void print(){
for(int i=0 ; i<nVertices ; i++){
for(int j=0 ; j<nVertices ; j++)
std::cout<<std::setw(4)<<g[i][j]<<" ";
std::cout<<"\n";
}
}
};
#endif