Dijkstra算法实现的性能
Performance of Dijkstra's algorithm implementation
下面是我根据维基百科文章中的伪代码编写的Dijkstra算法的实现。对于一个约有40000个节点和80000条边的图,运行需要3或4分钟。这是正确的数量级吗?如果没有,我的实现有什么问题?
struct DijkstraVertex {
int index;
vector<int> adj;
vector<double> weights;
double dist;
int prev;
bool opt;
DijkstraVertex(int vertexIndex, vector<int> adjacentVertices, vector<double> edgeWeights) {
index = vertexIndex;
adj = adjacentVertices;
weights = edgeWeights;
dist = numeric_limits<double>::infinity();
prev = -1; // "undefined" node
opt = false; // unoptimized node
}
};
void dijsktra(vector<DijkstraVertex*> graph, int source, vector<double> &dist, vector<int> &prev) {
vector<DijkstraVertex*> Q(G); // set of unoptimized nodes
G[source]->dist = 0;
while (!Q.empty()) {
sort(Q.begin(), Q.end(), dijkstraDistComp); // sort nodes in Q by dist from source
DijkstraVertex* u = Q.front(); // u = node in Q with lowest dist
u->opt = true;
Q.erase(Q.begin());
if (u->dist == numeric_limits<double>::infinity()) {
break; // all remaining vertices are inaccessible from the source
}
for (int i = 0; i < (signed)u->adj.size(); i++) { // for each neighbour of u not in Q
DijkstraVertex* v = G[u->adj[i]];
if (!v->opt) {
double alt = u->dist + u->weights[i];
if (alt < v->dist) {
v->dist = alt;
v->prev = u->index;
}
}
}
}
for (int i = 0; i < (signed)G.size(); i++) {
assert(G[i] != NULL);
dist.push_back(G[i]->dist); // transfer data to dist for output
prev.push_back(G[i]->prev); // transfer data to prev for output
}
}
您可以改进以下几点:
- 使用sort和erase实现优先级队列为运行时添加了一个|E|因子-使用STL的堆函数将log(N)插入和删除到队列中
- 不要一次将所有节点都放在队列中,而只放那些发现路径的节点(这可能是最优的,也可能不是最优的,因为您可以通过队列中的节点找到间接路径)
- 为每个节点创建对象会产生不必要的内存碎片。如果你关心挤出最后5-10%,你可以考虑一种解决方案,将关联矩阵和其他信息直接表示为数组
使用优先级队列。
我的Dijkstra实现:
struct edge
{
int v,w;
edge(int _w,int _v):w(_w),v(_v){}
};
vector<vector<edge> > g;
enum color {white,gray,black};
vector<int> dijkstra(int s)
{
int n=g.size();
vector<int> d(n,-1);
vector<color> c(n,white);
d[s]=0;
c[s]=gray;
priority_queue<pair<int,int>,vector<pair<int,int> >,greater<pair<int,int> > > q; // declare priority_queue
q.push(make_pair(d[s],s)); //push starting vertex
while(!q.empty())
{
int u=q.top().second;q.pop(); //pop vertex from queue
if(c[u]==black)continue;
c[u]=black;
for(int i=0;i<g[u].size();i++)
{
int v=g[u][i].v,w=g[u][i].w;
if(c[v]==white) //new vertex found
{
d[v]=d[u]+w;
c[v]=gray;
q.push(make_pair(d[v],v)); //add vertex to queue
}
else if(c[v]==gray && d[v]>d[u]+w) //shorter path to gray vertex found
{
d[v]=d[u]+w;
q.push(make_pair(d[v],v)); //push this vertex to queue
}
}
}
return d;
}
相关文章:
- 了解算法的性能差异(如果以不同的编程语言实现)
- C++分离功能,实现性能优化
- 为什么 C++ 代码实现的性能不比 python 实现更好?
- 为什么用于阈值矩阵元素的 Matlab 逻辑索引操作在性能上优于 mex 实现?
- 将函数及其实现移动到与主文件不同的文件(.hpp 和 .cpp)时,性能会受到很大影响
- 为什么这个普通的数组实现比STD ::向量实现性能慢
- 具有良好性能的c++映射实现
- Google Protobuf基于C++的python实现的性能
- 考虑 CPU 提升模式的多线程超线性性能实现
- 什么是通过调用_mm_stream_si64x()实现性能提升的示例程序
- 在 C++98 中实现移动构造函数和移动赋值运算符以获得更好的性能
- 性能不佳基于OpenCL的OpenCV平方实现
- 快速容器,实现一致的性能
- 并提高.进程间牺牲性能来实现可移植性
- 在c++中实现长方程时,如何通过高级方法提高性能?< / h1 >
- c++性能技术报告TR 18015中使用了哪些实现
- 并行线程执行以实现性能
- R stats::sd()与arma::stddev()与Rcpp实现的性能
- Dijkstra算法实现的性能
- c++仅用一行代码就实现了巨大的性能差异