Description: In this lecture, Professor Devadas introduces network flow, and the Max Flow, Min Cut algorithm.
Instructors: Srinivas Devadas
The following content is provided under a Creative Commons license. Your support will help MIT OpenCourseWare continue to offer high quality educational resources for free. To make a donation or view additional materials from hundreds of MIT courses, visit MIT OpenCourseWare at ocw.mit.edu.
SRINIVAS DEVADAS: All right. Good morning, everyone. Welcome back from spring break. Hope you had a nice time off and couldn't wait to get back to 6.046.
So exciting second half. Going to do flow networks today on Thursday. Next week, it's linear programming, on to complexity, distributed algorithms, cryptography. Topics going to come fast and furious. Hopefully, they'll all be interesting.
So there's a lot of setup associated with network flow, max flow. It's an optimization problem. And so I'm going to spend like the first hour here-- and hopefully, it won't be too boring-- setting up flow networks, describing the max flow problem. As you can see, this outline is fairly involved, talking about cuts in a network, residual networks.
And we'll, more or less, end the lecture with the statement, though not the proof-- we'll save that for next time-- of the mas-flow min-cut theorem, which is really an iconic theorem in the literature, and suddenly, the crucial theorem for flow networks. And we'll take the max-flow min-cut theorem and use that to get to the first ever max-flow algorithm, which was due to Ford and Fulkerson. And that should be, pretty much, at the end of today's lecture.
And next time, we'll talk about the proof of max-flow min-cut, talk about some of the issues with Ford-Fulkerson, and then use max flow as a hammer to solve interesting problems in bipartite matching, baseball playoff elimination, and things like that. So just like shortest paths, can be used not just to compute the shortest distance from point A to point B, you can imagine that other problems, for example, scheduling problems, time problems, could be solved using Dijkstra-- and you've probably seen examples of that-- max flow is another algorithmic hammer that's being used to solve a wide variety of problems. We won't really touch on that aspect today, but we'll spend a bunch of time on Thursday talking about that.
So let's get started. We're going to start with defining what a flow network is. And at some level, it's really simple. I mean, it's a graph. A graph is going to have vertices and edges. We're going to only look at directed graphs. And we're going to have a couple of constraints associated with these directed graphs that are going to make the algorithms, and the proofs, and the notation a lot simpler. I'll get to that in a few minutes.
And the key thing with the flow networks-- I mean, just like you have a source and a destination for shortest paths, in a flow network as well, you're going to have a source, and you're going to have a sink. So we're going to have distinguished vertices, two distinguished vertices. And we're going to call them the source, s, and a sink, t.
And so the basic idea here-- and just to sort of set things up right up front-- is that there's going to be some flow coming out of s. And it's going to have to obey some constraints associated with capacities of the edges, in order to make its way to t. And along the way-- this is flow. This is water. You can think of it as water, or cars, or what have you. It's a rate. You're not going to allow accumulation in the intermediate nodes.
So you're going to have law of conservation associated with this commodity that's flowing, be water, or cars, or people. And that essentially comes down to, for any vertex, other than s or t, everything entering the vertex has to leave the vertex. So that's like Kirchoff's current law, for example. So there's a lot of analogies here with respect to real life, or electricity in this case. And you'll see that, I think, over and over as we go along.
So let's take a look at a flow network. I'm not going to draw it out here. I'm going to keep this one example all through the lecture. But just to go off and talk about edges and capacities before we actually draw an example, we're going to have edges, directed edges, u, v. So you have an edge from u to v. And it's going to belong to E, obviously. That's the reason the edge is in the network.
And this edge is going to have a non-negative-- each edge is going to have a non-negative capacity, C(u,v). Right? And if perchance theres' no edge from, let's say, s1 to s2-- these are different vertices from the source or the sink, just as an example, you can say it's between a and b-- then, we can assume that the capacity is 0.
So if u, v does not belong to E, then assume that C(u,v) is 0. So there's no way of getting from u to v. This rate, wall water, cars-- you know, there's no road that gets you from u to v, OK?
So let's draw an example of a flow network. We'll talk a little bit about what the flow is and what the max flow is in example-driven algorithm design, if you will. So I've got a source, s. And I've got a sink, t. And then, I've got a bunch of nodes in the middle. Just draw them out.
I'm not going to bother naming those nodes. Well, that might be a mistake. We'll see. So this is not like it's an acyclic graph. You're allowed cycles in this graph. But we will have a couple of constraints that are associated with this graph that I'll get to in just a minute.
So first, that's all we've got. You've got g,v,e, directed graph. Can't have cycles in it. And I'm going to draw a couple of numbers here. The numbers I'm putting up here are the capacities associated with each of these edges. So those are just the capacities. Those are C(u,v). And I said that, if u,v does not belong to E, then you're going to assume that C(u,v) is 0.
So there's no edge, for example, between this node and that node. So there's no way that you can directly get from here to there. You can go like this, like this, and like that, and get from here to there. And you can obviously go like so, and like this, and like that, to get from the one on the top left to the one on the bottom right, OK?
So that's essentially the set up, except for the fact that we've just talked about capacities. And this is sort of the bandwidth, if you will. This is the amount of traffic that can go through this road. And now, we have to talk about the specific case where we're actually going to shove things through the network.
So we're going to have another number. So typically, we're going to have two numbers associated with each edge. One of them is going to be the capacity, and the other one is going to be the flow that goes through the edge. And as you can imagine, we're going to have this constraint that says that the flow can never exceed the capacity.
And that's the local constraint associated with each edge, OK? That doesn't mean that there aren't variations possible with respect to the overall flow of the network. Things can change. You obey the edge capacities. And there could be different flow coming out of s and going into t, et cetera. And so there is going to be an optimization here associated with the exact numbers that all obey these edge constraints, so these edge capacity constraints, OK?
So let's take a real simple example of a flow in this network. And ah, I have some colored chalk here. So I can put down the flow over here. And so this is flow. Wow. That is an ugly color.
But now, we're stuck for the rest of this lecture. So I've got 2, 2, 1, colon, 3. So the first number is the flow, and the second number is the capacity. Let me just write that out. This is-- and then, this is 1, colon, 3. This is 1, colon, 2. So that meets the capacity. This is 2, colon, 3. And then 1, colon, 3, 2, colon, 3, and 1, 2, right?
So that's my first example of a flow. And we want to make sure that this flow makes sense, OK? And we're going to write this down a little more precisely in just a minute, but I've sort of given you the intuition already.
I've talked about it's OK to have a flow from the source. It's the mountain spewing water, or that's the source of the river. And this is the sea, for example. And the river flows into it. But along the way, you really can't have accumulation, OK? Because when you think about it as a rate-- and so this is sort of gallons per second-- then maybe you'll have a little bit of accumulation allowed. But over a huge period of time, you can't have infinite accumulation. So that's where the conservation law kicks in, which says, anything that goes into a node that is not marked s or t has to leave the node.
So you look at this, and you go, well, there's two things coming in here. There's 1 and 1, which adds up to 2. And there's two 2 leaving. So we're good there. OK? And then pick another one. This one, for example. You've got 2 coming in, and you've got 1 and 1 leaving. We're good there, right? For t, you've got 3 coming in, 2 plus 1. And another check to do is, well, you've got 2 coming out of the source, right?
So hopefully, that all will make sense. And ask questions if you're confused.
One other thing to look at, which is interesting, is that you could have flows that are essentially cyclic. You could have commodities that are flowing in a little cycle. And can you see that? Can anyone see that over here? Yep? Go ahead.
STUDENT: The bottom-right triangle [INAUDIBLE].
SRINIVAS DEVADAS: Bottom-right triangle? This thing over here?
SRINIVAS DEVADAS: Like that? Good. Right? So you see this one going over this way, this way, and that way? And so there's nothing that's stopping us from taking this and-- I had 1 over here, so I'm going to make that 0. I had 2 over here, and I'm going to make that 1. And I had 2 over here, and I'm going to make that 1.
SRINIVAS DEVADAS: Oh. What is it?
STUDENT: It was 1.
SRINIVAS DEVADAS: It was 1 before? Oh, you're right. It was 1 before. So I should make that 0 then. Good.
I wanted to subtract 1 from what I had before, right? And I screwed that one up, the simple thing. All right? Wow. No wonder I didn't major in mathematics.
OK. Computer Science is this forgiving field.
So you can go 0-- well, this is 0. So now, let's take a look at what we have here and check that nothing went wrong, right? We want to check that nothing went wrong. And so 2 coming in, 1 going out, 1 going out. And nothing coming in here, so we're all good. And so on and so forth, OK?
So there's interesting things happening here with respect to the conservation laws and having to obey them. In general, you can imagine that what we're interested in is simply maximizing the flow from the source, and getting as much flow out of the source as possible, and pushing it into the sink. OK?
Now, the flow here into t, as you can see, is 2 plus 1, which is 3, OK? Can anyone take this particular flow network and increase the flow? I mean, it's easy to decrease the flow. You can make everything 0, and that'd be valid, right? But can you increase the flow? Do you think that this flow network allows for a larger flow than 3, given that the capacities of those edges are fixed and I'm not going to change them?
Let's see. I think all of you have Frisbees, right? Yeah. Yeah, back there.
STUDENT: I don't think you can, because you're maximizing two edges, which would have to be increased. Like, the bottom one coming out of s would have to be increased. Or the one on the very top would, too, also have to be increased.
SRINIVAS DEVADAS: People agree with that? Over there? Yep?
STUDENT: You can have a path going along the top with a flow of 2, so that s is the one on the top of it has 2. That, from that, to the right, has 2, like it has now. From that node, the t has 2. And then, along the bottom, we have another path that has 2, from s to the 1 [? plot of it. ?] And then [INAUDIBLE].
SRINIVAS DEVADAS: OK. So--
That made perfect sense-- to me. [CHUCKLES] It did.
So one of the crucial observations that [? Rajesh ?] made here-- and let me just focus in on that-- is-- and that's why I think the other gentleman said no-- is that you can actually decrease the flow in particular edges. And that's going to help you increase the overall flow, right? And that's why this problem is challenging. That's why we need so much of a setup, all right?
So one thing that I could do is I could essentially say, I'm going to take this and make this 0. So when I do that, essentially what I have is I get to push more flow out from here, right? So I get to push more flow. I can turn this into a 2. And I can turn this into a 2, right? Am I done?
SRINIVAS DEVADAS: Not quite. I mean, I've got one little bug here, but I can fix that, right? I've got one little bug here which says, I've got 2 coming out here. I made this 0, so I have to push something more. But hey, I'm lucky. I've got a s here, which is giving me as much as I want, correct? So I can just make this a 2. And so now we get a flow of 4, right?
You both get Frisbees. Shall we do blue and purple? Here you go. Could you stand up? Oh, OK. Over there.
So that actually kind of summarizes, at some level, our task ahead, right? So we have to find ways of increasing the flow. And sometimes, we have to take a step backwards in the sense that we decrease the flow on a particular edge, right?
So it's not this monotonic increase that Dijkstra would do or a greedy algorithm, like MST that Eric talked about. There's going to be something a little more interesting here. We eventually are going to end up doing things in a monotonic way, in terms of the overall flow.
So the max flow that we're trying to get at is going to start with the current flow. And we're going to improve the current flow constantly. But that doesn't mean that the edges are going to look monotonic in terms of the flows on a particular edge in relation to the capacity. You'll never exceed the capacity.
But as you saw in this little example already, we increase from 3 to 4, by taking that edge that was vertical up there, which says 0, colon, 3, and that was 1, and we shrank the flow on it. And so how are we going to discover these paths, especially if we have a 5,000-node network and-- I don't know-- 10,000 edges? And so that's essentially what we have to do for the rest of this lecture. Any questions so far?
OK. So we've done flow networks. I kind of defined what the max flow problem is. And let me just write that out more precisely. Given a flow network, G, find the flow with maximum value on G. And for that, the max flow is 4, right?
So that's another thing we haven't actually done, which is obviously important for us to do, which is we have to show that the 4, in this case, is the max flow, right? So now, of course, I've given that away. And so I'm not going to ask you can you push this over to 5. But you might think that 5 is a possibility, simply because the capacities of the edges that are coming out of the source are 3 plus 2, which is 5, right?
So it's certainly possible that you could push at least, if you only look at those two edges, that you could push 5 units from the source. But in this case, in this example, if you obey the laws of conservation, you cannot obey those laws and get 5 units from the source to the sink, t. But we have to prove that. And we have an algorithm that says this is the best that you can possibly do. And the algorithm terminates when that happens. And that's our Ford-Fulkerson algorithm, right?
Good. So that's what we have so far. I want to talk about flow network assumptions. And I can do that over here. This is going to make our life easier.
One of the things that's a little bit confusing sometimes is the circular flow and the fact that we're going to potentially have flows that correspond to edges coming in and edges going out. So for example, if I had something like s and u, for example-- and s could be the source in this case, or it could be another node-- suppose I had a little subnetwork that looks like this. And I'm just giving you what the capacities are.
This is a bit strange in the sense that you could have a situation where you essentially have zero flow, really, because you have one unit coming in here and one unit leaving. All right? And you can think of this-- let's just call this s1, to make it clear that it doesn't have to be the source, right? And so you could have the circularity that you saw over there. And now you're talking about, well, I might have 1, colon, 1 here, and 1, colon, 2 here, which is fine for this subnetwork.
But if I have stuff going out, what happens with that? Well that's got to be a 0. I could have a 1 and a 2. And if I have a 2 here, then-- if I had a 1 and 2 here, then that doesn't work, because maybe I need something else coming in. So you can see that, pretty quickly, it gets kind of confusing, if we end up having these cycles that are such simple cycles, especially the ones where you have Su and Us, OK? And so we're going to disallow cycles of two kinds, right?
The first cycle we're going to disallow is this simple one where we say, if I have a, then no self-loop edges allowed. So that would involve accumulation at a particular node. And it's going to make things really confusing. And CLRS disallows that. And most flow network algorithms assume that you're just going to discard these cycles.
This particular transformation that I'm going to describe here is something that is going to be forced on you. And this is for your benefit in over 6 lectures and sections. But it's not actually something that CLRS follows. And it's going to make things simpler, though.
And what we're going to do is we're going to take any pair of vertices that has this characteristic, where you have s1, u, and u, s1, and they have non-zero capacities. So s1, u has a capacity of 1. u, s1 has a capacity of 2. Both of these edges exist. And if these edges exist, that means they have non-zero capacity, positive capacity.
And we're going to transform that, very simply, into-- this is not changing the generality of the algorithm, but all I'm going to do is transform it-- call this s1-- into something that satisfies this restriction. So I could have 2 here, 1, and 1, OK? So all I've done is introduce u prime, right?
Then I can always do this-- if this is trivial for any pair of vertices, I can introduce one other vertex. It all works out. Linear expansion, constant factors, ignore them. Life is wonderful.
So all I've done is taken away the situation where I have-- you can think of it as two-way streets, right? Two-way streets are annoying. You don't quite know what the rate of traffic is from one end of the street to another, because cars are going in both directions. And you have to do subtraction. Subtraction is painful, so we don't want that.
So we're just going to assume that this is u prime. And now, you're all set. We allow this. So we have to allow for generality reasons. As we saw in that very first example there, we are going to have cycles here, OK? But we just don't want cycles to be of length 1 or 2, OK? So that's essentially what we're going to disallow. All right?
The good news is that, if you do this, then we'll only have a single notion of flow. Whereas, if you go read CLRS, you'll see that there's two notions of flow in CLRS. There's positive flow, which is different from net flow. And the positive flow is different from net flow in graphs that have this particular structure, or have nodes with these properties.
But if you disallow them, then you can just talk about flow, and it doesn't matter. Positive flow is the same as net flow, all right? So for the purposes of [? 6 over 6, ?] for this semester, we're going to simply think about flow and equate that to positive flow, equate that to net flow. And it's all going to work out, assuming your graphs satisfy these two properties of the cycle lengths. All right? Cool. Good.
So let's keep going here. So we're up to finished up on max flow. Let me just give you some sense of notation. I've talked a lot about constraints. But we've got to write some stuff out, because we're going to be getting more precise and proving things in just a few minutes.
So what is a flow? Well, to be precise, it is going to be a function that satisfies the following properties. It satisfies the capacity constraint. This is the obvious capacity constraint, intuitive capacity constraint. And then we've got flow conservation. And the important thing here is that I don't have it for all V, but I do have it for vertices, V, that are not the source or the sink. And I'm going to require f(u,v) equals 0, right?
And the last one, which I haven't talked about, but becomes easy to talk about, given this constraint, is skew symmetry. So if you take-- this doesn't have to be an edge between u and v. Now, I'm talking about the flow, f, between u and v. And so the u could be s, which is the source. v could be t, which is the sink.
So in general, I'm not talking about a flow. And there obviously has to be a path from u to v, in order for there to be a non-zero flow, f(u,v), right? If there's no path, there's no way of getting there. But having said that, the definition of a flow here in our network is the straightforward definition, which simply says, if there's a flow from u to v, regardless of what u and v are, then the value of that flow is simply the negation of the value of the flow from v to u, which makes perfect sense, right?
And this all works out under the definition of net flow. And so this is essentially what the definition of net flow is in the textbook. But for our purposes here, we don't have to add that adjective. We just are going to be talking about flows. Positive or net, they're the same, all right? All right. Good.
So one of the things you can do with this notation-- and we're going to use what's called implicit summation notation on top of this-- is to prove some interesting things, interesting theorems, that give you some intuition as to how algorithms on flow networks are going to work. And in particular, we're going to use this notation when we talk about the value of a flow. So the value of a flow, f, is denoted-- you can think of it as a cardinality of f. And f is v, belonging to capital V, f(s,v). And that is f(s,V), so what I have written here.
Well, given a flow network, I want one particular quantity that I want to maximize. And that particular quantity is going to be defined, based on how much I can push from s, how much can I push outward from s. That's the crucial quantity that I want to maximize. That quantity is-- you think about everything that is going out of s, and you add it all up together.
So from s, you look at any other vertex, every other vertex, and you say, what is f(s,v)? And I'm not talking about just the edges that come out of s. A vertex, v, small v, can be any vertex. If I add up all of the flows that come out of s, then that is the flow that responds to my flow network. That is everything that's getting pushed out of s, OK?
Now, it may be the case that-- remember, I'm talking about flow here-- so it may be the case that you have an edge from s coming in from v4. And there may be a flow associated with that. This is maybe something like 1, colon, 2, all right?
So what this means is that f(s,vr) is-- this is f, remember-- so this is minus f(v4,s). And in this particular case, this is 1. So this is minus 1, OK? So keep that in mind.
When I talk about the flow of the network, I'm going to be looking at the source. And I'm going to be looking at all of the flows that are going outward. And I have to keep in mind the skew symmetry relationship. I obviously have to obey capacity constraints and the conservation laws, all right?
So given that, let's use this implicit summation notation and show some simple properties of flow. So let's look at-- one thing I want to emphasize is what I've done here is use this implicit summation notation, which simply says, if I see a capital letter here, that's a set. And I'm going to have to enumerate all of the members of that set. And it's implicit summation. So as I enumerate those members, I'm going to add up all of these quantities, right? So that's really what this means.
So the sigma here gets embedded into this capital V. So two things going on. The small v turned into capital V, because I'm looking at the entire set. And the sigma gets in there too. And that's why it's implicit summation, not just implicit set notation.
So some simple properties. I can say, f(x,x) is 0, where x is an arbitrary set. All that says is, let's say, x has a single member in it, which is a. Then f(a,a) is always 0, because if you don't allow self-loop edges, and that's pretty much all you need.
If you have a pair of vertices here, a and b, then what you're saying is f(a,b) plus f(b,a) is 0. And that's true, because of skew symmetry. Right? We just wrote that out. So f(x,x) is 0. And in general, you can say, even though X and Y are sets of vertices, I'm going to be able to use skew symmetry to say that f(X,Y) is minus of f(Y,X), all right? Similar argument.
And then, lastly-- there's any number of these, we just do three of them here-- X of f(XUY, to Z) is f(X,Z) plus f(Y,Z)-- we've got to use these properties to prove our first theorem here on flow networks-- if X of X intersection Y is null. So you don't want to double-count. So that's all this is. Make sure you're not double-counting. You've got f(XUY), and you want to look at that entire set, the union, and then look at the flow from any member in XUY to any member in Z. And you can do that by breaking it up, provided you're careful about double-counting. And the fact that the two sets, X and Y, do not have an intersection, or they have a null intersection, implies that you're OK with the [? write ?] inside. All right?
So you might be going, why are we doing this? Well, here's a good reason to like implicit set notation. You can prove some interesting theorems in a very elegant way, using this notation. So let's do one example of that. You'll probably see others in section.
So one of the things that we'd like to do is prove a pretty important theorem, which I think all of you probably can assume in your heads, given all of the properties of flow networks that we have. And it's a very simple theorem that simply says, I have the law of conservation that is applied on all of these intermediate vertices, and I've got a bunch of commodities, I've got a flow going out of s, right? So where can this flow go? Where does this flow end up? It ends up at the sink, at t, right?
So the point is that, if you have all of these properties that we have up here, you're going to be able to show-- and you want to show this, you want to prove this-- that the value of a flow, which is defined as what gets pushed out from the source, is exactly what goes into the sink, right? If that's not the case, there's been a violation of some property, perhaps a capacity constraint, perhaps, more likely, a conservation constraint, OK?
So the theorem that we'd like to prove is simply that f is f(v,t), right? That's the theorem. And there's a lot going on here, so it's worth spending 30 seconds looking at what exactly this means.
What I have here is that, if you just look at this and that, I'm saying that f is what gets pushed out of the source, OK? And now what I'm saying here is that f, the value, is exactly what gets pushed into the sink, OK? So this is what I have to prove, right? And I should be able to prove that, by invoking my laws. That's it. I mean, that's my axiomatic system. I've got those laws. I've got a definition of a flow that may not necessarily be the max flow. It might be something much less than the max flow, it might be the max flow.
Regardless, what gets out of the source has to get into the sink, right? So how are we going to do that? And the implicit summation notation is going to give you, essentially, a three or four-line proof, which is very intuitive, right? So let's do that. And maybe you can help me.
So we're going to start with what we know. So that's the proof. f equals f(s,V). Right? So that's what we've got. That's the definition of cardinality of f, or a value of f, OK?
What I'm going to do is I'm going to say this is the same as-- I'll give you the first step, and then let's see if you can help me with the remaining-- is the same as f of v minus s capital V, right? So if you're having trouble differentiating between my cap V's and small v's, holler. I'm trying to write them as big as possible. Yeah?
STUDENT: Could you maybe put little hats on the top of them?
SRINIVAS DEVADAS: Put little hats on them. Yes, I will put little hats on them. I'd put little Frisbees on them, if I could, but-- I like Frisbees much better than hats. All right. That's good. That's good to do. So yeah. So I think, hopefully, I'll keep doing this, and it won't be confusing.
So what I've done here is invoke, essentially, this, except it's not exactly that, in the sense that it's written a little bit differently. But if you see what's going on here, what I've done is look at this s, and I've said, think of this s as being cap V minus s. Right? So that gives you s. And those are clearly disjoint, right? Those are clearly disjoint sets.
There is this one and this one are disjoint sets. That's what I mean to say. I mean, these two aren't disjoint, but this and that are disjoint. And that's what you need, in order to invoke the little property that you have here. And so that all make sense? You see why I did that? OK?
What can I say about either of these two quantities? Can I say something about either of these two quantities? Yeah?
STUDENT: f(V,V) is 0.
SRINIVAS DEVADAS: f(V,V) is 0. That's exactly right. f(V,V) is 0. There you go. Yep. So this is simply I'm going to invert that. I'm going to write this as f of V hat minus s, OK? I'll just flip this. I had a negative sign here, but I've flipped that. And skew symmetry tells me I can do that, right?
All right. So I'm up to this point here. Now, what I'm going to do is I'm going to do f(V,t). And the reason I want to do this is because this is where I want to get at, right? Eventually, I want to show something that corresponds to f(V,t), right?
And what I have here is V,t. But now, I could do plus f(V,V minus-- cap-- minus s minus t) right? So what I've done here is taken V minus s and pulled out t from it. Remember, t is part of cap V. Cap V contains all of the vertices. So I've pulled out t from it, but that implies that I have to do a V minus s minus t over here. And again, they're disjoint, so it's all good. What can I say about this? Yeah?
STUDENT: It's 0 because of flow conservation?
SRINIVAS DEVADAS: It's 0 because of flow conservation. That's exactly right. We didn't quite write it that way. But if you look at what the implicit summation notation would mean for that, you look at it and you say, maybe one more step would be, let me think about this as being, f(V,t). It'll become more obvious if I write it this way. f(V-- I'm putting a minus in here-- V minus s minus t and cap V again, right?
So all I've done here is flip these two. Skew symmetry allows me to do that. And now look at what I have here. I'm talking about a flow that corresponds to some-- for any vertex, I pick-- and it's not an s vertex, it's not a t vertex, so it's an intermediate vertex. And if I look at an intermediate vertex and look at the flow that goes out to all vertices, conservation says that has to be 0, right?
So that's exactly what this says. For any u that's neither s nor t but in V, the sum has to be 0. So this is zero, and we're done. All right.
Oh, you-- a Frisbee? Who is that? Ah. Here.
So that's the power of implicit summation notation. So we could invoke these different properties. It was fairly straightforward. Your first example of this. You'll probably see a few more. All right? Any questions so far? OK.
So as you can see, as I promised, or threatened at the beginning, but followed through on my threat, we have a lot of notation, a lot of baggage here before we get to algorithms. But we're slowly getting there.
The next major concept is the concept of cuts. So a cut, you think of a cut as being, well, a cut through paper, a cut through the air, whatever. It turns out that notion of a cut in a network is more general than that, right? A cut is basically a partition. A cut is a partition of nodes. And a partition means that you can't have a node in both sides, right? So a cut is going to give you two disjoint components at the end of it.
But the cut doesn't have to be something contiguous. It doesn't have to be a line through the network. And everything to the left of the line is in one half of the cut, and everything on the right of the line is in a different half of the cut. I can just break up these nodes into two disjoint parts. And the only constraint that I'm going to ask for is that s, which is the source, is on one side of the cut, and t, which is the sink, is another side of the cut, OK? That's it.
And given that, I'm going to say interesting things, really interesting things, about the flow through a cut, OK? And so let's do that. Let's define a cut.
So a cut is (S,T) of a flow network, G, is a partition of V, such that small s belongs to cap S, and small t belongs to cap T. I don't know. Do you want hats on the T too? I'll just write them large. If a flow on G-- if f is a flow on G, then the flow across the cut is f(S,T). OK?
So again, implicit summation notation here. The flow across the cut is as the sum of the flows corresponding to each pair of vertices, such that the source vertex is part of capital S. And the destination vertex is part of capital T. All right? That's it. I'm just going to add them all up. That's the flow across the cut.
So what I can do now is just talk about-- let's just go up here back to this. And I'm going to look at exactly what I have here. Is that right? Not exactly. I'm going to change this a little bit, because I want to make sure I don't have to add up numbers and do that incorrectly. So I need a 1. Yup. That's all I need to do is change it.
So I'm going to change our example here, not the topology of the example, but the actual numbers. And you'll need to verify that what I have here satisfies our flow network properties. And there's one more. OK? So I think I'm good. All right.
So this is going to be an example of a cut. I haven't defined the cut yet. Let's get rid of that. Holler if you think there's something wrong with this flow. All right? I think I got it right. It satisfies capacity constraints. It satisfies flow conservation constraints.
The flow that is going into t is 4. This happens to be a max flow. Doesn't really matter. So what we're going to talk about with respect to cuts, it doesn't require the flow to be maximum. Keep that in mind.
What do I mean by the flow across a cut via an example? I'm going to simply say that the shaded nodes, two of them, are part of capital S, OK? So as you can see, I just arbitrarily picked a couple of nodes. And that not necessarily something that can be easily partitioned using an actual cut line, a physical cut line. I just picked that one over there and the one over here with S.
And so, I can now look at this, and I can compute numerically, for this example. And it's worth doing at least once what the flow across this particular cut is, defined by the particular choice of cap S and cap T, OK? And that's what we're going to do.
So f(S,T) is-- I'm going to have to look at pairs of nodes, such that I've got a shaded node on the left-hand side and non-shaded node on the right-hand side. And I'm going to have to go through all of the combinations, right?
So if I look at this, I can first knock off this one, and that one, and that one. Let me actually put in-- let's call this a, b, and c here. And we can call that d. So we have s and d as being part of the cut, in terms of s, capital S. And the other ones are in cap T.
And so what I have is I could do Sa and Sb. So I've got 2 plus 2, all right? And this would correspond to Sa and Sb. So those are going out, right? So far, so good. And then, I'm going to write out a bunch of numbers here, minus 2 plus 1 minus 1 plus 2.
And the minus 2, where would the minus 2 come from? Well, an a,d, for example, is a minus 2, right? Because d is part of-- it would be d, a. So a, d has a flow of 2, correct? And so d, a has a flow of minus 2, right? And d, a is part of what I have here, because d is part of capital S, and A is part of capital T. You guys see that? So this is not trivial, so pay attention.
So this would be, for example, the minus 2 would correspond to d, a. That's what I need here. And I could also have-- what do I have here? I have something is going into d. So a c, d is 1. So d, c is minus 1, right? Make sense? d, c is minus 1.
What about the plus 1? Where do I get a plus 1 from?
STUDENT: d, b.
SRINIVAS DEVADAS: d, b is going out. That's exactly right, d, b. And the plus 2, it would be d, T, right?
And so you have to do the enumeration. It's worthwhile doing once. And then it gets kind of boring. We won't to do it again. But you have to realize that you have to absolutely look at every pair of vertices. And you have to use skew symmetry and ensure that, even though there's actually no edge going out, if there's an edge coming in, you've got to count that. And that's going to get a negative. Whatever is coming in, you've got to subtract, OK? So it's not that complicated. Yeah, go ahead.
STUDENT: Do we not consider S, c?
SRINIVAS DEVADAS: I'm sorry?
STUDENT: Do we not consider S, c?
SRINIVAS DEVADAS: So the beauty of this is that, when you don't have a particular edge from S to c, you can use skew symmetry to argue that S, c and c, S cancel out each other, all right? So that's the good part, right? And thanks for asking the question. That's a good question. All right. Here you go.
So you can do that by just looking at the edges. And you can add up the numbers, all right? And so I don't think this is going to be absolutely crucial to understand the rest of the lecture. Keep this in mind, that there's a process by which you define the value of a cut. And we're going to get back to this, when we prove the max-flow min-cut theorem next time. But at this point, I want to say something actually much more straightforward, which is going to be important when we look at residual networks, which is the last concept that we need to get at before we get to an algorithm. And that is simply that the capacity of a cut and the relationship between the capacity of the cut and the flow of a cut.
So the capacity of a cut is c(S,T). Oops. I didn't draw that properly. Open brackets, capital S, capital T. And we can do it exactly the same way, except this is a lot simpler, because you only look at edges and you only have positive quantities.
So in this case, you'll simply say it's 3 plus 2, corresponding to-- what did I have here? I had d, a-- S, a and S, d. And then, the capacity is you only need to look at the edges that go from a node in S to a node in capital T. And so those are 1 plus 3. And this simply would be the 1 would be d, b. And the 3 is d, t.
So you don't care about the other flows. This is not about flows, this is simply about capacity. So this adds up to 9, OK?
And so we have, at this point, we have defined the flow through a cut. And we know the capacity of a cut, OK? It's more or less obvious-- though you could certainly prove a theorem which is going to take a couple of lines-- to say that the value of any flow is bounded by the capacity of any cut. And sorry, I lied. It's not a trivial proof. And that is actually something profound going on here. And so I'll have to explain exactly what this means. And then we'll take a look at how we could prove something like this.
So what's cool about this is that you're saying that it's the value of any flow is bounded by the capacity of any cut, OK? And so that's an upper-bound on the maximum flow value, right? So I'm saying there's all these cuts that are possible in the network. And I'm making a statement about what the maximum flow can be, based on the values corresponding to the capacities of any cut, right?
So why is that the case? Well, we're not going to be able to prove that fully today. That's the max-flow min-cut theorem. But you can certainly get a sense of it, by looking at a different characterization of the flow value. So I'm going to give you one half of the proof, at least, and intuition about the other half. And we'll finish it next time.
But here's another characterization of the flow value. So our lemma here, which is going to lead us to this statement, is that, for any flow, f, and any cut, (S, T), we have a really powerful dilemma. Maybe you should call it a theorem.
But it essentially says, look, it doesn't matter what cut you choose, you've got a flow on the network. And when you look at the flow on the network, it's going to equal the flow across the cut. And the only reason for this is simply because you've got the source on one side of the cut. And you've got the sink on the other side of the cut. That's it. That's the only thing that you need, right?
You dump these vertices these into two bins. You know, dump the source on the left, and dump the sink on the right. And you compute the flow the way we've defined it. That's the flow. It doesn't matter how you partition these vertices, as long as you've got the source on the left and the sink on the right, OK?
And so we can prove this using implicit summation notation. We'll do that. And that'll give you a really good sense of why this statement is true, because we know that, for any given cut, the flow that cut is bounded by the capacity of that cut, right? You know that.
But to show this, here's how we could show that, f(S, T) is f(S, V) minus f(S, S), OK? So I'm playing around, just like I did before. I had taken the cap T-- I know that S union T is cap V, right? This is a partition. So I know that S union T is cap V. So I can put a V here and an S here, right? And that's a subtraction over there, of course, right?
So put that up here and finish this, a couple more lines. And what can I say about either of these? I could say something about one of these terms. Yep?
STUDENT: The one on the right is [INAUDIBLE].
SRINIVAS DEVADAS: The one on the right is 0. So call this f(S,V). Right? And now, I'm going to break it up again, make it small s, big V, plus f(S minus s, cap V). So broken this up into small s, which is just joined from cap S minus s, clearly.
And what can I say about this? This is a little more subtle than, perhaps, the previous question. What can I say about that quantity? I mean, the answer is not subtle, but-- yeah, go ahead.
STUDENT: That that is equal to 0.
SRINIVAS DEVADAS: And why?
STUDENT: Because the cap S doesn't contain t.
SRINIVAS DEVADAS: Ah. Beautiful. That's right. So that's what I wanted. So this does not contain t. And so, now you can use flow conservation, right? And that's the important thing.
You can use flow conservation, because this does not contain t. And then, it clearly does not contain small s, because I just took it out of it, right? So that goes to 0. And voila. That's simply f(S, V), which we know is f. We proved that. Our first implicit summation proof was showing that-- well, this is a definition. Excuse me. So we did it for the sink.
But this is simply the definition of the flow value, right? So this is beautiful. I mean, it's like fantastic, right? Why aren't people excited?
Because I put people to sleep before, in the hour before. But this is absolutely fantastic, because this says that I have ways of figuring out what the maximum flow of the network would be, by making arbitrary cuts through this network and looking for capacities of these cuts, right? Because I know that the capacity of any cut-- and now you see why min cut is interesting-- but you know that the capacity of any cut is going to bound the flow of the network, because the flow through a cut is the flow through the network.
So if I go through and look at the min cut corresponding to the minimum capacity associated with the flow network, that's going to point me to my max flow, because that going to be an upper bound on the max flow, right? And so now you see why the min-- not the min flow, sorry-- the min-cut max-flow theorem is an interesting one. But it relates-- and this is the beginning of that relationship, we're not quite done to prove it-- but the beginning of the relationship is that you can look at any cut, and you can look at the flow through the cut as being the flow through the network. And then you use the second part of it, which is the capacity bounding-- of course, in a very simple way, because of edge capacities-- the flow through the cut. And you can put those two things together, all right?
We still don't quite know how to find these cuts, right? So we don't quite know how to find these cuts. And that's the last thing that we're going to do today, give you a sense of how we're going to find these min cuts, so we can find the max flow. All right? Cool.
So the one last notion that we have here that is going to allow us to go into the algorithm domain, as opposed to the analysis domain-- all we've done so far is analysis, analysis, analysis-- is the notion of a residual network. OK? And a residual network, as its name implies, is something that has residual capacities. It's the network that points you to places where you can increase the flow, because there's capacity left.
Your flow is less than the edge capacity. It's a local notion, so it's easy to compute. There's a capacity of 3 on this edge, there's a flow of 2. The residual capacity is 1, right? 3 minus 2.
And so the residual network Gf (V, Ef), right? So the actual network is G(V, E). And the vertices are going to be the same. The graph is obviously different, but the edges are going to be different. There's going to be a different set of edges in the residual network, as opposed to the flow network, OK?
And you have strictly positive. That means greater than 0, strictly greater than 0, residual capacities. So Cf ) equals c(u,v) minus f(u,v). And that's strictly greater than 0. I'm going to put an edge in there, if there is a residual capacity. 0 doesn't mean there's any residual capacity. Edges in Ef admit more flow, OK?
And one last thing. If (V, u) does not belong to E-- so we are talking about the original network here, E means the original network-- then we know c(V, u) equals 0. That was our definition. If you don't have that edge, the capacity is 0.
But we are talking now about f, which is a flow, which doesn't necessarily require that there be an edge. And we are simply going to use our skew symmetry relationship. And you'll see that this may not be completely clear as to why I wrote this at this moment. But as I draw the residual network, you'll see why that is important. It's going to be the case that we're going to have extra edges in the residual network that don't exist in the original network, because of that last line there, right? So let me clear that up.
So we're going to draw a residual network for-- I'm going to change that yet again-- but we're going to draw the residual network for our example up there. Topology is going to stay the same. Numbers are going to change, because I want something slightly more interesting than what we have there.
So I'm going to take this out-- 2, 1. 1, 2-- go back to what it was before, I think. 1-- all right. Good. So I want a 1 over here. I want a 1 over here, a 2 over here. And keep checking to make sure I'm not messing up here, in terms of flow constraints. But that's pretty much all I got. OK?
So the flow here and the s and t don't particularly matter. The max flow is 4. The flow that you see up there is 3. This is what we had right at the beginning, all right?
So what I want to do now is give you what the residual network is for this particular flow. Remember, the residual network is defined, based on a flow. That's why you have Gf, G subscript f. f is a flow. So you're going to have a different residual network, if the flow is different. So that original example that I had would have a different residual network. This one is going to have the one I'm going to draw, all right?
So the residual network has the same set of vertices. So I can go ahead and draw these vertices. I'll just mark T and S over here. Those are exactly the same as before. And this is Gf, OK? That's a residual network.
And the edges are going to be different. All I have to do is look up there and say, look, I'm going to have a residual capacity of 2-- let me use a different color, since I have them-- corresponding to that edge from S to a, because I clearly have a capacity of 3, and I only have a flow of 1, right? So that's all there is to it.
Now, the interesting thing is that, because of this line over here, I'm actually going to define an edge in Ef, in Gf or Ef, that corresponds to this edge that didn't exist in E, because I can shrink the flow from 1 to 0. And that essentially says that that shrinkage is represented in the residual network by an edge that goes from this node, a, up there, to s, right? And that is going to have a residual capacity of 1, right?
So that's it. That's the only extra thing that you have to remember when you draw the residual network. You not only can increase the flow, you can also shrink it. You have to represent the shrinkage of the flow by an edge in the residual network. And you obviously represent the increase of the flow by an edge in the residual network. And now you see why this is all going to make sense.
Remember, way back, eons ago, only an hour ago, but we had this example where we had to shrink the flow in a particular edge, in order to get the overall flow to increase, right? The residual network is going to point us in the direction of, potentially, those edges whose flow has to shrink. But they're going to be represented, in effect, as these reverse edges with positive numbers associated with them.
So there's a 1 here. It's positive, because it goes from this node, call it a, back to s. And if I shrink this from 1 to 0, that is, in effect, taking what I have up here and making this 1 as 0, OK? That's the way you want to think about this. So that's pretty much it.
I could draw out the rest of this, and it should all make sense. I have an edge like that. So the edges that are at capacity up there aren't going to show up here. The edges that are not at capacity end up with two edges down below, if they have a flow that is non-zero, right? If you have a 0 flow up there, you're only going to get one edge. Obviously, you'll get one edge, because the capacity is non-zero. But the ones that are not quite at capacity end up to two edges, right? Think of that as being the simple rule.
And make sure that I'm following this rule. Good exercise is to check for bugs, lecture bugs. Best way of understanding the material.
OK? So that's my residual network. And let me just point-- I'll put in some numbers. Or maybe you can tell me what some of these numbers are. What is this number?
SRINIVAS DEVADAS: 2. Right? Now, this is a little more tricky. Take a look at the number that goes up, versus the number that comes down. What is this number? Goes up.
SRINIVAS DEVADAS: That's 2, because I can go from 1 to 3. And this number would be?
SRINIVAS DEVADAS: Beautiful. All right, you guys got it. Did my job.
All right, so that's our residual network for this particular flow. So a mechanical way of computing it. And you should be able to do that.
Now what exactly can we do with this residual network? It turns out that the algorithm now can be described in a couple of sentences, right? Essentially our Ford-Fulkerson algorithm-- I'm not going to bother writing this out, because I'm going to have to prove the max-flow min-cut theorem next time. And we're going to talk about the Ford-Fulkerson algorithm and issues with it next time.
But I'm going to show you how the Ford-Fulkerson algorithm works on this particular example. And it's only going to have one step, all right? So it's going to converge in one step. So it's going to be relatively easy. But the bottom line is the the Ford-Fulkerson algorithm is going to look for augmenting paths in Gf. Augmenting paths are defined in the residual network.
What is an augmenting path, you ask? Well, an augmenting path is simply a path from s in Gf to t in Gf, OK? That's it. That's all there is to it. If you can find a path, you could use depth-first search, you could use breadth-first search, you could use whatever you wanted. You find a path from s to t, OK?
If you find such a path, if this path exists, it means that the flow is not maximum, OK? If no path exists, the flow is maximum, and you're done. If such a path exists, you will be able to increase the flow, in this case, because we have integral quantities, by at least one, OK? And you will be able to increase the flow by one.
And not only that, the augmenting path is going to tell you exactly what to do with respect to what edges to change, sometimes subtract the flow from, sometimes increase, right? So the augmenting path is going to take care of it. But you've flipped it, so everything is positive. You know, life is great. Positive numbers.
Just look at s to t and give me any path from s to t here in the residual network. So let me just call them a, b, d, and c. And we don't care about partitions or cuts at this point. That's required for proofs. But give me a path from s to t Yeah, go ahead.
STUDENT: S to a, a to b--
All right a little bit more slowly. s a, OK. And then?
STUDENT: a to b.
SRINIVAS DEVADAS: a to b. Beautiful.
STUDENT: b to c.
SRINIVAS DEVADAS: b to c.
STUDENT: c to t.
SRINIVAS DEVADAS: And c to t. Wonderful. And I have a capacity, a residual capacity, of 2 here. I have a residual capacity of 1 here, 1 here, and 1 here. And so the value of this augmenting path is 1, right? It's not 2, because the minimum value is what I can push through the network. And I just need to take the min of all of the residual capacities corresponding to the edges that I traversed, that correspond to this particular path. And that min value of 2, 1, 1, 1, is 1, right?
So what this means is I've discovered an augmenting path of residual capacity, 1. Now I can go back to this thing over here. And these edges are going to point me, in some cases, to complimentary edges, in some cases to the direct edges that are going to have to have their flows changed, either increased or decreased, to increase the flow in the original network. So you're guaranteed now that f, which caused this residual network to have an augmenting path in it was not maximum. You're guaranteed that, because you found this path, OK?
So what happens here? Well, you go back up and you say, remember, I'm going to increment by plus 1, because that's the residual capacity. So I'm going to go up here, and I have s to a. You'll need to help me out again. So I'm going to make this 2, because I needed to add a one to it.
What happens here? This is the key step.
SRINIVAS DEVADAS: Subtract and make this a 0, right? We're not quite done. What's next? I have b to c, right? Right? You're still on the hook.
SRINIVAS DEVADAS: b to c becomes?
SRINIVAS DEVADAS: 3. Right. And then, lastly, this becomes 2. OK? And at this point, if you create a residual network for this new flow, you will not be able to find a path in that residual network from s to t. And you know you're done, right?
So all of this works. We haven't quite shown that it works, because we haven't done enough of the proofs. But you have a sense as to why this works. You could probably code this up. It would all work. A couple of issues in applications. See you next time.