We are given a network flow, as well as a max flow in the network. An edge would be called increasing edge if increasing its capacity in an arbitrary positive number, would also increase the max flow.
Present an algorithm the finds an increaing edge (if one exists) and runs at $O(n^2)$.
I thought about the following idea -
Find the minimum cut in the graph, as its given to us with the ford-fulkerson algorithm.
Increase the capacity of all the edges in the left hand side of the cut by 1.
Run BFS in the residual network to find if an improved path exists. If one exists, we have an increasing edge. To find it, we have to compare the original network with the new network. We have to do that n times since we have to check for an improved path every time we increase the capacity by 1.
Is it correct, an am I in line with the required running time?
Thank you!
I think you just need to find a path from the source to the sink that would be an augmenting path if at most one node were increased in capacity.
First find all the best paths to vertices you can reach with residual capacity. If you found the sink, then you weren't given a max flow to begin with.
Then find all the other vertices that are adjacent to those ones though edges that are at capacity.
Then try to find an augmenting path from those vertices to the sink.
Total complexity is O(N), so whoever asked you this question probably had something else in mind.
Related
I have questions about an optimal algorithm problem on a weighted graph. I am given an edgelist with weights, a list with savepoints, a starte- and end- node and the max distance for a step.
The output should be a list of savepoints, which are accessible in one step from starting- and end- node.
I thought of some kind of dijkstra's algorithm from each point of the list of savepoints.
I'm not sure if that's a good idea, since if I have many savepoints I calculate a lot of paths multiple times. Every idea/help is welcome!
Thank you very much in advance!
You have to have the condition that a weight cannot be negative, otherwise the problem becomes very intractable. Otherwise it's just a breadth first search, with marking the distance for every visited node. So you don't revisit a node is a previous move has visited it earlier at lower cost.
You keep a priority queue of all active nodes, so you are checking the lowest cost node each time. The priority queue is in fact the hardest part to get right. If you check the A* algorithm for my binary image library https://github.com/MalcolmMcLean/binaryimagelibrary you can take the priority queue for there. A* over a maze is very similar to shortest path over a graph, but you don't have a heuristic because you must have the exact shortest path, and instead of 4 / 8 edges per tile, you have nodes with arbitrary numbers of connections.
Consider the following graph:
nodes 1 to 6 are connected with a transition edge that have a direction and a volume property (red numbers). I'm looking for the right algorithm to find paths with a high volume. In the above example the output should be:
Path: [4,5,6] with a minimal volume of 17
Path: [1,2,3] with a
minimal volume of 15
I've looked at Floyd–Warshall algorithm but I'm not sure it's the right approach.
Any resources, comments or ideas would be appreciated.
Finding a beaten graph:
In the comments, you clarify that you are looking for "beaten" paths. I am assume this means that you are trying to contrast the paths with the average; for instance, looking for paths which can support weight at least e*w, where 0<e and w is the average edge weight. (You could have any number of contrast functions here, but the function you choose does not affect the algorithm.)
Then the algorithm to find all paths that meet this condition is incredibly simple and only takes O(m) time:
Loop over all edges to find the average weight. (Takes O(m) time.)
Calculate the threshold based on the average. (Takes O(1) time.)
Remove all edges which do not support the threshold weight. (Takes O(m) time.)
Any path in the resulting graph will be a member of the "widest path collection."
Example:
Consider that e=1.5. That is, you require that a beaten path support at least 1.5x the average edge weight. Then in graph you provided, you will loop over all the edges to find their average weight, and multiply this by e:
((20+4)+15+3+(2+20)+(1+1+17))/9 = 9.2
9.2*1.5 = 13.8
Then you loop over all edges, removing any that have weight less than 13.8. Any remaining paths in the graph are "beaten" paths.
Enumerating all beaten paths:
If you then want to find the set of beaten paths with maximal length (that is, they are not "parts" of paths), the modified graph is must be a DAG (because a cycle can be repeated infinite times). If it is a DAG, you can find the set of all maximal paths by:
In your modified graph, select the set of all source nodes (no incoming edges).
From each of these source nodes, perform a DFS (allowing repeated visits to the same node).
Every time you get to a sink node (no outgoing edges), write down the path that you took to get here.
This will take up to O(IncompleteGamma[n,1]) time (super exponential), depending on your graph. That is, it is not very feasible.
Finding the widest paths:
An actually much simpler task is to find the widest paths between every pair of nodes. To do this:
Start from the modified graph.
Run Floyd-Warshall's, using pathWeight(i,j,k+1) = max[pathWeight(i,j,k), min[pathWeight(i,k+1,k), pathWeight(k+1,j,k)]] (that is, instead of adding the weights of two paths, you take the minimum volume they can support).
Consider we have a network flow and using Edmond-Karp algorithm, we already have the maximum flow on the network. Now, if we add an arbitrary edge (with certain capacity) to the network, what is the best way to update the maximum flow? I was thinking about updating the residual network regarding the new edge and again look for augmenting path until we find new max flow, but I am not sure if it works or if it is the best way!
After doing maxflow you know the amount of content each edge flowed.
So, when the cost of an edge changed you can do the following things :
Suppose, the content flowed by that edge is w.
Now do a forward dfs and a backward dfs from that edge and undone total w content from the edge it linked.
Here each edge is represented by x/y, where y means the edge capacity and x means the content it flowed.
Now you want to change the cost of edge 4->3 from 2 to 3.
All you have to do is do a forward and backward dfs from 4->3 edge and undone 2 weight from these edge as 4->3 flowed w=2 content.
Here is the process will look like :
Now you are almost done :)
Change the cost of the edge 4->3 from 2 to 3 and again try to find an augmenting path :)
Let me know if you find it difficult to understand or if i'm wrong somehow :)
Edit :
If new edge cost is greater than current cost than you won't have to undone the weight. You can just try to find an augmenting path changing the edge's capacity.
But if the capacity reduced, you have to undone the weight and try to find an augmenting path.
If a new edge added, you can just add the edge and try to find an augmenting path if available. that's it.
Actually adding a new edge is not very difficult - you have the flows/ capacities of the edges before adding the edge and then you add the edge and its inverse. Then run the algorithm you use to find augmenting path until you find non-zero flow and that's it. Most of the max flow will already have been found so this should(in theory) not be too slow. I do not know which max flow algorithm you are using so I can not be more specific, but it is possible that after adding the new edge you violate the property of the algorithm and thus you find the max flow in a sub-optimal way. Still you've already processed most of the graph so this should not be a too big problem.
I would recommend you to use Ford-Fulkerson algorithm to finish of the task no matter what the original algorithm you used for the max flow is. I think it will perform well in cases that most of the max flow is already discovered.
So let me explain the question:
You are given a graph. You find the max flow. But it turns out that an edge, e_i, had the wrong capacity. It had one less. Unfortunately, the flow was maxed out at the old capacity.
Compute the new max flow in linear time (in terms of the number of edges and vertices) once you are told e_i had the wrong capacity.
Here's my plan: (1) You can't only drop the flow at edge e_i by one at an edge because you must violate certain constraints: like flow is conserved at an edge. Fix the flows so you can get a valid flow. But how?
(2) Someone has given me a hint: it will be helpful to show the valid flow = previous flow -1.mmm...
Help.
Here's a couple of tips:
Suppose you found a path with nonzero flow (i.e >= 1), and contained this edge e_i. How might you use this path to make the overall flow valid again? Now, suppose you aren't given this path. How might you get it yourself?
Now, you know that the max flow of the new graph is either the same, or one less than before (why?). How might you find out which in linear time?
I have a acyclic directed graph with a start vertice and an end vertice and some unknown number of vertices in between. A path starts from start vertice and end at end vertice. It is known that the number of vertices along the any paths between the start vertice and end vertice <100, but the number of possible vertices could be very large. Each vertice has a cost assigned to it, and the cost of the path is summation of the cost of vertices in between. Is there a way to use the random walk or any other means (this is to avoid explore all the vertices) to find for the path that has the highest (or near-highest) cost?
This problem is solved on Geekviewpoint.com with detailed explanation. It augments Dijkstra's algorithm. http://www.geekviewpoint.com/java/graph/dijkstra_constrained
EDIT: to account for 100 vertices between each path.
Originally your problem said there were 100 paths between the start and finish vertices. But by your correction, it's actually 100 vertices on the path. In that case your optimization is straightforward using DFS.
As you try to assemble a path, track the number of vertices you have seen. If the number reaches 99 and does not link start to finish, abort that path and try another one unit you get the answer if it exists. The algorithm you need to modify is DFS for cycle detection. Any algorithm textbook will have one of those. Since you also need to pick the best path among those found, you should also look at http://www.geekviewpoint.com/java/graph/count_paths.
I don't know if I should tell you how to do the obvious, but you will track the past path you have found similar to how you would find the maximum element in an array. The code is not difficult, you just have to combine a few small ideas:
DFS (similar to cycle detection and similar to counting paths, the two overlap)
track the best path you have seen: a one entry map where the idea is map which you keep replacing if you find a shorter path.