这是一个非常可爱的小问题。如果你的图连接良好,贪心方法可能会很有效。如:(1)将当前位置设置为最接近路径起点的节点,(2)移动到路径中最接近下一个点的相邻节点,直到没有更接近的点,(3)选择路径中的下一个点,如果未完成,则转到 (2)。
#include <assert.h>
#include <stddef.h>
#include <iostream>
#include <iterator>
#include <vector>
#include <limits>
double sq(double const d)
{
return d * d;
}
size_t min_dist_point(
std::vector<double> const& x,
std::vector<double> const& y,
std::vector<bool> const& adjacent,
double const fx,
double const fy
)
{
size_t const points = x.size();
double min_dist_sq = std::numeric_limits<double>::max();
size_t min_point;
for (size_t j = 0; j < points; ++j) {
if (!adjacent[j]) { continue; }
double const dist_sq = sq(x[j] - fx) + sq(y[j] - fy);
if (dist_sq < min_dist_sq) {
min_point = j;
min_dist_sq = dist_sq;
}
}
assert(min_dist_sq != std::numeric_limits<double>::max());
return min_point;
}
template <class out_t>
out_t f(
std::vector<double> const& x,
std::vector<double> const& y,
std::vector<std::vector<bool> > adjacent,
std::vector<double> const& follow_x,
std::vector<double> const& follow_y,
out_t out
)
{
size_t const points = x.size();
size_t const follow_len = follow_x.size();
for (size_t i = 0; i < points; ++i) {
adjacent[i][i] = 1;
}
std::vector<bool> const all (points, true);
size_t pos = min_dist_point(x, y, all, follow_x[0], follow_y[0]);
*out++ = pos;
for (size_t i = 1; i < follow_len; ++i) {
for (;;) {
size_t const next = min_dist_point(x, y, adjacent[pos], follow_x[i], follow_y[i]);
if (next == pos) { break; }
*out++ = (pos = next);
}
}
return out;
}
Run Code Online (Sandbox Code Playgroud)
如果该算法陷入循环,您将需要 A* 搜索。
http://www.boost.org/doc/libs/1_47_0/libs/graph/doc/astar_search.html