Single Depot Capacitated single Vehicle with different delivery magnitudes - python

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.

Related

Add extra cost depending on length of path

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.

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.

Is there a way that gives shortest path using Floyd-Warshall's algorithm where negative weight cycle exists whereas overlapped edges are not allowed?

We know that the result of Floyd-Warshall's algorithm is invalid if a negative weight cycle appears in the graph, that is because to travel multiple times on the negative weight cycle makes the weight sum arbitrarily small. However if we specify that no duplicated edge are allowed to be travelled on then the weight sum is correct by sense. I want to know a way that produces the least weight sum in such condition. Some modifications of the algorithm have been tried (Including to skip the loop when a weight sum from some vertex to itself is minus) but the predecessor matrix was still weird and the weight sum matrix was totally useless (By chance I knew that an exponentially increasing value of it would inevitably occur, see link).
An efficient solution to that problem would imply P=NP, so there almost certainly isn't such a solution.
With a polynomial-time solution to your problem, you could solve the longest trail problem by setting all edge weights to -1 and asking for the shortest path between two nodes.
As proven by Marzio De Biasi in the linked post, a solution to the longest trail problem can be used to solve the Hamiltonian cycle problem on grid graphs of max degree 3, by connecting two new nodes to the top-left node and asking for the longest trail.
The Hamiltonian cycle problem is still NP-complete when restricted to grid graphs of max degree 3, as proven in Christos H Papadimitriou, Umesh V Vazirani, On two geometric problems related to the travelling salesman problem, Journal of Algorithms, Volume 5, Issue 2, June 1984, Pages 231-246, ISSN 0196-6774.
Thus, your problem is NP-hard.

Shortest possible route, starting and finishing anywhere

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.

How do I find the path with the biggest sum of weights in a weighted graph?

I have a bunch of objects with level, weight and 0 or more connections to objects of the next levels. I want to know how do I get the "heaviest" path (with the biggest sum of weights).
I'd also love to know of course, what books teach me how to deal with graphs in a practical way.
Your graph is acyclic right? (I presume so, since a node always points to a node on the next level). If your graph can have arbritrary cycles, the problem of finding the largest path becomes NP-complete and brute force search becomes the only solution.
Back to the problem - you can solve this by finding, for each node, the heaviest path that leads up to it. Since you already have a topological sort of your DAG (the levels themselves) it is straighfoward to find the paths:
For each node, store the cost of the heaviest path that leads to it and the last node before that on the said path. Initialy, this is always empty (but a sentinel value, like a negative number for the cost, might simplify code later)
For nodes in the first level, you already know the cost of the heaviest path that ends in them - it is zero (and the parent node is None)
For each level, propagate the path info to the next level - this is similar to a normal algo for shortest distance:
for level in range(nlevels):
for node in nodes[level]:
cost = the cost to this node
for (neighbour_vertex, edge_cost) in (the nodes edges):
alt_cost = cost + edge_cost
if alt_cost < cost_to_that_vertex:
cost_to_that_vertex = alt_cost
My book recommendation is Steve Skiena's "Algorithm Design Manual". There's a nice chapter on graphs.
I assume that you can only go down to a lower level in the graph.
Notice how the graph forms a tree. Then you can solve this using recursion:
heaviest_path(node n) = value[n] + max(heaviest_path(children[n][0]), heaviest_path(children[n][1]), etc)
This can easily be optimized by using dynamic programming instead.
Start with the children with the lowest level. Their heaviest_path is just their own value. Keep track of this in an array. Then calculate the heaviest_path for then next level up. Then the next level up. etc.
The method which i generally use to find the 'heaviest' path is to negate the weights and then find the shortest path. there are good algorithms( http://en.wikipedia.org/wiki/Shortest_path_problem) to find the shortest path. But this method holds good as long as you do not have a positive-weight cycle in your original graph.
For graphs having positive-weight cycles the problem of finding the 'heaviest' path is NP-complete and your algorithm to find the heaviest path will have non-polynomial time complexity.

Categories