1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
|
std::shared_ptr<std::vector<StarSystem *>> StarSystem::find_fastest_route(StarSystem *dst, double max_distance){
if (dst->id == this->id)
return std::make_shared<std::vector<StarSystem *>>();
std::deque<std::pair<size_t, StarSystem *>> queue;
std::unordered_set<uintptr_t> visited;
std::vector<std::pair<size_t, StarSystem *>> came_from;
came_from.push_back({0, this});
queue.push_back({0, this});
visited.insert((uintptr_t)this);
while (queue.size()){
auto top = queue.front();
queue.pop_front();
auto n = top.second->nearby_systems.size();
for (size_t i = 0; i < n; i++){
auto distance = top.second->nearby_systems[i].second;
if (max_distance >= 0 && distance > max_distance)
continue;
auto nearby_system = top.second->nearby_systems[i].first;
if (visited.find((uintptr_t)nearby_system) != visited.end())
continue;
came_from.push_back({top.first, nearby_system});
if (nearby_system->id == dst->id)
return rebuild_list(came_from);
queue.push_back({came_from.size() - 1, nearby_system});
visited.insert((uintptr_t)nearby_system);
}
}
return std::shared_ptr<std::vector<StarSystem *>>();
}
struct AStarQueueElement{
double distance;
size_t came_from;
StarSystem *system;
bool operator<(const AStarQueueElement &b) const{
return this->distance < b.distance;
}
};
std::shared_ptr<std::vector<StarSystem *>> StarSystem::find_fastest_route_Astar(StarSystem *dst, double max_distance){
if (dst->id == this->id)
return std::make_shared<std::vector<StarSystem*>>();
std::priority_queue<AStarQueueElement, std::deque<AStarQueueElement>> queue;
std::unordered_set<uintptr_t> visited;
std::vector<std::pair<size_t, StarSystem *>> came_from;
came_from.push_back({0, this});
queue.push(AStarQueueElement{dst->distance_sqr(this), 0, this});
visited.insert((uintptr_t)this);
while (queue.size()){
auto top = queue.top();
queue.pop();
auto top_distance = top.distance;
auto top_came_from = top.came_from;
auto top_system = top.system;
auto n = top_system->nearby_systems.size();
for (size_t i = 0; i < n; i++){
auto distance = top_system->nearby_systems[i].second;
if (max_distance >= 0 && distance > max_distance)
continue;
auto nearby_system = top_system->nearby_systems[i].first;
if (visited.find((uintptr_t)nearby_system) != visited.end())
continue;
came_from.push_back({top_came_from, nearby_system});
if (nearby_system->id == dst->id)
return rebuild_list(came_from);
queue.push(AStarQueueElement{dst->distance_sqr(nearby_system), came_from.size() - 1, nearby_system});
visited.insert((uintptr_t)nearby_system);
}
}
return std::shared_ptr<std::vector<StarSystem *>>();
}
|