【发布时间】:2018-04-15 07:10:06
【问题描述】:
我正在为一个大图(40k 节点,100k 弧)实现 Djikstra 算法。对于较短的路径,对于较大的路径(从一端到另一端),搜索时间不到一秒,这需要几分钟才能完成。我也在搜索后绘制路径,所以我使用了一些 Qt 对象。我怎样才能让它更快?由于地图结构,我在搜索邻居时感觉我在浪费时间。
这是班级
class PathFinder {
public:
void findPath2(const Node & start, Node & finish);
static PathFinder& getInstance();
PathFinder();
PathFinder(Gps gps);
~PathFinder();
unsigned int* getPrev() const;
void setPrev(unsigned int* prev);
QVector<unsigned int> makePath(int target);
GraphicNode* getTo();
GraphicNode* getFrom();
void setTo(GraphicNode* node);
void setFrom(GraphicNode* node);
class Compare
{
public:
bool operator() (std::pair<Node*, int> a, std::pair<Node*, int> b)
{
return a.second > b.second;
}
};
private:
static PathFinder* _pathfinder;
Gps _gps;
GraphicNode* _from;
GraphicNode* _to;
unsigned int* _prev;
unsigned int* _dist;
unsigned int _notVisited;
bool selectedNode = false;
Node* getMinNode();
bool hasNotVisited();
};
这是搜索功能
void PathFinder::findPath2(const Node& start, Node& finish)
{
QVector<Node> nodes=_gps.graph().nodes();
std::priority_queue<std::pair<Node*,int>,std::vector<std::pair<Node*, int>>,Compare> q;
_dist[start.id()] = 0;
for (int i = 0; i < nodes.size(); i++) {
std::pair<Node*, int> p = std::make_pair(const_cast<Node*>(&nodes.at(i)), _dist[i]);
q.push(p);
}
while (!q.empty()) {
std::pair<Node*, int> top = q.top();
q.pop();
Node* minNode = top.first;
QMap<Node*, unsigned short> nextNodes = minNode->nextNodes();
if (*minNode == finish) {
return;
}
int minNodeId = minNode->id();
for (QMap<Node*, unsigned short>::iterator iterator=nextNodes.begin(); iterator != nextNodes.end(); iterator++) {
Node* nextNode = iterator.key();
int altDist = _dist[minNodeId] + nextNodes.value(nextNode);
int nextNodeId = nextNode->id();
if (altDist < _dist[nextNodeId]) {
_dist[nextNodeId] = altDist;
_prev[nextNodeId] = minNodeId;
std::pair<Node*, int> p = std::make_pair(nextNode, _dist[nextNodeId]);
q.push(p);
}
}
}
}
这是节点的结构,它包含一个到其邻居的映射,以权重为值,x和y是稍后绘制它的坐标,不要介意
class Node {
private:
unsigned short _id;
double _y;
double _x;
QMap<Node*, unsigned short> _nextNodes;
bool _visited = false;
public:
Node();
Node(unsigned short id, double longitude, double latitude);
unsigned short id() const;
double y() const;
void setY(double y);
double x() const;
void setX(double x);
bool operator==(const Node& other);
void addNextNode(Node* node, unsigned short length);
QMap<Node*, unsigned short> nextNodes() const;
};
【问题讨论】:
-
我投票结束这个问题,因为它属于Code Review。
-
你考虑过使用A*吗?
-
从
const QMap<Node*, unsigned short> & nextNodes和const QMap<Node*, unsigned short>& nextNodes() const开始,看看它能让你走多远。
标签: c++ algorithm qt search graph