图遍历问题

发布于 2024-11-13 05:59:48 字数 2441 浏览 4 评论 0原文

我的 Dijkstra 算法可以很好地找到路径。现在我想回去展示我走过的路。我标记一个访问过的顶点,并给它一个指向我来自“prev”的顶点的指针。不幸的是,当在 while 循环中循环时,这些指针会以某种方式被操纵,因此最后的顶点不知道它们来自哪里。你能帮助我吗?

可能这是我不明白的指针问题。我有一个复制构造函数和一个 = 运算符。

int MyMatrix::searchBreadth(MyVertex &from,MyVertex &to,int mode)  
{  
queue<MyVertex> q;//queue  
vector<MyVertex> nb;//vector of neighbours  
path=INFINITY;//path is very long  
visits.push_back(from.getName());  
from.setDistance(0);  
MyVertex n("start");  
from.setPrev(n);  
q.push(from);  
while(!q.empty())  
     {  
         MyVertex v=q.front(); 

         q.pop();
         int k=v.getDistance();
         nb.clear();
         nb = getNeighbours(v);


         for(unsigned int i=0;i<nb.size();i++)
         {
             if((!nb[i].getPrev())&&path==INFINITY) nb[i].setPrev(v);

             if(!mode){//unweighted
                if(!wasVisited(nb[i].getName())){
                    nb[i].setDistance(k+1);
                    q.push(nb[i]);
                }
             }
             if(mode){//length or weight
                 if(!wasVisited(nb[i].getName())){
                     int cost=0;
                     MyEdge e = m->getEdge(v,nb[i]);
                     if(mode==1)cost=(int) e.getLength();//length
                     if(mode==2)cost=(int) e.getWeight();//weigth
                     nb[i].setDistance(k+cost);
                     q.push(nb[i]);
                 }
             }

             if((nb[i].getName().compare(to.getName())==0) && (!wasVisited(nb[i].getName()))){//path found
                int j=nb[i].getDistance();
                if(j<path)path=j;
             }
             visits.push_back(nb[i].getName());
         }//end of for
         //end of 0size if
     }//end of while
     return path;
}

MyVertex::MyVertex()
{  
name="null";  
dist=0;  
visited=false;  
prev=0;  
}              
MyVertex::MyVertex(string name)
{
this->name=name;
visited=false;
dist=numeric_limits<int>::max();
prev=0;
}

MyVertex::~MyVertex(void)
{
if (!prev) prev=0;
}

MyVertex::MyVertex(const MyVertex& V){
this->name = V.name;
this->visited=V.visited;
    this->dist=V.dist;
this->prev=V.prev;

}

MyVertex& MyVertex::operator=(const MyVertex& L){
if (this == &L){ return *this;
  }else{

    delete prev;
    dist=L.dist;
    name=L.name;
    visited=L.visited;
    prev=L.prev;

  }

  return *this; 
}

My Dijkstra Algorithm works fine to find a path. Now I want to go back to show the way I went. I mark a visited vertex and give it a pointer to the vertex I came from "prev". Unfortunately these pointers get manipulated in some way when looping in the while loop, so that the vertices at the end don't know where they came from. Can you help me?

Probably it's a pointer problem I don't get. I have a copy constructor and a =operator.

int MyMatrix::searchBreadth(MyVertex &from,MyVertex &to,int mode)  
{  
queue<MyVertex> q;//queue  
vector<MyVertex> nb;//vector of neighbours  
path=INFINITY;//path is very long  
visits.push_back(from.getName());  
from.setDistance(0);  
MyVertex n("start");  
from.setPrev(n);  
q.push(from);  
while(!q.empty())  
     {  
         MyVertex v=q.front(); 

         q.pop();
         int k=v.getDistance();
         nb.clear();
         nb = getNeighbours(v);


         for(unsigned int i=0;i<nb.size();i++)
         {
             if((!nb[i].getPrev())&&path==INFINITY) nb[i].setPrev(v);

             if(!mode){//unweighted
                if(!wasVisited(nb[i].getName())){
                    nb[i].setDistance(k+1);
                    q.push(nb[i]);
                }
             }
             if(mode){//length or weight
                 if(!wasVisited(nb[i].getName())){
                     int cost=0;
                     MyEdge e = m->getEdge(v,nb[i]);
                     if(mode==1)cost=(int) e.getLength();//length
                     if(mode==2)cost=(int) e.getWeight();//weigth
                     nb[i].setDistance(k+cost);
                     q.push(nb[i]);
                 }
             }

             if((nb[i].getName().compare(to.getName())==0) && (!wasVisited(nb[i].getName()))){//path found
                int j=nb[i].getDistance();
                if(j<path)path=j;
             }
             visits.push_back(nb[i].getName());
         }//end of for
         //end of 0size if
     }//end of while
     return path;
}

MyVertex::MyVertex()
{  
name="null";  
dist=0;  
visited=false;  
prev=0;  
}              
MyVertex::MyVertex(string name)
{
this->name=name;
visited=false;
dist=numeric_limits<int>::max();
prev=0;
}

MyVertex::~MyVertex(void)
{
if (!prev) prev=0;
}

MyVertex::MyVertex(const MyVertex& V){
this->name = V.name;
this->visited=V.visited;
    this->dist=V.dist;
this->prev=V.prev;

}

MyVertex& MyVertex::operator=(const MyVertex& L){
if (this == &L){ return *this;
  }else{

    delete prev;
    dist=L.dist;
    name=L.name;
    visited=L.visited;
    prev=L.prev;

  }

  return *this; 
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

绝不放开 2024-11-20 05:59:48

您遗漏了很多代码,但您似乎正在调整节点的 Distance - 并设置其 prev - 而没有首先检查它是否已经有较小的距离。一旦找到任何路径,就停止设置prev,这样如果以后找到更短的路径,其节点可能不会被标记。

You're leaving a lot of code out, but you seem to be adjusting the Distance of a node -- and setting its prev -- without first checking whether it already has a lesser Distance. And once you've found any path, you stop setting prev, so that if you later find a shorter path, its nodes may not be marked.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文