{"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>\u00a0<\/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=\u201dbanner\u201d]\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[pastacode lang=\u201dcpp\u201d manual=\u201d%2F%2F%20A%20C%2B%2B%20program%20to%20find%20maximal%20Bipartite%20matching.%0A%23include%20%3Ciostream%3E%0A%23include%20%3Cstring.h%3E%0Ausing%20namespace%20std%3B%0A%20%0A%2F%2F%20M%20is%20number%20of%20applicants%20and%20N%20is%20number%20of%20jobs%0A%23define%20M%206%0A%23define%20N%206%0A%20%0A%2F%2F%20A%20DFS%20based%20recursive%20function%20that%20returns%20true%20if%20a%0A%2F%2F%20matching%20for%20vertex%20u%20is%20possible%0Abool%20bpm(bool%20bpGraph%5BM%5D%5BN%5D%2C%20int%20u%2C%20bool%20seen%5B%5D%2C%20int%20matchR%5B%5D)%0A%7B%0A%20%20%20%20%2F%2F%20Try%20every%20job%20one%20by%20one%0A%20%20%20%20for%20(int%20v%20%3D%200%3B%20v%20%3C%20N%3B%20v%2B%2B)%0A%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%2F%2F%20If%20applicant%20u%20is%20interested%20in%20job%20v%20and%20v%20is%0A%20%20%20%20%20%20%20%20%2F%2F%20not%20visited%0A%20%20%20%20%20%20%20%20if%20(bpGraph%5Bu%5D%5Bv%5D%20%26%26%20!seen%5Bv%5D)%0A%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20seen%5Bv%5D%20%3D%20true%3B%20%2F%2F%20Mark%20v%20as%20visited%0A%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20If%20job%20\u2019v\u2019%20is%20not%20assigned%20to%20an%20applicant%20OR%0A%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20previously%20assigned%20applicant%20for%20job%20v%20(which%20is%20matchR%5Bv%5D)%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20has%20an%20alternate%20job%20available.%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20Since%20v%20is%20marked%20as%20visited%20in%20the%20above%20line%2C%20matchR%5Bv%5D%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20in%20the%20following%20recursive%20call%20will%20not%20get%20job%20\u2019v\u2019%20again%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(matchR%5Bv%5D%20%3C%200%20%7C%7C%20bpm(bpGraph%2C%20matchR%5Bv%5D%2C%20seen%2C%20matchR))%0A%20%20%20%20%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20matchR%5Bv%5D%20%3D%20u%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20true%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%20%20%20%20return%20false%3B%0A%7D%0A%20%0A%2F%2F%20Returns%20maximum%20number%20of%20matching%20from%20M%20to%20N%0Aint%20maxBPM(bool%20bpGraph%5BM%5D%5BN%5D)%0A%7B%0A%20%20%20%20%2F%2F%20An%20array%20to%20keep%20track%20of%20the%20applicants%20assigned%20to%0A%20%20%20%20%2F%2F%20jobs.%20The%20value%20of%20matchR%5Bi%5D%20is%20the%20applicant%20number%0A%20%20%20%20%2F%2F%20assigned%20to%20job%20i%2C%20the%20value%20-1%20indicates%20nobody%20is%0A%20%20%20%20%2F%2F%20assigned.%0A%20%20%20%20int%20matchR%5BN%5D%3B%0A%20%0A%20%20%20%20%2F%2F%20Initially%20all%20jobs%20are%20available%0A%20%20%20%20memset(matchR%2C%20-1%2C%20sizeof(matchR))%3B%0A%20%0A%20%20%20%20int%20result%20%3D%200%3B%20%2F%2F%20Count%20of%20jobs%20assigned%20to%20applicants%0A%20%20%20%20for%20(int%20u%20%3D%200%3B%20u%20%3C%20M%3B%20u%2B%2B)%0A%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%2F%2F%20Mark%20all%20jobs%20as%20not%20seen%20for%20next%20applicant.%0A%20%20%20%20%20%20%20%20bool%20seen%5BN%5D%3B%0A%20%20%20%20%20%20%20%20memset(seen%2C%200%2C%20sizeof(seen))%3B%0A%20%0A%20%20%20%20%20%20%20%20%2F%2F%20Find%20if%20the%20applicant%20\u2019u\u2019%20can%20get%20a%20job%0A%20%20%20%20%20%20%20%20if%20(bpm(bpGraph%2C%20u%2C%20seen%2C%20matchR))%0A%20%20%20%20%20%20%20%20%20%20%20%20result%2B%2B%3B%0A%20%20%20%20%7D%0A%20%20%20%20return%20result%3B%0A%7D%0A%20%0A%2F%2F%20Driver%20program%20to%20test%20above%20functions%0Aint%20main()%0A%7B%0A%20%20%20%20%2F%2F%20Let%20us%20create%20a%20bpGraph%20shown%20in%20the%20above%20example%0A%20%20%20%20bool%20bpGraph%5BM%5D%5BN%5D%20%3D%20%7B%20%20%7B0%2C%201%2C%201%2C%200%2C%200%2C%200%7D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B1%2C%200%2C%200%2C%201%2C%200%2C%200%7D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B0%2C%200%2C%201%2C%200%2C%200%2C%200%7D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B0%2C%200%2C%201%2C%201%2C%200%2C%200%7D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B0%2C%200%2C%200%2C%200%2C%200%2C%200%7D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B0%2C%200%2C%200%2C%200%2C%200%2C%201%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%3B%0A%20%0A%20%20%20%20cout%20%3C%3C%20%22Maximum%20number%20of%20applicants%20that%20can%20get%20job%20is%20%22%0A%20%20%20%20%20%20%20%20%20%3C%3C%20maxBPM(bpGraph)%3B%0A%20%0A%20%20%20%20return%200%3B%0A%7D\u201d message=\u201d\u201d highlight=\u201d\u201d provider=\u201dmanual\u201d\/]\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=\u201dbanner\u201d]\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}]}}