void closest_pair(int64_t low, int64_t length){ // printf("\nentered closest_pair with low = %"PRId64"length = %"PRId64,low,length); if(length == 2){ P = X[low]; Q = X[low+1]; //return dist(X[low],X[low+1]) // base } else if(length==3){ bruteforce(low,length); } else if(length>3){ // printf("\nentered else"); closest_pair(low,(length/2)); // divide Pt pL1 = P, pL2 = Q; // int64_t d1 = (pL2.x - pL1.x)*(pL2.x - pL1.x) + (pL2.y - pL1.y)*(pL2.y - pL1.y); int64_t d1 = distance_square(pL1,pL2); // printf("\ndL = %"PRId64,d1); closest_pair(low+length/2,(length/2) + (length%2)); Pt pR1 = P, pR2 = Q; // int64_t d2 = (pR2.x - pR1.x)*(pR2.x - pR1.x) + (pR2.y - pR1.y)*(pR2.y - pR1.y); int64_t d2 = distance_square(pR1,pR2); // printf("\tdR = %"PRId64,d2); int64_t d = 0; if(d1<d2){ d=d1; P = pL1; Q = pL2; } else { d=d2; P = pR1; Q = pR2; } // printf("\tdmin = %"PRId64,d); // Sy = points in Py within d of L // merge Pt Sy[length],mid; int64_t j =0; mid.x = X[length/2].x; mid.y = X[length/2].y; for(int64_t i = low;i<(low+length);i++){ mid.y = X[i].x; if(is_closer_than(X[i],mid,d)){ Sy[j++] = X[i]; } } //For i = 1,...,|Sy|: //For j = 1,...,15: //d = min( dist(Sy[i], Sy[j]), d ) for(int64_t i = 0;i<j;i++){ for(int64_t k = 0; k<15;k++){ if(is_closer_than(Sy[i],Sy[k],d)){ P = Sy[i]; Q = Sy[k]; int64_t temp = distance_square(Sy[k],Sy[i]); (temp<d)?(d=temp):(d=d); } } } // Return d } // printf("\t Px = %"PRId64",Py = %"PRId64,P.x,P.y); // printf(" Qx = %"PRId64",Qy = %"PRId64,Q.x,Q.y); }
struct winner_info* closest_pair(int N, struct point* Px, struct point* Py){ struct winner_info* W_temp, *W; /*base case*/ if (N<=3){ W = brute_force_closest_pair(N, Px); return W; } /*create the array of points sorted vertically that are on each half of the plane*/ int mid = N/2; struct point* Pyl = malloc(sizeof(struct point)*mid); struct point* Pyr = malloc(sizeof(struct point)*(N-mid)); int li = 0, ri = 0; for(int i = 0; i<N; i++){ if (Py[i].x<=Px[mid-1].x){ Pyl[li].x = Py[i].x; Pyl[li].y = Py[i].y; li++; }else{ Pyr[ri].x = Py[i].x; Pyr[ri].y = Py[i].y; ri++; } } /*Recursive call to function on left half of points*/ struct winner_info* L1 = closest_pair(mid, Px, Pyl); /*Recursive call to function on right half of points*/ struct winner_info* R1 = closest_pair(N-mid, Px+mid, Pyr); /*Best out of the two halves*/ if ((L1->dist) < (R1->dist)) W_temp = L1; else W_temp = R1; /*Invoke closest split pair*/ struct winner_info* S1 = closest_split_pair(Py, N, W_temp->dist, Px[mid-1].x); /*Best of all*/ if((W_temp->dist)<(S1->dist)) W = W_temp; else W = S1; return W; }
int main(int argc, char* argv[]){ FILE* fp = fopen("grandma_coords.txt", "r"); struct point* input_coords; size_t num_coords; clock_t start, end; double cpu_time_used; num_coords = parse_input(fp, &input_coords); /*creating two arrays sorted by x-coord and y-coord*/ struct point* sorted_x_coords, *sorted_y_coords; sorted_x_coords = malloc(sizeof(struct point)*num_coords); sorted_y_coords = malloc(sizeof(struct point)*num_coords); for(int i = 0; i<num_coords; i++){ sorted_x_coords[i].x = input_coords[i].x; sorted_x_coords[i].y = input_coords[i].y; sorted_y_coords[i].x = input_coords[i].x; sorted_y_coords[i].y = input_coords[i].y; } qsort(sorted_x_coords, num_coords, sizeof(struct point), cmpfunc_x); qsort(sorted_y_coords, num_coords, sizeof(struct point), cmpfunc_y); /*Invoking the closest pair algo*/ start = clock(); struct winner_info* winner = closest_pair(num_coords, sorted_x_coords, sorted_y_coords); end = clock(); cpu_time_used = ((double)(end-start))/CLOCKS_PER_SEC; printf("The winning points are (%lf, %lf) and (%lf, %lf)\n", (winner->W1).x, (winner->W1).y, (winner->W2).x, (winner->W2).y); printf("\n Time taken by program = %f\n", cpu_time_used); return 0; }
int64_t main() { scanf("%"PRId64, &N); for (int64_t i = 0; i < N; ++i) scanf("%"PRId64"%"PRId64, &X[i].x, &X[i].y); for (int64_t i = 0; i < N; ++i) scanf("%"PRId64"%"PRId64, &Y[i].x, &Y[i].y); closest_pair(0,N); printf("%"PRId64" %"PRId64" %"PRId64" %"PRId64"\n", P.x, P.y, Q.x, Q.y); return 0; }
double closest_pair(Point p[], int n) { int nl = n/2, nr = n - nl; double dl, dr, d, ans; int i, j; dl = (nl > 1) ? closest_pair(p,nl) : INF; dr = (nr > 1) ? closest_pair(&p[nl],nr) : INF; ans = min(dl,dr); for (i=0; i < nl; i++) { if (p[nl].x-p[i].x > ans) continue; for (j=0; j < nr; j++) { if (fabs(p[nl+j].y-p[i].y) > ans) continue; d = dist_pp(&p[i],&p[nl+j]); ans = min(ans,d); } } return ans; }
/* closest_pair.c : Closest pair implementation as personal practice for Standford online course * Algorithms: Design and Analysis, Part I https://www.coursera.org/course/algo * Usage: closest_pair <file> * file must be a text file with the points x,y every point must be separated by blank spaces, the output will * be the closest pair */ int main(int argc, char *argv[]) { if (argc != 2) die("USAGE: closest_pair <file> "); struct PointArray *result = malloc(sizeof(struct PointArray)); char *filename = argv[1]; result = closest_pair(filename); /* printf("closest pair points :\n"); printf("point 1 :\n"); print_point(result->array[0]); printf("point 2 :\n"); print_point(result->array[1]); */ return 0; }
double run(const int num_trials) { fprintf(stderr,"run\n"); fprintf(stderr,"size = %d\n",size); fprintf(stderr,"num_trials = %d\n",num_trials); fprintf(stderr,"data = %p\n",data); assert(status==2); TimeStat clk(num_trials); double *tmp=(double*)malloc(sizeof(double)*size*2); assert(tmp); for (int i = 0; i < num_trials; i++) { //printf("\t%d\n",i); memcpy(tmp,data,sizeof(double)*size*2); double _Complex pos[2]; clk.tic(); closest_pair(size,tmp,pos); clk.toc(); } free(tmp); status=3; return clk.median(); }
int main() { int i, N, k; puts("Insert a value N, followed by N coordinates."); for (k = 0; scanf("%d", &N) == 1 && N; k++) { vp p; for (i = 0; i < N; i++) { double n1, n2; scanf("%lf %lf", &n1, &n2); p.push_back(Point((int)n1, (int)n2)); } sort(p.begin(), p.end());//sort by x-coordinate double dist1 = closest_pair(p, 0, N - 1); if (sqrt(dist1) >= INF_THRESHOLD) printf(" %d INFINITY\n", k); else printf("%d %.4lf\n", k, sqrt(dist1)); } return 0; }