I am having some troubles solving a problem about Minimum Spanning Tree. So each node in a graph is a city, and is possible to have weight edges connecting two nodes, which is the cost of building a road between two cities. The problem is basically telling the minimum cost of building the roads and have all cities connected some way. I can easily solve this by using Prim or kruskal algorithm to solve this sub-problem of my biggest problem.
The tricky part comes now: Each city (node) can have an airport and each airport has a one time cost (if you decide to build it). You can travel between two cities using an airport if both cities have airports. Now I have to calculate the minimium cost of building roads AND airports in order to have all cities connected, but I am having difficulty representing the connections with the airports with the rest of the network. Can somebody help me here? Maybe I am completely wrong about using MST?
The only solution I came up is: For each city that has an aiport, I will connect that city with another cities that have airports. Also If the cost of building two airports is lower then building a road I take it in consideration. I run kruskal in order to get the cheapest edge, but If kruskal chooses an "airport" edge, I will add it to the spanning tree and then 0 the cost of both airports (if they havent been built in the past). I believe, that by doing this dynamic weight changes while runing kruskal, I am destroyng the idea of getting the minimum cost.
There are two possibilities:
1) The optimal solution does not use airports. In this case you can ignore airports and construct the minimum spanning tree as usual.
2) The optimal solution uses airports. In this case add a dummy node to the graph called "sky". The cost of building a road from any city to "sky" is the cost of building an airport. The cost of the optimal solution using airports is the cost of the minimum spanning tree in this ammended graph.
So try both options and pick the minimum cost.
Related
I'm a bit stuck with this task.
We have a matrix with distances between every city (60 cities).
We have to pass through every city at least once with an electric car.
Every city has a charging point for the car. No limits on how many times we can stop at one city.
I have to find the minimal range with one charge the car needs to have so that we could pass through every city.
How should I encounter this task?
Update:
While MST (minimum spanning tree) works for this problem, it probably1 doesn't have the optimal time complexity. The problem should be considered as MSBT (minimum bottleneck spanning tree) instead, for which algorithms with linear time complexity in term of number of edges exist, such as Camerini's_algorithm.
You are looking for the maximum edge of the MST. There are many well-known algorithms for finding MST, of which Kruskal's and Prim's (which btilly uses in his answer) are the easiest to implement.
It is easy to see, why the maximum edge of MST is enough to drive through every city: you can traverse all cities, fully charging in each city and driving only roads that belong to the tree.
The range of at least the maximum edge of MST is required, because otherwise you will not be able to visit both cities that this edge is connected. This can be seen from the way Kruskal's algorithm is constructed. If only edges less that the maximum edge of MST are taken, then Kruskal's algorithm will fail to join all vertices into a single connected component.
Let's assume that there is a minimal spanning tree with an edge that is larger than the maximal edge of some other (minimal or not) spanning tree. Then we'll try to replace it with a smaller one. To do this, firstly delete this edge. Now we are left with two sets of vertices. The second tree must connect these sets with an edge. Lets take this edge and add it to the first tree. As this edge is smaller than the deleted one, then we've got a tree that has sum of edges less than minimal spanning tree, so the tree can't be minimal spanning tree in the first place and there is contradiction. In conclusion:
the larger spanning tree can't have smaller maximal edge
all maximal edges of every minimal spanning the tree are the same
The first statement means that the MST is the tree to look for solution, and the second statement means that it doesn't matter, which algorithm to use to find the MST
The key concept that you need is a priority queue which is usually implemented with a heap. This is a data structure that allows you to put things in with some sort of weight, and then pull out the lowest weight one.
Let's also use a set of things.
The idea now is this. We start somewhere. We have a priority queue of ways of getting to another city. We always look at the shortest-range drive that gets to that city. If it gets to a new to us city, we add it to the cities we can get to, and update our range if this was a longer drive than any other that we've seen.
Once we've visited all cities, we're done.
Now here is pseudo-code.
choose a start_city
initialize set visited_cities
initialize priority queue named queue to (0, start_city)
initialize min_range = 0
while len(visited_cities) < number of cities:
(distance, city) = queue.pop()
if city not in visited_cities:
min_range = max(min_range, distance)
visited_cities.add(city)
for other_city in all cities:
if other_city not in visited_cities:
queue.add(distance from city to other_city, other_city)
min_range is the answer
Assume a state has 10 cities A,B,C,D,E,F,G,H,I,J. Now let's say D and G both have an airport. Given the distance of each city from one another, what is the minimum length of road that should be built so that all the cities are connected to an airport? There can be a direct route or indirect route (i.e. via some other city) from each cities to an airport; our objective is to construct minimum length of road.
Your problem reduces to the minimum spanning tree problem by simply chaining together the vertexes associated to airports with edges of zero weight. As such, you can solve it by using e.g. the classical Prim algorithm:
Initialize the solution with all the vertexes containing an airport
Among all the remaining edges, select the cheapest one that augments the spanning tree
Iterate until every vertex is covered.
Background: You have a map stored as a undirected graph. Edges present streets or highways. There are two kinds of edges - green and red- and both kind of edges have weights. The weight of an edge is the distance that edge represents. Red edges represent represent toll roads, if you cross a red edge you pay as many cents as the weight of the edge. For example the red edge (r, 20) is 20 miles long and costs you 20 cents. All the green edges are free.
Problem: Write an algorithm to find the cheapest/shortest path from city S to city D. Cost has higher priority than distance. For example a free 500-mile long path is better than a 300-mile long path that costs 70 cents!
he problem is exactly the shortest path problem if all edges are green. Also if there is a connected path from S to V with all red edges removed, then it is the shortest path problem. What if S and V are not connected with all red edges removed? Then maybe insert cheapest red edge, if S and V are connected with it then again the problem becomes the shortest path problem. So now I found three simple cases:
1. All green graph.
2. Graph with a path from S to V when all red edges are connected.
3. Graph with a path from S to V when cheapest red edge is connected.
After this point it get a little difficult, or does it???
Cost has higher priority than distance. For example a free 500-mile long path is better than a 300-mile long path that costs 70 cents!
Run Djikstra's algorithm using a min-priority queue where the routes explored are prioritised by, firstly, lowest cost then, secondly, lowest distance.
Since all-green routes will have zero-cost then these will be explored first looking for the shortest distance route; if there are no zero-cost routes then, and only then, will red routes be explored in priority order of lowest cost.
The problem is more about how you handle the data than the algorithm. Let me propose this. Say the sum of the length of all the paths is less than 1'000'000. Then I can encode the cost and length as cost * 1'000'000 + length. Now you have a simple graph where you only have one metric to optimize.
I think it's clear that the most important thing the search is going to optimize is cost (since we multiplied it by 1'000'000) and that for paths of equal cost the length is going to be the deciding factor.
To actually implement this you don't need the assumption or to conversion I just did. You can keep cost and length everywhere and simply modify your comparisons to first compare the cost and only when it's a tie to compare the lengths.
Just run a "little modified" Dijkstra on this graph with setting weight of each edge to its price. You find all low-cost solutions with it and then you choose the shortest one.
The only real problem is that you can have edges with cost 0, but it can be solved - if you are in situation where you can open multiple nodes (they would have all same price), select the one with the lowest distance.
The only difference to classic Dijkstra.
In dijkstra in each step you open the node with lowest cost. If there are multiple nodes with lowest cost, you just choose any of them (it really does not matter).
In this case, if you have multiple nodes with lowest cost, you choose the one with lowest distance. If there are multiple nodes with lowest cost and lowest distance, you can open any of them (it really does not matter).
This solves every case you mentioned.
In a connected graph, there are n points where hungry people are standing. Every hungry person wants to go one of the k restaurants in the graph. The travel distance should be within a 1 km distance for each person. A restaurant can fit no more than CEILING[n/k] guests.
Provided the points of these hungry people and the restaurants in the area, is there an efficient algorithm that runs in polynomial time that tells whether EVERY guest can be accommodated (as in True or False)?
This sort of reminds me of the Travelling Salesman problem so is it just a modified version of it?
This is an example of a matching problem on a bipartite graph. This is much easier to solve than the travelling salesman problem and can be done in O((n+k)^3).
There are two subproblems:
Find which people can reach each restaurant
Find how to match people to restaurants to avoid overflowing the constraints
Reaching Restaurants
It is possible to compute the shortest path between any pair of points in O(n^3) by using, for example, the Floyd-Warshall algorithm.
The allowed matchings are then the connections of distance less than 1 km.
Matching people to restaurants
This matching problem can be solved by constructing a graph and then solving for the maximum flow.
An appropriate graph is to have a source node, a sink node, and a node for each person and each restaurant.
Connect the source to each person with capacity 1
Connect each person to each restaurant within 1km with capacity 1
Connect each restaurant to the sink node with capacity Ceil(n/k).
Then compute the maximum flow through this graph. Every guest can be accomodated if and only if the maximum flow is n.
There are many algorithms to compute the maximum flow. One example would be push-relabel with complexity O(V^3) where V is the number of vertices (V=n+k+2 in this problem).
I have Graph with N nodes and edges with cost. (graph may be Complete but also can contain zero edges).
I want to find K trees in the graph (K < N) to ensure every node is visited and cost is the lowest possible.
Any recommendations what the best approach could be?
I tried to modify the problem to finding just single minimal spanning tree, but didn't succeeded.
Thank you for any hint!
EDIT
little detail, which can be significant. To cost is not related to crossing the edge. The cost is the price to BUILD such edge. Once edge is built, you can traverse it forward and backwards with no cost. The problem is not to "ride along all nodes", the problem is about "creating a net among all nodes". I am sorry for previous explanation
The story
Here is the story i have heard and trying to solve.
There is a city, without connection to electricity. Electrical company is able to connect just K houses with electricity. The other houses can be connected by dropping cables from already connected houses. But dropping this cable cost something. The goal is to choose which K houses will be connected directly to power plant and which houses will be connected with separate cables to ensure minimal cable cost and all houses coverage :)
As others have mentioned, this is NP hard. However, if you're willing to accept a good solution, you could use simulated annealing. For example, the traveling salesman problem is NP hard, yet near-optimal solutions can be found using simulated annealing, e.g. http://www.codeproject.com/Articles/26758/Simulated-Annealing-Solving-the-Travelling-Salesma
You are describing something like a cardinality constrained path cover. It's in the Traveling Salesman/ Vehicle routing family of problems and is NP-Hard. To create an algorithm you should ask
Are you only going to run it on small graphs.
Are you only going to run it on special cases of graphs which do have exact algorithms.
Can you live with a heuristic that solves the problem approximately.
Assume you can find a minimum spanning tree in O(V^2) using prim's algorithm.
For each vertex, find the minimum spanning tree with that vertex as the root.
This will be O(V^3) as you run the algorithm V times.
Sort these by total mass (sum of weights of their vertices) of the graph. This is O(V^2 lg V) which is consumed by the O(V^3) so essentially free in terms of order complexity.
Take the X least massive graphs - the roots of these are your "anchors" that are connected directly to the grid, as they are mostly likely to have the shortest paths. To determine which route it takes, you simply follow the path to root in each node in each tree and wire up whatever is the shortest. (This may be further optimized by sorting all paths to root and using only the shortest ones first. This will allow for optimizations on the next iterations. Finding path to root is O(V). Finding it for all V X times is O(V^2 * X). Because you would be doing this for every V, you're looking at O(V^3 * X). This is more than your biggest complexity, but I think the average case on these will be small, even if their worst case is large).
I cannot prove that this is the optimal solution. In fact, I am certain it is not. But when you consider an electrical grid of 100,000 homes, you can not consider (with any practical application) an NP hard solution. This gives you a very good solution in O(V^3 * X), which I imagine is going to give you a solution very close to optimal.
Looking at your story, I think that what you call a path can be a tree, which means that we don't have to worry about Hamiltonian circuits.
Looking at the proof of correctness of Prim's algorithm at http://en.wikipedia.org/wiki/Prim%27s_algorithm, consider taking a minimum spanning tree and removing the most expensive X-1 links. I think the proof there shows that the result has the same cost as the best possible answer to your problem: the only difference is that when you compare edges, you may find that the new edge join two separated components, but in this case you can maintain the number of separated components by removing an edge with cost at most that of the new edge.
So I think an answer for your problem is to take a minimum spanning tree and remove the X-1 most expensive links. This is certainly the case for X=1!
Here is attempt at solving this...
For X=1 I can calculate minimal spanning tree (MST) with Prim's algorithm from each node (this node is the only one connected to the grid) and select the one with the lowest overall cost
For X=2 I create extra node (Power plant node) beside my graph. I connect it with random node (eg. N0) by edge with cost of 0. I am now sure I have one power plant plug right (the random node will definitely be in one of the tree, so whole tree will be connected). Now the iterative part. I take other node (eg. N1) and again connected with PP with 0 cost edge. Now I calculate MST. Then repeat this process with replacing N1 with N2, N3 ...
So I will test every pair [N0, NX]. The lowest cost MST wins.
For X>2 is it really the same as for X=2, but I have to test connect to PP every (x-1)-tuple and calculate MST
with x^2 for MST I have complexity about (N over X-1) * x^2... Pretty complex, but I think it will give me THE OPTIMAL solution
what do you think?
edit by random node I mean random but FIXED node
attempt to visualize for x=2 (each description belongs to image above it)
Let this be our city, nodes A - F are houses, edges are candidates to future cables (each has some cost to build)
Just for image, this could be the solution
Let the green one be the power plant, this is how can look connection to one tree
But this different connection is really the same (connection to power plant(pp) cost the same, cables remains untouched). That is why we can set one of the nodes as fixed point of contact to the pp. We can be sure, that the node will be in one of the trees, and it does not matter where in the tree is.
So let this be our fixed situation with G as PP. Edge (B,G) with zero cost is added.
Now I am trying to connect second connection with PP (A,G, cost 0)
Now I calculate MST from the PP. Because red edges are the cheapest (the can actually have even negative cost), is it sure, that both of them will be in MST.
So when running MST I get something like this. Imagine detaching PP and two MINIMAL COST trees left. This is the best solution for A and B are the connections to PP. I store the cost and move on.
Now I do the same for B and C connections
I could get something like this, so compare cost to previous one and choose the better one.
This way I have to try all the connection pairs (B,A) (B,C) (B,D) (B,E) (B,F) and the cheapest one is the winner.
For X=3 I would just test other tuples with one fixed again. (A,B,C) (A,B,D) ... (A,C,D) ... (A,E,F)
I just came up with the easy solution as follows:
N - node count
C - direct connections to the grid
E - available edges
1, Sort all edges by cost
2, Repeat (N-C) times:
Take the cheapest edge available
Check if adding this edge will not caused circles in already added edge
If not, add this edge
3, That is all... You will end up with C disjoint sets of edges, connect every set to the grid
Sounds like the famous Traveling Salesman problem. The problem known to be NP-hard. Take a look at the Wikipedia as your starting point: http://en.wikipedia.org/wiki/Travelling_salesman_problem