Sie sind auf Seite 1von 4

854 lecture 9/29

blocking flows
notion of admissible graph of shortest path "layers"
start from source, do bfs to get layers of graph
no edges skip layers forward
edges either have one layer forward, stay in same layer, or go backwards
"admissible edges" : those that go forward by one step
every admissible s-t path is a shortest path
admissible paths always in residual graph
what is blocking flow?
flow that saturates some edge on each admissible path
destroys all shortest paths
increases s-t distance
block flow algo?
repeadtedly use bfs to build admissible graph of current residua
l graph
find a blocking flow in admmisslbe graph to find distance from s
-t
terminates with max-flow
O(n)
n blocking flows yield a max
find blocking flow?
any max-flow will find BF in the DAG
but this sucks
so
also
in blocking flow there may be residual flow
but in max flow always no residual flow
i.e. all maxflows are BFs, but not reverse
construct blocking flow
first find a path with nonzero flow
we don't care about doing residuals because it doesn't have to b
e max flow
the capacity on these edges are now consumed.
look for another path;but it intersects the first path! what to
do
can't continue;
so back up one
once retreated, this edge becomes useless. burn it.
pick a different fork, find a path which actually works.
burn this path.
repeat
analysis (advance/retreat/augment) for unit capacity graph:
start at s; advance along edges until:
either we get t
in which case we augment along the advanced path
now destroy all capactiiyes on path
or we intersect a previous path, dead end
retreat; destroy retreated edge
continue augmenting;
if dead end, goto 1
correctness claim: produces blocking flow
the destroyed edges aren't on any augmenting paths
the augmented paths are all accounted for
therefore every path on s-t is admissible path
thus correctness
runtime
retreating: m edges: O(m)
augments: same thing; m possible edges: O(m)
advances: 0, because every advance is either a future re
treat or augment
thus total time: O(m)
time for max-flow: O(mn)
why do this? already had mn algo
because we no longer need just simple graph
can have parallel edges
so bound O(mn) is tight
also
even better bounds for unit and matching graphs
suppose a path has unit capacity
we do k blocking flows
know that distance between s and t is at least k in residual gra
ph
means every single path in G is at least k distance from s to t
consider max flow in G
decompose into s-t paths
each path uses k edges
say what about value of flow?
only have m/k paths
implies that residual flow is m/k
time to finish a max flow: m/k additional blocking flow
will finish finding max flow
time: phase 1: k*m
phase 2: m^2/k
O(km + m^2/k)
bound: O(m^3/2)
also works not only for unit-capacity graphs, but also for graph
s bound by some constant
bipartite matching problem
has a pretty good structure to exploit
source s, sink t, a lot of bipartite parallel edges
i.e. every vertex on left/right of bipartite has out/in degree 1
if in/out degree 1 is true, what's true about number of paths?
number of paths on any vertex is at most 1
paths are vertex-disjoint, not edge-disjoint
at most m/k paths
give O(m sqrt*n)) bound
what breaks in general capacity graphs?
try to use advance/augment/retreat
what goes wrong? relationship between maximum number of paths and vertic
es/edges disappears
problem: it's possible to augment the same edge multiple times
why? because when you augment along the path, not every
edge gets destroyed!
worst case: only one edge gets destroyed; everything els
e has leftover capacity
claim: every advance yields a retreat or an augment
so we can ignore advance costs
claim: still at most m retreats
still only retrate on each edge once
problem with augmenting remains
an augment only kills one edge (guaranteed)
amortization: charge cost of entire augment to edge that gets de
stroyed
worst case: charge n work per edge
O(mn) augment work
O(m) retreat work
BF takes O(mn) time
so max-flow takes O(mn^2)
even better:
over entire sequence of n blocking flows, only going to do f aug
ments
charge augments to a unit of flow
becomes O(nf) over all blocking flow rounds
retreat work: O(m) per phase, so O(mn) overall)
becomes O(mn + nf)
strongly polynomial; may be real capacities
--------------
2 approaches to dealing better with capacities
(1) fancy data structures
waste work re-augmenting edges
sol: remember more from the advances
so don't waste time on them again
take two parts of path left after agumentation .-.-. .-.-.
do something like .-.-. .-.-.
\.-./
get lots of path fragments, connect them to other path fragment
get a forest of paths, which can be hooked together to produce o
ther paths
so, maintain this forest of paths for exploration
when you advance, link two trees together
were on the root of one tree; look for head vertex of an
other tree, attach, augment
thus an augment cuts edge and separates two trees
also need another operation: teleports from current vertex to root of tr
ee we;re in
so algo:
explore edge
link to another tree
go to root of that tree
something...
augmentation requires finding min path from vertex to root
also needs global decrement -- from s to t, decrease every capacity on p
ath by some c
solution: use datastruct which implicitly represents values
slater-tarjan: link-cut trees
supports all these ops in O(logn) amortized
built on top of splay trees
since we already bounded by O(m) time
link-cut trees give BF in O(mlogn) time
max-flow in O(mnlogn)
pretty fucking good
how link-cut?
represent each path as a tree over the vertices
then joining two paths = joining two splay trees
store deltas instead of actual values
(2) apply unit-capacity techniques to larger capacities (Scaling)
do log(u) phases of scaling -- all capacities rounded down to 0; find ma
x-flow
roll in high-order bit of machine words (one bit at a time)
now we have unit-capacity graph
we can do this
key observation for augmenting paths that made scaling a good idea:
before a phase, we had min cut 0
after we scale in a bit, min cut edge capacities are at most 1
=>min cut, thus max flow, is at most m
(assuming int capacities) => BF takes O((m+f)n)=O(mn)
scaling a single bit costs mn
=> scaling all bits takes O(mnlog u) where u is maximum capacity... obvi
ous
------
wrap up max flow:
goldberg, rao : scaling : m^3/2 log U, msqrt(n) log u
other work: push-relabel algorithms
pipeline BF algo
instead of having kill-build rounds, maintain local-distance est
imate for bounds
advance, pulling flow behind you
instead of just retreating, change the distance of current verte
x
simultaneously pushing flow around graph and updating distances
of vertices
usually linear O(m)
interior-point methods
approximations: with epsilon of max, achieve O(m/e^2)
all linalg

Das könnte Ihnen auch gefallen