用邻接表C ++实现Dijkstra

时间:2018-07-08 22:38:15

标签: c++ algorithm

我正在尝试使用用户定义的对象对Dijkstra的邻接表进行算法编程。

这个项目是我工作的一部分,因此我必须保持一般性。

我正在使用邻接列表和STL优先级队列

这是我比较不同节点的方式

class priorityQueueCompareNodes
{
    public:
    bool operator() ( const Node& leftSideNode, 
                  const Node& rightSideNode  )
    {
        return leftSideNode.cost > rightSideNode.cost;
    }
};

这是我弹出并插入优先级队列的方式。

//get the node with the lowest cost from the priority queue
Node closestNode = priorityQueue.top();

//pop this node from the queue
priorityQueue.pop();

当我放松边缘并将成本更改到其他节点时,我更改了邻接表,而不是优先级队列。

我的问题是如何更改优先级队列中的值,以便每次放宽边缘权重并更改距离/父级时都有更新的优先级队列。

谢谢大家。

1 个答案:

答案 0 :(得分:0)

使用任何类型的指针来访问ls mysql/db/*.MYD | xargs -n1 basename | sed 's/\.MYD//g' | xargs -i bash -c "cp mysql/db/{}.* new_folder" 的内部操作以更新其中的元素是有问题的。例如,在最小优先级队列中,数据结构可确保节点的值小于其子节点的值。如果选择更新优先级队列中的值,则必须手动执行冒泡操作,以保留该保证的完整性。手动执行气泡上升/下降操作要比使用std::priority_queue这样的集合要重要。

使用std::priority_queue提供了一种可行的选择。要检索最小值和最大值,您可以简单地使用集合的std::setbegin指针。除集合外,您还应为节点保留最小距离rbegin的数组/向量(即随机访问集合)。每当放宽产生到节点M的较短路径时,都可以删除v的旧集合条目,更新v,然后将M[v]条目插入到集合中使用新的v值。更新M[v]是在恒定的时间内完成的,而设置操作要花费M[v]的时间。因此,即使它具有比优先级队列更大的恒定因子,使用集合也具有相同的渐近复杂度。

下面是说明用法的伪代码。由于您的代码不完整,因此我求助于使用标准数据类型。图的顶点是0索引的,对于v i ,邻接表O(log|V|)adjList中保留传出边的向量。对于每个边缘,分别保留目标顶点的索引和该边缘的权重。

adjList[i]

很明显,在代码库中对边缘成本和相关邻接列表条目的检索可能有所不同,但是由于您未提供这些细节,因此我尝试提供一种更通用的代码示例,以最小地强调这一点。基本上,该集合可以只保留一对成本和节点索引,而您已经全部完成。

或者,您可以为void dijkstra(vector< vector< pair<int, long long> > >& adjList, int source) { set< pair<long long, int> > priorityQueue; vector< long long > minCosts(adjList.size(), INFINITY); minCosts[source] = 0LL; priorityQueue.insert( make_pair(minCosts[source], source) ); while(!priorityQueue.empty()) { set< pair<long long, int> >::iterator it = priorityQueue.begin(); int u = it->second; long long costU = it->first; for(int i=0; i < adjList[u].size(); ++i) { int v = adjList[u][i].first; long long w = adjList[u][i].second; if (costU + w < minCosts[v]) { if(minCosts[v] < INFINITY) { priorityQueue.erase( make_pair(minCosts[v], v) ); } minCosts[v] = costU + w; priorityQueue.insert( make_pair(minCosts[v], v) ); } } } // minCosts[] now keeps the minimal distance of all nodes from source } 类型定义比较运算符,并将其保留在集合中,而不是一对成本和节点。但这只是特定于实现的决定,而不是问题的重点。