In the network below, the numbers indicate capacities of the edges. It is a network flow problem. The question asks for the minimum total capacity cut. My lecturer's answer, shown in the image with a red jiggly line, is:
The minimum total capacity cut contains arcs {AB, SC, SE} as shown.
My answer is {SA, SC, EF}. I'm basically doing the same, only I avoid edge SA and use EF rather than AB. Why am I wrong?
the flow can still pass through S->E->C->D->T so your set of edges is not even a cut.
A cut is a set of edges that once removes makes it impossible for flow to happen from S to T.
Do keep in mind that removing edges does not remove the vertices themselves.
Here's an easy way to get minimum cut:
Run any max flow algorithm on residual graph (Ford-Fulkerson, Edmonds
Karp, Dinic, etc)
Do BFS from source node ignoring saturated edges
(edges where flow value = edge capacity)
Now take all edges that go
from visited nodes to unvisited nodes
Those edges will be one of possible min cuts
Related
Let's say I have a graph and run a max-flow on it. I get some flow, f. However, I want to to flow f1 units where f1>f. Of course, I need to go about increasing some of the edge capacities. I want to make as small a total increase as possible to the capacities. Is there a clever algorithm to achieve this?
If it helps, I care for my application about bi-partite graphs with source (s) to left vertices (L) having some finite, integer capacities (c_l), left vertices L to right vertices R having some connectivity with infinite capacities and all right vertices, R connected to a sink vertex with finite integer capacities (c_r). Here, c_l and c_r sum to the same number. Also, there are no connections among the left vertices or among the right ones.
An example is provided in the image below. The blue numbers are the flow capacities and the pink numbers are the actual flows in the max-flow. Currently, 5 units are flowing but I want 9 units to flow.
In general, turn the flow instance into a min-cost flow instance by setting the cost of existing arcs to zero and adding new, infinite-capacity arcs doubling them of cost one.
For these particular instances, the best you're going to do is to repeatedly find an unsaturated arc of finite capacity and push flow along any path that includes it. Once everything's saturated just use any path.
This seems a little too easy to be what you want, so I'll mention that it's possible to formulate more sophisticated objectives and solve them using linear programming techniques.
The graph is undirected, and all the "middle" vertices have infinite capacity. That means we can unify all vertices connected by infinite capacity in L and R, making a very simple graph indeed.
For example, in the above graph, an equivalent graph would be:
s -8-> Vertex 1+2+4 -4-> t
s -1-> Vertex 3+5 -5-> t
So we end up with just a bunch of unique paths with no branching. We can unify the nodes with a simple "floodfill" or DFS type search on infinite-capacity edges. When we unify nodes, we add up their "left" and "right" capacities.
To maximize flow in this graph we:
First, if the left and right paths are not equal, increase the lower one until they are equal. This lets us convert an increase of cost X, into an increase in flow of X.
Once the left and right paths are equal for all nodes, we pick any path. Then, we increase both halves of the path with cost 2X, increasing the flow by X.
Given a N*M array of 0 and 1.
A lake is a set of cells(1) which are horizontally or vertically adjacent.
We are going to connect all lakes on map by updating some cell(0) to 1.
The task is finding the way that number of updated cells is the smallest in a given time limit.
I found this similar question: What is the minimum cost to connect all the islands?
The solution on this topic get some problem:
1) It uses lib (pulp) to solve the task
2) It take time to get output
Is there an optimization solution for this problem
Thank you in advance
I think this is a tricky question but if you really draw it out and look at this matrix as a graph it makes it simpler.
Consider each cell as a node and each connection to its top/right/bottom/left to be an edge.
Start by connection the edges of the lakes to the nearby vertices. Keep doing the same for each each and only connect two vertices if it doesn't create a cycle.
At this stage carry out the same process for the immediate neighbours of the lakes. Keep doing the same and break if its creating cycles.
After this you should have a connected tree.
Once you have a connected tree you can find all the articulation point (Cut vertex) of the tree. (A vertex in an undirected connected graph is an articulation point (or cut vertex) iff removing it (and edges through it) disconnects the graph. Articulation points represent vulnerabilities in a connected network – single points whose failure would split the network into 2 or more disconnected components)
The number of cut vertex in the tree (excluding the initial lakes) would be the smallest number of cells that you need to change.
You can search there are many efficient ways to find cut vertex of a graph.
Finding articulation points takes O(V+E)
Preprocessing takes O(V+E) as it somewhat similar to a BFS.
Don't know whether you are still interested but I have an idea. What about a min cost flow algorithm.
Assume you have an m*n 2-d input array and i Islands. Create a graph where each position in the 2-d array is a node and has 4 edges to each neighbour. Each edge will be assigned a cost later on. Each edge has minimum capacity 0 and maximum capacity infinit.
Choose a random island to be the source. Create an extra node target and connect it to all other islands except the source with each new edge having maximum and minimum flow capacity 1 and cost 0.
Now assign the old edges costs, so that an edge connecting two island nodes costs nothing, but an edge between and island and a water node or an edge between two water nodes costs 1.
Calculate min cost flow over this graph. The initial graph generating can be done in nm and the min cost flow algorithm in (nm) ^3
I am trying to find a minimum cut of the following network
I am using the following algorithm:
Run Ford-Fulkerson algorithm and consider the final residual graph.
Find the set of vertices that are reachable from source in the residual graph.
All edges which are from a reachable vertex to non-reachable vertex are minimum cut edges. Print all such edges.
In the first step, my algorithm finds 3 paths:
- s->b->h->t **value: 1**
- s->d->e->t **value: 1**
- s->c->h->i->m->d->g->t **value: 0.5**
So the maximum flow (and therefore minimum cut) is equal to 2.5.
However, when I later try to eliminate the aforementioned paths from the network I end up with something like this:
The reachable vertices are s, c and h, which form a cut equal to 3.5.
What am I missing? Why can't I traverse the graph like I would normally to get the minimum cut?
Every time you increase the capacity of an edge in the residual graph, you need to increase the capacity of the opposite edge by the same amount.
Example graph:
Here is the residual graph without backward edges and the the set of the vertices reachable from S (which do not constitute a min-cut):
And the correct residual graph with the min-cut:
I assume, that your definition of residual graph is that you put edge A->B in residual graph if:
a) There is some different between flow and capacity in direction A->B (aka forward edge)
b) There is some flow in direction B->A (aka backward edge)
In this definition your step 2 is wrong.
To find minimum cut, you only walk through forward edges from start. Now you can denote vertices reachable from start as set R and rest as set R'.
Now the cut is made by edges between R and R'.
And the size of the cut is flow between R and R'.
Let G = (V,E) be an arbitrary flow network, with a source s and target t and positive integer capacity c(e) for every edge e. Let (S,T) be a minimum s-t cut with respect to these capacities. Now suppose we increase the capacity of every edge by one, i.e. c_new(e) = c(e) + 1 for all edges, then is (S, T) still a minimum s-t cut with respect to these new capacities {c_new} ?
My intuition is, had G contained edges of different capacities, increased capacity might have resulted in different minimum cut. But when all edges have same capacity then minimum cut would remain same.
Am I correct? How to prove this?
Yes, your intuition is correct.
When G contains edges of different capacities, increasing the capacity of every edge by 1 might change the minimum cut. This is easily demonstrated by example, as shown below. The minimum cut (in red) has capacity 3. Increasing the capacity of each edge increases that cut to 6. So the connection from S to A becomes the new minimum cut with a capacity of 5.
When all the edges have the same capacity, increasing the capacity of every edge by 1 will not change the minimum cut. The basic idea behind the proof is that the capacity of a cut is nc where n is the number of edges cut, and c is the capacity of each edge. Since c is a constant, the minimum cut is the cut with minimum n. We'll refer to that minimum as N.
Now if the capacity of each edge is increased by 1, then the new capacity of each cut is n(c+1). Hence, the new capacity of the cut that used to be the minimum cut is N(c+1). Suppose a cut with capacity larger than N(c+1) exists: since all edges have weight c+1, such a cut must be an M-edge cut, for some M > N. But then in the original graph this same cut would have capacity Mc > Nc, contradicting the assumption that the N-edge cut is optimal there, so no such M-edge cut can exist, meaning that the N-edge cut (now with capacity N(c+1)) remains optimal in the new graph.
If ALL edge capicities are increased by a constant, then the min-cut is the same. Provided the edge capacities in the graph are same. Otherwise it may change.
A simple explanation would be -
We calculate min-cut/max-flow by dinic algorithm, using BFS. We apply bfs from source to sink and substact the least capacity/bottle-neck capacity edge in the bfs path. We add this edge-wt. to flow. We continue this until there is no path from source to sink.
If you were to increse edge capacities by a constant, the cut would always remain same. As BFS paths in all iterations of this algorithm would be the same. Only the max-flow value would change.
If all the edges have the same capacity,then the problem is equal to:
"If all edge capacities are multiplied by a positive number, the minimum cut remains unchanged. (A)"
It's easy to prove (A).And this question should be a special case of (A) where all edge capacities are multiplied by c+1/c.
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.