Skip to content

nighthawk1020/Divide-and-conquer-closest-pair-algorithm

Repository files navigation

To run this program you have to type make into the command line.
Then after compilation you have to type:
./submission inputFile.txt outputFile.txt
Anything else will not be allowed.
It runs under the assumption that the input file looks like:
index	x	y
index	x	y
and will output a file that gives:
distance
index	x	y
index	x	y
The time complexity of the Divide and Conquer is going to be O(n*log(n)^2) and the brute force algorithm will be O(n^2)
It will output the time of the brute force algorithm as well as the divide and conquer algorithm in nanoseconds to the command line.
My code is as follows:
#include <stdio.h>
#include <float.h>
#include <stdlib.h>
#include <math.h>
#include <vector>
#include <algorithm>
#include <iostream>
#include <fstream>
#include <chrono>
using namespace std;
struct Point{
	int index;
	double x;
	double y;
};
Point smallestP1;
Point smallestP2;
Point smallestP3;
Point smallestP4;
vector<Point> *vec = new vector<Point>;
vector<Point> *vec2 = new vector<Point>;
int arraySize = 0;
int compX(const void* lhs, const void* rhs){
	Point* p1 = (Point*) lhs;
	Point* p2 = (Point*) rhs;
	return (p1->x - p2->x);
};
int compY(const void* lhs, const void* rhs){
	Point* p1 = (Point*) lhs;
	Point* p2 = (Point*) rhs;
	return (p1->y - p2->y);
};
void read(ifstream& stream){
	Point point;
	stream>>point.index;
	while(stream.is_open()){
		stream>>point.x;
		stream>>point.y;
		vec->push_back(point);
		vec2->push_back(point);
		stream>>point.index;
		if(stream.eof()){
			stream.close();
		}
	}arraySize = (int)vec->size();
};
int distance(Point p1, Point p2){
	return sqrt((p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y));
};
int smallestDistance(Point a[], int size){
	double min = DBL_MAX;
	for(int i = 0; i < size; i++){
		for(int j = i + 1; j < size; j++){
			if(distance(a[i], a[j]) < min){
				min = distance(a[i], a[j]);
				smallestP1 = a[i];
				smallestP2 = a[j];
			}
		}
	}return min;
};
int min(int x, int y){
	if(x < y){
		return x;
	}else{
		return y;
	}
};
double closest(Point a[], int size, double dist){
	double min = dist;
	qsort(a, size, sizeof(Point), compY);
	for(int i = 0; i < size; i++){
		for(int j = i + 1; j < size && (a[j].y - a[i].y) < min; j++){
			if(distance(a[i], a[j]) < min){
				min = distance(a[i], a[j]);
			}
		}
	}return min;
};
double closestPoints(Point a[], int size){
	if(size <= 3){
		return smallestDistance(a, size);
	}int middle = size/2;
	Point midPoint = a[middle];
	double leftSmallestDistance = closestPoints(a, middle);
	double rightSmallestDistance = closestPoints(a + middle, size - middle);
	double smallestDist = min(leftSmallestDistance, rightSmallestDistance);
	Point stripArr[size];
	int j = 0;
	for(int i = 0; i < size; i++){
		if(abs(a[i].x - midPoint.x) > smallestDist){
			stripArr[j] = a[i];
			j++;
		}
	}return min(smallestDist, closest(stripArr, j, smallestDist));
};
void closestPointsAux(Point a[], int size, ofstream& outFile){
	double retVal = closestPoints(a, size);
	outFile<<retVal<<endl;
	outFile<<smallestP2.index<<"	"<<smallestP2.x<<"	"<<smallestP2.y<<endl;
	outFile<<smallestP1.index<<"	"<<smallestP1.x<<"	"<<smallestP1.y<<endl;
};
void findClosest(Point a[], ofstream& outFile){
	qsort(a, arraySize, sizeof(Point), compX);
	closestPointsAux(a, arraySize, outFile);
};
void bruteForceAlgorithm(vector<Point> *vector1, ofstream& outFile){
	double minDist = DBL_MAX;
	for(int i = 0; i < (int) vector1->size(); i++){
		for(int j = i + 1; j < (int) vector1->size(); j++){
			if(distance(vector1->at(i), vector1->at(j)) < minDist){
				minDist = distance(vector1->at(i), vector1->at(j));
				smallestP3 = vector1->at(i);
				smallestP4 = vector1->at(j);
			}
		}
	}outFile<<minDist<<endl;
	outFile<<smallestP3.index<<"	"<< smallestP3.x<<"	"<<smallestP3.y<<endl;
	outFile<<smallestP4.index<<"	"<< smallestP4.x<<"	"<<smallestP4.y<<endl;
};
int main(int argc, char* argv[]){
	if(argc != 3){
		cout<<"Please input an inputFile and an outputFile"<<endl;
		return 1;
	}else{
		ifstream in(argv[1]);
		ofstream out(argv[2]);
		ofstream out2("BruteForceOutput.txt");
		if(!in.is_open()){
			cout<<"Please input a valid file"<< endl;
			return 1;
		}read(in);
		Point a[arraySize];
		for(int i = 0; i < (int)vec->size(); i++){
			a[i] = vec->at(i);
		}
		chrono::nanoseconds elapsed;
		chrono::steady_clock::time_point start, finish;
		start = chrono::steady_clock::now();
		bruteForceAlgorithm(vec2, out2);
		finish = chrono::steady_clock::now();
		elapsed = chrono::duration_cast<chrono::nanoseconds>(finish - start);
		cout<<"The timing of my brute force algorithm is "<<elapsed.count()<<" nanosedconds"<<endl;
		start = chrono::steady_clock::now();
		findClosest(a, out);
		finish = chrono::steady_clock::now();
		elapsed = chrono::duration_cast<chrono::nanoseconds>(finish - start);
		cout<<"The timing of my divide and conquer algorithm is "<<elapsed.count()<<" nanoseconds"<<endl;
	}return 0;
};
trial run for the first example in the assignment document:
output file:
1.41421
0	10000	10000
1	9999	9999

command line output:
The timing of my brute force algorithm is 3100430819 nanoseconds
The timing of my divide and conquer algorithm is 16279863 nanoseconds

trial run for the second example in the assignment document:
output file:
1.41421
0	0	0
1	1	1

command line output:
The timing of my brute force algorithm is 3100430819 nanoseconds
The timing of my divide and conquer algorithm is 16279863 nanoseconds

There are no bugs that i can find. My program works perfectly for my test cases.

About

A divide and conquer algorithm for the closest pair of points problem

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published