[英]Dijkstra's algorithm not working
我正在為學校項目創建游戲,我想將Dijkstra的算法作為AI的一部分,用於玩家需要躲避的物體。
因此,我有一個圖(一個鄰接矩陣),我想使用Dijkstra獲取從每個對象到播放器的路徑,但是現在,當我調用算法時,如果播放器位於該對象之后,它將找不到播放器。
以我的理解,Dijkstra的算法應該訪問所有節點,直到找到目的地為止,但是在我看來,這不是。
到目前為止,這是我的算法:
Node* Graph::DijkstrasAlgorithm(Node* sNode, Node* dNode){
std::cout<<"Hello Dijkstra!!"<<std::endl;
for(unsigned int i = 0; i < this->nodeList.size(); ++i){
nodeList.at(i)->setDistance(INT_MAX);
nodeList.at(i)->setVisited(false);
}
std::cout<<"everything is set"<<std::endl;
sNode->setDistance(0);
int numberVisited = 0;
Node* u = new Node();
std::cout<<"before while lus"<<std::endl;
while(numberVisited < numberOfNodes){
u->setDistance(INT_MAX);
for(unsigned int j = 0; j < this->nodeList.size(); ++j){
if((u->getDistance() > this->nodeList.at(j)->getDistance()) && !this->nodeList.at(j)->isVisited() ){
u = this->nodeList.at(j);
u->setVisited(true);
numberVisited++;
}
}
std::cout<<u->getNodeName()<<"=="<<dNode->getNodeName()<<std::endl;
if((u == dNode) || (u->getDistance() == INT_MAX)){
std::cout<<"true"<<std::endl;
break;
}
for(int k = 0; k < u->numberOfneighbors(); ++k){
if(!u->getNeighbors(k)->isVisited())
{
// std::cout<<u->getDistance()<<std::endl;
int alt = u->getDistance() + 1;
if( alt < u->getNeighbors(k)->getDistance()){
u->getNeighbors(k)->setDistance(alt);
u->getNeighbors(k)->setPrevious(u);
}
}
}
}
std::vector<Node* > stack;
u = dNode;
while(u->getPrevious() != NULL){
stack.insert(stack.begin(), u);
u = u->getPrevious();
}
if(!stack.empty())
return stack.at(0);
else
return sNode;
}
在這種情況下, dNode
是目標節點,而sNode
是起始節點。
有人知道我在做什么錯嗎?
在Dijkstra算法中,僅將最短擴充路徑指向的節點標記為已訪問。 我可以看到您在這里犯的錯誤:
u = this->nodeList.at(j);
u->setVisited(true);
不要將節點標記為立即訪問。
標記為只訪問了節點u
將指向循環后
for(unsigned int j = 0; j < this->nodeList.size(); ++j){
否則,對於每一項改進,您都將節點標記為已訪問,甚至不處理所有節點。
它甚至看起來都不像Dijkstra算法。
要實現Dijkstra算法,您需要維護兩個節點列表:
我在您的代碼中都看不到這些列表。
您還將成本存儲在節點中。 這將不起作用,因為到達節點的成本將取決於路由(除非您可以存儲與節點關聯的多個成本)。
我希望代碼看起來像這樣:
// pseudo code.
// Note all features used are strictly available
//
Node* Graph::DijkstrasAlgorithm(Node* sNode, Node* dNode)
{
std::list<Node*> searchedNodes;
std::list<std::pair<Node*, cost>> edgeNodes;
edgeNodes.push_sorted(sNode, 0);
while(!edgeNodes.empty())
{
std::pair<Node*, cost> next = edgeNodes.pop_front();
searchedNodes.push_back(next.first);
if (next.first == dnode)
{ // We found the route
return STUFF;
}
for(Edge* edge, next.first->getEdges())
{
if (searchedNodes.find(edge->dst) != searchedNodes.end())
{ continue;
}
edgeNodes.push_sorted(dest.dst, next.second + edge->cost);
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.