I'm working on a program that reads coordinates from a textfile that contains several coordinates. Starting from the first coordinate, the program then outputs the closest coordinate, and so on. For example, if a textfile contains the coordinates (1,3) then (5,7) and (2,4), the program outputs 1,3 and then 2,4 and finally 5,7.
My situation is that I'm not entirely sure where to start. I currently have the very basics of the program. Though I'm not entirely sure how to get the program to output the closest coordinate after it outputs the first one. While I'm certainly not asking anyone to do the entire program for me, some help to put me in the right direction would be greatly appreciated.
The algorithm you use to find the nearest neighbor depends entirely on the dynamism of your data. If your data changes a lot you will want to use a different algorithm than if your data never changes.
How did YOU figure out it should go 1,3 2,4 5,7? Tell your program the same thing.
This sort of functionality can be implemented in quite a lot of ways- the slowest possible (and most naive) implementation would be to go through the list of objects for each object and find the nearest object using the Pythagorean theorum distance = sqrt(pow(x2-x1,2)+pow(y2-y1,2));
Two things to keep in mind.
1. Don't return the same object your searching for the nearest neighbor of.
2. Don't return any previous neighbors (probably) otherwise you'll get a cyclical list.
The data only changes if the user goes into the textfile and manually changes it. It is not dynamic within the program itself.
I just started considering this: assign an int variable with the value of the first coordinate. Then a while loop reads through the x and y value, and searches for the next closest set of coordinates with an if statement and so on and then outputs them at the end. However, thinking about it now, I can't see it working properly when I have to compare it with the if statement.
I hadn't thought about using the Pythagorean theorum though. I'm going to toy with that now.
To use the Pythagorean theorem, how would I go about assigning each coordinate at x1 and y1 and then x2 and y2? I was thinking about using a while loop that reads through the text file and assigns the coordinates of the first set to x1 and y1, but is there a way where I can have a while loop do that for every set of coordinates while comparing the distance between them?
The term 'closest' is relative so the question is closest to where. If you have 3 points and a vantage point from where distances are measured then that is where you start to analyze your date by reading it into some form of array of points, calculating the distance to each by pythagoras and determining the minimum of those distances.
So if you have 3 points on file you have a couple of choices to make whether the vantage point is a fourth (reference) point ( maybe the origin (0,0) or somewhere else ) or is it one of the 3 points in which case the closest is the point with the lesser of the two distances?
is there a way where I can have a while loop do that for every set of coordinates while comparing the distance between them?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
struct/class point
x , y coordinates ( z?? :] )
struct/class line
point a to/from point b
list of point
list of distances
read in first point
loop until finished:
read in next point
calculate and record distances to all existing points
analyse and sort list of distances
output results
Ok, so I'm messing around with the code above but now the program only outputs the first set of coordinates. Does anyone know what is a good way to output the rest of the coordinates? Here is the code:
#include <iostream>
#include <fstream>
#include <vector>
using std::cin;
using std::cout;
using std::endl;
using std::vector;
using std::ostream;
using std::istream;
using std::ifstream;
using std::operator>>;
using std::operator<<;
struct point
{
int x = 0;
int y = 0;
};
ostream& operator<< (ostream& out, const point &p)
{
out << "(" << p.x << "," << p.y << ")";
return out;
}
istream& operator>> (istream& in, point& point)
{
in >> point.x >> point.y;
return in;
}
struct line
{
point start;
point finish;
int sqDistance()
{
int dx = start.x - finish.x;
int dy = start.y - finish.y;
return dx * dx + dy * dy;
}
};
ostream& operator<< (ostream& out, const line &ln)
{
out << "From " << ln.start << " to " << ln.finish;
return out;
}
istream& operator>> (istream& in, line ln)
{
cout << "Enter x y start then x y finish: ";
in >> ln.start.x >> ln.start.y >> ln.finish.x >> ln.finish.y;
return in;
}
int main()
{
point origin, input;
line ray;
vector<line> side;
// READ POINTS FROM FILE
ifstream pointfile("paths.txt");
if (pointfile.is_open())
{
pointfile >> origin.x >> origin.y;
cout << "Origin: " << origin << endl;
ray.start = origin;
while (pointfile >> ray.finish)
{
cout
<< "Point entered " << ray.finish
<< " and distance squared to start: "
<< ray.sqDistance() << endl;
side.push_back(ray);
}
}
else
cout << "Unable to open file";
pointfile.close();
/*
cout << "Start: ";
cin >> origin;
cout << origin << endl;
cout << "Press any alpha to end" << endl;
while (cin >> input)
{
cout << input;
ray.start = origin;
ray.finish = input;
cout << " and distance squared to start: "
<< ray.sqDistance() << endl << endl;
side.push_back(ray);
}
*/
vector<line>::iterator iter = side.begin();
line temp, closest = *iter;
int minimumDistance = closest.sqDistance(), distance = 0;
for (iter = side.begin(); iter != side.end(); ++iter)
{
temp = *iter;
distance = temp.sqDistance();
cout
<< "Distance "
<< temp << " is " << distance << endl;
if (distance < minimumDistance)
closest = temp;
}
cout << endl;
cout << "Point closest to origin is " << closest.finish << endl;
return 0;
}
Origin: (1,-2)
(3,4) and distance squared to start: 40
(5,-1) and distance squared to start: 17
(-9,6) and distance squared to start: 164
(-3,-3) and distance squared to start: 17
Distance From (1,-2) to (3,4) is 40
Distance From (1,-2) to (5,-1) is 17
Distance From (1,-2) to (-9,6) is 164
Distance From (1,-2) to (-3,-3) is 17
Point closest to origin is (-3,-3)
Press any key to continue . . .
I'm going to do it soon, but the short answer is 'yes'. I just got carried away with the technology and tried out a few things. (The square distance is not a bad time-saving idea I thought) :)
Code looks good! I get a "Vector Iterator Not dereferencable at Line 72" though when I try running it. As I'm still somewhat rusty/new to C++, I'm not really sure what that means.
Edit: Oh, I see. My text file has commas between the x- and y-values, while your's has spaces. That is what was causing my problems.
Oh, I see. My text file has commas between the x- and y-values, while your's has spaces. That is what was causing my problems.
Yeah spaces are the only delimiter we need and I hate data that's riddled with commas.
I'm glad it was so easily fixed.
One trick with the preparation of the data file is to only save data via the program rather than manually because it can get out of sync very easily and difficult to debug.
Yeah, I could see why. I typically prefer getting data from the program, but I'm messing around with reading from textfile questions from my textbook. Since it's a beginners textbook, I'd figure reading coordinates with the commas would be easy (as the textbook does), but I'm starting to see it is difficult.
You can have commas but you need to write the input routines so that commas are recognised as delimiters. Check out this thread http://www.cplusplus.com/forum/beginner/8045/
istream& operator>> (istream& in, line ln)
{
char dummy;
cout << "Enter x y start then x y finish: ";
in >> ln.start.x >> dummy >> ln.start.y >> dummy>> ln.finish.x >> dummy>> ln.finish.y;
return in;
}
And famous last words, that adjustment allows comma or space (and probably any alpha character as a delimiter which makes sense (subject to testing properly to find out possible limitations like " ," .