我正在爲A *編寫一個圖形版本來解決8拼圖問題,我實現了一個樹版本測試它,它工作正常。我只是通過跟蹤我訪問的節點來擴展樹版本來完成圖形版本。A *圖算法給出不正確的輸出
原來這裏是樹的版本:
int AStarTreeVersion (Node initialState){
priority_queue<Node, vector<Node>, greater<Node> > fringe;
fringe.push(initialState);
while (true){
if (fringe.empty()) // no solution
return -1;
Node current = fringe.top();
fringe.pop();
if (current.isGoal())
return current.getDistance();
auto successors = current.getSuccessors();
for (auto s : successors)
if (s != current)
fringe.push(s);
}
}
和圖形版本:
int AStarGraphVersion(Node initialState){
priority_queue<Node, vector<Node>, greater<Node> > fringe;
fringe.push(initialState);
unordered_set<Node> visited; // <---
visited.insert(initialState);// <---
while (true){
if (fringe.empty()) // no solution
return -1;
Node current = fringe.top();
fringe.pop();
if (current.isGoal())
return current.getDistance();
auto successors = current.getSuccessors();
for (auto s : successors){
auto pair = visited.insert(s); //<--
if (pair.second) //<--
fringe.push(s); //<--
}
}
}
我添加了一個箭頭,表示兩個版本之間的差異。任何人都可以看到出了什麼問題?
下面是測試情況下,解決8拼圖:
array<int, 9> a= {1, 6, 4, 8, 7, 0, 3, 2, 5};
Node ini(a);
cout<<"Tree solution "<<AStarTreeVersion(ini)<<endl;
cout<<"Graph solution "<<AStarGraphVersion(ini)<<endl;
輸出:
Tree solution 21
Graph solution 23
編輯
這裏是Node
的相關細節等級:
class Node {
public:
bool operator>(const Node& that) const
{return this->getHeuristicValue() > that.getHeuristicValue() ;}
friend inline bool operator==(const Node & lhs, const Node & rhs)
{ return lhs.board == rhs.board;}
friend inline bool operator!=(const Node & lhs, const Node & rhs)
{ return ! operator==(lhs,rhs) ;}
size_t getHashValue()const{
size_t seed = 0;
for (auto v : board)
seed ^= v + 0x9e3779b9 + (seed << 6) + (seed >> 2);
return seed;
}
private:
array<int, 9> board;
};
,這裏是我如何重載hash
模板:
namespace std {
template <> struct hash<Node>
{
size_t operator()(const Node & t) const
{
return t.getHashValue();
}
};
}
你是否在其中一個實現中遺漏了第一個或最後一個節點? – user1767754
@ user1767754:「離開」是什麼意思? –
如果沒有完整的例子,很難說,也許你有'運營商=='糟糕的'節點'? – zch