Let's say we have a problem where there are several cities with variable path costs (in time taken) between them, and we have 2 salesmen that must visit every city at least once, between the two of them.
Now, suppose we have an algorithm that given a salesman and a set of cities, can devise an optimal path for that salesman. What we want to do is split up the cities in such a way that assigning one set to the first salesman and the other set to the other salesman gives us a solution that allows the total time taken to be as low as possible. What is a good way to do this? We want a solution thats good, but not necessarily optimal.
My thought was that we could use some sort of heuristic to determine whether a given split was good or bad, but there are a lot of cities and so picking the split is hard. I'm not entirely sure how to go about this.
To clarify: each city must be visited by at least one salesman, not both.
Edit: its more a Hamiltonian path, we don't need to return to the origin city.
I would start by running Kruskal's algorithm to find the minimum spanning tree. Then cut each edge in turn. Since Kruskal's algorithm finds the minimum spanning tree, cutting an edge should always result in two sets of cities. Check the total spanning distance for the two sets of cities. If the total spanning distance is approximately equal, then the split is worth considering, and you can run the traveling salesman (TS) algorithm on the two sets. If the TS algorithm results in two times that are approximately equal, then that's a good solution. Otherwise, continue cutting edges on the minimum spanning tree.
Related
Suppose you have "n" managers and "n" stores all located randomly across a geographic area. I need to be able to assign each manager to a store. The managers will travel daily from their homes to their assigned store. In general I'd like to minimize the daily distance travelled. This can be interpreted in two ways:
Minimize the average daily travel distance (which is also the same as minimizing the total travel distance.
Minimize the maximum travel distance for any single manager
Is this a known problem? Are there any obvious algorithms to solve it? It seems similar to the traveling salesman problem but it's not quite the same.
Both can be solved polynomially
I'll quickly cover both ways to define an optimal allocation as described in the question. Note that I won't make any assumption on the traveling times, such as triangle inequality. Of course such a property is likely to hold in practice, and there may be better algorithms that use these properties.
Minimize total distance
For this instance, we consider the managers and the stores to be a weighted complete bipartite graph. We then want a matching that minimizes the sum of the weights.
This is called the Balanced Assignment Problem, which is a specific case of minimum/maximum matching. Because the graph is bipartite, this can be solved polynomially. Wikipedia lists a couple of algorithms for solving this problem, most notably the Hungarian algorithm.
Minimize maximum distance
If we wish to minimize the maximum distance, we can find a solution through a binary search. Specifically, we binary search over the maximum distance and attempt to find a matching that does not violate this maximum distance.
For any given maximum distance x, we create the bipartite graph that has edges between manager M and store S if and only if d(M, S) < x. We then try to create a complete matching on this bipartite graph with any bipartite matching algorithm, and through success and failure complete the binary search for the smallest x that allows for matching, thus minimizing the maximum distance.
The title is a mouth-full, but put simply, I have a large, undirected, incomplete graph, and I need to visit some subset of vertices in the (approximately) shortest time possible. Note that this isn't TSP, as I don't need to visit all vertices.
The naive approach would be to simply brute-force the solution by trying every possible walk which includes the required vertices, using A*, for example, to calculate the walks between required vertices. However, this is O(n!) where n is the number of required vertices. This is unfeasible for me, as n > 40 in my average case, and n ≈ 80 in my worst case.
Is there a more efficient algorithm for this, perhaps one that approximates the solution?
This question is similar to the question here, but differs in the fact that my graph is larger than the one in the linked question. There are several other similar questions, but none that I've seen exactly solve my specific problem.
If you allow visiting the same nodes several times, find the shortest path between each pair of mandatory vertices. Then you solve the TSP between the mandatory vertices, using the above shortest path costs. If you disallow multiple visits, the problem is much worse.
I am afraid you cannot escape the TSP.
I am given a weighted graph and want to find a set of edges such that every node is only incident to one edge and such that the sum of the selected edge weights is maximized. As far as I know this problem is generally referred to as maximum weight matching and there exist fast approximations for it: https://web.eecs.umich.edu/~pettie/papers/ApproxMWM-JACM.pdf
However, for my application it would be better if only a certain ratio of nodes is paired. It's more important for my application that the nodes that get paired have a high weight between them. Leaving some nodes unpaired is no big problem.
Currently, I sort the weights between nodes in descending order and always select the edge with the highest weight until I have paired a certain number of nodes. Of course I ensure that pairs of nodes are mutually exclusive. This is only a 1/2 approximation to the original problem and it's probably even worse for the modified problem.
Could you please suggest an algorithm for this issue or tell me how this problem is called?
Some thoughts.
The greedy algorithm for this problem is a 2-approximation. Imagine that, during the execution of the greedy algorithm, we keep score versus an optimal solution in the following manner. Every time we add an edge to the greedy solution, we delete the incident edges in the optimal solution, which I claim must have weight no greater than the greedy edge. If no edge would be deleted from the optimal solution, we delete the two heaviest edges instead, which also I claim must have weight no greater than the greedy edge. Since the greedy solution must have at least half as many edges as the optimal solution, I claim that there are no optimal edges left at the end, and hence greedy is a 2-approximation because we never deleted more than 2x weight with each greedy edge.
A complete 20,000-vertex graph is right on that line where I don't know whether integer programming would be a good idea. I think it's still worth a try because it's easy enough.
There are polynomial-time algorithms for computing the maximum-weight independent set in the intersection of two matroids (for this problem, the matching matroid and the uniform matroid whose bases have size equal to the size of the desired matching). I don't know if they would be practical.
Assume we're given a graph on a 2D-plane with n nodes and edge between each pair of nodes, having a weight equal to a euclidean distance. The initial problem is to find MST of this graph and it's quite clear how to solve that using Prim's or Kruskal's algorithm.
Now let's say we have k extra nodes, which we can place in any integer point on our 2D-plane. The problem is to find locations for these nodes so as new graph has the smallest possible MST, if it is not necessary to use all of these extra nodes.
It is obviously impossible to find the exact solution (in poly-time), but the goal is to find the best approximate one (which can be found within 1 sec). Maybe you can come up with some hints of the most efficient way of going throw possible solutions, or provide with some articles, where the similar problem is covered.
It is very interesting problem which you are working on. You have many options to attack this problem. The best known heuristics in such situation are - Genetic Algorithms, Particle Swarm Optimization, Differential Evolution and many others of this kind.
What is nice for such kind of heuristics is that you can limit their execution to a certain amount of time (let say 1 second). If it was my task to do I would try first Genetic Algorithms.
You could try with a greedy algorithm, try the longest edges in the MST, potentially these could give the largest savings.
Select the longest edge, now get the potential edge from each vertex that are closed in angle to the chosen one, from each side.
from these select the best Steiner point.
Fix the MST ...
repeat until 1 sec is gone.
The challenge is what to do if one of the vertexes is itself a Steiner point.
I have an graph with the following attributes:
Undirected
Not weighted
Each vertex has a minimum of 2 and maximum of 6 edges connected to it.
Vertex count will be < 100
Graph is static and no vertices/edges can be added/removed or edited.
I'm looking for paths between a random subset of the vertices (at least 2). The paths should simple paths that only go through any vertex once.
My end goal is to have a set of routes so that you can start at one of the subset vertices and reach any of the other subset vertices. Its not necessary to pass through all the subset nodes when following a route.
All of the algorithms I've found (Dijkstra,Depth first search etc.) seem to be dealing with paths between two vertices and shortest paths.
Is there a known algorithm that will give me all the paths (I suppose these are subgraphs) that connect these subset of vertices?
edit:
I've created a (warning! programmer art) animated gif to illustrate what i'm trying to achieve: http://imgur.com/mGVlX.gif
There are two stages pre-process and runtime.
pre-process
I have a graph and a subset of the vertices (blue nodes)
I generate all the possible routes that connect all the blue nodes
runtime
I can start at any blue node select any of the generated routes and travel along it to reach my destination blue node.
So my task is more about creating all of the subgraphs (routes) that connect all blue nodes, rather than creating a path from A->B.
There are so many ways to approach this and in order not confuse things, here's a separate answer that's addressing the description of your core problem:
Finding ALL possible subgraphs that connect your blue vertices is probably overkill if you're only going to use one at a time anyway. I would rather use an algorithm that finds a single one, but randomly (so not any shortest path algorithm or such, since it will always be the same).
If you want to save one of these subgraphs, you simply have to save the seed you used for the random number generator and you'll be able to produce the same subgraph again.
Also, if you really want to find a bunch of subgraphs, a randomized algorithm is still a good choice since you can run it several times with different seeds.
The only real downside is that you will never know if you've found every single one of the possible subgraphs, but it doesn't really sound like that's a requirement for your application.
So, on to the algorithm: Depending on the properties of your graph(s), the optimal algorithm might vary, but you could always start of with a simple random walk, starting from one blue node, walking to another blue one (while making sure you're not walking in your own old footsteps). Then choose a random node on that path and start walking to the next blue from there, and so on.
For certain graphs, this has very bad worst-case complexity but might suffice for your case. There are of course more intelligent ways to find random paths, but I'd start out easy and see if it's good enough. As they say, premature optimization is evil ;)
A simple breadth-first search will give you the shortest paths from one source vertex to all other vertices. So you can perform a BFS starting from each vertex in the subset you're interested in, to get the distances to all other vertices.
Note that in some places, BFS will be described as giving the path between a pair of vertices, but this is not necessary: You can keep running it until it has visited all nodes in the graph.
This algorithm is similar to Johnson's algorithm, but greatly simplified thanks to the fact that your graph is unweighted.
Time complexity: Since there is a constant number of edges per vertex, each BFS will take O(n), and the total will take O(kn), where n is the number of vertices and k is the size of the subset. As a comparison, the Floyd-Warshall algorithm will take O(n^3).
What you're searching for is (if I understand it correctly) not really all paths, but rather all spanning trees. Read the wikipedia article about spanning trees here to determine if those are what you're looking for. If it is, there is a paper you would probably want to read:
Gabow, Harold N.; Myers, Eugene W. (1978). "Finding All Spanning Trees of Directed and Undirected Graphs". SIAM J. Comput. 7 (280).