0

I have to make a program to randomly generate 1000000 points and get the shortest distance using brute force and divide and conquer. When I use values < 100,000 it works fine for divide and conquer, but above that it gives me that error. Here is the code and some comments. The brute force stops working after around 10k points.

#include <iostream>
#include <cfloat>
#include <cstdlib>
#include <cmath>
#include <stdlib.h>
#include <time.h>
using namespace std;

/*
 * Point Declaration
 */
struct Point
{
    int x, y;
};

/*
 * sort array of points according to X coordinate
 */
int compareX(const void* a, const void* b)
{
    Point *p1 = (Point *)a, *p2 = (Point *)b;
    return (p1->x - p2->x);
}
/*
 * sort array of points according to Y coordinate
 */
int compareY(const void* a, const void* b)
{
    Point *p1 = (Point *)a, *p2 = (Point *)b;
    return (p1->y - p2->y);
}
/*
 * find the distance between two points
 */
float dist(Point p1, Point p2)
{
    return sqrt((p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y));
}
/*
 * return the smallest distance between two points
 */
float small_dist(Point P[], int n)
{
    float min = FLT_MAX;
    for (int i = 0; i < n; ++i)
    {
        for (int j = i + 1; j < n; ++j)
        {
            if (dist(P[i], P[j]) < min)
                min = dist(P[i], P[j]);
        }
    }
    return min;
}
/*
 * find the distance beween the closest points of strip of given size
 */
float stripClosest(Point strip[], int size, float d)
{
    float min = d;
    for (int i = 0; i < size; ++i)
    {
        for (int j = i + 1; j < size && (strip[j].y - strip[i].y) < min; ++j)
        {
            if (dist(strip[i],strip[j]) < min)
                min = dist(strip[i], strip[j]);
        }
    }
    return min;
}
/*
 * find the smallest distance.
 */
float closestUtil(Point Px[], Point Py[], int n)
{
    if (n <= 3)
        return small_dist(Px, n);
    int mid = n / 2;
    Point midPoint = Px[mid];
    Point Pyl[mid + 1];
    Point Pyr[n - mid - 1];
    int li = 0, ri = 0;
    for (int i = 0; i < n; i++)
    {
        if (Py[i].x <= midPoint.x)
            Pyl[li++] = Py[i];
        else
            Pyr[ri++] = Py[i];
    }
    float dl = closestUtil(Px, Pyl, mid);
    float dr = closestUtil(Px + mid, Pyr, n-mid);
    float d = min(dl, dr);
    Point strip[n];
    int j = 0;
    for (int i = 0; i < n; i++)
    {
        if (abs(Py[i].x - midPoint.x) < d)
            strip[j] = Py[i], j++;
    }
    return min(d, stripClosest(strip, j, d));
}
/*
 * finds the smallest distance
 */
float closest(Point P[], int n)
{
    Point Px[n];
    Point Py[n];
    for (int i = 0; i < n; i++)
    {
        Px[i] = P[i];
        Py[i] = P[i];
    }
    qsort(Px, n, sizeof(Point), compareX);
    qsort(Py, n, sizeof(Point), compareY);
    return closestUtil(Px, Py, n);
}

void randomPoints(int n, Point P[]){
    for(int i=0; i<n; i++){
        P[i].x = rand();
        P[i].y = rand();
    }
}

void printPoints(int n, Point P[]){
    for(int i=0; i<n; i++){
        cout << "(" << P[i].x << ", " << P[i].y << ")";
        cout << endl;
    }
}

void distanceAll(int n, Point P[]){
    for(int i=0; i<n-1; i++){
        for(int j=i+1; j<n; j++){
            cout << dist(P[i], P[j]) << endl;
        }
    }
}

/*
 * Main
 */
int main()
{
    srand (time(NULL));
    int n;
    cout << "How many points do you want? ";
    cin >> n;
    Point *P = new Point[n];
    randomPoints(n, P);

    // Driver Function
    int option;

    cout << "1. Display all points generated.\n";
    cout << "2. Display distance between all possible points.\n";
    cout << "3. Distance between closest pair of points (brute force).\n";
    cout << "4. Distance between closest pair of points (divide & conquer).\n";

    cout << "Enter an option (-1 to exit): ";
    cin >> option;

    // Validation
    while(option != -1){
        if(option == 1){
            printPoints(n, P);
        }
        else if(option == 2){
            distanceAll(n, P);
            cout << endl;
        }
        else if(option == 3){
            cout << "The closest distance (divide & conquer) is: " << small_dist(P, n) << endl;
        }
        else if(option == 4){
            cout << "The closest distance (divide & conquer) is: " << closest(P, n) << endl;
        }
        else{
            cout << "Please enter a valid option: ";
            cin >> option;
        }
        cout << "\n1. Display all points generated.\n";
        cout << "2. Display distance between all possible points.\n";
        cout << "3. Distance between closest pair of points (brute force).\n";
        cout << "4. Distance between closest pair of points (divide & conquer).\n";
        cout << "Enter an option (-1 to exit): ";
        cin >> option;
        cout << endl;
    }

    return 0;
}
worknovel
  • 73
  • 9
  • Strap it into a debugger and find out more about where this went off the rails. – tadman Nov 25 '20 at 05:11
  • **WARNING**: Using [`rand()` can be highly problematic](https://channel9.msdn.com/Events/GoingNative/2013/rand-Considered-Harmful) and you’re strongly encouraged to use an appropriate [random number generator facility in the Standard Library](http://en.cppreference.com/w/cpp/numeric/random) that produces high-quality random values. Using `time(NULL)` as a random number will produce identical results if run in the same second, and on many platforms `rand()` is *barely* random at all. – tadman Nov 25 '20 at 05:12
  • Also consider using `std::vector` instead of `new[]`. These are easier to pass around, are automatically destroyed for you, and have an intrinsic size. – tadman Nov 25 '20 at 05:12
  • 3
    `Point Px[n];` See [Declare large array on Stack](https://stackoverflow.com/questions/17029671/declare-large-array-on-stack) why not (besides not being standard C++). – dxiv Nov 25 '20 at 05:12
  • 3
    `-1073741571` is `0xC00000FD` which is the windows error code which is same as this sites name! – drescherjm Nov 25 '20 at 05:13
  • 1
    `-1073741571` is `C00000FD` or `STATUS_STACK_OVERFLOW` https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-erref/596a1078-e883-4972-9bbc-49e60bebca55 – Retired Ninja Nov 25 '20 at 05:14
  • 1
    The two consecutive qsort's in a row will not do what you think they will do. This is also broken, and should be fixed in addition to non-standard large array in automatic scope. This is what `std::vector` is for. – Sam Varshavchik Nov 25 '20 at 05:20
  • `Point Px[n];` -- This code and lines that look like this are not C++. – PaulMcKenzie Nov 25 '20 at 06:00
  • @PaulMcKenzie What do you mean? Is there an effect of doing that? – worknovel Nov 25 '20 at 06:14
  • [C++ does not have variable length arrays](https://stackoverflow.com/questions/1887097/why-arent-variable-length-arrays-part-of-the-c-standard). Use `std::vector` – PaulMcKenzie Nov 25 '20 at 11:38

0 Answers0