Dijkstra的算法 - 优先级队列中的比较

时间:2014-06-04 22:14:22

标签: c++ algorithm set graph-algorithm dijkstra

我已经在C ++ from this page中复制了dijkstra的算法并对其进行了修改以适合我的图表表示类。基本上,我仅将std::pair作为模板参数替换为std::set我自己的结构edge

struct edge
{
    int vertex;
    unsigned long weight;

    edge(int v = 0, unsigned long wt = 0) : vertex(v), weight(wt) { }

    bool operator<(const edge& e2) const
    {
        //return weight < e2.weight;
        return weight < e2.weight || ((e2.weight >= weight) && vertex < e2.vertex);
    }
};

但是,我必须实现运算符&lt;类似于在std :: pair中找到的那个。当我使用注释的return语句时,输出是错误的。但是,只要true e2.weight >= weight e2.weightweight实际大于<{strong> vertex < e2.vertex,{{1}}就会返回{{1}}。但顶点数字不会出现在Dijkstra算法的定义中。

那么为什么程序只使用第二个return语句才能正常工作?

1 个答案:

答案 0 :(得分:1)

重述正确的退货声明:

return (this->weight < e2.weight) || ((this->weight <= e2.weight) && this->vertex < e2.vertex);

相当于:

return (this->weight < e2.weight) || ((this->weight == e2.weight) && this->vertex < e2.vertex);

(&lt; =由于第一个条件的短路而分解为==)

所以我希望自己的体重更小......或者如果相等,顶点要小一些。

编辑(误解了原文为什么语法不通): 标准集需要严格的订购......

当你插入图形边时,这些边的权重可以是相同的 - 因此,权重本身并不是边的唯一标识符,因此它不是根据Djikstra的逻辑排序机制 - 它是一个保持所有边缘而不会在集合中相互覆盖的方式。

对于更明显的失败案例,请尝试使用op&lt;:

的两个定义执行此操作
//int verticeIdx[4] = {0, 1, 2, 3} 
int constWeight = 3;
edge myEdge(0, constWeight), myNewEdge(1, constWeight);
std::set<edge> edges;
edges.insert(myEdge);
edges.insert(myNewEdge);
std::cout << edges.size();