예제 #1
0
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;
	}
예제 #4
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;
}
예제 #5
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;
}
예제 #6
0
/* 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;
}
예제 #7
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();
		}
예제 #8
0
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;
}