maximum_weighted_matching.hpp 49 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313
  1. //=======================================================================
  2. // Copyright (c) 2018 Yi Ji
  3. //
  4. // Distributed under the Boost Software License, Version 1.0.
  5. // (See accompanying file LICENSE_1_0.txt or copy at
  6. // http://www.boost.org/LICENSE_1_0.txt)
  7. //
  8. //=======================================================================
  9. #ifndef BOOST_GRAPH_MAXIMUM_WEIGHTED_MATCHING_HPP
  10. #define BOOST_GRAPH_MAXIMUM_WEIGHTED_MATCHING_HPP
  11. #include <algorithm> // for std::iter_swap
  12. #include <boost/shared_ptr.hpp>
  13. #include <boost/make_shared.hpp>
  14. #include <boost/graph/max_cardinality_matching.hpp>
  15. namespace boost
  16. {
  17. template < typename Graph, typename MateMap, typename VertexIndexMap >
  18. typename property_traits<
  19. typename property_map< Graph, edge_weight_t >::type >::value_type
  20. matching_weight_sum(const Graph& g, MateMap mate, VertexIndexMap vm)
  21. {
  22. typedef typename graph_traits< Graph >::vertex_iterator vertex_iterator_t;
  23. typedef
  24. typename graph_traits< Graph >::vertex_descriptor vertex_descriptor_t;
  25. typedef typename property_traits< typename property_map< Graph,
  26. edge_weight_t >::type >::value_type edge_property_t;
  27. edge_property_t weight_sum = 0;
  28. vertex_iterator_t vi, vi_end;
  29. for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
  30. {
  31. vertex_descriptor_t v = *vi;
  32. if (get(mate, v) != graph_traits< Graph >::null_vertex()
  33. && get(vm, v) < get(vm, get(mate, v)))
  34. weight_sum += get(edge_weight, g, edge(v, mate[v], g).first);
  35. }
  36. return weight_sum;
  37. }
  38. template < typename Graph, typename MateMap >
  39. inline typename property_traits<
  40. typename property_map< Graph, edge_weight_t >::type >::value_type
  41. matching_weight_sum(const Graph& g, MateMap mate)
  42. {
  43. return matching_weight_sum(g, mate, get(vertex_index, g));
  44. }
  45. template < typename Graph, typename MateMap, typename VertexIndexMap >
  46. class weighted_augmenting_path_finder
  47. {
  48. public:
  49. template < typename T > struct map_vertex_to_
  50. {
  51. typedef boost::iterator_property_map<
  52. typename std::vector< T >::iterator, VertexIndexMap >
  53. type;
  54. };
  55. typedef typename graph::detail::VERTEX_STATE vertex_state_t;
  56. typedef typename graph_traits< Graph >::vertex_iterator vertex_iterator_t;
  57. typedef
  58. typename graph_traits< Graph >::vertex_descriptor vertex_descriptor_t;
  59. typedef typename std::vector< vertex_descriptor_t >::const_iterator
  60. vertex_vec_iter_t;
  61. typedef
  62. typename graph_traits< Graph >::out_edge_iterator out_edge_iterator_t;
  63. typedef typename graph_traits< Graph >::edge_descriptor edge_descriptor_t;
  64. typedef typename graph_traits< Graph >::edge_iterator edge_iterator_t;
  65. typedef typename property_traits< typename property_map< Graph,
  66. edge_weight_t >::type >::value_type edge_property_t;
  67. typedef std::deque< vertex_descriptor_t > vertex_list_t;
  68. typedef std::vector< edge_descriptor_t > edge_list_t;
  69. typedef typename map_vertex_to_< vertex_descriptor_t >::type
  70. vertex_to_vertex_map_t;
  71. typedef
  72. typename map_vertex_to_< edge_property_t >::type vertex_to_weight_map_t;
  73. typedef typename map_vertex_to_< bool >::type vertex_to_bool_map_t;
  74. typedef typename map_vertex_to_< std::pair< vertex_descriptor_t,
  75. vertex_descriptor_t > >::type vertex_to_pair_map_t;
  76. typedef
  77. typename map_vertex_to_< std::pair< edge_descriptor_t, bool > >::type
  78. vertex_to_edge_map_t;
  79. typedef typename map_vertex_to_< vertex_to_edge_map_t >::type
  80. vertex_pair_to_edge_map_t;
  81. class blossom
  82. {
  83. public:
  84. typedef boost::shared_ptr< blossom > blossom_ptr_t;
  85. std::vector< blossom_ptr_t > sub_blossoms;
  86. edge_property_t dual_var;
  87. blossom_ptr_t father;
  88. blossom() : dual_var(0), father(blossom_ptr_t()) {}
  89. // get the base vertex of a blossom by recursively getting
  90. // its base sub-blossom, which is always the first one in
  91. // sub_blossoms because of how we create and maintain blossoms
  92. virtual vertex_descriptor_t get_base() const
  93. {
  94. const blossom* b = this;
  95. while (!b->sub_blossoms.empty())
  96. b = b->sub_blossoms[0].get();
  97. return b->get_base();
  98. }
  99. // set a sub-blossom as a blossom's base by exchanging it
  100. // with its first sub-blossom
  101. void set_base(const blossom_ptr_t& sub)
  102. {
  103. for (blossom_iterator_t bi = sub_blossoms.begin();
  104. bi != sub_blossoms.end(); ++bi)
  105. {
  106. if (sub.get() == bi->get())
  107. {
  108. std::iter_swap(sub_blossoms.begin(), bi);
  109. break;
  110. }
  111. }
  112. }
  113. // get all vertices inside recursively
  114. virtual std::vector< vertex_descriptor_t > vertices() const
  115. {
  116. std::vector< vertex_descriptor_t > all_vertices;
  117. for (typename std::vector< blossom_ptr_t >::const_iterator bi
  118. = sub_blossoms.begin();
  119. bi != sub_blossoms.end(); ++bi)
  120. {
  121. std::vector< vertex_descriptor_t > some_vertices
  122. = (*bi)->vertices();
  123. all_vertices.insert(all_vertices.end(), some_vertices.begin(),
  124. some_vertices.end());
  125. }
  126. return all_vertices;
  127. }
  128. };
  129. // a trivial_blossom only has one vertex and no sub-blossom;
  130. // for each vertex v, in_blossom[v] is the trivial_blossom that contains it
  131. // directly
  132. class trivial_blossom : public blossom
  133. {
  134. public:
  135. trivial_blossom(vertex_descriptor_t v) : trivial_vertex(v) {}
  136. virtual vertex_descriptor_t get_base() const { return trivial_vertex; }
  137. virtual std::vector< vertex_descriptor_t > vertices() const
  138. {
  139. std::vector< vertex_descriptor_t > all_vertices;
  140. all_vertices.push_back(trivial_vertex);
  141. return all_vertices;
  142. }
  143. private:
  144. vertex_descriptor_t trivial_vertex;
  145. };
  146. typedef boost::shared_ptr< blossom > blossom_ptr_t;
  147. typedef typename std::vector< blossom_ptr_t >::iterator blossom_iterator_t;
  148. typedef
  149. typename map_vertex_to_< blossom_ptr_t >::type vertex_to_blossom_map_t;
  150. weighted_augmenting_path_finder(
  151. const Graph& arg_g, MateMap arg_mate, VertexIndexMap arg_vm)
  152. : g(arg_g)
  153. , vm(arg_vm)
  154. , null_edge(std::pair< edge_descriptor_t, bool >(
  155. num_edges(g) == 0 ? edge_descriptor_t() : *edges(g).first, false))
  156. , mate_vector(num_vertices(g))
  157. , label_S_vector(num_vertices(g), graph_traits< Graph >::null_vertex())
  158. , label_T_vector(num_vertices(g), graph_traits< Graph >::null_vertex())
  159. , outlet_vector(num_vertices(g), graph_traits< Graph >::null_vertex())
  160. , tau_idx_vector(num_vertices(g), graph_traits< Graph >::null_vertex())
  161. , dual_var_vector(std::vector< edge_property_t >(
  162. num_vertices(g), std::numeric_limits< edge_property_t >::min()))
  163. , pi_vector(std::vector< edge_property_t >(
  164. num_vertices(g), std::numeric_limits< edge_property_t >::max()))
  165. , gamma_vector(std::vector< edge_property_t >(
  166. num_vertices(g), std::numeric_limits< edge_property_t >::max()))
  167. , tau_vector(std::vector< edge_property_t >(
  168. num_vertices(g), std::numeric_limits< edge_property_t >::max()))
  169. , in_blossom_vector(num_vertices(g))
  170. , old_label_vector(num_vertices(g))
  171. , critical_edge_vectors(num_vertices(g),
  172. std::vector< std::pair< edge_descriptor_t, bool > >(
  173. num_vertices(g), null_edge))
  174. ,
  175. mate(mate_vector.begin(), vm)
  176. , label_S(label_S_vector.begin(), vm)
  177. , label_T(label_T_vector.begin(), vm)
  178. , outlet(outlet_vector.begin(), vm)
  179. , tau_idx(tau_idx_vector.begin(), vm)
  180. , dual_var(dual_var_vector.begin(), vm)
  181. , pi(pi_vector.begin(), vm)
  182. , gamma(gamma_vector.begin(), vm)
  183. , tau(tau_vector.begin(), vm)
  184. , in_blossom(in_blossom_vector.begin(), vm)
  185. , old_label(old_label_vector.begin(), vm)
  186. {
  187. vertex_iterator_t vi, vi_end;
  188. edge_iterator_t ei, ei_end;
  189. edge_property_t max_weight
  190. = std::numeric_limits< edge_property_t >::min();
  191. for (boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei)
  192. max_weight = std::max(max_weight, get(edge_weight, g, *ei));
  193. typename std::vector<
  194. std::vector< std::pair< edge_descriptor_t, bool > > >::iterator vei;
  195. for (boost::tie(vi, vi_end) = vertices(g),
  196. vei = critical_edge_vectors.begin();
  197. vi != vi_end; ++vi, ++vei)
  198. {
  199. vertex_descriptor_t u = *vi;
  200. mate[u] = get(arg_mate, u);
  201. dual_var[u] = 2 * max_weight;
  202. in_blossom[u] = boost::make_shared< trivial_blossom >(u);
  203. outlet[u] = u;
  204. critical_edge_vector.push_back(
  205. vertex_to_edge_map_t(vei->begin(), vm));
  206. }
  207. critical_edge
  208. = vertex_pair_to_edge_map_t(critical_edge_vector.begin(), vm);
  209. init();
  210. }
  211. // return the top blossom where v is contained inside
  212. blossom_ptr_t in_top_blossom(vertex_descriptor_t v) const
  213. {
  214. blossom_ptr_t b = in_blossom[v];
  215. while (b->father != blossom_ptr_t())
  216. b = b->father;
  217. return b;
  218. }
  219. // check if vertex v is in blossom b
  220. bool is_in_blossom(blossom_ptr_t b, vertex_descriptor_t v) const
  221. {
  222. if (v == graph_traits< Graph >::null_vertex())
  223. return false;
  224. blossom_ptr_t vb = in_blossom[v]->father;
  225. while (vb != blossom_ptr_t())
  226. {
  227. if (vb.get() == b.get())
  228. return true;
  229. vb = vb->father;
  230. }
  231. return false;
  232. }
  233. // return the base vertex of the top blossom that contains v
  234. inline vertex_descriptor_t base_vertex(vertex_descriptor_t v) const
  235. {
  236. return in_top_blossom(v)->get_base();
  237. }
  238. // add an existed top blossom of base vertex v into new top
  239. // blossom b as its sub-blossom
  240. void add_sub_blossom(blossom_ptr_t b, vertex_descriptor_t v)
  241. {
  242. blossom_ptr_t sub = in_top_blossom(v);
  243. sub->father = b;
  244. b->sub_blossoms.push_back(sub);
  245. if (sub->sub_blossoms.empty())
  246. return;
  247. for (blossom_iterator_t bi = top_blossoms.begin();
  248. bi != top_blossoms.end(); ++bi)
  249. {
  250. if (bi->get() == sub.get())
  251. {
  252. top_blossoms.erase(bi);
  253. break;
  254. }
  255. }
  256. }
  257. // when a top blossom is created or its base vertex getting an S-label,
  258. // add all edges incident to this blossom into even_edges
  259. void bloom(blossom_ptr_t b)
  260. {
  261. std::vector< vertex_descriptor_t > vertices_of_b = b->vertices();
  262. vertex_vec_iter_t vi;
  263. for (vi = vertices_of_b.begin(); vi != vertices_of_b.end(); ++vi)
  264. {
  265. out_edge_iterator_t oei, oei_end;
  266. for (boost::tie(oei, oei_end) = out_edges(*vi, g); oei != oei_end;
  267. ++oei)
  268. {
  269. if (target(*oei, g) != *vi && mate[*vi] != target(*oei, g))
  270. even_edges.push_back(*oei);
  271. }
  272. }
  273. }
  274. // assigning a T-label to a non S-vertex, along with outlet and updating pi
  275. // value if updated pi[v] equals zero, augment the matching from its mate
  276. // vertex
  277. void put_T_label(vertex_descriptor_t v, vertex_descriptor_t T_label,
  278. vertex_descriptor_t outlet_v, edge_property_t pi_v)
  279. {
  280. if (label_S[v] != graph_traits< Graph >::null_vertex())
  281. return;
  282. label_T[v] = T_label;
  283. outlet[v] = outlet_v;
  284. pi[v] = pi_v;
  285. vertex_descriptor_t v_mate = mate[v];
  286. if (pi[v] == 0)
  287. {
  288. label_T[v_mate] = graph_traits< Graph >::null_vertex();
  289. label_S[v_mate] = v;
  290. bloom(in_top_blossom(v_mate));
  291. }
  292. }
  293. // get the missing T-label for a to-be-expanded base vertex
  294. // the missing T-label is the last vertex of the path from outlet[v] to v
  295. std::pair< vertex_descriptor_t, vertex_descriptor_t > missing_label(
  296. vertex_descriptor_t b_base)
  297. {
  298. vertex_descriptor_t missing_outlet = outlet[b_base];
  299. if (outlet[b_base] == b_base)
  300. return std::make_pair(
  301. graph_traits< Graph >::null_vertex(), missing_outlet);
  302. vertex_iterator_t vi, vi_end;
  303. for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
  304. old_label[*vi] = std::make_pair(label_T[*vi], outlet[*vi]);
  305. std::pair< vertex_descriptor_t, vertex_state_t > child(
  306. outlet[b_base], graph::detail::V_EVEN);
  307. blossom_ptr_t b = in_blossom[child.first];
  308. for (; b->father->father != blossom_ptr_t(); b = b->father)
  309. ;
  310. child.first = b->get_base();
  311. if (child.first == b_base)
  312. return std::make_pair(
  313. graph_traits< Graph >::null_vertex(), missing_outlet);
  314. while (true)
  315. {
  316. std::pair< vertex_descriptor_t, vertex_state_t > child_parent
  317. = parent(child, true);
  318. for (b = in_blossom[child_parent.first];
  319. b->father->father != blossom_ptr_t(); b = b->father)
  320. ;
  321. missing_outlet = child_parent.first;
  322. child_parent.first = b->get_base();
  323. if (child_parent.first == b_base)
  324. break;
  325. else
  326. child = child_parent;
  327. }
  328. return std::make_pair(child.first, missing_outlet);
  329. }
  330. // expand a top blossom, put all its non-trivial sub-blossoms into
  331. // top_blossoms
  332. blossom_iterator_t expand_blossom(
  333. blossom_iterator_t bi, std::vector< blossom_ptr_t >& new_ones)
  334. {
  335. blossom_ptr_t b = *bi;
  336. for (blossom_iterator_t i = b->sub_blossoms.begin();
  337. i != b->sub_blossoms.end(); ++i)
  338. {
  339. blossom_ptr_t sub_blossom = *i;
  340. vertex_descriptor_t sub_base = sub_blossom->get_base();
  341. label_S[sub_base] = label_T[sub_base]
  342. = graph_traits< Graph >::null_vertex();
  343. outlet[sub_base] = sub_base;
  344. sub_blossom->father = blossom_ptr_t();
  345. // new top blossoms cannot be pushed back into top_blossoms
  346. // immediately, because push_back() may cause reallocation and then
  347. // invalid iterators
  348. if (!sub_blossom->sub_blossoms.empty())
  349. new_ones.push_back(sub_blossom);
  350. }
  351. return top_blossoms.erase(bi);
  352. }
  353. // when expanding a T-blossom with base v, it requires more operations:
  354. // supply the missing T-labels for new base vertices by picking the minimum
  355. // tau from vertices of each corresponding new top-blossoms; when label_T[v]
  356. // is null or we have a smaller tau from missing_label(v), replace T-label
  357. // and outlet of v (but don't bloom v)
  358. blossom_iterator_t expand_T_blossom(
  359. blossom_iterator_t bi, std::vector< blossom_ptr_t >& new_ones)
  360. {
  361. blossom_ptr_t b = *bi;
  362. vertex_descriptor_t b_base = b->get_base();
  363. std::pair< vertex_descriptor_t, vertex_descriptor_t > T_and_outlet
  364. = missing_label(b_base);
  365. blossom_iterator_t next_bi = expand_blossom(bi, new_ones);
  366. for (blossom_iterator_t i = b->sub_blossoms.begin();
  367. i != b->sub_blossoms.end(); ++i)
  368. {
  369. blossom_ptr_t sub_blossom = *i;
  370. vertex_descriptor_t sub_base = sub_blossom->get_base();
  371. vertex_descriptor_t min_tau_v
  372. = graph_traits< Graph >::null_vertex();
  373. edge_property_t min_tau
  374. = std::numeric_limits< edge_property_t >::max();
  375. std::vector< vertex_descriptor_t > sub_vertices
  376. = sub_blossom->vertices();
  377. for (vertex_vec_iter_t v = sub_vertices.begin();
  378. v != sub_vertices.end(); ++v)
  379. {
  380. if (tau[*v] < min_tau)
  381. {
  382. min_tau = tau[*v];
  383. min_tau_v = *v;
  384. }
  385. }
  386. if (min_tau < std::numeric_limits< edge_property_t >::max())
  387. put_T_label(
  388. sub_base, tau_idx[min_tau_v], min_tau_v, tau[min_tau_v]);
  389. }
  390. if (label_T[b_base] == graph_traits< Graph >::null_vertex()
  391. || tau[old_label[b_base].second] < pi[b_base])
  392. boost::tie(label_T[b_base], outlet[b_base]) = T_and_outlet;
  393. return next_bi;
  394. }
  395. // when vertices v and w are matched to each other by augmenting,
  396. // we must set v/w as base vertex of any blossom who contains v/w and
  397. // is a sub-blossom of their lowest (smallest) common blossom
  398. void adjust_blossom(vertex_descriptor_t v, vertex_descriptor_t w)
  399. {
  400. blossom_ptr_t vb = in_blossom[v], wb = in_blossom[w],
  401. lowest_common_blossom;
  402. std::vector< blossom_ptr_t > v_ancestors, w_ancestors;
  403. while (vb->father != blossom_ptr_t())
  404. {
  405. v_ancestors.push_back(vb->father);
  406. vb = vb->father;
  407. }
  408. while (wb->father != blossom_ptr_t())
  409. {
  410. w_ancestors.push_back(wb->father);
  411. wb = wb->father;
  412. }
  413. typename std::vector< blossom_ptr_t >::reverse_iterator i, j;
  414. i = v_ancestors.rbegin();
  415. j = w_ancestors.rbegin();
  416. while (i != v_ancestors.rend() && j != w_ancestors.rend()
  417. && i->get() == j->get())
  418. {
  419. lowest_common_blossom = *i;
  420. ++i;
  421. ++j;
  422. }
  423. vb = in_blossom[v];
  424. wb = in_blossom[w];
  425. while (vb->father != lowest_common_blossom)
  426. {
  427. vb->father->set_base(vb);
  428. vb = vb->father;
  429. }
  430. while (wb->father != lowest_common_blossom)
  431. {
  432. wb->father->set_base(wb);
  433. wb = wb->father;
  434. }
  435. }
  436. // every edge weight is multiplied by 4 to ensure integer weights
  437. // throughout the algorithm if all input weights are integers
  438. inline edge_property_t slack(const edge_descriptor_t& e) const
  439. {
  440. vertex_descriptor_t v, w;
  441. v = source(e, g);
  442. w = target(e, g);
  443. return dual_var[v] + dual_var[w] - 4 * get(edge_weight, g, e);
  444. }
  445. // backtrace one step on vertex v along the augmenting path
  446. // by its labels and its vertex state;
  447. // boolean parameter "use_old" means whether we are updating labels,
  448. // if we are, then we use old labels to backtrace and also we
  449. // don't jump to its base vertex when we reach an odd vertex
  450. std::pair< vertex_descriptor_t, vertex_state_t > parent(
  451. std::pair< vertex_descriptor_t, vertex_state_t > v,
  452. bool use_old = false) const
  453. {
  454. if (v.second == graph::detail::V_EVEN)
  455. {
  456. // a paranoid check: label_S shoule be the same as mate in
  457. // backtracing
  458. if (label_S[v.first] == graph_traits< Graph >::null_vertex())
  459. label_S[v.first] = mate[v.first];
  460. return std::make_pair(label_S[v.first], graph::detail::V_ODD);
  461. }
  462. else if (v.second == graph::detail::V_ODD)
  463. {
  464. vertex_descriptor_t w = use_old ? old_label[v.first].first
  465. : base_vertex(label_T[v.first]);
  466. return std::make_pair(w, graph::detail::V_EVEN);
  467. }
  468. return std::make_pair(v.first, graph::detail::V_UNREACHED);
  469. }
  470. // backtrace from vertices v and w to their free (unmatched) ancesters,
  471. // return the nearest common ancestor (null_vertex if none) of v and w
  472. vertex_descriptor_t nearest_common_ancestor(vertex_descriptor_t v,
  473. vertex_descriptor_t w, vertex_descriptor_t& v_free_ancestor,
  474. vertex_descriptor_t& w_free_ancestor) const
  475. {
  476. std::pair< vertex_descriptor_t, vertex_state_t > v_up(
  477. v, graph::detail::V_EVEN);
  478. std::pair< vertex_descriptor_t, vertex_state_t > w_up(
  479. w, graph::detail::V_EVEN);
  480. vertex_descriptor_t nca;
  481. nca = w_free_ancestor = v_free_ancestor
  482. = graph_traits< Graph >::null_vertex();
  483. std::vector< bool > ancestor_of_w_vector(num_vertices(g), false);
  484. std::vector< bool > ancestor_of_v_vector(num_vertices(g), false);
  485. vertex_to_bool_map_t ancestor_of_w(ancestor_of_w_vector.begin(), vm);
  486. vertex_to_bool_map_t ancestor_of_v(ancestor_of_v_vector.begin(), vm);
  487. while (nca == graph_traits< Graph >::null_vertex()
  488. && (v_free_ancestor == graph_traits< Graph >::null_vertex()
  489. || w_free_ancestor == graph_traits< Graph >::null_vertex()))
  490. {
  491. ancestor_of_w[w_up.first] = true;
  492. ancestor_of_v[v_up.first] = true;
  493. if (w_free_ancestor == graph_traits< Graph >::null_vertex())
  494. w_up = parent(w_up);
  495. if (v_free_ancestor == graph_traits< Graph >::null_vertex())
  496. v_up = parent(v_up);
  497. if (mate[v_up.first] == graph_traits< Graph >::null_vertex())
  498. v_free_ancestor = v_up.first;
  499. if (mate[w_up.first] == graph_traits< Graph >::null_vertex())
  500. w_free_ancestor = w_up.first;
  501. if (ancestor_of_w[v_up.first] == true || v_up.first == w_up.first)
  502. nca = v_up.first;
  503. else if (ancestor_of_v[w_up.first] == true)
  504. nca = w_up.first;
  505. else if (v_free_ancestor == w_free_ancestor
  506. && v_free_ancestor != graph_traits< Graph >::null_vertex())
  507. nca = v_up.first;
  508. }
  509. return nca;
  510. }
  511. // when a new top blossom b is created by connecting (v, w), we add
  512. // sub-blossoms into b along backtracing from v_prime and w_prime to
  513. // stop_vertex (the base vertex); also, we set labels and outlet for each
  514. // base vertex we pass by
  515. void make_blossom(blossom_ptr_t b, vertex_descriptor_t w_prime,
  516. vertex_descriptor_t v_prime, vertex_descriptor_t stop_vertex)
  517. {
  518. std::pair< vertex_descriptor_t, vertex_state_t > u(
  519. v_prime, graph::detail::V_ODD);
  520. std::pair< vertex_descriptor_t, vertex_state_t > u_up(
  521. w_prime, graph::detail::V_EVEN);
  522. for (; u_up.first != stop_vertex; u = u_up, u_up = parent(u))
  523. {
  524. if (u_up.second == graph::detail::V_EVEN)
  525. {
  526. if (!in_top_blossom(u_up.first)->sub_blossoms.empty())
  527. outlet[u_up.first] = label_T[u.first];
  528. label_T[u_up.first] = outlet[u.first];
  529. }
  530. else if (u_up.second == graph::detail::V_ODD)
  531. label_S[u_up.first] = u.first;
  532. add_sub_blossom(b, u_up.first);
  533. }
  534. }
  535. // the design of recursively expanding augmenting path in
  536. // (reversed_)retrieve_augmenting_path functions is inspired by same
  537. // functions in max_cardinality_matching.hpp; except that in weighted
  538. // matching, we use "outlet" vertices instead of "bridge" vertex pairs: if
  539. // blossom b is the smallest non-trivial blossom that contains its base
  540. // vertex v, then v and outlet[v] are where augmenting path enters and
  541. // leaves b
  542. void retrieve_augmenting_path(
  543. vertex_descriptor_t v, vertex_descriptor_t w, vertex_state_t v_state)
  544. {
  545. if (v == w)
  546. aug_path.push_back(v);
  547. else if (v_state == graph::detail::V_EVEN)
  548. {
  549. aug_path.push_back(v);
  550. retrieve_augmenting_path(label_S[v], w, graph::detail::V_ODD);
  551. }
  552. else if (v_state == graph::detail::V_ODD)
  553. {
  554. if (outlet[v] == v)
  555. aug_path.push_back(v);
  556. else
  557. reversed_retrieve_augmenting_path(
  558. outlet[v], v, graph::detail::V_EVEN);
  559. retrieve_augmenting_path(label_T[v], w, graph::detail::V_EVEN);
  560. }
  561. }
  562. void reversed_retrieve_augmenting_path(
  563. vertex_descriptor_t v, vertex_descriptor_t w, vertex_state_t v_state)
  564. {
  565. if (v == w)
  566. aug_path.push_back(v);
  567. else if (v_state == graph::detail::V_EVEN)
  568. {
  569. reversed_retrieve_augmenting_path(
  570. label_S[v], w, graph::detail::V_ODD);
  571. aug_path.push_back(v);
  572. }
  573. else if (v_state == graph::detail::V_ODD)
  574. {
  575. reversed_retrieve_augmenting_path(
  576. label_T[v], w, graph::detail::V_EVEN);
  577. if (outlet[v] != v)
  578. retrieve_augmenting_path(outlet[v], v, graph::detail::V_EVEN);
  579. else
  580. aug_path.push_back(v);
  581. }
  582. }
  583. // correct labels for vertices in the augmenting path
  584. void relabel(vertex_descriptor_t v)
  585. {
  586. blossom_ptr_t b = in_blossom[v]->father;
  587. if (!is_in_blossom(b, mate[v]))
  588. { // if v is a new base vertex
  589. std::pair< vertex_descriptor_t, vertex_state_t > u(
  590. v, graph::detail::V_EVEN);
  591. while (label_S[u.first] != u.first
  592. && is_in_blossom(b, label_S[u.first]))
  593. u = parent(u, true);
  594. vertex_descriptor_t old_base = u.first;
  595. if (label_S[old_base] != old_base)
  596. { // if old base is not exposed
  597. label_T[v] = label_S[old_base];
  598. outlet[v] = old_base;
  599. }
  600. else
  601. { // if old base is exposed then new label_T[v] is not in b,
  602. // we must (i) make b2 the smallest blossom containing v but not
  603. // as base vertex (ii) backtrace from b2's new base vertex to b
  604. label_T[v] = graph_traits< Graph >::null_vertex();
  605. for (b = b->father; b != blossom_ptr_t() && b->get_base() == v;
  606. b = b->father)
  607. ;
  608. if (b != blossom_ptr_t())
  609. {
  610. u = std::make_pair(b->get_base(), graph::detail::V_ODD);
  611. while (!is_in_blossom(
  612. in_blossom[v]->father, old_label[u.first].first))
  613. u = parent(u, true);
  614. label_T[v] = u.first;
  615. outlet[v] = old_label[u.first].first;
  616. }
  617. }
  618. }
  619. else if (label_S[v] == v || !is_in_blossom(b, label_S[v]))
  620. { // if v is an old base vertex
  621. // let u be the new base vertex; backtrace from u's old T-label
  622. std::pair< vertex_descriptor_t, vertex_state_t > u(
  623. b->get_base(), graph::detail::V_ODD);
  624. while (
  625. old_label[u.first].first != graph_traits< Graph >::null_vertex()
  626. && old_label[u.first].first != v)
  627. u = parent(u, true);
  628. label_T[v] = old_label[u.first].second;
  629. outlet[v] = v;
  630. }
  631. else // if v is neither a new nor an old base vertex
  632. label_T[v] = label_S[v];
  633. }
  634. void augmenting(vertex_descriptor_t v, vertex_descriptor_t v_free_ancestor,
  635. vertex_descriptor_t w, vertex_descriptor_t w_free_ancestor)
  636. {
  637. vertex_iterator_t vi, vi_end;
  638. // retrieve the augmenting path and put it in aug_path
  639. reversed_retrieve_augmenting_path(
  640. v, v_free_ancestor, graph::detail::V_EVEN);
  641. retrieve_augmenting_path(w, w_free_ancestor, graph::detail::V_EVEN);
  642. // augment the matching along aug_path
  643. vertex_descriptor_t a, b;
  644. vertex_list_t reversed_aug_path;
  645. while (!aug_path.empty())
  646. {
  647. a = aug_path.front();
  648. aug_path.pop_front();
  649. reversed_aug_path.push_back(a);
  650. b = aug_path.front();
  651. aug_path.pop_front();
  652. reversed_aug_path.push_back(b);
  653. mate[a] = b;
  654. mate[b] = a;
  655. // reset base vertex for every blossom in augment path
  656. adjust_blossom(a, b);
  657. }
  658. for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
  659. old_label[*vi] = std::make_pair(label_T[*vi], outlet[*vi]);
  660. // correct labels for in-blossom vertices along aug_path
  661. while (!reversed_aug_path.empty())
  662. {
  663. a = reversed_aug_path.front();
  664. reversed_aug_path.pop_front();
  665. if (in_blossom[a]->father != blossom_ptr_t())
  666. relabel(a);
  667. }
  668. for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
  669. {
  670. vertex_descriptor_t u = *vi;
  671. if (mate[u] != graph_traits< Graph >::null_vertex())
  672. label_S[u] = mate[u];
  673. }
  674. // expand blossoms with zero dual variables
  675. std::vector< blossom_ptr_t > new_top_blossoms;
  676. for (blossom_iterator_t bi = top_blossoms.begin();
  677. bi != top_blossoms.end();)
  678. {
  679. if ((*bi)->dual_var <= 0)
  680. bi = expand_blossom(bi, new_top_blossoms);
  681. else
  682. ++bi;
  683. }
  684. top_blossoms.insert(top_blossoms.end(), new_top_blossoms.begin(),
  685. new_top_blossoms.end());
  686. init();
  687. }
  688. // create a new blossom and set labels for vertices inside
  689. void blossoming(vertex_descriptor_t v, vertex_descriptor_t v_prime,
  690. vertex_descriptor_t w, vertex_descriptor_t w_prime,
  691. vertex_descriptor_t nca)
  692. {
  693. vertex_iterator_t vi, vi_end;
  694. std::vector< bool > is_old_base_vector(num_vertices(g));
  695. vertex_to_bool_map_t is_old_base(is_old_base_vector.begin(), vm);
  696. for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
  697. {
  698. if (*vi == base_vertex(*vi))
  699. is_old_base[*vi] = true;
  700. }
  701. blossom_ptr_t b = boost::make_shared< blossom >();
  702. add_sub_blossom(b, nca);
  703. label_T[w_prime] = v;
  704. label_T[v_prime] = w;
  705. outlet[w_prime] = w;
  706. outlet[v_prime] = v;
  707. make_blossom(b, w_prime, v_prime, nca);
  708. make_blossom(b, v_prime, w_prime, nca);
  709. label_T[nca] = graph_traits< Graph >::null_vertex();
  710. outlet[nca] = nca;
  711. top_blossoms.push_back(b);
  712. bloom(b);
  713. // set gamma[b_base] = min_slack{critical_edge(b_base, other_base)}
  714. // where each critical edge is updated before, by
  715. // argmin{slack(old_bases_in_b, other_base)};
  716. vertex_vec_iter_t i, j;
  717. std::vector< vertex_descriptor_t > b_vertices = b->vertices(),
  718. old_base_in_b, other_base;
  719. vertex_descriptor_t b_base = b->get_base();
  720. for (i = b_vertices.begin(); i != b_vertices.end(); ++i)
  721. {
  722. if (is_old_base[*i])
  723. old_base_in_b.push_back(*i);
  724. }
  725. for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
  726. {
  727. if (*vi != b_base && *vi == base_vertex(*vi))
  728. other_base.push_back(*vi);
  729. }
  730. for (i = other_base.begin(); i != other_base.end(); ++i)
  731. {
  732. edge_property_t min_slack
  733. = std::numeric_limits< edge_property_t >::max();
  734. std::pair< edge_descriptor_t, bool > b_vi = null_edge;
  735. for (j = old_base_in_b.begin(); j != old_base_in_b.end(); ++j)
  736. {
  737. if (critical_edge[*j][*i] != null_edge
  738. && min_slack > slack(critical_edge[*j][*i].first))
  739. {
  740. min_slack = slack(critical_edge[*j][*i].first);
  741. b_vi = critical_edge[*j][*i];
  742. }
  743. }
  744. critical_edge[b_base][*i] = critical_edge[*i][b_base] = b_vi;
  745. }
  746. gamma[b_base] = std::numeric_limits< edge_property_t >::max();
  747. for (i = other_base.begin(); i != other_base.end(); ++i)
  748. {
  749. if (critical_edge[b_base][*i] != null_edge)
  750. gamma[b_base] = std::min(
  751. gamma[b_base], slack(critical_edge[b_base][*i].first));
  752. }
  753. }
  754. void init()
  755. {
  756. even_edges.clear();
  757. vertex_iterator_t vi, vi_end;
  758. typename std::vector<
  759. std::vector< std::pair< edge_descriptor_t, bool > > >::iterator vei;
  760. for (boost::tie(vi, vi_end) = vertices(g),
  761. vei = critical_edge_vectors.begin();
  762. vi != vi_end; ++vi, ++vei)
  763. {
  764. vertex_descriptor_t u = *vi;
  765. out_edge_iterator_t ei, ei_end;
  766. gamma[u] = tau[u] = pi[u]
  767. = std::numeric_limits< edge_property_t >::max();
  768. std::fill(vei->begin(), vei->end(), null_edge);
  769. if (base_vertex(u) != u)
  770. continue;
  771. label_S[u] = label_T[u] = graph_traits< Graph >::null_vertex();
  772. outlet[u] = u;
  773. if (mate[u] == graph_traits< Graph >::null_vertex())
  774. {
  775. label_S[u] = u;
  776. bloom(in_top_blossom(u));
  777. }
  778. }
  779. }
  780. bool augment_matching()
  781. {
  782. vertex_descriptor_t v, w, w_free_ancestor, v_free_ancestor;
  783. v = w = w_free_ancestor = v_free_ancestor
  784. = graph_traits< Graph >::null_vertex();
  785. bool found_alternating_path = false;
  786. // note that we only use edges of zero slack value for augmenting
  787. while (!even_edges.empty() && !found_alternating_path)
  788. {
  789. // search for augmenting paths depth-first
  790. edge_descriptor_t current_edge = even_edges.back();
  791. even_edges.pop_back();
  792. v = source(current_edge, g);
  793. w = target(current_edge, g);
  794. vertex_descriptor_t v_prime = base_vertex(v);
  795. vertex_descriptor_t w_prime = base_vertex(w);
  796. // w_prime == v_prime implies that we get an edge that has been
  797. // shrunk into a blossom
  798. if (v_prime == w_prime)
  799. continue;
  800. // a paranoid check
  801. if (label_S[v_prime] == graph_traits< Graph >::null_vertex())
  802. {
  803. std::swap(v_prime, w_prime);
  804. std::swap(v, w);
  805. }
  806. // w_prime may be unlabeled or have a T-label; replace the existed
  807. // T-label if the edge slack is smaller than current pi[w_prime] and
  808. // update it. Note that a T-label is "deserved" only when pi equals
  809. // zero. also update tau and tau_idx so that tau_idx becomes T-label
  810. // when a T-blossom is expanded
  811. if (label_S[w_prime] == graph_traits< Graph >::null_vertex())
  812. {
  813. if (slack(current_edge) < pi[w_prime])
  814. put_T_label(w_prime, v, w, slack(current_edge));
  815. if (slack(current_edge) < tau[w])
  816. {
  817. if (in_blossom[w]->father == blossom_ptr_t()
  818. || label_T[w_prime] == v
  819. || label_T[w_prime]
  820. == graph_traits< Graph >::null_vertex()
  821. || nearest_common_ancestor(v_prime, label_T[w_prime],
  822. v_free_ancestor, w_free_ancestor)
  823. == graph_traits< Graph >::null_vertex())
  824. {
  825. tau[w] = slack(current_edge);
  826. tau_idx[w] = v;
  827. }
  828. }
  829. }
  830. else
  831. {
  832. if (slack(current_edge) > 0)
  833. {
  834. // update gamma and critical_edges when we have a smaller
  835. // edge slack
  836. gamma[v_prime]
  837. = std::min(gamma[v_prime], slack(current_edge));
  838. gamma[w_prime]
  839. = std::min(gamma[w_prime], slack(current_edge));
  840. if (critical_edge[v_prime][w_prime] == null_edge
  841. || slack(critical_edge[v_prime][w_prime].first)
  842. > slack(current_edge))
  843. {
  844. critical_edge[v_prime][w_prime]
  845. = std::pair< edge_descriptor_t, bool >(
  846. current_edge, true);
  847. critical_edge[w_prime][v_prime]
  848. = std::pair< edge_descriptor_t, bool >(
  849. current_edge, true);
  850. }
  851. continue;
  852. }
  853. else if (slack(current_edge) == 0)
  854. {
  855. // if nca is null_vertex then we have an augmenting path;
  856. // otherwise we have a new top blossom with nca as its base
  857. // vertex
  858. vertex_descriptor_t nca = nearest_common_ancestor(
  859. v_prime, w_prime, v_free_ancestor, w_free_ancestor);
  860. if (nca == graph_traits< Graph >::null_vertex())
  861. found_alternating_path
  862. = true; // to break out of the loop
  863. else
  864. blossoming(v, v_prime, w, w_prime, nca);
  865. }
  866. }
  867. }
  868. if (!found_alternating_path)
  869. return false;
  870. augmenting(v, v_free_ancestor, w, w_free_ancestor);
  871. return true;
  872. }
  873. // slack the vertex and blossom dual variables when there is no augmenting
  874. // path found according to the primal-dual method
  875. bool adjust_dual()
  876. {
  877. edge_property_t delta1, delta2, delta3, delta4, delta;
  878. delta1 = delta2 = delta3 = delta4
  879. = std::numeric_limits< edge_property_t >::max();
  880. vertex_iterator_t vi, vi_end;
  881. for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
  882. {
  883. delta1 = std::min(delta1, dual_var[*vi]);
  884. delta4 = pi[*vi] > 0 ? std::min(delta4, pi[*vi]) : delta4;
  885. if (*vi == base_vertex(*vi))
  886. delta3 = std::min(delta3, gamma[*vi] / 2);
  887. }
  888. for (blossom_iterator_t bi = top_blossoms.begin();
  889. bi != top_blossoms.end(); ++bi)
  890. {
  891. vertex_descriptor_t b_base = (*bi)->get_base();
  892. if (label_T[b_base] != graph_traits< Graph >::null_vertex()
  893. && pi[b_base] == 0)
  894. delta2 = std::min(delta2, (*bi)->dual_var / 2);
  895. }
  896. delta = std::min(std::min(delta1, delta2), std::min(delta3, delta4));
  897. // start updating dual variables, note that the order is important
  898. for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
  899. {
  900. vertex_descriptor_t v = *vi, v_prime = base_vertex(v);
  901. if (label_S[v_prime] != graph_traits< Graph >::null_vertex())
  902. dual_var[v] -= delta;
  903. else if (label_T[v_prime] != graph_traits< Graph >::null_vertex()
  904. && pi[v_prime] == 0)
  905. dual_var[v] += delta;
  906. if (v == v_prime)
  907. gamma[v] -= 2 * delta;
  908. }
  909. for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
  910. {
  911. vertex_descriptor_t v_prime = base_vertex(*vi);
  912. if (pi[v_prime] > 0)
  913. tau[*vi] -= delta;
  914. }
  915. for (blossom_iterator_t bi = top_blossoms.begin();
  916. bi != top_blossoms.end(); ++bi)
  917. {
  918. vertex_descriptor_t b_base = (*bi)->get_base();
  919. if (label_T[b_base] != graph_traits< Graph >::null_vertex()
  920. && pi[b_base] == 0)
  921. (*bi)->dual_var -= 2 * delta;
  922. if (label_S[b_base] != graph_traits< Graph >::null_vertex())
  923. (*bi)->dual_var += 2 * delta;
  924. }
  925. for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
  926. {
  927. vertex_descriptor_t v = *vi;
  928. if (pi[v] > 0)
  929. pi[v] -= delta;
  930. // when some T-vertices have zero pi value, bloom their mates so
  931. // that matching can be further augmented
  932. if (label_T[v] != graph_traits< Graph >::null_vertex()
  933. && pi[v] == 0)
  934. put_T_label(v, label_T[v], outlet[v], pi[v]);
  935. }
  936. // optimal solution reached, halt
  937. if (delta == delta1)
  938. return false;
  939. // expand odd blossoms with zero dual variables and zero pi value of
  940. // their base vertices
  941. if (delta == delta2 && delta != delta3)
  942. {
  943. std::vector< blossom_ptr_t > new_top_blossoms;
  944. for (blossom_iterator_t bi = top_blossoms.begin();
  945. bi != top_blossoms.end();)
  946. {
  947. const blossom_ptr_t b = *bi;
  948. vertex_descriptor_t b_base = b->get_base();
  949. if (b->dual_var == 0
  950. && label_T[b_base] != graph_traits< Graph >::null_vertex()
  951. && pi[b_base] == 0)
  952. bi = expand_T_blossom(bi, new_top_blossoms);
  953. else
  954. ++bi;
  955. }
  956. top_blossoms.insert(top_blossoms.end(), new_top_blossoms.begin(),
  957. new_top_blossoms.end());
  958. }
  959. while (true)
  960. {
  961. // find a zero-slack critical edge (v, w) of zero gamma values
  962. std::pair< edge_descriptor_t, bool > best_edge = null_edge;
  963. std::vector< vertex_descriptor_t > base_nodes;
  964. for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
  965. {
  966. if (*vi == base_vertex(*vi))
  967. base_nodes.push_back(*vi);
  968. }
  969. for (vertex_vec_iter_t i = base_nodes.begin();
  970. i != base_nodes.end(); ++i)
  971. {
  972. if (gamma[*i] == 0)
  973. {
  974. for (vertex_vec_iter_t j = base_nodes.begin();
  975. j != base_nodes.end(); ++j)
  976. {
  977. if (critical_edge[*i][*j] != null_edge
  978. && slack(critical_edge[*i][*j].first) == 0)
  979. best_edge = critical_edge[*i][*j];
  980. }
  981. }
  982. }
  983. // if not found, continue finding other augment matching
  984. if (best_edge == null_edge)
  985. {
  986. bool augmented = augment_matching();
  987. return augmented || delta != delta1;
  988. }
  989. // if found, determine either augmenting or blossoming
  990. vertex_descriptor_t v = source(best_edge.first, g),
  991. w = target(best_edge.first, g);
  992. vertex_descriptor_t v_prime = base_vertex(v),
  993. w_prime = base_vertex(w), v_free_ancestor,
  994. w_free_ancestor;
  995. vertex_descriptor_t nca = nearest_common_ancestor(
  996. v_prime, w_prime, v_free_ancestor, w_free_ancestor);
  997. if (nca == graph_traits< Graph >::null_vertex())
  998. {
  999. augmenting(v, v_free_ancestor, w, w_free_ancestor);
  1000. return true;
  1001. }
  1002. else
  1003. blossoming(v, v_prime, w, w_prime, nca);
  1004. }
  1005. return false;
  1006. }
  1007. template < typename PropertyMap > void get_current_matching(PropertyMap pm)
  1008. {
  1009. vertex_iterator_t vi, vi_end;
  1010. for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
  1011. put(pm, *vi, mate[*vi]);
  1012. }
  1013. private:
  1014. const Graph& g;
  1015. VertexIndexMap vm;
  1016. const std::pair< edge_descriptor_t, bool > null_edge;
  1017. // storage for the property maps below
  1018. std::vector< vertex_descriptor_t > mate_vector;
  1019. std::vector< vertex_descriptor_t > label_S_vector, label_T_vector;
  1020. std::vector< vertex_descriptor_t > outlet_vector;
  1021. std::vector< vertex_descriptor_t > tau_idx_vector;
  1022. std::vector< edge_property_t > dual_var_vector;
  1023. std::vector< edge_property_t > pi_vector, gamma_vector, tau_vector;
  1024. std::vector< blossom_ptr_t > in_blossom_vector;
  1025. std::vector< std::pair< vertex_descriptor_t, vertex_descriptor_t > >
  1026. old_label_vector;
  1027. std::vector< vertex_to_edge_map_t > critical_edge_vector;
  1028. std::vector< std::vector< std::pair< edge_descriptor_t, bool > > >
  1029. critical_edge_vectors;
  1030. // iterator property maps
  1031. vertex_to_vertex_map_t mate;
  1032. vertex_to_vertex_map_t label_S; // v has an S-label -> v can be an even
  1033. // vertex, label_S[v] is its mate
  1034. vertex_to_vertex_map_t
  1035. label_T; // v has a T-label -> v can be an odd vertex, label_T[v] is its
  1036. // predecessor in aug_path
  1037. vertex_to_vertex_map_t outlet;
  1038. vertex_to_vertex_map_t tau_idx;
  1039. vertex_to_weight_map_t dual_var;
  1040. vertex_to_weight_map_t pi, gamma, tau;
  1041. vertex_to_blossom_map_t
  1042. in_blossom; // map any vertex v to the trivial blossom containing v
  1043. vertex_to_pair_map_t old_label; // <old T-label, old outlet> before
  1044. // relabeling or expanding T-blossoms
  1045. vertex_pair_to_edge_map_t
  1046. critical_edge; // an not matched edge (v, w) is critical if v and w
  1047. // belongs to different S-blossoms
  1048. vertex_list_t aug_path;
  1049. edge_list_t even_edges;
  1050. std::vector< blossom_ptr_t > top_blossoms;
  1051. };
  1052. template < typename Graph, typename MateMap, typename VertexIndexMap >
  1053. void maximum_weighted_matching(const Graph& g, MateMap mate, VertexIndexMap vm)
  1054. {
  1055. empty_matching< Graph, MateMap >::find_matching(g, mate);
  1056. weighted_augmenting_path_finder< Graph, MateMap, VertexIndexMap > augmentor(
  1057. g, mate, vm);
  1058. // can have |V| times augmenting at most
  1059. for (std::size_t t = 0; t < num_vertices(g); ++t)
  1060. {
  1061. bool augmented = false;
  1062. while (!augmented)
  1063. {
  1064. augmented = augmentor.augment_matching();
  1065. if (!augmented)
  1066. {
  1067. // halt if adjusting dual variables can't bring potential
  1068. // augment
  1069. if (!augmentor.adjust_dual())
  1070. break;
  1071. }
  1072. }
  1073. if (!augmented)
  1074. break;
  1075. }
  1076. augmentor.get_current_matching(mate);
  1077. }
  1078. template < typename Graph, typename MateMap >
  1079. inline void maximum_weighted_matching(const Graph& g, MateMap mate)
  1080. {
  1081. maximum_weighted_matching(g, mate, get(vertex_index, g));
  1082. }
  1083. // brute-force matcher searches all possible combinations of matched edges to
  1084. // get the maximum weighted matching which can be used for testing on small
  1085. // graphs (within dozens vertices)
  1086. template < typename Graph, typename MateMap, typename VertexIndexMap >
  1087. class brute_force_matching
  1088. {
  1089. public:
  1090. typedef
  1091. typename graph_traits< Graph >::vertex_descriptor vertex_descriptor_t;
  1092. typedef typename graph_traits< Graph >::vertex_iterator vertex_iterator_t;
  1093. typedef
  1094. typename std::vector< vertex_descriptor_t >::iterator vertex_vec_iter_t;
  1095. typedef typename graph_traits< Graph >::edge_iterator edge_iterator_t;
  1096. typedef boost::iterator_property_map< vertex_vec_iter_t, VertexIndexMap >
  1097. vertex_to_vertex_map_t;
  1098. brute_force_matching(
  1099. const Graph& arg_g, MateMap arg_mate, VertexIndexMap arg_vm)
  1100. : g(arg_g)
  1101. , vm(arg_vm)
  1102. , mate_vector(num_vertices(g))
  1103. , best_mate_vector(num_vertices(g))
  1104. , mate(mate_vector.begin(), vm)
  1105. , best_mate(best_mate_vector.begin(), vm)
  1106. {
  1107. vertex_iterator_t vi, vi_end;
  1108. for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
  1109. best_mate[*vi] = mate[*vi] = get(arg_mate, *vi);
  1110. }
  1111. template < typename PropertyMap > void find_matching(PropertyMap pm)
  1112. {
  1113. edge_iterator_t ei;
  1114. boost::tie(ei, ei_end) = edges(g);
  1115. select_edge(ei);
  1116. vertex_iterator_t vi, vi_end;
  1117. for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
  1118. put(pm, *vi, best_mate[*vi]);
  1119. }
  1120. private:
  1121. const Graph& g;
  1122. VertexIndexMap vm;
  1123. std::vector< vertex_descriptor_t > mate_vector, best_mate_vector;
  1124. vertex_to_vertex_map_t mate, best_mate;
  1125. edge_iterator_t ei_end;
  1126. void select_edge(edge_iterator_t ei)
  1127. {
  1128. if (ei == ei_end)
  1129. {
  1130. if (matching_weight_sum(g, mate)
  1131. > matching_weight_sum(g, best_mate))
  1132. {
  1133. vertex_iterator_t vi, vi_end;
  1134. for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
  1135. best_mate[*vi] = mate[*vi];
  1136. }
  1137. return;
  1138. }
  1139. vertex_descriptor_t v, w;
  1140. v = source(*ei, g);
  1141. w = target(*ei, g);
  1142. select_edge(++ei);
  1143. if (mate[v] == graph_traits< Graph >::null_vertex()
  1144. && mate[w] == graph_traits< Graph >::null_vertex())
  1145. {
  1146. mate[v] = w;
  1147. mate[w] = v;
  1148. select_edge(ei);
  1149. mate[v] = mate[w] = graph_traits< Graph >::null_vertex();
  1150. }
  1151. }
  1152. };
  1153. template < typename Graph, typename MateMap, typename VertexIndexMap >
  1154. void brute_force_maximum_weighted_matching(
  1155. const Graph& g, MateMap mate, VertexIndexMap vm)
  1156. {
  1157. empty_matching< Graph, MateMap >::find_matching(g, mate);
  1158. brute_force_matching< Graph, MateMap, VertexIndexMap > brute_force_matcher(
  1159. g, mate, vm);
  1160. brute_force_matcher.find_matching(mate);
  1161. }
  1162. template < typename Graph, typename MateMap >
  1163. inline void brute_force_maximum_weighted_matching(const Graph& g, MateMap mate)
  1164. {
  1165. brute_force_maximum_weighted_matching(g, mate, get(vertex_index, g));
  1166. }
  1167. }
  1168. #endif