matching.h 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. /*
  2. * Hopcroft-Karp algorithm for finding a maximal matching in a
  3. * bipartite graph.
  4. */
  5. #ifndef MATCHING_MATCHING_H
  6. #define MATCHING_MATCHING_H
  7. /*
  8. * The actual algorithm.
  9. *
  10. * Inputs:
  11. *
  12. * - 'scratch' is previously allocated scratch space of a size
  13. * previously determined by calling 'matching_scratch_size'.
  14. *
  15. * - 'nl' is the number of vertices on the left side of the graph.
  16. * Left vertices are numbered from 0 to nl-1.
  17. *
  18. * - 'nr' is the number of vertices on the left side of the graph.
  19. * Right vertices are numbered from 0 to nr-1.
  20. *
  21. * - 'adjlists' and 'adjsizes' represents the graph in adjacency-list
  22. * form. For each left vertex L, adjlists[L] points to an array of
  23. * adjsizes[L] integers giving the list of right vertices adjacent
  24. * to L.
  25. *
  26. * - 'rs', if not NULL, is a random_state used to perturb the
  27. * progress of the algorithm so as to choose randomly from the
  28. * possible matchings if there's more than one. (The exact
  29. * probability distribution can't be guaranteed, but at the very
  30. * least, any matching that exists should be a _possible_ output.)
  31. *
  32. * If 'rs' is not NULL, then each list in adjlists[] will be permuted
  33. * during the course of the algorithm as a side effect. (That's why
  34. * it's not an array of _const_ int pointers.)
  35. *
  36. * Output:
  37. *
  38. * - 'outl' may be NULL. If non-NULL, it is an array of 'nl'
  39. * integers, and outl[L] will be assigned the index of the right
  40. * vertex that the output matching paired with the left vertex L,
  41. * or -1 if L is unpaired.
  42. *
  43. * - 'outr' may be NULL. If non-NULL, it is an array of 'nr'
  44. * integers, and outr[R] will be assigned the index of the left
  45. * vertex that the output matching paired with the right vertex R,
  46. * or -1 if R is unpaired.
  47. *
  48. * - the returned value from the function is the total number of
  49. * edges in the matching.
  50. */
  51. int matching_with_scratch(void *scratch,
  52. int nl, int nr, int **adjlists, int *adjsizes,
  53. random_state *rs, int *outl, int *outr);
  54. /*
  55. * The above function expects its 'scratch' parameter to have already
  56. * been set up. This function tells you how much space is needed for a
  57. * given size of graph, so that you can allocate a single instance of
  58. * scratch space and run the algorithm multiple times without the
  59. * overhead of an alloc and free every time.
  60. */
  61. size_t matching_scratch_size(int nl, int nr);
  62. /*
  63. * Simplified version of the above function. All parameters are the
  64. * same, except that 'scratch' is constructed internally and freed on
  65. * exit. This is the simplest way to call the algorithm as a one-off;
  66. * however, if you need to call it multiple times on the same size of
  67. * graph, it is probably better to call the above version directly so
  68. * that you only construct 'scratch' once.
  69. *
  70. * Additional return value is now -1, meaning that scratch space
  71. * could not be allocated.
  72. */
  73. int matching(int nl, int nr, int **adjlists, int *adjsizes,
  74. random_state *rs, int *outl, int *outr);
  75. /*
  76. * Diagnostic routine used in testing this algorithm. It is passed a
  77. * pointer to a piece of scratch space that's just been used by
  78. * matching_with_scratch, and extracts from it a labelling of the
  79. * input graph that acts as a 'witness' to the maximality of the
  80. * returned matching.
  81. *
  82. * The output parameter 'witness' should be an array of (nl+nr)
  83. * integers, indexed such that witness[L] corresponds to an L-vertex (for
  84. * L=0,1,...,nl-1) and witness[nl+R] corresponds to an R-vertex (for
  85. * R=0,1,...,nr-1). On return, this array will assign each vertex a
  86. * label which is either 0 or 1, and the following properties will
  87. * hold:
  88. *
  89. * + all vertices not paired up by the matching are type L0 or R1
  90. * + every L0->R1 edge is used by the matching
  91. * + no L1->R0 edge is used by the matching.
  92. *
  93. * The mere existence of such a labelling is enough to prove the
  94. * maximality of the matching, because if there is any larger matching
  95. * then its symmetric difference with this one must include at least
  96. * one 'augmenting path', which starts at a free L-vertex and ends at
  97. * a free R-vertex, traversing only unused L->R edges and only used
  98. * R->L edges. But that would mean it starts at an L0, ends at an R1,
  99. * and never follows an edge that can get from an 0 to a 1.
  100. */
  101. void matching_witness(void *scratch, int nl, int nr, int *witness);
  102. #endif /* MATCHING_MATCHING_H */