-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathmain.cpp
More file actions
338 lines (252 loc) · 10.7 KB
/
Copy pathmain.cpp
File metadata and controls
338 lines (252 loc) · 10.7 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
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
#include <fstream>
#include <iostream>
#include <functional>
#include "ArchivosRectangulo.h"
#include "Rectangulo.h"
#include "AuxFunctions.h"
const unsigned int M = 40; // Capacidad máxima de HIJOS de un nodo.
const unsigned int N = 600;
Nodo* construirRtree(const std::vector<Rectangulo>& rectangulosOrdenados) {
if (rectangulosOrdenados.empty()) return nullptr;
// Convertir los rectángulos en nodos hoja.
std::vector<Nodo*> nodos;
for (const auto& rect : rectangulosOrdenados) {
Nodo* nodo = new Nodo();
nodo->entradas.push_back(Entrada(rect));
nodos.push_back(nodo);
}
for (const auto& nodo_ptr : nodos) {
nodo_ptr->entradas[0].mbr.imprimir(); //ESTO SOLO PARA COMPROBAR QUE CREA LOS NODOS HOJA!!!
}
// Si el número de nodos (o rectángulos) es menor a M, entonces simplemente deberíamos tener un nodo raíz que apunte a todos ellos.
if (nodos.size() <= M) {
Nodo* raiz = new Nodo();
for (Nodo* nodo : nodos) {
raiz->entradas.push_back(Entrada(nodo->calcularMBR(), nodo));
}
return raiz;
}
// Agrupamos los nodos en grupos de tamaño M y creamos nuevos nodos hasta llegar a la raíz.
while (nodos.size() > M) {
std::vector<Nodo*> nodosNuevos;
for (size_t i = 0; i < nodos.size(); i += M) {
Nodo* padre = new Nodo();
// Por cada nodo en este grupo, añadimos una entrada al nodo padre.
for (size_t j = i; j < i + M && j < nodos.size(); ++j) {
Nodo* hijo = nodos[j];
Rectangulo mbr = hijo->calcularMBR();
padre->entradas.push_back(Entrada(mbr, hijo));
}
nodosNuevos.push_back(padre);
}
nodos = nodosNuevos;
}
// Finalmente, el único nodo que queda es la raíz.
return nodos[0];
}
void imprimirRtree(Nodo* nodo, int nivel = 0) {
if (!nodo) return;
// Sangría para visualización jerárquica.
for (int i = 0; i < nivel; ++i) {
std::cout << " "; // Usamos dos espacios por nivel.
}
// Imprime información del nodo actual.
Rectangulo mbrNodo = nodo->calcularMBR();
std::cout << "Nodo (MBR: [" << mbrNodo.x1 << ", " << mbrNodo.y1 << ", " << mbrNodo.x2 << ", " << mbrNodo.y2 << "])" << std::endl;
// Si es un nodo hoja, imprime directamente las entradas.
if (nodo->entradas[0].hijo == nullptr) {
for (const auto& entrada : nodo->entradas) {
for (int i = 0; i < nivel + 1; ++i) {
std::cout << " ";
}
std::cout << "Entrada (MBR: [" << entrada.mbr.x1 << ", " << entrada.mbr.y1 << ", " << entrada.mbr.x2 << ", " << entrada.mbr.y2 << "])" << std::endl;
}
}
else {
// Si no es una hoja, imprimimos recursivamente los hijos.
for (const auto& entrada : nodo->entradas) {
imprimirRtree(entrada.hijo, nivel + 1);
}
}
}
void guardarNodo(const Nodo* nodo, std::ofstream& outFile) {
if (nodo->entradas[0].hijo) {
outFile << "N "; // Nodo interno
}
else {
outFile << "L "; // Nodo hoja
}
outFile << nodo->entradas.size() << std::endl; // Guardar cuántas entradas tiene el nodo.
for (const Entrada& entrada : nodo->entradas) {
// Guardar el MBR.
outFile << entrada.mbr.x1 << " " << entrada.mbr.y1 << " " << entrada.mbr.x2 << " " << entrada.mbr.y2 << std::endl;
// Si tiene un hijo, recursivamente guardar ese nodo.
if (entrada.hijo) {
guardarNodo(entrada.hijo, outFile);
}
}
}
void guardarRTree(const Nodo* raiz, const std::string& filename) {
std::ofstream outFile(filename);
if (outFile.is_open()) {
guardarNodo(raiz, outFile);
outFile.close();
}
}
Nodo* leerNodo(std::ifstream& inFile) {
char tipoNodo;
inFile >> tipoNodo;
Nodo* nodo = new Nodo();
size_t numEntradas;
inFile >> numEntradas;
for (size_t i = 0; i < numEntradas; ++i) {
Rectangulo mbr;
inFile >> mbr.x1 >> mbr.y1 >> mbr.x2 >> mbr.y2;
Entrada entrada(mbr);
if (tipoNodo == 'N') {
entrada.hijo = leerNodo(inFile);
}
nodo->entradas.push_back(entrada);
}
return nodo;
}
Nodo* leerRTree(const std::string& filename) {
std::ifstream inFile(filename);
if (!inFile.is_open()) {
std::cerr << "Error: No se pudo abrir el archivo " << filename << "\n";
return nullptr;
}
Nodo* raiz = leerNodo(inFile);
inFile.close();
return raiz;
}
void buscarNodo(std::ifstream& inFile, const Rectangulo& C, std::vector<Rectangulo>& resultados, int& accesos) {
accesos++;
char tipoNodo;
inFile >> tipoNodo;
size_t numEntradas;
inFile >> numEntradas;
for (size_t i = 0; i < numEntradas; ++i) {
Rectangulo mbr;
inFile >> mbr.x1 >> mbr.y1 >> mbr.x2 >> mbr.y2;
if (C.intersecta(mbr)) {
if (tipoNodo == 'N') { // Nodo interno
buscarNodo(inFile, C, resultados, accesos);
}
else { // Nodo hoja
resultados.push_back(mbr);
}
}
}
}
std::vector<Rectangulo> buscarRectangulosIntersectados(const std::string& filename, const Rectangulo& C, int& accesos) {
std::vector<Rectangulo> resultados;
accesos = 0;
std::ifstream inFile(filename, std::ios::binary);
if (!inFile.is_open()) {
std::cerr << "Error: No se pudo abrir el archivo " << filename << "\n";
return resultados;
}
buscarNodo(inFile, C, resultados, accesos);
inFile.close();
return resultados;
}
int main() {
//ver si pudimos escribir los rectangulos
escribirRectangulos(N, "rectangles.bin");
std::cout << "Se escribieron " << N << " rectangulos en rectangles.bin\n"; //1ra linea
//este bloque de codigo es solo para chequear si ordenamos bien los rectangulos
std::string filename = "ordered-rectangles.bin";
ordenarRectangulosPorCentro("rectangles.bin", filename);
if (estanOrdenados("ordered-rectangles.bin")) {
std::cout << "Los rectangulos estan correctamente ordenados.\n"; //2da linea
std::cout << "Se pusieron ordenados en ordered-rectangles.bin\n"; //3ra linea
}
else {
std::cerr << "Los rectángulos no están ordenados.\n";
}
//estas dos lineas solo revisa que se lean los rectangulos ORDENADOS desde el binario
//que los TENIA ordenados.
std::vector < Rectangulo > rectangles = leerRectangulos(filename);
std::cout << "Se leyeron los rectangulos de ordered-bin y se guardaron en un array\n"; //4ta linea
// PARA MAS COMPROBACION DE LO ANTERIOR.
// en esta las lineas.
// imprimimos todos los rectangulos ordenados.
std::cout << "\nAhora los imprimimos ordenados (estos rectangulos serian las hojas)\n"; //5ta linea
for (const Rectangulo& rect : rectangles) {
rect.imprimir();
}
// Aqui construimos el R-tree EN RAM y lo imprimimos
std::cout << "\nComenzamos la construccion del R-tree\n";
Nodo* raiz = construirRtree(rectangles);
std::cout << "Construido!\n";
std::cout << "\nAHORA LO IMPRIMIMOS\n";
std::cout << "-----------------" << std::endl;
imprimirRtree(raiz, 0);
// este bloque es importante porque aqui guardamos el arbol anterior en.
// disco y lo volvimos a imprimir para comprobar que sea igual al anterior.
std::cout << "\n\n";
guardarRTree(raiz, "Rtree.bin");
Nodo* raizLeida = leerRTree("Rtree.bin");
std::cout << "Arbol R leido del archivo, pero leido desde el archivo:\n";
std::cout << "--------------------------\n";
imprimirRtree(raizLeida, 0);
std::cout << "--------------------------\n";
int accesos = 0;
Rectangulo C(0.1,0.1, 499999.0, 499999.0 ); // Define tu rectángulo de consulta aquí.
std::vector<Rectangulo> rectangulosIntersectados = buscarRectangulosIntersectados("Rtree.bin", C, accesos);
std::cout << "Accesos a disco: " << accesos << std::endl;
for (const Rectangulo& rect : rectangulosIntersectados) {
std::cout << "\nAAASHDJAakakaHAHD\n";
rect.imprimir();
}
// Crear y mostrar grupos de rectángulos
std::cout << "\nAhora los agrupamos en grupos de tamano" << M << " y los imprimimos : \n";
std::vector < std::vector < Rectangulo >> grupos = agruparRectangulos(rectangles, M);
int numeroGrupo = 1; // Iniciar contador de grupos
for (const auto& grupo : grupos) {
std::cout << "\n---- Grupo " << numeroGrupo << " ----\n";
for (const Rectangulo& rect : grupo) {
rect.imprimir();
}
std::cout << "--------------\n";
numeroGrupo++;
}
std::cout << "\n--------------------------" << "\n--------------------------\n";
std::cout << "\n111111111111111111\n";
// Después de haber creado los grupos:
std::vector<Nodo> nodos = crearNodosDesdeGrupos(grupos);
std::cout << "Aqui los grupos que creamos antes los transformamos en nodos!\n";
std::cout << "Se crearon " << nodos.size() << " nodos." << std::endl;
std::cout << "\n--------------------------\n";
std::cout << "\nprinteamos los hijos de cada unos de estos nodos\n";
for (size_t i = 0; i < nodos.size(); ++i) {
std::cout << "Nodo " << (i + 1) << " tiene los siguientes hijos:\n";
for (const Entrada& entrada : nodos[i].entradas) {
if (entrada.hijo) {
// Si tienes alguna forma de identificar cada nodo, la puedes imprimir aquí.
// Por simplicidad, aquí solo indicamos que hay un hijo.
std::cout << " - Tiene un hijo\n";
}
else {
// No hay hijo, solo es una entrada de hoja.
entrada.mbr.imprimir();
}
}
std::cout << "------------------------\n";
}
//Aqui calculamos el MBR de cada uno de los nodos que creamos antes y los ordenamos, obviamente
std::cout << "\nAqui calculamos el MBR de cada uno de los nodos que creamos antes y los ordenamos, obviamente\n";
std::vector<Rectangulo> rectangulosMBRS = calcularMBRsDeNodos(nodos); //ESTAN DESORDENADOS.
ordenarPorCentroX(rectangulosMBRS);
// Imprimir rectángulos MBRS de
std::cout << "\nAhora los imprimimos \n" << "--------------------------\n";
for (const Rectangulo& rect : rectangulosMBRS) {
rect.imprimir();
}
std::cout << "--------------------------\n";
std::cout << "Esta ultima parte es mas que nada para comprobar\nque se estaba haciendo bien el procedimiento\n";
imprimirMBRsDeNodos(nodos);
std::cout << "--------------------------\n";
return 0;
}