-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgraph.cpp
More file actions
309 lines (270 loc) · 9.24 KB
/
graph.cpp
File metadata and controls
309 lines (270 loc) · 9.24 KB
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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
#include "graph.h"
// Metodo que vai inserir na classe seus atributos
Materia::Materia(string id, string nome, int peso)
{
this->id = id;
this->nome = nome;
this->peso = peso;
this->grau = 0;
}
void Materia::InsertCon(Materia *materia)
{
conexoes.push_back(materia);
}
void Materia::InsertAnt(Materia *materia)
{
antecessor.push_back(materia);
}
// vai procurar o index da materia
int SearchMateriaIndex(vector<Materia *> materias, Materia *materia)
{
int i = 0;
while (materias[i]->id != materia->id)
{
i++;
}
return i;
}
// Vai procurar se tem a materia
bool SearchMateria(vector<Materia *> materias, Materia *materia)
{
for (int i = 0; i < materias.size(); i++)
{
if (materias[i]->id == materia->id)
{
return true;
}
}
return false;
}
vector<Materia *> OrganizacaoTopologica(vector<Materia *> materias)
{
queue<Materia *> fila;
queue<Materia *> filafinal;
int contadordevertices = 0;
// Vai colocar na pilha as materias que nao tem depedencia
for (int i = 0; i < materias.size(); i++)
{
if (materias[i]->grau == 0)
{
fila.push(materias[i]);
}
}
// parte do programa que vai percorrer as conexoes pra fazer a ordenacao topologica
while (!fila.empty())
{
contadordevertices++;
if (fila.front()->conexoes.size() != 0)
{
for (int i = 0; i < fila.front()->conexoes.size(); i++)
{
// verifica se grau da conexao eh 0, pelo fato de quando chegar a zero
// significa que nao tem mais caminho para percorre e vai ser adicionado na fila
fila.front()->conexoes[i]->grau--;
if (fila.front()->conexoes[i]->grau == 0)
{
fila.push(fila.front()->conexoes[i]);
}
}
}
filafinal.push(fila.front());
fila.pop();
}
// Vai inverter a pilha
vector<Materia *> vecordenado;
for (int i = (filafinal.size() - 1); i >= 0; i--)
{
vecordenado.push_back(filafinal.front());
filafinal.pop();
}
return vecordenado;
}
// Funcao vai fazer o caminho pra ver quais materias faz parte do caminho critico
vector<Materia *> BuildPath(vector<Materia *> materias, int *distanciaMaterias, int distanciaMax, int indexMax)
{
vector<Materia *> temp;
stack<Materia *> pilha;
Materia *materiaAtual = materias[indexMax];
int Distancia = 0;
pilha.push(materiaAtual);
//Construindo caminho para a materia selecionada
while (Distancia != distanciaMax)
{
for (int i = 0; i < materias.size(); i++)
{
for (int j = 0; j < materias[i]->conexoes.size(); j++)
{
int atualIndex = SearchMateriaIndex(materias, materiaAtual);
int previous = SearchMateriaIndex(materias, materias[i]);
// Verifica se a soma da distancia e o peso da materia anterior vai ser o peso total do caminho
if ((materias[i]->conexoes[j] == materiaAtual) && (distanciaMaterias[atualIndex] == distanciaMaterias[previous] + materias[i]->peso))
{
pilha.push(materias[i]);
Distancia += materias[i]->peso;
materiaAtual = materias[i];
}
}
}
}
//Invertendo ordem da pilha para o vetor a ser retornado
while (!pilha.empty())
{
temp.push_back(pilha.top());
pilha.pop();
}
return temp;
}
// Funcao que vai fazer o caminho critico
vector<vector<Materia *>> CPM(vector<Materia *> materias)
{
vector<Materia *> materias2 = materias;
vector<Materia *> materias3 = materias;
queue<Materia *> fila;
int distancia[materias.size()];
//Inicializando vetor de distancias e fila de materias
for (int i = 0; i < materias.size(); i++)
{
distancia[i] = 0;
if (materias[i]->grau == 0)
{
fila.push(materias[i]);
}
}
// Preenchendo vetor de distancias e fila ordenada
// Nela vai colocar a maior distancia que que a materia pode ter
while (!fila.empty())
{
Materia *materia = fila.front();
fila.pop();
for (int i = 0; i < materia->conexoes.size(); i++)
{
// procura os index da materia que vai ser analisado e sua anterior
int indexMateria = SearchMateriaIndex(materias, materia->conexoes[i]);
int previousMateria = SearchMateriaIndex(materias, materia);
// Vai adicionar os pesos maximos para cada materia, adicionando a distancia total da anterior
// mais o peso dela.
distancia[indexMateria] = max(distancia[indexMateria], distancia[previousMateria] + materia->peso);
materia->conexoes[i]->grau--;
if (materia->conexoes[i]->grau == 0)
{
fila.push(materia->conexoes[i]);
}
}
}
int Max1 = 0;
int Max2 = 0;
int Max3 = 0;
int index1 = 0;
int index2 = 0;
int index3 = 0;
//Materias com a maiores distancias
for (int i = 0; i < materias.size(); i++)
{
if (distancia[i] >= Max1)
{
Max1 = distancia[i];
index1 = i;
}
}
//Gerando caminhos criticos e retornando
vector<vector<Materia *>> CPM;
vector<Materia *> firstCPM = BuildPath(materias, distancia, Max1, index1);
// Colocando os graus ao normal, ja que foram zerados
for(int i = 0; i < materias.size(); i++){
for(int j = 0; j < materias[i]->conexoes.size(); j++)
materias2[i]->conexoes[j]->grau++;
}
//Inicializando vetor de distancias e fila de materias
for (int i = 0; i < materias2.size(); i++)
{
distancia[i] = 0;
if (materias2[i]->grau == 0)
{
fila.push(materias2[i]);
}
}
// Preenchendo vetor de distancias e fila ordenada
// Nela vai colocar a maior distancia que que a materia pode ter
while (!fila.empty())
{
Materia *materia = fila.front();
fila.pop();
// Verifica se a materia ja foi chamada nos outros caminhos criticos
if(!SearchMateria(firstCPM,materia)){
for (int i = 0; i < materia->conexoes.size(); i++)
{
// procura os index da materia que vai ser analisado e sua anterior
int indexMateria = SearchMateriaIndex(materias2, materia->conexoes[i]);
int previousMateria = SearchMateriaIndex(materias2, materia);
// Vai adicionar os pesos maximos para cada materia, adicionando a distancia total da anterior
// mais o peso dela.
distancia[indexMateria] = max(distancia[indexMateria], distancia[previousMateria] + materia->peso);
materia->conexoes[i]->grau--;
if (materia->conexoes[i]->grau == 0)
{
fila.push(materia->conexoes[i]);
}
}
}
}
for (int i = 0; i < materias.size(); i++)
{
if (distancia[i] >= Max2)
{
Max2 = distancia[i];
index2 = i;
}
}
vector<Materia *> secondCPM = BuildPath(materias2, distancia, Max2, index2);
// Colocando os graus ao normal, ja que foram zerados
for(int i = 0; i < materias.size(); i++){
for(int j = 0; j < materias[i]->conexoes.size(); j++)
materias3[i]->conexoes[j]->grau++;
}
//Inicializando vetor de distancias e fila de materias
for (int i = 0; i < materias3.size(); i++)
{
distancia[i] = 0;
if (materias3[i]->grau == 0)
{
fila.push(materias3[i]);
}
}
// Preenchendo vetor de distancias e fila ordenada
// Nela vai colocar a maior distancia que que a materia pode ter
while (!fila.empty())
{
Materia *materia = fila.front();
fila.pop();
// Verifica se a materia ja foi chamada nos outros caminhos criticos
if(!SearchMateria(firstCPM,materia) && !SearchMateria(secondCPM,materia)){
for (int i = 0; i < materia->conexoes.size(); i++)
{
// procura os index da materia que vai ser analisado e sua anterior
int indexMateria = SearchMateriaIndex(materias3, materia->conexoes[i]);
int previousMateria = SearchMateriaIndex(materias3, materia);
// Vai adicionar os pesos maximos para cada materia, adicionando a distancia total da anterior
// mais o peso dela.
distancia[indexMateria] = max(distancia[indexMateria], distancia[previousMateria] + materia->peso);
materia->conexoes[i]->grau--;
if (materia->conexoes[i]->grau == 0)
{
fila.push(materia->conexoes[i]);
}
}
}
}
for (int i = 0; i < materias.size(); i++)
{
if (distancia[i] >= Max3)
{
Max3 = distancia[i];
index3 = i;
}
}
vector<Materia *> thirdCPM = BuildPath(materias, distancia, Max3, index3);
CPM.push_back(firstCPM);
CPM.push_back(secondCPM);
CPM.push_back(thirdCPM);
return CPM;
}