如何解决双向A-Star算法崩溃问题
我正在尝试使用Eucledean启发式方法实现双向Dijkstra的算法,但是当我将其提交给平地机时,它会崩溃。第一次使用集提取最小边缘权重时,我以为那是错误,但我更改了优先级队列,但没有任何反应。我不认为它会崩溃是因为它占用了大量内存,在最坏的情况下,它为矢量使用了880000个内存空间,但是也许我不知道如何估计在最坏的情况下所使用的内存量。谁知道我的代码为什么会崩溃?
这是我的代码:
#include <cstdio>
#include <cassert>
#include <vector>
#include <limits>
#include <utility>
#include <math.h>
#include <queue>
#include <iostream>
using namespace std;
// Vector to represent a graph as an adjacency list
typedef vector<vector<vector<int>>> Adj;
// Distances can grow out of int type
typedef long long Len;
// Vector of two priority_queue - for forward and backward searches.
typedef vector<priority_queue<pair<Len,int>,vector<pair<Len,int>>,greater<pair<Len,int>>>> Queue;
const Len MAX_ = numeric_limits<Len>::max() / 4;
class AStar {
// Size of the nodes
int n_;
// adj_[0] and cost_[0] stores the original edges and its weights
// adj_[1] and cost_[1] stores the reverses edges and its weights
Adj adj_;
Adj cost_;
// distance_[0] stores the distance for the forward search
// distance_[1] stores the distance for the backward search
vector<vector<Len>> distance_;
// hdistance_[0] stores the distance plus the heuristics value for the forward search
// hdistance_[1] stores the distance plus the heuristics value for the backward search
vector<vector<Len>> hdistance_;
// Stores the nodes discovered in the path neither from source to target or from target to source
vector<int> workset_;
// Stores the visited nodes
vector<bool> visited_;
// Coordinates of the nodes
std::vector<std::pair<Len,Len>> xy_;
public:
AStar(int n,Adj adj,Adj cost,std::vector<std::pair<Len,Len>> xy)
: n_(n),adj_(adj),cost_(cost),distance_(2,vector<Len>(n_,MAX_)),hdistance_(2,visited_(n),xy_(xy),workset_(n)
{}
// Reset everything
void clear() {
for (unsigned int i = 0; i < workset_.size(); ++i) {
int v = workset_[i];
visited_[v] = false;
}
distance_= vector<vector<Len>>(2,MAX_));
hdistance_= vector<vector<Len>>(2,MAX_));
workset_.clear();
}
// Return the heuristic distance from the node to the target and from the source to the node
long long potential(int a,int side,int s,int t){
long long pi_f=sqrt(pow(xy_[a].first-xy_[t].first,2)+pow(xy_[a].second-xy_[t].second,2));
long long pi_r=sqrt(pow(xy_[s].first-xy_[a].first,2)+pow(xy_[s].second-xy_[a].second,2));
//cout<<"pi_f="<<pi_f<<",pi_r="<<pi_r<<'\n';
return side?(pi_r-pi_f)/2:(pi_f-pi_r)/2;
}
// Visit each neighbor node and change is distance value if it's needed
void visit(Queue& q,pair<Len,int> u,int t) {
for(unsigned int i=0; i<adj_[side][u.second].size();i++){
int v=adj_[side][u.second][i];
int w=cost_[side][u.second][i];
//cout<<"Node -> "<<v<<",distance: "<<w<<'\n';
long long h=potential(v,side,s,t);
//cout<<"heuristics: "<<h<<'\n';
//cout<<" - "<<distance_[side][v]<<" "<<distance_[side][u.second]+w<<'\n';
if((hdistance_[side][v]==MAX_)||(distance_[side][v]>distance_[side][u.second]+w)){
distance_[side][v]=distance_[side][u.second]+w;
hdistance_[side][v]=distance_[side][u.second]+w+h;
q[side].push(make_pair(hdistance_[side][v],v));
}
}
workset_.push_back(u.second);
}
// Returns the shortest distance to the target
Len Shortest_Path() {
long long distance=MAX_;
for(unsigned int i=0; i<workset_.size();i++){
if(distance_[0][workset_[i]]+distance_[1][workset_[i]]<distance){
distance=distance_[0][workset_[i]]+distance_[1][workset_[i]];
}
}
return distance;
}
// Process each query
Len query(int s,int t) {
clear();
Queue q(2);
q[0].push(make_pair(0,s));
q[1].push(make_pair(0,t));
distance_[0][s]=0;
hdistance_[0][s]=0;
hdistance_[1][t]=0;
distance_[1][t]=0;
pair<Len,int> v;
do{
// Forward search
if(q[0].size()==0){
break;
}
v=q[0].top();
q[0].pop();
//If it's a non-updated node
if(hdistance_[0][v.second]!=v.first){
continue;
}
visit(q,v,t);
if(visited_[v.second]==1){
return Shortest_Path();
}
visited_[v.second]=1;
// Backward search
if(q[1].size()==0){
break;
}
v=q[1].top();
q[1].pop();
//If it's a non-updated node
if(hdistance_[1][v.second]!=v.first){
continue;
}
visit(q,1,t);
if(visited_[v.second]==1){
return Shortest_Path();
}
visited_[v.second]=1;
}while(true);
return -1;
}
};
int main() {
int n,m;
scanf("%d%d",&n,&m);
std::vector<std::pair<Len,Len>> xy(n);
for (unsigned int i=0;i<n;++i){
int a,b;
scanf("%d%d",&a,&b);
xy[i] = make_pair(a,b);
}
Adj adj(2,vector<vector<int>>(n));
Adj cost(2,vector<vector<int>>(n));
for (unsigned int i=0; i<m; ++i) {
int u,c;
scanf("%d%d%d",&u,&v,&c);
adj[0][u-1].push_back(v-1);
cost[0][u-1].push_back(c);
adj[1][v-1].push_back(u-1);
cost[1][v-1].push_back(c);
}
AStar astar(n,adj,cost,xy);
int t;
scanf("%d",&t);
for (int i=0; i<t; ++i) {
int u,v;
scanf("%d%d",&v);
printf("%lld\n",astar.query(u-1,v-1));
}
}
以下是约束条件:
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。