-
Notifications
You must be signed in to change notification settings - Fork 0
nighthawk1020/Divide-and-conquer-closest-pair-algorithm
Folders and files
| Name | Name | Last commit message | Last commit date | |
|---|---|---|---|---|
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 0
No packages published