We are working on a project which involves running a shortest path algorithm on a big map.
We are using AStar with the Air Distance heaurstic for now.
Our project involves receiving updates to links in the database.
Currently we restart the search for each link update or at every predefined interval.
Is there a way to update the AStar algorithm to update the search without restarting the search on every update received? Is there a better algorithm suited for this task?
Disclosure: This is part of students project.
Thank you.
You might be looking for a routing algorithm (that by nature deals with constantly changing graphs).
One way to achieve it is with Distance Vector Routing Protocol (which is a distributed version of Bellman Ford algorithm) and works as follows1:
periodically, every vertex sends its "distances vector" to its
neighbors [the vector indicates how much it 'costs' to travel from the sending vertex, to each other vertex.
Its neighbors try to update their routing tables [through which edge is it best to move to the each target]
for your case, each node knows what is the fastest way to get to its neighbors (1 if the graph is unweighted) and it (the vertex) adds this number to each entree in the distance vector, in order to know how to and how much time it will take, to get to the destination. Every time a modification arrives, the relevant node will invoke a new iteration of the protocol until it re-converges.
Note however, that this algorithm is uninformed (but deals well with changing graphs, with certain limitations, there is still the count to infinity problem)
(1) The explanation of the algorithm is based on an explanation I provided some time back in this thread, with some modifications. (It is the same suggested algorithm after all).
Related
I am given a map that looks like so:
Every node is connected with its horizontal and vertical (not diagonal) neighbors and all connections have the same cost.
I want to find the best path, from one location to a set of end locations (the one which can be reached quickest). Also note that every node has the ability to be blocked and and thus not be used as a node in the path.
What would be the most efficient algorithm to solve this problem with?
I have thought of maybe A* but find it difficult to apply the multiple endpoint rule.
In my unweighed graph, I need from a source vertex to reach an imposed vertex and come back to source.
All vertex may be visited at most once.
(There may be cycles in that graph.)
I want the length of the shortest such path.
Looking for a "fast" algorithm:
I have already made several attempts in Python but not fast enough. ;-)
Latest for instance : generator of all paths from source to imposed point (in order of increasing length), every time I get a new path, compare it with all those already calculated and stop if disjoint.
Good result, but too slow / memory expensive.
Earlier (same issue) : consider sub states with information : position, already been to imposed point or not, set of already visited vertexes... good result too but too slow / memory expensive.
DP solution welcome.
Could not find something with google. Point me to if you know where there is something.
Thanks.
--- example ---
e...
#!!#
#!.#
...s
This is a maze; you enter at 'e' and need to reach the sword 's' and back to the entrance 'e'.
'#' are unpassable. '!' are traps, when you walk on these, you trigger them and cannot pass again.
I have turned this into a graph with 5 vertices in this case : e,s, (2,2), (3,2) and (2,3)
--- case where Suurballe algo yields two not disjoined paths ----
.....
##!!#
#!!!#
#!!##
.....
For unweighted graph shortest path BFS in both directions might be the most efficient solution.
You can use BFS to determine how far every node is from your source.
after you find the path, you can remove every node beside the source and target so you will not repeat a node on the path more than once, and then use BFS from the target back to your source.
The total complexity is linear O(V+E)
more on that:
https://www.geeksforgeeks.org/shortest-path-unweighted-graph/
If I understood your question correctly, then I think what you're looking for are node disjoint paths. The classic algorithm to uncover them was proposed by Suurballe. Another algorithm based on network flow is implemented in networkx: networkx.algorithms.connectivity.disjoint_paths.node_disjoint_paths.
Hopefully these pointers solve the problem in your graphs with sufficient speed.
So given a graph that has a cycle from vertex S to E as it goes through every vertex then ends on E. My goal here is to remove all extra edges so that there is just a path from S to E. To help me with this I have a function called check(node) I'm not given the code for it but it returns True or False if there still exist a path from S to E such that all nodes were visited only once until we end at E.
Example:
The plan is to remove a edge from vertex a to b and then run check(node) on the mutated graph and see if it still returns True so we know its safe to remove that edge, and if it returns False then add it back. Do that for every edge so only the needed edge remains, however I have no idea how to iterate through the edges.
I stored the graphs in a dictionary
Usually the approach to an Algorithms problem like this is you first figure out what algorithmic tools you can use. Most basic problems can be solved with an existing algorithm. Your first objective is to see if you can modify the problem set (ie the given graph) in such a way that you don't need to modify the algorithm, because modifying the algorithm lends to difficulties in assessing Big-O for the problem. If the graph can't be modified in any way that makes running a black boxed Algorithm easy, then you modify the algorithm. The last resort is to come up wit your own algorithm to solve the problem.
If my Algorithms recollection is correct, in short this is the Travelling Salesman Problem. If I'm understanding your question correctly, you want the shortest path possible that visits every node. You don't even need to modify your given graph in order to use the algorithm. It should theoretically find you the desired path. Only after the algorithm has run do you need to reduce the graph to its desired state. So I suggest finding some way to implement TSP to your specifications, and remove all edges that aren't part of the solution.
Here is some sample code from GeeksForGeeks that could help you get started
Hi I have been trying to implement the DBSCAN algorithm for Neo4j, but am running into serious performance bottlenecks. I'll describe the implementation then ask for help.
I discretized the possible epsilon values and put counts of the number of neighbors under each discretization in each node in order to be able to retrieve all of the core nodes in one query.
START a = node(*)
WHERE a.rel<cutoff threshold>! >= {minp}
RETURN a
This part is fast, the part that isn't fast is the follow up query :
START a = node({i})
SET a.label<cutoff threshold>_<minpoints> = {clust}
WITH a
MATCH a -[:'|'.join(<valid distance relations>)]- (x)
WHERE not(has(x.label<cutoff threshold>_<minpoints>))
WITH x
SET x.label<cutoff threshold>_<minpoints>={clust}
RETURN x
I then pick a core node to start from, and as long as there are still core node neighbors, run the above query to label their neighbors.
I think the problem is that my graph has very different levels of sparsity - starting from only weak similarity it is almost fully connected, with ~50M relations between ~10k nodes, whereas at strong similarity there are as few as ~20k relations between ~10k nodes (or fewer). No matter what, it is always REALLY slow. What is the best way for me to handle this? Is it to index on relationship type and starting node? I haven't been able to find any resources on this problem, and surprisingly there isn't already an implementation since this is a pretty standard graph algorithm. I could use scikit.learn but then I would be restricted to in-memory distance matricies only :(
What version of neo4j did you try this with?
Up until 1.8 performance has been no design goal of cypher (rather the language)
Have a look at a recent snapshot (1.9-SNAP).
Also make sure that your hot dataset is not just loaded from disk (otherwise you measure disk-io) so your memory mapped settings and also JVM heap is large enough.
You might also want to check out the GCR cache from Neo4j enterprise which has a smaller memory footprint.
What is the cardinality of count(x) in your query? If it is too small you have too many small transactions going on. Depending if your run python embedded or REST use a larger tx-scope or REST-batch-operations
You're already using parameters which is great. What is the variability of your rel-types ?
Any chance to share your dataset/generator and the code with us (Neo4j) for performance testing on our side?
There are DBSCAN implementations around that use indexing. I don't know about neo4j so I can't really tell if your approach is efficient. The thing you might need to precompute is actually a sparse version of your graph, with only the edges that are within the epsilon threshold.
What I'd like to point out that apparently you have different densities in your data set, so you might want to instead use OPTICS, which is a variant of DBSCAN that does away with the epsilon parameter (and also doesn't need to distinguish "core" nodes, as every node is a core node for a certain epsilon). Do not use the Weka version (or the weka-inspired python version that is floating around). They are half OPTICS and half DBSCAN.
When you have efficient sorted updatable heaps available, OPTICS can be pretty fast.
I want to retrace maps from google earth these maps would then be used for calculating fastest route from A to B as well as location probability defined by some factors. How would i go about doing these? My first thought is pygame and using some already made ones or using them as a template.
I've worked on a routing application for a while. The most common algorithm for this is to start on both ends (start and finish) and move towards each other, traversing all possible methods of travel. The branches that meet in the middle will be your ideal path.
You can weight things appropriately, like speed limit, by setting checks in the code to only move x distance every time step.
These should do you:
Good graph traversal algorithm
Link
http://en.wikipedia.org/wiki/A*_search_algorithm/
Map Routing, a la Google Maps?
Have you looked at Google Maps, rather than Google Earth? This has roads and a routing engine.