我正在尝试使用用户定义的对象对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();
当我放松边缘并将成本更改到其他节点时,我更改了邻接表,而不是优先级队列。
我的问题是如何更改优先级队列中的值,以便每次放宽边缘权重并更改距离/父级时都有更新的优先级队列。
谢谢大家。
答案 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::set
和begin
指针。除集合外,您还应为节点保留最小距离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
}
类型定义比较运算符,并将其保留在集合中,而不是一对成本和节点。但这只是特定于实现的决定,而不是问题的重点。