min_cut.w
Upload User: gzelex
Upload Date: 2007-01-07
Package Size: 707k
Code Size: 12k
Development Platform:

MultiPlatform

  1. From leda@mpi-sb.mpg.de Tue Jul 18 17:04:43 1995
  2. To: stefan@mpi-sb.mpg.de
  3. Content-Length: 12222
  4. X-Lines: 421
  5. input cwebmac
  6. documentstyle[comments]{cweb}
  7. newcommand{qed}{rule[-0.2ex]{0.3em}{1.4ex}}
  8. newenvironment{remark}{{bf Remark:}}{par}
  9. newtheorem{theorem}{Theorem}
  10. newtheorem{lemma}{Lemma}
  11. newtheorem{corollary}[theorem]{Corollary}
  12. newtheorem{fact}{Fact}
  13. newtheorem{claim}{Claim}
  14. newenvironment{proof}%
  15.                {parvspace{0.5ex}noindent{bf Proof:}hspace{0.5em}}%
  16.                {nopagebreak%
  17.                 strutnopagebreak%
  18.                 hspace{fill}qedparmedskipnoindent}
  19. let3=ss
  20. defck{discretionary{k-}{k}{ck}}
  21. newcommand{IR}{hbox{Ikern-.15em R}}
  22. newcommand{IN}{hbox{Ikern-.15em N}}
  23. newcommand{abs}[1]{| #1 |}
  24. newcommand{la}{$langle$}
  25. newcommand{ra}{$rangle$ }
  26. newcommand{Litem}[2]{$langle$#1,#2$rangle$ }
  27. newcommand{Listitem}[1]{$langle$#1$rangle$ }
  28. newcommand{precond}{\ {em precondition}: }
  29. newcommand{Msection}[1]{\
  30. medskip 
  31. { large {bf #1}}\  
  32. smallskip
  33. }
  34. newcommand{Msubsection}[1]{\
  35. medskip
  36. {bf #1}\ 
  37. smallskip
  38.  
  39. begin{document}
  40. title{The minimum cut algorithm of\
  41.        Stoer and Wagner}
  42. author{Kurt Mehlhorn and Christian Uhrig}
  43. maketitle
  44. thispagestyle{empty}
  45. newpage
  46. setcounter{page}{1}
  47. @s Float int
  48. @s GRAPH int
  49. @s UGRAPH int
  50. @s Int int
  51. @s Point int
  52. @s polygon int
  53. @s Segment int
  54. @s Segment1 int
  55. @s _priority_queue int
  56. @s _sortseq int
  57. @s _d_array int
  58. @s _dictionary int
  59. @s array int
  60. @s array2 int
  61. @s block int
  62. @s bool int
  63. @s b_queue int
  64. @s char int
  65. @s d_array int
  66. @s dic_item int
  67. @s dictionary int
  68. @s edge int
  69. @s edge_array int
  70. @s etype int
  71. @s face int
  72. @s file_ostream int
  73. @s file_istream int
  74. @s forall while
  75. @s forall while
  76. @s forall_adj_edges while
  77. @s forall_adj_nodes while
  78. @s forall_defined while 
  79. @s forall_edges while
  80. @s forall_items while
  81. @s forall_nodes while
  82. @s forever while
  83. @s graph int
  84. @s int_set int
  85. @s istream int
  86. @s list int
  87. @s list_item int
  88. @s node int
  89. @s node_array int
  90. @s node_matrix int
  91. @s node_partition int
  92. @s node_pq int
  93. @s num_type int
  94. @s ostream int
  95. @s panel int
  96. @s partition_item int
  97. @s partition int
  98. @s planar_map int
  99. @s point int
  100. @s p_dictionary int
  101. @s pq_item int
  102. @s priority_queue int
  103. @s queue int
  104. @s segment int
  105. @s seq_item int
  106. @s set int
  107. @s slist int
  108. @s sortseq int
  109. @s stack int
  110. @s string int
  111. @s template int
  112. @s ugraph int
  113. @s vtype int
  114. @s window int
  115. @s GenPtr int
  116. @* Min-cuts in undirected graphs.
  117. Let |G=(V,E)| be an undirected graph (self-loops and 
  118. parallel edges are allowed) and let $|w:E| to Re_{ge 0}$ be a
  119. non-negative weight function on the edges of |G|. A cut |C| of |G|
  120. is any subset of |V| with $emptyset ne |C| ne |V|$. 
  121. The weight of a cut is the total
  122. weight of the edges crossing the cut, i.e., 
  123. $$w(E)=sum_{e in E; vert e cap C vert =1} w(e).$$
  124. A minimum cut is a cut of minimum
  125. weight. For a pair {|s|,|t|} of distinct vertices of |G| a cut
  126. is called an |s|-|t| cut if |C| contains exactly one of |s| and |t|.
  127. We describe a particularly simple and efficient min-cut algorithm
  128. due to Stoer and Wagner (cite{SW94}). The algorithm runs in time $O(nm + n^2 log n)$.
  129. The algorithm works in phases. In each phase it determines a pair
  130. of vertices |s| and |t| and a minimum |s|-|t| cut |C|. If there is a minimum
  131. cut of |G| separating |s| and |t| then |C| is a minimum cut of |G|. 
  132. If not then any minimum cut of |G| has |s| and |t| on the same side and 
  133. therefore the graph obtained from |G| by {em combining} |s| and |t| has 
  134. the same minimum cut as |G|. So a phase determines vertices |s| and |t|
  135. and a minimum |s|-|t| cut |C| and then combines |s| and |t| into one node. 
  136. After $|n|-1$ phases the graph is shrunk to a single node and one
  137. of the phases must have determined a minimum cut of |G|.
  138. @(mincut.c@> =
  139. #include <LEDA/graph_alg.h>
  140. #include <LEDA/ugraph.h>
  141. #include <LEDA/stream.h>
  142. #include <LEDA/node_pq.h>
  143. list<node> MIN_CUT(const graph& G0, edge_array<int> &weight) 
  144. { @<initialization@>@;
  145.   /* |n| is now the number of nodes of the current graph and |a| 
  146.      is a fixed vertex */
  147.   while (n>=2) { @<a phase@> }
  148.   @<output best cut@>@;
  149. }
  150. @ We call our input graph |G0| and our current Graph |G|. |G| is of type
  151. |UGRAPH<list<node>*, int>|. Every node of |G| represents a set
  152. of nodes of |G0|. This set is stored in a linear list pointed to by |G[v]|.
  153. Every edge $e = {v,w}$ of $G$ represents a set of
  154. edges of |G0|, namely $ { {x,y}; x in G[v] mbox{ and } y in G[w] }$.
  155. The total weight of these edges is stored in |G[e]|.
  156. It is easy to initialize |G|. We simply make |G| a copy of |G0| (except 
  157. for self-loops) and
  158. initialize |G[v]| to the appropriate singleton set for every vertex |v|
  159. of |G|.
  160.  
  161. @<initialization@> =
  162. typedef list<node> nodelist;
  163. UGRAPH<nodelist*, int> G;
  164. node v,x; 
  165. edge e;
  166. node_array<node> partner(G0); 
  167. forall_nodes(x, G0)
  168.  {partner[x]=G.new_node(new nodelist);
  169.  G[partner[x]]->append(x);
  170.  }
  171. forall_edges(e, G0) 
  172.     if (source(e) != target(e)) G.new_edge(partner[source(e)], partner[target(e)],weight[e]); 
  173. @ We also need to fix a particular node |a| of |G|, define |n| as the
  174. number of nodes of |G|, and introduce variables to store the currently
  175. best cut.
  176. @<initialization@> +=
  177. node a=G.first_node();
  178. int n=G.number_of_nodes();
  179. list<node> best_cut;
  180. int best_value=MAXINT;
  181. int cut_weight;
  182. @ Outputting the best cut is easy.
  183. @<output best cut@> =
  184.   return best_cut;
  185. @ We now come to the heart of the matter, a phase. A phase initializes
  186. a set |A| to the singleton set {|a|} and then successively merges
  187. all the other nodes of |G| into |A|. In each stage the node 
  188. $|v| notin |A|$ which maximizes 
  189. $$w(v,A)=sum { w(e); e= { v,y } {hbox{ for some }} y in A }$$
  190. is merged into |A|. Let |s| and |t| be the last two vertices added to |A|
  191. in a phase. The cut |C| computed by the phase is the cut consisting of node |t|
  192. only; in the graph |G0| this corresponds to the cut |G[t]|.
  193. begin{lemma} 
  194. Let |s| and |t| be the last two nodes
  195. merged into |A| during 
  196. a phase. Then {|t|} is a minimum |s|-|t| cut.
  197. end{lemma}
  198. begin{proof} 
  199. Let $C'$ be any |s|-|t| cut. We show that 
  200. $|w|(|C|') ge |w|({|t|})$.
  201. Let $v_{1}, dots , v_{n}$ be the order in which the nodes are added to |A|.
  202. Then $v_{1}=a, v_{n-1}=s$, and $v_{n}=t$. 
  203.   
  204. Call a vertex $v=v_{i}$ critical if $i ge 2$ and $v_{i}$ and $v_{i-1}$
  205. belong to different sides of $C'$. Note that |t| is critical. Let $k$ be
  206. the number of critical nodes and let $i_1$, $i_2$,..., $i_k$ be the indices
  207. of the critical nodes. Then $i_k = n$. For integer $i$ use
  208. $A_{i}$ to denote the set ${v_{1}, dots, v_{i}}$. Then 
  209. $w({t}) = w(v_{i_k},A_{i_k - 1})$ and $w(C') ge 
  210. sum_{j = 1}^k w(v_{i_j},A_{i_j -1} setminus A_{i_{j-1} - 1})$ 
  211. since any edge counted on the right side
  212. is also counted on the left and edge costs are
  213. non-negative. We now show for all integer $l$, $1 le l le k$, that
  214. $$ w(v_{i_l},A_{i_l - 1}) le sum_{j = 1}^l w(v_{i_j},A_{i_j -1} 
  215. setminus A_{i_{j-1} - 1}). $$ 
  216. For $l = 1$ we have equality. So assume $ l ge 2$.
  217. We have
  218. begin{eqnarray*} 
  219. w(v_{i_l},A_{i_l - 1}) &=& w(v_{i_l},A_{i_{l-1}-1}) + w(v_{i_l},A_{i_l-1} 
  220. setminus A_{i_{l-1}-1}) \
  221. &le& w(v_{i_{l -1}},A_{i_{l-1}-1}) + w(v_{i_l},A_{i_l-1} 
  222. setminus A_{i_{l-1}-1}) \
  223. &le& sum_{j = 1}^{l-1} w(v_{i_j},A_{i_j -1} 
  224. setminus A_{i_{j-1} - 1}) +  w(v_{i_l},A_{i_l-1} setminus A_{i_{l-1}-1}) \
  225. &le&sum_{j = 1}^{l} w(v_{i_j},A_{i_j -1} 
  226. setminus A_{i_{j-1} - 1}) .
  227. end{eqnarray*}
  228. Here the first inequality follows from the fact that $v_{i_{l -1}}$ is added to
  229. $A_{i_{l-1}-1}$ and not $v_{i_l}$ and the second inequality uses the induction hypothesis.
  230. end{proof}
  231. @<a phase@> =
  232. @<determine |s| and |t| and the value |cut_weight| of the cut {|t|}@>;
  233. if (cut_weight<best_value)
  234.   { best_cut=*(G[t]);
  235.     best_value=cut_weight;
  236.   }
  237. @<combine |s| and |t|@>;
  238. n--;
  239. @ How can we determine the order in which the vertices are merged into $A$?
  240. This can be done in a manner akin to Prim's
  241. minimum spanning tree algorithm. We keep the vertices |v|, $v notin A$, 
  242. in a priority queue ordered according to |w(v,A)|. In each stage we select
  243. the node, say |u|, with maximal |w(u,A)| and add it to |A|. This
  244. increases |w(v,A)| by $w( { v,u } )$ for any vertex $v notin A$
  245. and $v ne u$. Since LEDA priority queues select minimal values we 
  246. store |-w(v,A)| in the queue.
  247. The node added last to |A| is the vertex |t|.
  248. The value |cut_weight| is $w(t,A_{t})$.
  249. @<determine |s| and |t| and...@> =
  250. node t=a;  
  251. node s;
  252. node_array<bool> in_PQ(G); 
  253. node_pq<int> PQ(G);
  254. forall_nodes(v,G) 
  255. if (v!=a) 
  256. { PQ.insert(v,0); // $w(v,A) = 0$ if there is no edge connecting |v| to |A|
  257.   in_PQ[v]=true;
  258.  } 
  259.  else
  260.  {
  261.   in_PQ[v]=false;
  262.   }
  263. {
  264. forall_adj_edges(e,a)
  265.      PQ.decrease_inf(G.opposite(a,e),PQ.inf(G.opposite(a,e))-G[e]);
  266. }    
  267. while (!PQ.empty())
  268. { s=t;
  269.   cut_weight=-PQ.inf(PQ.find_min());
  270.   t=PQ.del_min(); 
  271.   in_PQ[t]=false;
  272.   forall_adj_edges(e,t)
  273.     { if (in_PQ[v=G.opposite(t,e)]) @+ PQ.decrease_inf(v,PQ.inf(v)-G[e]);
  274.     }
  275. }
  276. @ It remains to combine |s| and |t|. We do so by deleting |t| from |G| and
  277. moving all edges incident to |t| to |s|. More precisley, we need to do three
  278. things:
  279. begin{itemize}
  280. item Add |G[t]| to |G[s]| (|G[s] -> conc(*(G[t]))|).
  281. item Increase $G[ { s,v } ]$ by $G[ { t,v } ]$ for all vertices |v| with
  282. $ { t,v } in E$ and $v not= s$.
  283. item Delete |t| and all its incident edges from |G| (|G.del_node(t)|).
  284. end{itemize}
  285. The second step rises two difficulties: The edge ${ s,v }$ might not exist
  286. and there is no simple way to go from the edge $ { t,v } $ to the edge
  287. ${ s,v }$. We overcome these problems by first recording the edge  
  288. ${ s,v }$ in |s_edge[v]| for every neighbor |v| of |s|. We then go through
  289. the neighbors |v| of |t|: If |v| is connected to |s| then we simply increase 
  290. $G[ { s,v } ]$ by $G[ { t,v } ]$, if |v| is not connected to |s| and 
  291. different from |s| then we add a new edge $ { s,v }$ with weight  $G[ { t,v } ]$.
  292. @<combine |s| and |t|@> =
  293. G[s]->conc(*(G[t]));
  294. node_array<edge> s_edge(G,nil);
  295. {
  296. forall_adj_edges(e,s) @+ s_edge[G.opposite(s,e)]= e;
  297. }
  298. {
  299. forall_adj_edges(e,t)
  300.  {if (s_edge[v = G.opposite(t,e)] == nil)
  301.   G.new_edge(s,v,G[e]);
  302.  else G[s_edge[v]] += G[e];
  303.  }
  304.  
  305. delete G[t];
  306. G.del_node(t);
  307. @ The running time of our algorithm is clearly
  308. at most $n$ times the running time of a phase. A phase takes time 
  309. $O(m + nlog n)$ to merge all nodes into the set $A$ ( the argument
  310. is the same as for Prim's algorithm) and time $O(n)$ to
  311. record the cut computed and to merge |s| and |t|. The total running time is 
  312. therefore $O(nm + n^2log n)$.
  313. Table 1
  314. lists the running times (in seconds)
  315. for some experiments with 
  316. random graphs
  317. on a SPARCstation 10/52.
  318. The first column gives the number of nodes and the first row the
  319. number of edges. If there are more than 400 nodes
  320. the running time is about $9 n m + 8.5 n^2 log n$ $mu$sec.
  321. vspace{1cm}
  322. begin{table}[h]
  323. begin{center}
  324. begin{tabular}{*{11}{@@{vline }r@@{ }}@@{vline}} hline
  325. & 1000 & 2000 & 3000 & 4000 & 5000 & 6000 & 7000 & 8000 & 9000 & 10000\
  326. hline
  327. 100 & 0.52 & 0.96 & 1.31 & 1.51 & 1.76 & 2.03 & 2.56 & 3.02 & 2.75 & 3.54\
  328. hline
  329. 200 & 1.72 & 2.91 & 4.01 & 4.62 & 5.62 & 6.43 & 7.26 & 7.74 & 8.58 & 9.29\ 
  330. hline
  331. 300 & 3.19 & 5.17 & 7.13 & 8.79 & 10.57 & 12.37 & 13.33 & 14.66 & 16.62 & 17.86\ 
  332. hline
  333. 400 & 4.59 & 8.12 & 11.31 & 14.02 & 16.40 & 18.82 & 20.61 & 22.80 & 26.04 & 28.12\ 
  334. hline
  335. 500 & 6.26 & 11.04 & 15.43 & 18.93 & 22.47 & 26.05 & 29.14 & 32.17 & 35.79 & 40.12\ 
  336. hline
  337. 600 & 8.42 & 14.50 & 20.09 & 24.81 & 29.89 & 33.75 & 38.84 & 42.38 & 46.71 & 50.54\ 
  338. hline
  339. 700 & 10.91 & 18.08 & 24.19 & 31.03 & 36.55 & 43.24 & 48.47 & 53.72 & 61.18 & 68.01\ 
  340. hline
  341. 800 & 13.74 & 22.81 & 30.92 & 39.65 & 46.75 & 52.78 & 58.95 & 64.46 & 71.39 & 79.24\ 
  342. hline
  343. 900 & 15.71 & 25.38 & 35.80 & 42.83 & 52.73 & 60.99 & 68.59 & 76.98 & 85.08 & 92.24\ 
  344. hline
  345. 1000 & 18.70 & 31.75 & 41.38 & 50.95 & 60.13 & 70.62 & 79.04 & 87.96 & 96.38 & 107.13\ 
  346. hline
  347. end{tabular}
  348. end{center}
  349. caption{Some experimental results}
  350. end{table}
  351. begin{thebibliography}{{von} 28}
  352. bibitem[SW94]{SW94}
  353. M.~Stoer, and F.~Wagner.
  354. newblock A Simple Min Cut Algorithm.\
  355. newblock {em Algorithms - ESA '94, LNCS 855}, 141--147, 1994.
  356. end{thebibliography}
  357. end{document}