{"id":26640,"date":"2017-12-22T19:27:01","date_gmt":"2017-12-22T13:57:01","guid":{"rendered":"https:\/\/www.wikitechy.com\/technology\/?p=26640"},"modified":"2017-12-22T19:27:01","modified_gmt":"2017-12-22T13:57:01","slug":"c-algorithm-maximum-bipartite-matching","status":"publish","type":"post","link":"https:\/\/www.wikitechy.com\/technology\/c-algorithm-maximum-bipartite-matching\/","title":{"rendered":"C++ Algorithm &#8211; Maximum Bipartite Matching"},"content":{"rendered":"<p>A matching in a Bipartite Graph is a set of the edges chosen in such a way that no two edges share an endpoint. A maximum matching is a matching of maximum size (maximum number of edges). <span id=\"more-120260\"><\/span>In a maximum matching, if any edge is added to it, it is no longer a matching. There can be more than one maximum matchings for a given Bipartite Graph.<\/p>\n<p><strong>Why do we care?<\/strong><br \/>\nThere are many real world problems that can be formed as Bipartite Matching. For example, consider the following problem:<br \/>\n<em>There are M job applicants and N jobs. Each applicant has a subset of jobs that he\/she is interested in. Each job opening can only accept one applicant and a job applicant can be appointed for only one job. Find an assignment of jobs to applicants in such that as many applicants as possible get jobs.<\/em><\/p>\n<p>&nbsp;<\/p>\n<p>We strongly recommend to read the following post first.<\/p>\n<p>Ford-Fulkerson Algorithm for Maximum Flow Problem<\/p>\n[ad type=&#8221;banner&#8221;]\n<p><strong>Maximum Bipartite Matching and Max Flow Problem<\/strong><br \/>\n<strong>M<\/strong>aximum <strong>B<\/strong>ipartite <strong>M<\/strong>atching (<strong>MBP<\/strong>) problem can be solved by converting it into a flow network (See this video to know how did we arrive this conclusion). Following are the steps.<\/p>\n<p><em><strong>1) Build a Flow Network<\/strong><\/em><br \/>\nThere must be a source and sink in a flow network. So we add a source and add edges from source to all applicants. Similarly, add edges from all jobs to sink. The capacity of every edge is marked as 1 unit.<\/p>\n<p>2) Find the maximum flow.<br \/>\nWe use Ford-Fulkerson algorithm to find the maximum flow in the flow network built in step 1. The maximum flow is actually the MBP we are looking for.<br \/>\n<strong>How to implement the above approach?<\/strong><br \/>\nLet us first define input and output forms. Input is in the form of Edmonds matrix which is a 2D array \u2018bpGraph[M][N]\u2019 with M rows (for M job applicants) and N columns (for N jobs). The value bpGraph[i][j] is 1 if i\u2019th applicant is interested in j\u2019th job, otherwise 0.<br \/>\nOutput is number maximum number of people that can get jobs.<\/p>\n<p>A simple way to implement this is to create a matrix that represents adjacency matrix representation of a directed graph with M+N+2 vertices. Call the fordFulkerson() for the matrix. This implementation requires O((M+N)*(M+N)) extra space.<\/p>\n<p>Extra space can be be reduced and code can be simplified using the fact that the graph is bipartite and capacity of every edge is either 0 or 1. The idea is to use DFS traversal to find a job for an applicant (similar to augmenting path in Ford-Fulkerson). We call bpm() for every applicant, bpm() is the DFS based function that tries all possibilities to assign a job to the applicant.<\/p>\n<p>In bpm(), we one by one try all jobs that an applicant \u2018u\u2019 is interested in until we find a job, or all jobs are tried without luck. For every job we try, we do following.<br \/>\nIf a job is not assigned to anybody, we simply assign it to the applicant and return true. If a job is assigned to somebody else say x, then we recursively check whether x can be assigned some other job. To make sure that x doesn\u2019t get the same job again, we mark the job \u2018v\u2019 as seen before we make recursive call for x. If x can get other job, we change the applicant for job \u2018v\u2019 and return true. We use an array maxR[0..N-1] that stores the applicants assigned to different jobs.<\/p>\n<p>If bmp() returns true, then it means that there is an augmenting path in flow network and 1 unit of flow is added to the result in maxBPM()<\/p>\n<p><strong>C++ Programming:<\/strong><\/p>\n<div class=\"code-embed-wrapper\"> <div class=\"code-embed-infos\"> <\/div> <pre class=\"language-cpp code-embed-pre line-numbers\"  data-start=\"1\" data-line-offset=\"0\"><code class=\"language-cpp code-embed-code\">\/\/ A C++ program to find maximal Bipartite matching.<br\/>#include &lt;iostream&gt;<br\/>#include &lt;string.h&gt;<br\/>using namespace std;<br\/> <br\/>\/\/ M is number of applicants and N is number of jobs<br\/>#define M 6<br\/>#define N 6<br\/> <br\/>\/\/ A DFS based recursive function that returns true if a<br\/>\/\/ matching for vertex u is possible<br\/>bool bpm(bool bpGraph[M][N], int u, bool seen[], int matchR[])<br\/>{<br\/>    \/\/ Try every job one by one<br\/>    for (int v = 0; v &lt; N; v++)<br\/>    {<br\/>        \/\/ If applicant u is interested in job v and v is<br\/>        \/\/ not visited<br\/>        if (bpGraph[u][v] &amp;&amp; !seen[v])<br\/>        {<br\/>            seen[v] = true; \/\/ Mark v as visited<br\/> <br\/>            \/\/ If job &#039;v&#039; is not assigned to an applicant OR<br\/>            \/\/ previously assigned applicant for job v (which is matchR[v]) <br\/>            \/\/ has an alternate job available. <br\/>            \/\/ Since v is marked as visited in the above line, matchR[v] <br\/>            \/\/ in the following recursive call will not get job &#039;v&#039; again<br\/>            if (matchR[v] &lt; 0 || bpm(bpGraph, matchR[v], seen, matchR))<br\/>            {<br\/>                matchR[v] = u;<br\/>                return true;<br\/>            }<br\/>        }<br\/>    }<br\/>    return false;<br\/>}<br\/> <br\/>\/\/ Returns maximum number of matching from M to N<br\/>int maxBPM(bool bpGraph[M][N])<br\/>{<br\/>    \/\/ An array to keep track of the applicants assigned to<br\/>    \/\/ jobs. The value of matchR[i] is the applicant number<br\/>    \/\/ assigned to job i, the value -1 indicates nobody is<br\/>    \/\/ assigned.<br\/>    int matchR[N];<br\/> <br\/>    \/\/ Initially all jobs are available<br\/>    memset(matchR, -1, sizeof(matchR));<br\/> <br\/>    int result = 0; \/\/ Count of jobs assigned to applicants<br\/>    for (int u = 0; u &lt; M; u++)<br\/>    {<br\/>        \/\/ Mark all jobs as not seen for next applicant.<br\/>        bool seen[N];<br\/>        memset(seen, 0, sizeof(seen));<br\/> <br\/>        \/\/ Find if the applicant &#039;u&#039; can get a job<br\/>        if (bpm(bpGraph, u, seen, matchR))<br\/>            result++;<br\/>    }<br\/>    return result;<br\/>}<br\/> <br\/>\/\/ Driver program to test above functions<br\/>int main()<br\/>{<br\/>    \/\/ Let us create a bpGraph shown in the above example<br\/>    bool bpGraph[M][N] = {  {0, 1, 1, 0, 0, 0},<br\/>                        {1, 0, 0, 1, 0, 0},<br\/>                        {0, 0, 1, 0, 0, 0},<br\/>                        {0, 0, 1, 1, 0, 0},<br\/>                        {0, 0, 0, 0, 0, 0},<br\/>                        {0, 0, 0, 0, 0, 1}<br\/>                      };<br\/> <br\/>    cout &lt;&lt; &quot;Maximum number of applicants that can get job is &quot;<br\/>         &lt;&lt; maxBPM(bpGraph);<br\/> <br\/>    return 0;<br\/>}<\/code><\/pre> <\/div>\n<div class=\"responsive-tabs-wrapper\">\n<div class=\"responsive-tabs responsive-tabs--enabled\">\n<div id=\"tablist1-panel2\" class=\"tabcontent responsive-tabs__panel responsive-tabs__panel--active\">\n<p><strong>Output:<\/strong><\/p>\n<pre>Maximum number of applicants that can get job is 5<\/pre>\n<\/div>\n<\/div>\n<\/div>\n[ad type=&#8221;banner&#8221;]\n","protected":false},"excerpt":{"rendered":"<p>C++ Algorithm &#8211; Maximum Bipartite Matching &#8211; Graph Algorithm &#8211; A matching in a Bipartite Graph is a set of the edges chosen in such a way <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[83515,1,73906,78429],"tags":[79482,79488,79271,79483,79486,79481,79480,79485,79489,79487,79484],"class_list":["post-26640","post","type-post","status-publish","format-standard","hentry","category-c-programming-3","category-coding","category-graph-algorithms","category-maximum-flow","tag-bipartite-matching-network-flow","tag-ford-fulkerson-bipartite-matching","tag-hopcroft-karp-algorithm","tag-hopcroft-karp-algorithm-c","tag-maximal-matching","tag-maximum-bipartite-matching-ford-fulkerson","tag-maximum-matching-algorithm-for-bipartite-graphs","tag-maximum-matching-in-bipartite-graphs-video","tag-perfect-matching-algorithm","tag-perfect-matching-bipartite-graph","tag-weighted-bipartite-matching"],"_links":{"self":[{"href":"https:\/\/www.wikitechy.com\/technology\/wp-json\/wp\/v2\/posts\/26640","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.wikitechy.com\/technology\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.wikitechy.com\/technology\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.wikitechy.com\/technology\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.wikitechy.com\/technology\/wp-json\/wp\/v2\/comments?post=26640"}],"version-history":[{"count":0,"href":"https:\/\/www.wikitechy.com\/technology\/wp-json\/wp\/v2\/posts\/26640\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.wikitechy.com\/technology\/wp-json\/wp\/v2\/media?parent=26640"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.wikitechy.com\/technology\/wp-json\/wp\/v2\/categories?post=26640"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.wikitechy.com\/technology\/wp-json\/wp\/v2\/tags?post=26640"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}