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.
Related
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.
I have a graph/network that obviously consists of some nodes and some edges. Each edge has a weight attached to it, or in this case a cost. Each edge also have a distance attached to it AND a type. So basically the weight/cost is pre-calculated from the distance of the edge along with some other metrics for both type of edges.
However, in my case I would like there to be added some additional cost for let's say every 100 distance or so, but only for one type of edge.But I'm not even certain if it is possible to add additional cost/distance depending on the sum of the previous steps in the path in algorithms such as Dijkstra's ?
I know I could just divide the cost into each distance unit, and thus getting a somewhat estimate. The problem there would be the edge cases, where the cost would be almost double at distance 199 compared to adding the cost at exactly each 100 distance, i.e. adding cost at 100 and 200.
But maybe there are other ways to get around this ?
I think you cannot implement this using Dijkstra, because you would validate the invariant, which is needed for correctness (see e.g. wikipedia). In each step, Dijkstra builds on this invariant, which more or less states, that all "already found paths" are optimal, i.e. shortest. But to show that it does not hold in your case of "additional cost by edge type and covered distance", let's have a look at a counterexample:
Counterexample against Usage of Dijkstra
Assume we have two types of edges, first type (->) and second type (=>). The second type has an additional cost of 10 after a total distance of 10. Now, we take the following graph, with the following edges
start -1-> u_1
start -1-> u_2
start -1-> u_3
...
start -1-> u_7
u_7 -1-> v
start =7=> v
v =4=> end
When, we play that through with Dijkstra (I skip all intermediate steps) with start as start node and end as target, we will first retrieve the path start=7=>v. This path has a length of 7 and that is shorter than the "detour" start-1->u_1-1->... -1->u_7->v, which has a length of 8. However, in the next step, we have to choose the edge v=4=>end, which makes the first path to a total of 21 (11 original + 10 penalty). But the detour path becomes now shorter with a length of 12=8+4 (no penalty).
In short, Dijkstra is not applicable - even if you modify the algorithm to take the "already found path" into account for retrieving the cost of next edges.
Alternative?
Maybe you can build your algorithm around a variant of Dijkstra, which usually retrieves multiple (suboptimal) solutions. First, you would need to extend Dijkstra, so that it takes the already found path into account. (In this function replace cost = weight(v, u, e) with cost = weight(v, u, e, paths[v]) and write a suitable function to calculate the penalty based on the previous path and the considered edge). Afterwards, remove edges from your original optimal solution and iterate the procedure to find a new alternative shortest path. However, I see no easy way of selecting which edge to remove from the graph-beside those from your penalty type-and the runtime complexity is probably awful.
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.
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.
I know Dijkstra's algorithm is a popular solution for the "shortest path" problem, however it seems to be backfiring when implementing time tables.
Say I have this graph with the following weights (time to get from one point to another):
A-----C A->C: 10
\--B--/ A->B: 5
B->C: 5
If you throw it into Dijkstra, it'll return route A->C. That's fine until you refer to a timetable that says route A->C only exists within a certain time frame. You could easily remove the A->C edge if the requested time frame falls outside the range when that edge is used. But obviously the data set I'm working with has a bunch of other ways to get from A->C with other, higher, costs. Not to mention what if you want to get from Z->Y which requires going from A->C in the middle. It doesn't seem like an ideal solution.
Is there a better way, other than Dijkstra, to create a shortest path while also keeping a timetable in mind? Or should the algorithm be modified to consider two weights when finding the optimal path?
If it matters, I'm using python.
[edit]
The time table is a basic table that says a train (in my case) leaves from point A at (say) 12:00 and leaves from station B at 12:05 then leaves from C at 12:10. When it doesn't stop at B, its column is empty and A will have 08:00 and C will have 08:10
A B C
800 8:10
12:00 12:05 12:10
One way could be creating a set of trees that denotes all simple paths between to given nodes and just selecting the shortest one among those that are not contain a deprecated edge. You can find all paths by adapting Dijkstra's algorithm or another algorithm like DFS or BFS. Also finding all paths between two nodes is considered to be a hard problem but based on your need and the type of graphs that you're dealing with you can create what you want. You can also read this post regarding this matter. -> Find all paths between two graph nodes. i.e you can have a limited set of paths (if using Dijkstra top N shortest).
Now for Optimizing this step so that find out if an edge is deprecated or not I suggest to have a dictionary of all edge ids or names as keys and their deprecation timestamp as value then filter the dictionary by comparing the values with now().timestamp() and after each find just remove the items from dictionary. Also note that before you start filtering you should check if the edge exist in dictionary or not (in order to prevent the lagorithm to run the filtering multiple times for duplicate edges).
The code should be like following:
def filter_edge(u_id):
if edge in deprecation:
time_stamp = deprecation[u_id]
if time_stamp > datetime.now().timestamp():
return True
return False
And the path validation is something like following:
def validate_path(path):
return not any(filter_edge(edge.id) for edge in path)