Let us have a graph. When we remove an edge, 2 'cars' are created, one from each vertice of the edge. when these 2 cars meet they stop. The problem is to create a spanning tree so that the sum of the numbers of cars that pass through each vertice is minimal.
The added difficulty is that if a vertice has n cars passing from it, then the cost is K^n and not n*K.
some thoughts. We could find the shortest chordless cycles as a start but the position of those chordless cycles, ie whether they touch each other, changes the metric and thus what the shortest cycle is.
This is not a minimum spanning tree problem. I want to solve this because each car represents a varriable and the spanning tree is the most efficient way to compute an optimization problem. When 2 cars from the same edge meet and stop, I have a reduction of one varriable from the optimization.
edit:
The process is like this. We remove a number of edges to make the graph a spanning tree. Each removed edge creates 2 cars, one at each vertice of the removed edge, that need to meet each other. We fix a path for each of those twin cars. We then check how many cars (from all the edges that we removed) pass through each vertice. If the number of the cars that pass from a vertice is n, the cost is K^n where K is a constant. We then add all the costs and that is the global cost that needs to be minimized.
please tell me if something is unclear.
https://mathoverflow.net/questions/86301/spanning-tree-that-minimizes-a-dynamic-metric
Here's one insight - cars will never pass through an articulation point, so you can break the graph up into its blocks and solve for each block separately (the minimum overall cost function is the sum of the minimum cost for each block).
To find the minimum cost for a block - you could enumerate all the spanning trees for that block and calculate the cost for each one - a brute force approach, but it should work.
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
Given a G(V,E) weighted(on edges) graph i need to find the number of edges that belong in every MST as well as the number of the edges that belong in at least one but not all and the ones that belong in none.
The graph is given as input in the following form(example):
3 3
1 2 1
1 3 1
2 3 2
First 3 is the number of nodes,second 3 is the number of edges.The following three lines are the edges where first number is where they start,second is where they end and third is the value.
I've thought about running kruskal once to find an MST and then for each edge belonging in G check in(linear?) time if it can be replace an edge in this MST without altering it's overall weight.If it can't it belongs in none.If it can it belongs in one but not all.I can also mark the edges in the first MST(maybe with a second value 1 or 0)and in the end check how many of them could not be replaced.These are the ones belonging in every possible MST. This algorithm is probably O(V^2) and i am not quite sure how to write it in C++.My questions are,could we somehow reduce it's complexity? If i add an edge to the MST how can i check(and implement in C++) if the cycle formed contains an edge that has less weight?
You can do this by adding some extra work to Kruskal's algorithm.
In Kruskal's algorithm, edges with the same weight can be in any order, and the order in which they are actually checked determines which MST you get out of all possible MSTs. For every MST, there is a sort-consistent order of the edges that will produce that tree.
No matter what sort-consistent order is used, the state of the union-find structure will be the same between weights.
If there is only one edge of a specific weight, then it is in every MST if Kruskal's algorithm selects it, because it would be selected with any sort-consistent edge order, and otherwise it is in no MSTs.
If there are multiple edges with the same weight, and Kruskal's algorithm would select at least one of them, then you can pause Kruskal's at that point and make a new (small) graph with just those edges that connect different sets, using the sets that they connect as vertices.
All of those edges are in at least one MST, because Kruskal's might pick them first. Any of those edges that are bridges in the new graph are in every MST, because Kruskal's would select them no matter what. See: https://en.wikipedia.org/wiki/Bridge_(graph_theory)
So, modify Kruskal's algorithm as follows:
When Kruskal's would select an edge, before doing the union, gather and process ALL the non-redundant edges with the same weight.
Make a small graph with those edges using the find() sets they connect as vertices
Use Tarjan's algorithm or equivalent (see the link) to find all the bridges in the graph. Those edges are in ALL MSTs.
The remaining edges in the small graph are in some, but not all, MSTs.
perform all the unions for edges in the small graph and move on to the next weight.
Since bridge-finding can be done in linear time, and every edge is in at most one small graph, the whole algorithm is still O(|V| + |E| log |E|).
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.
I have a weighted graph G and a pair of nodes s and t. I want to find, of all the paths from s to t with the fewest number of edges, the one that has the lowest total cost. I'm not sure how to do this. Here are my thoughts:
I am thinking of finding the shortest path and if there are more than one path then i should compare the number of steps of these paths.
I think I can find the number of steps by setting the weights of all edges to 1 and calculate the distance.
A reasonable first guess for a place to start here is Dijkstra's algorithm, which can solve each individual piece of this problem (minimize number of edges, or minimize total length). The challenge is getting it to do both at the same time.
Normally, when talking about shortest paths, we think of paths as having a single cost. However, you could imagine assigning paths two different costs: one cost based purely on the number of edges, and one cost based purely on the weights of those edges. You could then represent the cost of a path as a pair (length, weight), where length is the number of edges in the path and weight is the total weight of all of those edges.
Imagine running Dijkstra's algorithm on a graph with the following modifications. First, instead of tracking a candidate distance to each node in the graph, you track a pair of candidate distances to each node: a candidate length and a candidate weight. Second, whenever you need to fetch the lowest-code node, pick the node that has the shortest length (not weight). If there's a tie between multiple nodes with the same length, break the tie by choosing the one with the lowest weight. (If you've heard about lexicographical orderings, you could consider this as taking the node whose (length, weight) is lexicographically first). Finally, whenever you update a distance by extending a path by one edge, update both the candidate length and the candidate weight to that node. You can show that this process will compute the best path to each node, where "best" means "of all the paths with the minimum number of edges, the one with the lowest cost."
You could alternatively implement the above technique by modifying all the costs of the edges in the graph. Suppose that the maximum-cost edge in the graph has cost U. Then do the following: Add U+1 to all the costs in the graph, then run Dijkstra's algorithm on the result. The net effect of this is that the shortest path in this new graph will be the one that minimizes the number of edges used. Why? Well, every edge adds U+1 to the cost of the path, and U+1 is greater than the cost of any edge in the graph, so if one path is cheaper than another, it either uses at least one fewer edge, or it uses the same number of edges but has cheaper weights. In fact, you can prove that this approach is essentially identical to the one above using pairs of weights - it's a good exercise!
Overall, both of these approaches will run in the same time as a normal Dijkstra's algorithm (O(m + n log n) with a Fibonacci heap, O(m log n) with another type of heap), which is pretty cool!
One node to another would be a shortest-path-algorithm (e.g. Dijkstra).
It depends on your input whether you use a heuristic function to determine the total distance to the goal-node.
If you consider heuristics, you might want to choose A*-search instead. Here you just have to accumulate the weights to each node and add the heuristic value according to it.
If you want to get all paths from any node to any other node, you might consider Kruskal’s or Prim’s algorithm.
Both to basically the same, incl. pruning.
I have a connected, non-directed, graph with N nodes and 2N-3 edges. You can consider the graph as it is built onto an existing initial graph, which has 3 nodes and 3 edges. Every node added onto the graph and has 2 connections with the existing nodes in the graph. When all nodes are added to the graph (N-3 nodes added in total), the final graph is constructed.
Originally I'm asked, what is the maximum number of nodes in this graph that can be visited exactly once (except for the initial node), i.e., what is the maximum number of nodes contained in the largest Hamiltonian path of the given graph? (Okay, saying largest Hamiltonian path is not a valid phrase, but considering the question's nature, I need to find a max. number of nodes that are visited once and the trip ends at the initial node. I thought it can be considered as a sub-graph which is Hamiltonian, and consists max. number of nodes, thus largest possible Hamiltonian path).
Since i'm not asked to find a path, I should check if a hamiltonian path exists for given number of nodes first. I know that planar graphs and cycle graphs (Cn) are hamiltonian graphs (I also know Ore's theorem for Hamiltonian graphs, but the graph I will be working on will not be a dense graph with a great probability, thus making Ore's theorem pretty much useless in my case). Therefore I need to find an algorithm for checking if the graph is cycle graph, i.e. does there exist a cycle which contains all the nodes of the given graph.
Since DFS is used for detecting cycles, I thought some minor manipulation to the DFS can help me detect what I am looking for, as in keeping track of explored nodes, and finally checking if the last node visited has a connection to the initial node. Unfortunately
I could not succeed with that approach.
Another approach I tried was excluding a node, and then try to reach to its adjacent node starting from its other adjacent node. That algorithm may not give correct results according to the chosen adjacent nodes.
I'm pretty much stuck here. Can you help me think of another algorithm to tell me if the graph is a cycle graph?
Edit
I realized by the help of the comment (thank you for it n.m.):
A cycle graph consists of a single cycle and has N edges and N vertices. If there exist a cycle which contains all the nodes of the given graph, that's a Hamiltonian cycle. – n.m.
that I am actually searching for a Hamiltonian path, which I did not intend to do so:)
On a second thought, I think checking the Hamiltonian property of the graph while building it will be more efficient, which is I'm also looking for: time efficiency.
After some thinking, I thought whatever the number of nodes will be, the graph seems to be Hamiltonian due to node addition criteria. The problem is I can't be sure and I can't prove it. Does adding nodes in that fashion, i.e. adding new nodes with 2 edges which connect the added node to the existing nodes, alter the Hamiltonian property of the graph? If it doesn't alter the Hamiltonian property, how so? If it does alter, again, how so? Thanks.
EDIT #2
I, again, realized that building the graph the way I described might alter the Hamiltonian property. Consider an input given as follows:
1 3
2 3
1 5
1 3
these input says that 4th node is connected to node 1 and node 3, 5th to node 2 and node 3 . . .
4th and 7th node are connected to the same nodes, thus lowering the maximum number of nodes that can be visited exactly once, by 1. If i detect these collisions (NOT including an input such as 3 3, which is an example that you suggested since the problem states that the newly added edges are connected to 2 other nodes) and lower the maximum number of nodes, starting from N, I believe I can get the right result.
See, I do not choose the connections, they are given to me and I have to find the max. number of nodes.
I think counting the same connections while building the graph and subtracting the number of same connections from N will give the right result? Can you confirm this or is there a flaw with this algorithm?
What we have in this problem is a connected, non-directed graph with N nodes and 2N-3 edges. Consider the graph given below,
A
/ \
B _ C
( )
D
The Graph does not have a Hamiltonian Cycle. But the Graph is constructed conforming to your rules of adding nodes. So searching for a Hamiltonian Cycle may not give you the solution. More over even if it is possible Hamiltonian Cycle detection is an NP-Complete problem with O(2N) complexity. So the approach may not be ideal.
What I suggest is to use a modified version of Floyd's Cycle Finding algorithm (Also called the Tortoise and Hare Algorithm).
The modified algorithm is,
1. Initialize a List CYC_LIST to ∅.
2. Add the root node to the list CYC_LIST and set it as unvisited.
3. Call the function Floyd() twice with the unvisited node in the list CYC_LIST for each of the two edges. Mark the node as visited.
4. Add all the previously unvisited vertices traversed by the Tortoise pointer to the list CYC_LIST.
5. Repeat steps 3 and 4 until no more unvisited nodes remains in the list.
6. If the list CYC_LIST contains N nodes, then the Graph contains a Cycle involving all the nodes.
The algorithm calls Floyd's Cycle Finding Algorithm a maximum of 2N times. Floyd's Cycle Finding algorithm takes a linear time ( O(N) ). So the complexity of the modied algorithm is O(N2) which is much better than the exponential time taken by the Hamiltonian Cycle based approach.
One possible problem with this approach is that it will detect closed paths along with cycles unless stricter checking criteria are implemented.
Reply to Edit #2
Consider the Graph given below,
A------------\
/ \ \
B _ C \
|\ /| \
| D | F
\ / /
\ / /
E------------/
According to your algorithm this graph does not have a cycle containing all the nodes.
But there is a cycle in this graph containing all the nodes.
A-B-D-C-E-F-A
So I think there is some flaw with your approach. But suppose if your algorithm is correct, it is far better than my approach. Since mine takes O(n2) time, where as yours takes just O(n).
To add some clarification to this thread: finding a Hamiltonian Cycle is NP-complete, which implies that finding a longest cycle is also NP-complete because if we can find a longest cycle in any graph, we can find the Hamiltonian cycle of the subgraph induced by the vertices that lie on that cycle. (See also for example this paper regarding the longest cycle problem)
We can't use Dirac's criterion here: Dirac only tells us minimum degree >= n/2 -> Hamiltonian Cycle, that is the implication in the opposite direction of what we would need. The other way around is definitely wrong: take a cycle over n vertices, every vertex in it has exactly degree 2, no matter the size of the circle, but it has (is) an HC. What you can tell from Dirac is that no Hamiltonian Cycle -> minimum degree < n/2, which is of no use here since we don't know whether our graph has an HC or not, so we can't use the implication (nevertheless every graph we construct according to what OP described will have a vertex of degree 2, namely the last vertex added to the graph, so for arbitrary n, we have minimum degree 2).
The problem is that you can construct both graphs of arbitrary size that have an HC and graphs of arbitrary size that do not have an HC. For the first part: if the original triangle is A,B,C and the vertices added are numbered 1 to k, then connect the 1st added vertex to A and C and the k+1-th vertex to A and the k-th vertex for all k >= 1. The cycle is A,B,C,1,2,...,k,A. For the second part, connect both vertices 1 and 2 to A and B; that graph does not have an HC.
What is also important to note is that the property of having an HC can change from one vertex to the other during construction. You can both create and destroy the HC property when you add a vertex, so you would have to check for it every time you add a vertex. A simple example: take the graph after the 1st vertex was added, and add a second vertex along with edges to the same two vertices of the triangle that the 1st vertex was connected to. This constructs from a graph with an HC a graph without an HC. The other way around: add now a 3rd vertex and connect it to 1 and 2; this builds from a graph without an HC a graph with an HC.
Storing the last known HC during construction doesn't really help you because it may change completely. You could have an HC after the 20th vertex was added, then not have one for k in [21,2000], and have one again for the 2001st vertex added. Most likely the HC you had on 23 vertices will not help you a lot.
If you want to figure out how to solve this problem efficiently, you'll have to find criteria that work for all your graphs that can be checked for efficiently. Otherwise, your problem doesn't appear to me to be simpler than the Hamiltonian Cycle problem is in the general case, so you might be able to adjust one of the algorithms used for that problem to your variant of it.
Below I have added three extra nodes (3,4,5) in the original graph and it does seem like I can keep adding new nodes indefinitely while keeping the property of Hamiltonian cycle. For the below graph the cycle would be 0-1-3-5-4-2-0
1---3---5
/ \ / \ /
0---2---4
As there were no extra restrictions about how you can add a new node with two edges, I think by construction you can have a graph that holds the property of hamiltonian cycle.