最短路径算法建模时的队列问题
我有一个队列问题。对图进行建模,我正在用 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;
}
I have a queue problem. Modeling a graph, I'm doing a shortest path algorithm in C++.
In my while (!q.empty())
the front vertex*
gets changed when I return to this statement.
Can you figure out why?
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;
}
here comes 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;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您的问题很微妙,但与 q.push(&nb[i]) 相关。您所做的是添加一个指向向量中某个位置的指针,这在概念上与添加一个指向
MyVertex
对象的指针不同。邻居向量包含“按值”的MyVertex
对象(如果这有助于您理解问题)。查看内存中的
nb
可能会有所帮助:当您推送
&nb[1]
时,您正在推送地址nb + (1 * sizeof(MyVertex) )
。nb
在堆栈上声明,因此该地址将位于堆栈上的某个位置。因此,当您的 for 循环返回时,nb 会刷新(可以这么说)并添加新数据。但是,您的队列
q
包含不再有效的nb
地址!简而言之:您的队列引用向量中的位置,而不是向量中的数据。
如果您想保持方法不变,这意味着getNeighbors
需要更改为返回MyVertex*
向量。您应该简单地编辑
BreadthFirstSearch
采用两个MyVertex&
,而不是指针。然后,您可以将q
更改为queue
,将v
更改为MyVertex
,最后您应该更改q.push(&nb[i])
为q.push(nb[i])
。Your problem is subtle, but related to
q.push(&nb[i])
. What you're doing is adding a pointer to a location in a vector, which is not conceptually the same as adding a pointer to aMyVertex
object. The vector of neighbors contains theMyVertex
objects "by value" (if that helps in your understanding of the problem).A look at
nb
in memory may help:When you push
&nb[1]
you're pushing the addressnb + (1 * sizeof(MyVertex))
.nb
is declared on the stack, so that address is going to be somewhere on the stack.So when your
for
-loop comes back around,nb
gets refreshed (so to speak) and new data is added. However, your queueq
contains addresses intonb
that are no longer valid!Simply put: your queue is referencing a LOCATION in the vector, not the DATA in the vector.
If you want to keep your method as-is, this meansgetNeighbors
needs to change to return a vector ofMyVertex*
.You should simply edit
BreadthFirstSearch
to take twoMyVertex&
, rather than pointers. You would then changeq
to be aqueue<MyVertex>
,v
toMyVertex
, and finally you should changeq.push(&nb[i])
to justq.push(nb[i])
.