diff --git a/src/divide_and_conquer.c b/src/divide_and_conquer.c index b846522..a22f1f8 100644 --- a/src/divide_and_conquer.c +++ b/src/divide_and_conquer.c @@ -20,31 +20,54 @@ /** * Encontrar los 2 puntos más cercano usando el metodo de dividir para conquistar - * @param points Los puntos a calcular - * @param n La cantidad de puntos en el array points + * @param point_ts Los puntos a calcular + * @param n La cantidad de puntos en el array point_ts * @param minimum_dist La distancia minimo encontrado * @return Retorna los 2 puntos mas cercanos */ int compareX(const void* a, const void* b){ //ordena el arreglo de puntos de acuerdo a X - Point *p1 = (Point *)a, *p2 = (Point *)b; + point_t *p1 = (point_t *)a, *p2 = (point_t *)b; return (p1->x - p2->x); } int compareY(const void* a, const void* b){ //ordena el arreglo de puntos de acuerdo a Y - Point *p1 = (Point *)a, *p2 = (Point *)b; + point_t *p1 = (point_t *)a, *p2 = (point_t *)b; return (p1->y - p2->y); } -float min(float x, float y){ // Función para encontrar la distancia minima entre dos valores de tipo flotante +float min(float x, float y){ // Función para encontrar el mayor entre dos valores flotantes return (x < y)? x : y; } +float closestUtil(point_t P[], int n){ // Función para encontrar la distancia más corta entre puntos + int mid = n/2; + point_t midpoint_t = P[mid]; + + // Consider the vertical line passing through the middle point_t + // calculate the smallest distance dl on left of middle point_t and + // dr on right side + float dl = closestUtil(P, mid); + float dr = closestUtil(P + mid, n-mid); + + float d = min(dl, dr); // Encontrar la distancia minima de dos puntos + + /* Crea un arreglo que contiene los puntos cercanos, mas cerca que d*/ + point_t strip[n]; + int j = 0; + for (int i = 0; i < n; i++) + if (abs(P[i].x - midpoint_t.x) < d) + strip[j] = P[i], j++; + + /*Encontrar el punto más cercano en la cinta, retornando el minimo de d y el más cercano + distance es strip[]*/ + return min(d, stripClosest(strip, j, d) ); +} -float stripClosest(Point strip[], int size, float d) // Función para encontrar la distancia entre los puntos más cerca del arreglo dado +float stripClosest(point_t strip[], int size, float d) // Función para encontrar la distancia entre los puntos más cerca del arreglo dado { float min = d; // inicializa en la distancia minima d - qsort(strip, size, sizeof(Point), compareY); + qsort(strip, size, sizeof(point_t), compareY); for (int i = 0; i < size; ++i) for (int j = i+1; j < size && (strip[j].y - strip[i].y) < min; ++j) @@ -55,99 +78,50 @@ float stripClosest(Point strip[], int size, float d) // Función para encontrar } point_t * divide_and_conquer(point_t *points, unsigned int n, double *minimum_dist) { - - if (n <= 3) - return brute_force(points, n, &minimum_dist); + point_t *closest_pair = malloc(sizeof(point_t) * 2); - // Función para encontrar la distancia más corta entre puntos - float closestUtil(Point P[], int n) + float closest(point_t P[], int n) + { + qsort(P, n, sizeof(point_t), compareX); + return closestUtil(P, n); /*Uso recursivo de la funcion closestUtil() para encontrar la distancia más pequeña*/ + } + return closest_pair; + } + + float closestUtil(point_t P[], int n) /*Función recursiva para encontrar la distancia más pequeña. El arreglo + P contiene todos los puntos ordenados respecto a la cordenada X */ { - // Si hay igual o menos puntos a 3 utilizará el de fuerza bruta - if (n <= 3) - return bruteForce(P, n); - ------ int mid = n/2; - Point midPoint = P[mid]; - - // Consider the vertical line passing through the middle point - // calculate the smallest distance dl on left of middle point and - // dr on right side + point_t midpoint_t = P[mid]; + /*Considerando la linea vertical que pasa a travez del punto medio, calcula el distanca mas corta en dl + de la izquierda de la mitad y dr en el lado derecho*/ float dl = closestUtil(P, mid); float dr = closestUtil(P + mid, n-mid); // Find the smaller of two distances float d = min(dl, dr); - // Build an array strip[] that contains points close (closer than d) - // to the line passing through the middle point - Point strip[n]; + // Build an array strip[] that contains point_ts close (closer than d) + // to the line passing through the middle point_t + point_t strip[n]; int j = 0; for (int i = 0; i < n; i++) - if (abs(P[i].x - midPoint.x) < d) + if (abs(P[i].x - midpoint_t.x) < d) strip[j] = P[i], j++; - // Find the closest points in strip. Return the minimum of d and closest + // Find the closest point_ts in strip. Return the minimum of d and closest // distance is strip[] return min(d, stripClosest(strip, j, d) ); } // The main functin that finds the smallest distance // This method mainly uses closestUtil() - float closest(Point P[], int n) + float closest(point_t P[], int n) { - qsort(P, n, sizeof(Point), compareX); + qsort(P, n, sizeof(point_t), compareX); // Use recursive function closestUtil() to find the smallest distance return closestUtil(P, n); } -return closest_pair; -} --------- -float closestUtil(Point P[], int n) /*Función recursiva para encontrar la distancia más pequeña. El arreglo - P contiene todos los puntos ordenados respecto a la cordenada X */ -{ - int mid = n/2; - Point midPoint = P[mid]; - - // Consider the vertical line passing through the middle point - // calculate the smallest distance dl on left of middle point and - // dr on right side - float dl = closestUtil(P, mid); - float dr = closestUtil(P + mid, n-mid); - - // Find the smaller of two distances - float d = min(dl, dr); - - // Build an array strip[] that contains points close (closer than d) - // to the line passing through the middle point - Point strip[n]; - int j = 0; - for (int i = 0; i < n; i++) - if (abs(P[i].x - midPoint.x) < d) - strip[j] = P[i], j++; - - // Find the closest points in strip. Return the minimum of d and closest - // distance is strip[] - return min(d, stripClosest(strip, j, d) ); -} - -// The main functin that finds the smallest distance -// This method mainly uses closestUtil() -float closest(Point P[], int n) -{ - qsort(P, n, sizeof(Point), compareX); - - // Use recursive function closestUtil() to find the smallest distance - return closestUtil(P, n); -} - -// Driver program to test above functions -int main() -{ - Point P[] = {{2, 3}, {12, 30}, {40, 50}, {5, 1}, {12, 10}, {3, 4}}; - int n = sizeof(P) / sizeof(P[0]); - printf("The smallest distance is %f ", closest(P, n)); - return 0; -} \ No newline at end of file