我编写了尝试解决传教士和食人族问题的代码,并实现了Node
来将信息保存在Node::arr
和Node::parent
中。这些由函数bfs
返回时,将以最短路径给出状态。
当bfs
返回时,它具有正确的parents
编号。但是,当我在Visual Studio调试器中检查Node last
时,我注意到它的parents.arr
包含垃圾,即arr[0]=-858993460
。但是Node last
具有正确的arr
(问题{0,0,1,3,3,0}
的最终状态)。这些信息如何丢失?
节点
#pragma once
#include <array>
class Node {
public:
std::array<int, 6> arr;
Node *parent;
Node(std::array<int, 6> arr, Node *parent = NULL);
Node();
};
node.cpp
#include "Node.h"
Node::Node(std::array<int, 6> arr, Node *parent) : arr(arr), parent(parent) {};
Node::Node(): parent(NULL) {};
main.cpp
void applyMoves(queue<Node> &q, Node current_node, array<int, 3> moves) {
array<int, 6> arr = current_node.arr;
array<int, 3> left, right;
// apply valid moves to arr
// copy the arr to left and right and check if the move applied are valid
// if valid and no duplicates in the queue do proceed to the next lines below
Node n = Node(arr, ¤t_node);
q.push(n);
}
Node bfs(queue<Node> &q, array<array<int, 3>, 5> moves) {
while (!q.empty()) {
Node current = q.front();
q.pop();
if (achievedGoal(current.arr) == 1) {
return current;
}
for (const auto& move : moves) {
applyMoves(q, current, move);
}
}
Node n;
return n;
}
int main() {
array<int, 6> init_state{ 3,3,1,0,0,0 };
array<array<int, 3>, 5> moves{ { {1,0,1}, {0,1,1}, {1,1,1}, {2,0,1}, {0,2,1} } };
Node n = Node(init_state);
queue<Node> q;
q.push(n);
Node last = bfs(q, moves);
}
最佳答案
我相信问题出在
void applyMoves(queue<Node> &q, Node current_node, array<int, 3> moves) {
array<int, 6> arr = current_node.arr;
array<int, 3> left, right;
// apply valid moves to arr
// copy the arr to left and right and check if the move applied are valid
// if valid and no duplicates in the queue do line 31 and 32
Node n = Node(arr, ¤t_node);
q.push(n);
}
current_node
是副本,您正在存储它的地址。函数结束时,该副本被销毁,现在您有了一个悬空的指针。您应该可以通过引用current_node
来修复它。编辑:
您在
Node bfs(queue<Node> &q, array<array<int, 3>, 5> moves) {
while (!q.empty()) {
Node current = q.front();
q.pop();
if (achievedGoal(current.arr) == 1) {
return current;
}
for (const auto& move : moves) {
applyMoves(q, current, move);
}
}
Node n;
return n;
}
在这里,创建
current
这是一个本地自动对象,然后将队列的前端复制到其中,然后从队列中获得pop()
前端。因此,当将此节点用作父节点时,一切都很好,直到您移至while循环的下一个迭代。一旦执行此操作,current
就被破坏了,这意味着指向它的所有内容现在都在晃来晃去。然后循环开始备份并创建一个新的current
。如果此对象是在我认为是的示例位置中创建的,那么您创建的所有节点的父节点现在都指向该新节点。他们目前正在执行的操作将无法正常工作。我不太确定如何更改它才能获得正确的行为。