【问题标题】:Queue Problem while modeling a shortest path algorithm建模最短路径算法时的队列问题
【发布时间】:2011-05-27 17:41:08
【问题描述】:

我有一个队列问题。建模一个图,我正在用 C++ 做一个最短路径算法。

在我的while (!q.empty()) 中,当我返回此语句时,前面的vertex* 会发生变化。

你能找出原因吗?

int MyMatrix::searchBreadth(MyVertex* from,MyVertex* to)
{
queue<MyVertex*> q;  
path=INFINITY;

from->visit();  
from->setDistance(0);  
q.push(from);  

//here q.front()'s attributes get changed when returning from the for-loop  
while(!q.empty())
{  
    MyVertex* v=q.front();  
    q.pop();  
    int k=v->getDistance();  
    vector<MyVertex> nb=getNeighbours(*v);  
    for(int i=0;i<nb.size();i++)  
    {  
        if(nb[i].getDistance()==INFINITY)
        {  
            nb[i].setDistance(k+1);  
            q.push(&nb[i]);  
        }

        if((nb[i].getName().compare(to->getName())==0)
           && !nb[i].isVisited())
        {
            //path found  
            int j=nb[i].getDistance();  
            if(j<path) path=j;  
        }  

        nb[i].visit();  
     }  
}  
return path;  

}   

getNeighbours() 来了

vector<MyVertex> MyMatrix::getNeighbours(MyVertex &v)
{  
    int index=0;  
    for(int l=0; l<stations.size(); l++ )
    {  
        if(stations[l].getName().compare(v.getName())==0)index=l;  
    }

    vector<MyVertex> out;  
    for(int k=0;k<matrixSize;k++)
    {  
        if(matrix[index][k].getName().compare("null")!=0)
        {  
            out.push_back(matrix[index][k].getTo());  
        }  
    }  

    return out;
}

【问题讨论】:

  • 我想我不是 100% 确定我是否理解您的问题。 q.front() 应该在每次迭代时更改。除非您的意思是 vfor 循环期间发生变化。
  • @sixlettervariables OP 表示q.front()属性正在改变,而不是q.front() 本身。
  • @Howard:谢谢,我已经更新了答案以解决原因。
  • 谢谢,我添加了 getNeighbours()

标签: c++ algorithm graph queue vertex


【解决方案1】:

您的问题很微妙,但与q.push(&amp;nb[i]) 有关。您正在做的是添加指向向量中某个位置的指针,这在概念上与添加指向 MyVertex 对象的指针不同。邻居向量包含“按值”的MyVertex 对象(如果这有助于您理解问题)。

查看内存中的nb 可能会有所帮助:

        0         1                   I
nb [MyVertex0|MyVertex1|   ...   |MyVertexI]
             +---------+
                  | (Notice it is NOT pointing to MyVertex1!)
&nb[1]------------+

当您推送&amp;nb[1] 时,您推送的是地址nb + (1 * sizeof(MyVertex))nb 在堆栈中声明,因此该地址将位于堆栈中的某个位置。

因此,当您的 for-loop 再次出现时,nb 会被刷新(可以这么说)并添加新数据。但是,您的队列 @9​​87654331@ 包含不再有效的 nb 中的地址!

简单地说:您的队列引用的是向量中的位置,而不是向量中的数据

如果您想保持方法不变,这意味着getNeighbors 需要更改以返回MyVertex* 的向量。


您应该简单地编辑BreadthFirstSearch 以获取两个MyVertex&amp;,而不是指针。然后将q 更改为queue&lt;MyVertex&gt;,将v 更改为MyVertex,最后将q.push(&amp;nb[i]) 更改为q.push(nb[i])

【讨论】:

  • 太棒了!谢谢你的帮助!我将 nb 的范围更改为方法范围,并在下一次调用 getNeighbours() 之前添加了一个 clear() 现在地址不再被操作!很好的帮助!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多