我有一个项目,我正在使用C ++类实现Dijkstra的最短路径算法。它使用OpenGL,但肯定会与我的问题分开。我需要对Dijkstra类方法中的错误有所了解。这是我的相关代码:
class Node {
public:
GLfloat x, y, z;
int numLinks;
Node *link1;
Node *link2;
GLfloat distance;
Node *previous;
Node(GLfloat x, GLfloat y, Node *link1, Node *link2);
Node(GLfloat x, GLfloat y, Node *link1);
Node();
Node(GLfloat x, GLfloat y);
~Node();
bool dijkstra(Node* graph[], Node *source, Node *target); //returns true if a path to target is found
int dist(Node &n1, Node &n2);
};
int Node::dist(Node &n1, Node &n2) {
GLfloat d = sqrt((pow((n2.x - n1.x), 2)) + (pow((n2.y - n1.y), 2)));
return d;
}
bool Node::dijkstra(Node* graph[], Node *source, Node *target) {
queue<Node> q;
int i;
for (i = 0; i < NUM_NODES; i++) {
graph[i]->distance = INFIN;
}
source->distance = 0;
i = 0;
q.push(*source);
while (!q.empty()) {
Node temp = q.front();
GLfloat d1 = dist(temp, temp->link1);
GLfloat d2 = dist(temp, temp->link2);
temp.link1.distance = d1;
temp.link1.distance = d2;
GLfloat alt = temp.distance + temp->link1.distance;
if (alt < temp->link1.distance) {
temp->link1.distance = alt;
temp->previous = temp;
}
alt = temp->distance + temp->link2->distance;
if (alt < temp->link2->distance) {
temp->link2->distance = alt;
temp->previous = temp;
}
if(d1 > d2) {
q.push(temp->link2);
q.push(temp->link1);
} else {
q.push(temp->link1);
q.push(temp->link2);
}
q.pop();
i++;
}
return true;
}
我的猜测是我正在使用“ - &gt;”和“。”经营者都错了。我尝试编译时遇到了很多这些错误:
error: base operand of ‘->’ has non-pointer type ‘Node’
我对Dijkstra算法的实现有些改进以满足我的需求并且可能是错误的,但是我需要这个来编译所以我可以调试它。
列出的代码是唯一给我悲伤的代码但是如果你想看到它的另一部分只是问。我将非常感谢你对我做错的一个很好的解释。
答案 0 :(得分:0)
你应该使用' - &gt;'访问数据通过指针时的运算符。否则你应该使用'。' opearator。
例如,以下这些行是相同的
Node *node = &q.front();
(*node).link1->distance = 1;
node1->link1->distance = 1;
至于编译问题,问题在于你如何访问temp。 temp被声明为
Node temp = q.front();
这意味着temp是队列前面节点的副本,而不是指向它的指针。这就是编译器在您尝试访问它时抱怨的原因,就像它是一个指针一样。例如:
temp->link1.distance = alt;
应该看起来像
temp.link1->distance = alt;
因为temp不是指针而是link1是。
答案 1 :(得分:0)
有关您设计的一些问题:
dijkstra
真的是一个可以应用于节点的方法吗?这似乎是一个整体应用于图表的操作。
class Graph
{
std::vector<NodeId> dijkstra(NodeId const& start, NodeId const& target);
};
previous
?该节点似乎有一些内部指针,仅用于算法Node *previous;
该节点不应包含此类信息。
这是否意味着节点只能链接到其他两个节点。看起来这不是一张图,但更像是树吗?
class Node
{
std::vector<LinkId> links;
};
class Graph
{
class Link
{
NodeId src;
NodeId dst;
float dist; // only calculate once for each link
};
class Node
{
float x,y;
std::vector<boost::shard_ptr<Link> > links;
};
typedef std::vector<Node> GraphContainer;
GraphContainer graphPoints;
public:
typedef GraphContainer::size_type NodeId;
NodeId addNode(float x, float y);
void link(NodeId& p1, NodeId& p2);
std::vector<NodeId> dijkstra(NodeId const& start, NodeId const& target);
};
现在干净利落地写起来要简单得多。