home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD2.mdf / c / library / dos / diverses / leda / src / graph_al / _mwb_mat.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-11-15  |  4.4 KB  |  222 lines

  1. /*******************************************************************************
  2. +
  3. +  LEDA  2.1.1                                                 11-15-1991
  4. +
  5. +
  6. +  _mwb_matching.c
  7. +
  8. +
  9. +  Copyright (c) 1991  by  Max-Planck-Institut fuer Informatik
  10. +  Im Stadtwald, 6600 Saarbruecken, FRG     
  11. +  All rights reserved.
  12. *******************************************************************************/
  13.  
  14.  
  15.  
  16. /*******************************************************************************
  17. *                                                                              *
  18. *  MAX_WEIGHT_BIPARTITE_MATCHING  (maximum weight bipartite matching)          *
  19. *                                                                              *
  20. *******************************************************************************/
  21.  
  22.  
  23.  
  24. #include <LEDA/graph_alg.h>
  25.  
  26.  
  27. // for integer edge weights:
  28.  
  29. list(edge) MAX_WEIGHT_BIPARTITE_MATCHING (graph& G, 
  30.                                           const list(node)& A, 
  31.                                           const list(node)& B, 
  32.                                           const edge_array(int)& weight )
  33.  
  34.  
  35. node v;
  36. edge e;
  37.  
  38. forall(v,B) 
  39.   forall_adj_edges(e,v)
  40.    { error_handler(0,"mwb_matching: edge from B to A (deleted)");
  41.      G.del_edge(e);
  42.     }
  43.  
  44. node s = G.new_node();
  45.  
  46. node_array(int)  dist(G);
  47. node_array(int)  u(G,0);
  48. node_array(edge) pred(G);
  49.  
  50.  
  51. forall(v,A) 
  52.   { int m = 0;
  53.     forall_adj_edges(e,v) if (weight[e] > m) m = weight[e];
  54.     if (m > 0)  G.new_edge(s,v);
  55.     u[v] = m;
  56.    }
  57.  
  58. edge_array(int)  p(G,0);
  59.  
  60.  
  61. while (outdeg(s) > 0)
  62.   forall_edges(e,G) 
  63.   { p[e] = u[source(e)] + u[target(e)]; 
  64.     if (source(e) != s) p[e] -= weight[e];
  65.    }
  66.  
  67.   DIJKSTRA(G,s,p,dist,pred);
  68.  
  69.   node j0,i0;
  70.   int min_A = Infinity; 
  71.   int min_B = Infinity;
  72.  
  73.   forall(v,B) 
  74.    { int x = dist[v];
  75.  
  76.      if ( outdeg(v)==0 && x < min_A ) 
  77.       { j0 = v; 
  78.         min_A = x;
  79.        }
  80.  
  81.     }
  82.  
  83.   forall(v,A) 
  84.    { int x = dist[v];
  85.      int y = x+u[v];
  86.  
  87.      if ( x < Infinity && y < min_B ) 
  88.       { i0 = v; 
  89.         min_B = y;
  90.        }
  91.  
  92.     }
  93.  
  94.   node k0 = j0; 
  95.   int d = min_A;
  96.   if (min_A > min_B) { k0 = i0; d = min_B; }
  97.  
  98.   forall(v,A) if (d > dist[v]) u[v] -= d-dist[v];
  99.   forall(v,B) if (d > dist[v]) u[v] += d-dist[v];
  100.  
  101.   if (e = pred[k0])
  102.    { while (source(e) != s)
  103.        { G.rev_edge(e);      /* "source(e) heisst jetzt target(e)" */
  104.          e=pred[target(e)];
  105.         }
  106.      G.del_edge(e);
  107.     }
  108. }
  109.  
  110. edgelist result;
  111. forall(v,B) forall_adj_edges(e,v) result.append(e);
  112.  
  113. // restore graph
  114. G.del_node(s);
  115. forall(e,result) G.rev_edge(e);
  116.  
  117. return result;
  118. }
  119.  
  120.  
  121.  
  122.  
  123. #ifndef NO_REAL_GRAPH_ALG
  124.  
  125. // for real edge weights:
  126.  
  127. list(edge) MAX_WEIGHT_BIPARTITE_MATCHING (graph& G, 
  128.                                           const list(node)& A, 
  129.                                           const list(node)& B, 
  130.                                           const edge_array(real)& weight )
  131.  
  132.  
  133. node v;
  134. edge e;
  135.  
  136. forall(v,B) 
  137.   forall_adj_edges(e,v)
  138.    { error_handler(0,"mwb_matching: edge from B to A (deleted)");
  139.      G.del_edge(e);
  140.     }
  141.  
  142. node s = G.new_node();
  143.  
  144. node_array(real)  dist(G);
  145. node_array(real)  u(G,0);
  146. node_array(edge) pred(G);
  147.  
  148.  
  149. forall(v,A) 
  150.   { real m = 0;
  151.     forall_adj_edges(e,v) if (weight[e] > m) m = weight[e];
  152.     if (m > 0)  G.new_edge(s,v);
  153.     u[v] = m;
  154.    }
  155.  
  156. edge_array(real)  p(G,0);
  157.  
  158. // edge_array(real)  w(G,0);
  159. // forall_edges(e,G) if (source(e)!=s) w[e] = weight[e];
  160.  
  161.  
  162. while (outdeg(s) > 0)
  163.  
  164.   /* forall_edges(e,G) p[e] = u[source(e)] + u[target(e)] - w[e]; */ 
  165.  
  166.   forall_edges(e,G) 
  167.   { p[e] = u[source(e)] + u[target(e)]; 
  168.     if (source(e) != s) p[e] -= weight[e];
  169.    }
  170.  
  171.   DIJKSTRA(G,s,p,dist,pred);
  172.  
  173.   node j0,i0;
  174.   real min_A = Infinity; 
  175.   real min_B = Infinity;
  176.  
  177.   forall(v,B) 
  178.     if ((outdeg(v)==0)&&(dist[v] < min_A)) 
  179.      { j0 = v; 
  180.        min_A = dist[v];
  181.       }
  182.  
  183.   forall(v,A) 
  184.     if (dist[v] < Infinity && (dist[v]+u[v]) < min_B) 
  185.      { i0 = v; 
  186.        min_B = dist[v] + u[v]; 
  187.       }
  188.  
  189.   node k0 = j0; 
  190.   real d = min_A;
  191.   if (min_A > min_B) { k0 = i0; d = min_B; }
  192.  
  193.   forall(v,A) if (d > dist[v]) u[v] -= d-dist[v];
  194.   forall(v,B) if (d > dist[v]) u[v] += d-dist[v];
  195.  
  196.   if (e = pred[k0])
  197.    { while (source(e) != s)
  198.        { G.rev_edge(e);      /* "source(e) heisst jetzt target(e)" */
  199.          e=pred[target(e)];
  200.         }
  201.      G.del_edge(e);
  202.     }
  203. }
  204.  
  205. edgelist result;
  206. forall(v,B) forall_adj_edges(e,v) result.append(e);
  207.  
  208. // restore graph
  209. G.del_node(s);
  210. forall(e,result) G.rev_edge(e);
  211.  
  212. return result;
  213. }
  214.  
  215.  
  216. #endif
  217.