我正在将我的算法问题解决方案提交给在线评分系统,最初,解决方案超出了时间限制,大约需要4 s。
我完全确定复杂性是正确的,所以我开始优化代码的一部分,并没有发生什么大的事情,直到我发现确实很奇怪的东西。
我正在使用成对的优先级队列,因此选择实现自己的比较器
struct Comparator{
bool operator()(pair<int, int> node1, pair<int, int> node2){
return node1.second < node2.second;
}
};
当我将其更改为greater
库的<algorithm>
比较器时,性能得到了显着提高。解决方案通过了,只花了约300毫秒。
其他信息:我正在使用优先级队列来实现Dijkstra的“调整”版本。队列声明为:priority_queue<pair<int, int>, vector<pair<int, int>>, Comparator> q;
,我将其更改为:
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> q;
。
我真的很好奇为什么会这样。对我来说,比较器应该做什么很简单,我想不出任何更有效的方法。
任何帮助将不胜感激:)
答案 0 :(得分:3)
有几件事会导致性能差异:
struct Comparator{
bool operator()(pair<int, int> node1, pair<int, int> node2){
return node1.second < node2.second;
}
};
vs。 std::greater
std::greater
按引用获取对象。我怀疑这样做的效果是否会超过10%。 std::greater
比较node2.first < node1.first
是否为node2.first != node1.first
,否则为node2.second < node1.second
。比较完全不同于Comparator
的{{1}}。
由于比较结果不同,因此您的代码将经历完全不同的路径。经历不同的路径会对O的复杂性和性能产生深远的影响。这很可能是造成差异的真正原因。
对于node1.second < node2.second
的参考,请查看std::pair::operator<
在做什么:
如果
std::greater
,则返回lhs.first<rhs.first
。否则,如果true
,则返回rhs.first<lhs.first
。否则,如果false
,则返回lhs.second<rhs.second
。否则,返回true
。