Shortest possible route, starting and finishing anywhere - python

I'm looking for an algorithm that will connect a large amount of geographic coordinates (100-1000), creating the shortest possible route between them, starting anywhere and finishing anywhere else. I'm working with Python.
I have researched the available algorithms, and my problem is similar to the Traveling Salesman, but it requires me to define a starting point, and will come back to this same point at the end. I will be taking an Uber to any starting point and from any other ending point back home. What I want is to cover all points while walking as little as possible. I don't care where it starts or ends.
Prim's and Kruskal's algorithms seem to find good starting and ending points, but they create a tree, not an optimized walking route as TSP.
Prim's algorithm:
Kruskal's algorithm:
Desired outcome based on Prim/Kruskal, but using TSP logic (example drawn by hand, not optimized):

If you don't need a productionized solution, write Python to dump your distance matrix in TSPLIB format with an extra city (representing the place that you will Uber to/from) with distance zero to each other city. Then feed it to (e.g.) Concorde or LKH.

Prim and Kruskal are algorithms to find a spanning tree. You're trying to solve a well-known variant of TS (the Traveling Salesman problem), in which you do not return to your starting point.
The location of your home is immaterial, per your definition. Your defined problem is to visit every location with the least distance traveled, without returning to your starting point. This is covered well in "the literature".
The "quick strike" solution is to take any standard TS solution and remove the longest segment. This is a good heuristic, although it doesn't guarantee the optimal solution.

Related

Match the vertices of two identical labelled graphs

I have a rather simple problem to define but I did not find a simple answer so far.
I have two graphs (ie sets of vertices and edges) which are identical. Each of them has independently labelled vertices. Look at the example below:
How can the computer detect, without prior knowledge of it, that 1 is identical to 9, 2 to 10 and so on?
Note that in the case of symmetry, there may be several possible one to one pairings which give complete equivalence, but just finding one of them is sufficient to me.
This is in the context of a Python implementation. Does someone have a pointer towards a simple algorithm publicly available on the Internet? The problem sounds simple but I simply lack the mathematical knowledge to come up to it myself or to find proper keywords to find the information.
EDIT: Note that I also have atom types (ie labels) for each graphs, as well as the full distance matrix for the two graphs to align. However the positions may be similar but not exactly equal.
This is known as the graph isomorphism problem, and probably very hard; although the exactly details of how hard are still subject of research.
(But things look better if you graphs are planar.)
So, after searching for it a bit, I think that I found a solution that works most of the time for moderate computational cost. This is a kind of genetic algorithm which uses a bit of randomness, but it is practical enough for my purposes it seems. I didn't have any aberrant configuration with my samples so far even if it is theoretically possible that this happens.
Here is how I proceeded:
Determine the complete set of 2-paths, 3-paths and 4-paths
Determine vertex types using both atom type and surrounding topology, creating an "identity card" for each vertex
Do the following ten times:
Start with a random candidate set of pairings complying with the allowed vertex types
Evaluate how much of 2-paths, 3-paths and 4-paths correspond between the two pairings by scoring one point for each corresponding vertex (also using the atom type as an additional descriptor)
Evaluate all other shortlisted candidates for a given vertex by permuting the pairings for this candidate with its other positions in the same way
Sort the scores in descending order
For each score, check if the configuration is among the excluded configurations, and if it is not, take it as the new configuration and put it into the excluded configurations.
If the score is perfect (ie all of the 2-paths, 3-paths and 4-paths correspond), then stop the loop and calculate the sum of absolute differences between the distance matrices of the two graphs to pair using the selected pairing, otherwise go back to 4.
Stop this process after it has been done 10 times
Check the difference between distance matrices and take the pairings associated with the minimal sum of absolute differences between the distance matrices.

Vehicle Routing Problem - How to finish/determine when certain locations are visited?

