У меня был долгий сеанс отладки (6 часов и более).Я отлаживал свою реализацию алгоритма A *.
После проверки каждой возможности, после добавления регистрации, пошаговой отладки и т. Д., Я наконец нашел ответ.По сути, все сводится к одной строке, где я ищу минимальное значение в векторе.
Проверьте это:
auto open_set = std::vector<std::shared_ptr<node>>{start_node};
std::shared_ptr<node> current;
while (!open_set.empty())
{
current = *std::min_element(open_set.begin(), open_set.end());
Строка current = *std::min_element(open_set.begin(), open_set.end());
должна была найтисамый низкий node
в векторе.Это моя node
реализация:
class node
{
public:
node() : G(0), H(0) {}
node(const QPoint& p) : pos(p), G(0), H(0) {}
bool operator==(const node& o) const { return pos == o.pos;}
bool operator==(const QPoint& o) const { return pos == o; }
bool operator!=(const node& o) const { return pos != o.pos; }
bool operator<(const node& o) const { return G + H < o.G + o.H; }
QPoint pos;
std::shared_ptr<node> parent;
int G;
int H;
};
Итак, у меня есть operator<
, необходимый для поиска min_element
.Проблема в том, что после многократного просмотра моих журналов я обнаружил, что у меня есть node
, то есть G = 8, H = 10 и узел G = 10, H = 10. Угадайте, что было выбрано как min_element
-> Второй!Я понятия не имел, почему, и я был в ярости, поэтому я написал простую лямбду для сравнения узлов:
current = *std::min_element(open_set.begin(), open_set.end(),
[&] (const std::shared_ptr<node>& lhs, const std::shared_ptr<node>& rhs)
{
return lhs->G + lhs->H < rhs->G + rhs->H;
});
И бум, это:
изменено на это:
Очевидно, что вы можете видеть, что первое неверно.И я проверял это много раз, теперь он всегда работает хорошо, поэтому проблема была действительно здесь.
Итак, мой вопрос здесь, почему это не сработало, когда я использовал std::min_element
.Связано ли это с тем, что у меня std::vector
std::shared_ptr<node>
с, а не просто node
с?Должен ли я писать operator<
в node
классе по-другому?