背景:我正在为旅行商问题实施最近邻算法。我需要计算巡回旅行的距离以及跟踪所访问点的顺序。我已经定义了一个带有实例变量x
和y
的点类以及一个用于计算两点之间距离的函数calcDist
。我首先将所有点存储在名为std::unordered_set
的{{1}}中,创建一个名为points
的空std::vector
来存储游览路径,并将起点指定为{{ 1}},并将这些传递给我的path
函数:
startPoint
问题是,一旦程序退出外部for循环,nearestNeighbor()
中的所有点都会以某种方式被覆盖。看看我的意思,这是输出:
void nearestNeighbor(unordered_set<Point, PointHasher> points, vector<Point> &path, Point startPoint) {
// Declare variables
unordered_set<Point, PointHasher>::iterator it;
Point currentLocation, possibleNeighbor, nearestNeighbor;
double totalDist = 0;
int pointsCount = path.capacity() - 1;
// Set the starting location
it = points.find(startPoint);
currentLocation = *it;
path[0] = currentLocation;
points.erase(currentLocation);
cout << "Start location: " << path[0].x << ", " << path[0].y << endl;
// Create the path
for (int i = 1; points.size() > 0; i++) {
double minDist = -1;
// Find the current location's nearest neighbor
for (it = points.begin(); it != points.end(); it++) {
possibleNeighbor = *it;
int currentDist = currentLocation.calcDist(possibleNeighbor);
if (minDist == -1 || currentDist < minDist) {
minDist = currentDist;
nearestNeighbor = possibleNeighbor;
}
}
// Record nearest neighbor data and prepare for the next iteration
currentLocation = nearestNeighbor;
path[i] = currentLocation;
points.erase(currentLocation);
totalDist += minDist;
cout << "Nearest neighbor: " << path[i].x << ", " << path[i].y << endl;
}
// Return to the starting location
path[pointsCount] = startPoint;
cout << "End location: " << startPoint.x << ", " << startPoint.y << endl;
cout << "Path:" << endl;
for (int i = 0; i < path.size(); i++) {
cout << path[0].x << ", " << path[0].y << endl;
}
cout << "Total distance: " << totalDist << endl;
}
我认为这要么是向量元素的指针/地址的问题,要么是具有范围的东西,因为问题在退出for循环后发生。我甚至尝试在每次迭代后打印path
以查看它何时被更改,但它在整个循环中是正确的,并且只在结尾处输出更改。有什么想法吗?我很难过。如果你已经做到这一点,非常感谢你的时间。
答案 0 :(得分:2)
您始终输出路径[0] man
for (int i = 0; i < path.size(); i++) {
cout << path[0].x << ", " << path[0].y << endl;
}
答案 1 :(得分:1)
你有
for (int i = 0; i < path.size(); i++) {
cout << path[0].x << ", " << path[0].y << endl;
}
这不会遍历i
。将您的0更改为i
,您可能会看到更有帮助的内容:
for (int i = 0; i < path.size(); i++) {
cout << path[i].x << ", " << path[i].y << endl;
}
修改:将path[i] = currentLocation;
更改为path.push_back(currentLocation);
- 这会自动增加path
向量的大小以适应新元素。
void nearestNeighbor(
unordered_set<Point, PointHasher> points,
vector<Point> &path,
Point startPoint,
double &totalDist) // note the new variable passed here
{
// Declare variables
unordered_set<Point, PointHasher>::iterator it;
Point currentLocation, possibleNeighbor, nearestNeighbor;
// double totalDist = 0; Remove this line
// int pointsCount = path.capacity() - 1; And this
// Set the starting location
it = points.find(startPoint);
currentLocation = *it;
path.push_back(currentLocation); // Changed this line
points.erase(currentLocation);
cout << "Start location: " << path[0].x << ", " << path[0].y << endl;
// Create the path
for (int i = 1; points.size() > 0; i++) {
double minDist = -1;
// Find the current location's nearest neighbor
for (it = points.begin(); it != points.end(); it++) {
possibleNeighbor = *it;
int currentDist = currentLocation.calcDist(possibleNeighbor);
if (minDist == -1 || currentDist < minDist) {
minDist = currentDist;
nearestNeighbor = possibleNeighbor;
}
}
// Record nearest neighbor data and prepare for the next iteration
currentLocation = nearestNeighbor;
path.push_back(currentLocation); // And this line
points.erase(currentLocation);
totalDist += minDist;
cout << "Nearest neighbor: " << path[i].x << ", " << path[i].y << endl;
}
// Return to the starting location
path.push_back(startPoint); // And here also!
cout << "End location: " << startPoint.x << ", " << startPoint.y << endl; // This I didn't change,
// but perhaps you should make it reflect the last point in the vector,
// not the start point which is supposed to be the last point in the vector
cout << "Path:" << endl;
for (int i = 0; i < path.size(); i++) {
cout << path[i].x << ", " << path[i].y << endl;
}
cout << "Total distance: " << totalDist << endl;
}
答案 2 :(得分:0)
我看不到任何增加path
向量大小的地方。
我怀疑你为第二个参数传递了一个空的std :: vector,并且只要你点击path[0]=currentLocation;
...未定义的行为。
另外,我并不认为capacity()会按照您的想法行事。
那,并且正如其他人所指出的那样,你并没有正确地输出数组的内容,但这是一个小问题。这里的主要问题是这个程序可能会乱写并破坏堆。