I am trying to implement max-flow with vertex capacities in addition to edge's capacities.
I found in wiki a reduction to a new graph G where each vertex corresponds to v_in and v_out and some appropriate changes to the edges .
My initial implementation did something else and I am wondering if it is wrong .
In the step that the original ford-fulkerson examines a path it increases the flow of the path with respect to the edge of minimum capacity in this path (we cannot exceed that).
What if I also found the minimum vertex capacity in this path ? The largest between these quantities (max(b(v)) and max(b(e)) for v and e in path p) would define the maximum flow that can run through that path , wouldn't it ?
And the complexity remains the same .
A lot of graph algorithms are described in terms of making a new graph, but then in practical implementations we try to optimize that step away.
That sounds like what you're doing: Does every augmenting path that you find in your flow graph correspond to a valid augmenting path in the (now imaginary) new graph? If so, then your algorithm is fine.
The main reason to use split node technique is because most of the time max-flow algorithms are used as a black box You don't want to change the algorithm implementation that's why you split the nodes.
Your algorithm is definitely correct.
Related
Given a weighted directed multigraph, I have to find shortest path between starting vertex u to vertex v. Apart from weight, each edge also has time. The path connecting u and v cannot take more than a given maximum time. The trouble is while using Djikstra, there are chances that shortest path takes more time than the limit.
My approach is to find all valid paths between u and v and than minimize the weight. But the approach is not practical due to its high complexity.
Any ideas?
If weights are small enough
In this case, what you can do is for each node, store all possible sums of weights that you can get on path to that node. Now you can do dijsktra on this new graph and try to minimize time over nodes which are pairs (node, weight_sum).
If times are small enough
You can do the same as in previous example, but over pairs (node, time).
General problem
I'm afraid that in general all you can do is try all possible paths, try to improve it with prunning.
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.
I have a follow-up question on this:
Finding shortest path distances in a graph containing at most two negative edges
Ranveer's solution looks great, but it is not fast enough because I need O(|E| + |V|*log|V|) fast algorithm.
I guess Dukeling's solution works great. It makes sense and it operates in the same running time of Dijkstra's algorithm.
However, my goal is to find shortest path distances from a given node s to ALL the nodes in V.
If I apply Dukeling's algorithm by setting all the nodes in V as end vertex e, I will need to run it |V| - 1 times. Then, the running time will be O(|V||E| + |V^2|*log|V|).
Any help would be appreciated!
Dijkstra's algorithm, in its original form, finds all the shortest paths from a source node to all other nodes in the graph.
You have (at least) two options for your problem:
Use Bellman - Ford. It's not as slow as its big-oh would suggest, at least not necessarily. Make sure you implement it like you would a BF search: using a FIFO queue. This means you will insert a node into the queue every time the distance to it is updated, and only if it isn't already in the queue. Other optimizations are also possible, but this should already give you a fast algorithm in practice;
Use Dijkstra's, but modified similarly to Bellman - Ford: the default Dijkstra's never inserts a node twice into the priority queue. Make sure you reinsert nodes if you have updated the distance to them. This will deal with negative cost edges. It essentially makes the algorithm closer to the Bellman - Ford described above, but using a priority queue instead of a FIFO queue. This will also get you closer to your desired complexity.
What algorithms are there, for weighted directed graphs, to find the maximum cost and path for going from a vertex A to a vertex K ?
I was thinking of modfied Dijkstra, but while watching and learning this algorithm, I found out it can't be used with negative weights and can't be used to find the maximum cost.
I suggest the following: choose any algorithm for minimum cost(distance) and also works with negative edges(thus Dijkstra can not be used for this). Then run this algorithm using the negation of the cost for each edge. You can use Bellman–Ford algorithm for instance.
You could use a modified version of the A* (A-star) algorithm. I say modified but it wouldn't actually be modified. You just need an appropriate heuristic. It is a path finding algorithm, you would just need to set your heuristic to chooses the costliest path.
A* works by starting at some vertex V, and adding all of that vertex's adjacent neighbors to an open list. Then it moves, in your case, to the node with the highest cost. The previously visited node is moved to a closed list. Then all the adjacent nodes to the current node are added to the open list. And so on and so forth.
It will find your K, and if your heuristic is to always choose the costliest path, you will have the maximum cost route.
Here is A* being applied to Infinite Mario.
I have directed graph with lot of cycles, probably strongly connected, and I need to get a minimal cycle from it. I mean I need to get cycle, which is the shortest cycle in graph, and every edge is covered at least once.
I have been searching for some algorithm or some theoretical background, but only thing I have found is Chinese postman algorithm. But this solution is not for directed graph.
Can anybody help me? Thanks
Edit>> All edges of that graph have the same cost - for instance 1
Take a look at this paper - Directed Chinese Postman Problem. That is the correct problem classification though (assuming there are no more restrictions).
If you're just reading into theory, take a good read at this page, which is from the Algorithms Design Manual.
Key quote (the second half for the directed version):
The optimal postman tour can be constructed by adding the appropriate edges to the graph G so as to make it Eulerian. Specifically, we find the shortest path between each pair of odd-degree vertices in G. Adding a path between two odd-degree vertices in G turns both of them to even-degree, thus moving us closer to an Eulerian graph. Finding the best set of shortest paths to add to G reduces to identifying a minimum-weight perfect matching in a graph on the odd-degree vertices, where the weight of edge (i,j) is the length of the shortest path from i to j. For directed graphs, this can be solved using bipartite matching, where the vertices are partitioned depending on whether they have more ingoing or outgoing edges. Once the graph is Eulerian, the actual cycle can be extracted in linear time using the procedure described above.
I doubt that it's optimal, but you could do a queue based search assuming the graph is guaranteed to have a cycle. Each queue entry would contain a list of nodes representing paths. When you take an element off the queue, add all possible next steps to the queue, ensuring you are not re-visiting nodes. If the last node is the same as the first node, you've found the minimum cycle.
what you are looking for is called "Eulerian path". You can google it to find enough info, basics are here
And about algorithm, there is an algorithm called Fleury's algorithm, google for it or take a look here
I think it might be worth while just simply writing which vertices are odd and then find which combo of them will lead to the least amount of extra time (if the weights are for times or distances) then the total length will be every edge weight plus the extra. For example, if the odd order vertices are A,B,C,D try AB&CD then AC&BD and so on. (I'm not sure if this is a specifically named method, it just worked for me).
edit: just realised this mostly only works for undirected graphs.
The special case in which the network consists entirely of directed edges can be solved in polynomial time. I think the original paper is Matching, Euler tours and the Chinese postman (1973) - a clear description of the algorithm for the directed graph problem begins on page 115 (page 28 of the pdf):
When all of the edges of a connected graph are directed and the graph
is symmetric, there is a particularly simple and attractive algorithm for
specifying an Euler tour...
The algorithm to find an Euler tour in a directed, symmetric, connected graph G is to first find a spanning arborescence of G. Then, at
any node n, except the root r of the arborescence, specify any order for
the edges directed away from n so long as the edge of the arborescence
is last in the ordering. For the root r, specify any order at all for the
edges directed away from r.
This algorithm was used by van Aardenne-Ehrenfest and de Bruin to
enumerate all Euler tours in a certain directed graph [ 1 ].