我已经在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.weight
,weight
实际大于<{strong> ,vertex < e2.vertex
,{{1}}就会返回{{1}}。但顶点数字不会出现在Dijkstra算法的定义中。
那么为什么程序只使用第二个return语句才能正常工作?
答案 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();