I have VRP problem. I have vehicles starting positions and I have distance matrix. I want solution to be terminated/finished when certain locations are visited.
So I don't want it to actually visit each index of location_matrix but if visiting different index beside "MUST VISITS" make for better solution then I have no problem. Because you know sometimes going from directly 1 to 3 is slower than 1-2-3. (visiting 2 which is not necessary but make it for shortcut)
I defined a dummy depot which cost 0 , I used this for end because if you use starts you have to define ends. And I put ends 000 which are basically ending position. You might ask why you didnt put your "JOB" locations. But this means they have to end there. So it doesn't seem optimal because example one vehicle could be really near to both of "JOB" locations but if it terminates / ends because it has END defined vehicle would stop.
I have no idea how to make this work. Basically what I want that if certain locations are visited once just terminate - that's the solution. So if jobs are (1,3,5) and Vehicle 1 visited 1,3 and Vehicle 2 just visited 2 it should be finished.
If I use solver in ortools It will be like TSP problem which will try to visit each location in distance_matrix. I don't exactly want this. It could visit if results better solution(does it make sense?) but it should be focusing on "JOB" locations and how to go them faster
Potential approach: Compute a new distance matrix with only the "MUST VISIT" locations, and run a VRP with this matrix.
Compute a distance matrix with only the "MUST VISIT" locations.
Each cell contains the shortest path between two "MUST VISIT" locations.
Store all the pairwise shortest paths found.
Run a regular VRP on this distance matrix.
Reconstruct the full path using the shortest paths found earlier.

OR-Tools solve traveling salesman (TSP) without returning to the home node

I'm using Google Or-Tools to solve a Traveling Salesman Problem by using this example (basically I just replaced the distances matrix with mine). As in the example, I set data['depot'] = 0.
For my application it is not important to return to the first node at the end of the path. I can remove the last edge from the solution but I wonder that if I could remove this constraint altogether it might find a better path overall.
Make sure the distance from all nodes to 0 (the depot) is null. This is equivalent to what you are asking for.

Single Depot Capacitated single Vehicle with different delivery magnitudes

I want to build an algorithm that gives the optimum route (minimum overall distance and it may have cycles) through which a single delivery vehicle, which has a limited capacity and starts from a fixed point (depot) and also ends at that point, can deliver the required amount of products on nodes.
Where should I start and what techniques/logic should I use? I have knowledge of graphs, trees, Dijkstra's algorithm etc.
I also think that this will be related to the Travelling Salesman problem in someway.
I will implement this on Python 3.6.
First implement Dijkstra's algorithm and find the shortest distance list. Then start from a node and deliver to the node that has the shortest distance from the selected node.
you should keep checking the capacity of the vehicle, if it reaches its limit so go back to the starting vertex, refill, and continue from the node where you left from.
Repeat this process until all the nodes have been reached.

Adjustment to a shortest path algorithm

for a datastructures & algorithms class in college we have to implement an algorithm presented in a paper. The paper can be found here.
So i fullly implemented the algorithm, with still some errors left (but that's not really why I'm asking this question, if you want to see how I implemented it thus far, you can find it here)
The real reason why I'm asking a question on Stackoverflow is the second part of the assignment: we have to try to make the algorithm better. I had a few ways in mind, but all of them sound good in theory but they won't really do good in practice:
Draw a line between the source and end node, search the node closest to the middle of that line and divide the "path" in 2 recursively. The base case would be a smaller graph were a single Dijkstra would do the computation. This isn't really an adjustment to the current algorithm but with some thinking it is clear this wouldn't give an optimal solution.
Try to give the algorithm some sense of direction by giving a higher priority to edges that point to the end node. This also won't be optimal..
So now I'm all out of ideas and hoping that someone here could give me a little hint for a possible adjustment. It doesn't really have to improve the algorithm, I think the first reason why they asked us to do this is so we don't just implement the algorithm from the paper without knowing what's behind it.
(If Stackoverflow isn't the right place to ask this question, my apologies :) )
A short description of the algorithm:
The algorithm tries to select which nodes look promising. By promising I mean that they have a good chance on lying on a shortest path. How promising a node is is represented by it's 'reach'. The reach of a vertex on a path is the minimum of it's distances to the start and to the end. The reach of a vertex in a graph is the maximum of the reaches of the vertex on all shortest paths.
To eventually determine whether a node is added to the priority queue in Dijkstra's algorithm, a test() function is added. Test returns true (if the reach of a vertex in the graph is larger or equal then the weight of the path from the origin to v at the time v is to be inserted in the priority queue) or (the reach of the vertex in the graph is larger or equal then the euclidean distance from v to the end vertex).
Harm De Weirdt
Your best bet in cases like this is to think like a researcher: Research in general and Computer Science research specifically is about incremental improvement, one person shows that they can compute something faster using Dijkstra's Algorithm and then later they, or someone else, show that they can compute the same thing a little faster using A*. It's a series of small steps.
That said, the best place to look for ways to improve an algorithm presented in a paper is in the future directions section. This paper gives you a little bit to work on in that direction, but your gold mine in this case lies in sections 5 and 6. There are multiple places where the authors admit to different possible approaches. Try researching some of these approaches, this should lead you either to a possible improvement in the algorithm or at least an arguable one.
Best of luck!

Categories