DriveHQ Start Menu
Cloud Drive Mapping
Folder Sync
Cloud Backup
True Drop Box
FTP/SFTP Hosting
Group Account
DriveHQ Start Menu
Online File Server
My Storage
|
Manage Shares
|
Publishes
|
Drop Boxes
|
Group Account
WebDAV Drive Mapping
Cloud Drive Home
|
WebDAV Guide
|
Drive Mapping Tool
|
Drive Mapping URL
Complete Data Backup
Backup Guide
|
Online Backup Tool
|
Cloud-to-Cloud Backup
FTP, Email & Web Service
FTP Home
|
FTP Hosting FAQ
|
Email Hosting
|
EmailManager
|
Web Hosting
Help & Resources
About
|
Enterprise Service
|
Partnership
|
Comparisons
|
Support
Quick Links
Security and Privacy
Download Software
Service Manual
Use Cases
Group Account
Online Help
Blog
Contact
Cloud Surveillance
Sign Up
Login
Features
Business Features
Online File Server
FTP Hosting
Cloud Drive Mapping
Cloud File Backup
Email Backup & Hosting
Cloud File Sharing
Folder Synchronization
Group Management
True Drop Box
Full-text Search
AD Integration/SSO
Mobile Access
IP Camera & DVR Solution
More...
Personal Features
Personal Cloud Drive
Backup All Devices
Mobile APPs
Personal Web Hosting
Sub-Account (for Kids)
Home/PC/Kids Monitoring
More...
Software
DriveHQ Drive Mapping Tool
DriveHQ FileManager
DriveHQ Online Backup
DriveHQ Mobile Apps
Pricing
Business Plans & Pricing
Personal Plans & Pricing
Price Comparison with Others
Feature Comparison with Others
Install Mobile App
Sign up
Creating account...
Invalid character in username! Only 0-9, a-z, A-Z, _, -, . allowed.
Username is required!
Invalid email address!
E-mail is required!
Password is required!
Password is invalid!
Password and confirmation do not match.
Confirm password is required!
I accept
Membership Agreement
Please read the Membership Agreement and check "I accept"!
Free Quick Sign-up
Sign-up Page
Log in
Signing in...
Username or e-mail address is required!
Password is required!
Keep me logged in
Quick Login
Forgot Password
Up
Upload
Download
Share
Publish
New Folder
New File
Copy
Cut
Delete
Paste
Rate
Upgrade
Rotate
Effect
Edit
Slide
History
//======================================================================= // Copyright (c) 2005 Aaron Windsor // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // //======================================================================= #ifndef BOOST_GRAPH_MAXIMUM_CARDINALITY_MATCHING_HPP #define BOOST_GRAPH_MAXIMUM_CARDINALITY_MATCHING_HPP #include
#include
#include
#include
// for std::sort and std::stable_sort #include
// for std::pair #include
#include
// for boost::tie #include
#include
#include
#include
#include
#include
namespace boost { namespace graph { namespace detail { enum { V_EVEN, V_ODD, V_UNREACHED }; } } // end namespace graph::detail template
typename graph_traits
::vertices_size_type matching_size(const Graph& g, MateMap mate, VertexIndexMap vm) { typedef typename graph_traits
::vertex_iterator vertex_iterator_t; typedef typename graph_traits
::vertex_descriptor vertex_descriptor_t; typedef typename graph_traits
::vertices_size_type v_size_t; v_size_t size_of_matching = 0; vertex_iterator_t vi, vi_end; for(tie(vi,vi_end) = vertices(g); vi != vi_end; ++vi) { vertex_descriptor_t v = *vi; if (get(mate,v) != graph_traits
::null_vertex() && get(vm,v) < get(vm,get(mate,v))) ++size_of_matching; } return size_of_matching; } template
inline typename graph_traits
::vertices_size_type matching_size(const Graph& g, MateMap mate) { return matching_size(g, mate, get(vertex_index,g)); } template
bool is_a_matching(const Graph& g, MateMap mate, VertexIndexMap vm) { typedef typename graph_traits
::vertex_descriptor vertex_descriptor_t; typedef typename graph_traits
::vertex_iterator vertex_iterator_t; vertex_iterator_t vi, vi_end; for( tie(vi,vi_end) = vertices(g); vi != vi_end; ++vi) { vertex_descriptor_t v = *vi; if (get(mate,v) != graph_traits
::null_vertex() && v != get(mate,get(mate,v))) return false; } return true; } template
inline bool is_a_matching(const Graph& g, MateMap mate) { return is_a_matching(g, mate, get(vertex_index,g)); } //*************************************************************************** //*************************************************************************** // Maximum Cardinality Matching Functors //*************************************************************************** //*************************************************************************** template
struct no_augmenting_path_finder { no_augmenting_path_finder(const Graph& g, MateMap mate, VertexIndexMap vm) { } inline bool augment_matching() { return false; } template
void get_current_matching(PropertyMap p) {} }; template
class edmonds_augmenting_path_finder { // This implementation of Edmonds' matching algorithm closely // follows Tarjan's description of the algorithm in "Data // Structures and Network Algorithms." public: //generates the type of an iterator property map from vertices to type X template
struct map_vertex_to_ { typedef boost::iterator_property_map
::iterator, VertexIndexMap> type; }; typedef typename graph_traits
::vertex_descriptor vertex_descriptor_t; typedef typename std::pair< vertex_descriptor_t, vertex_descriptor_t > vertex_pair_t; typedef typename graph_traits
::edge_descriptor edge_descriptor_t; typedef typename graph_traits
::vertices_size_type v_size_t; typedef typename graph_traits
::edges_size_type e_size_t; typedef typename graph_traits
::vertex_iterator vertex_iterator_t; typedef typename graph_traits
::out_edge_iterator out_edge_iterator_t; typedef typename std::deque
vertex_list_t; typedef typename std::vector
edge_list_t; typedef typename map_vertex_to_
::type vertex_to_vertex_map_t; typedef typename map_vertex_to_
::type vertex_to_int_map_t; typedef typename map_vertex_to_
::type vertex_to_vertex_pair_map_t; typedef typename map_vertex_to_
::type vertex_to_vsize_map_t; typedef typename map_vertex_to_
::type vertex_to_esize_map_t; edmonds_augmenting_path_finder(const Graph& arg_g, MateMap arg_mate, VertexIndexMap arg_vm) : g(arg_g), vm(arg_vm), n_vertices(num_vertices(arg_g)), mate_vector(n_vertices), ancestor_of_v_vector(n_vertices), ancestor_of_w_vector(n_vertices), vertex_state_vector(n_vertices), origin_vector(n_vertices), pred_vector(n_vertices), bridge_vector(n_vertices), ds_parent_vector(n_vertices), ds_rank_vector(n_vertices), mate(mate_vector.begin(), vm), ancestor_of_v(ancestor_of_v_vector.begin(), vm), ancestor_of_w(ancestor_of_w_vector.begin(), vm), vertex_state(vertex_state_vector.begin(), vm), origin(origin_vector.begin(), vm), pred(pred_vector.begin(), vm), bridge(bridge_vector.begin(), vm), ds_parent_map(ds_parent_vector.begin(), vm), ds_rank_map(ds_rank_vector.begin(), vm), ds(ds_rank_map, ds_parent_map) { vertex_iterator_t vi, vi_end; for(tie(vi,vi_end) = vertices(g); vi != vi_end; ++vi) mate[*vi] = get(arg_mate, *vi); } bool augment_matching() { //As an optimization, some of these values can be saved from one //iteration to the next instead of being re-initialized each //iteration, allowing for "lazy blossom expansion." This is not //currently implemented. e_size_t timestamp = 0; even_edges.clear(); vertex_iterator_t vi, vi_end; for(tie(vi,vi_end) = vertices(g); vi != vi_end; ++vi) { vertex_descriptor_t u = *vi; origin[u] = u; pred[u] = u; ancestor_of_v[u] = 0; ancestor_of_w[u] = 0; ds.make_set(u); if (mate[u] == graph_traits
::null_vertex()) { vertex_state[u] = graph::detail::V_EVEN; out_edge_iterator_t ei, ei_end; for(tie(ei,ei_end) = out_edges(u,g); ei != ei_end; ++ei) even_edges.push_back( *ei ); } else vertex_state[u] = graph::detail::V_UNREACHED; } //end initializations vertex_descriptor_t v,w,w_free_ancestor,v_free_ancestor; w_free_ancestor = graph_traits
::null_vertex(); v_free_ancestor = graph_traits
::null_vertex(); bool found_alternating_path = false; while(!even_edges.empty() && !found_alternating_path) { // since we push even edges onto the back of the list as // they're discovered, taking them off the back will search // for augmenting paths depth-first. edge_descriptor_t current_edge = even_edges.back(); even_edges.pop_back(); v = source(current_edge,g); w = target(current_edge,g); vertex_descriptor_t v_prime = origin[ds.find_set(v)]; vertex_descriptor_t w_prime = origin[ds.find_set(w)]; // because of the way we put all of the edges on the queue, // v_prime should be labeled V_EVEN; the following is a // little paranoid but it could happen... if (vertex_state[v_prime] != graph::detail::V_EVEN) { std::swap(v_prime,w_prime); std::swap(v,w); } if (vertex_state[w_prime] == graph::detail::V_UNREACHED) { vertex_state[w_prime] = graph::detail::V_ODD; vertex_state[mate[w_prime]] = graph::detail::V_EVEN; out_edge_iterator_t ei, ei_end; for( tie(ei,ei_end) = out_edges(mate[w_prime], g); ei != ei_end; ++ei) even_edges.push_back(*ei); pred[w_prime] = v; } //w_prime == v_prime can happen below if we get an edge that has been //shrunk into a blossom else if (vertex_state[w_prime] == graph::detail::V_EVEN && w_prime != v_prime) { vertex_descriptor_t w_up = w_prime; vertex_descriptor_t v_up = v_prime; vertex_descriptor_t nearest_common_ancestor = graph_traits
::null_vertex(); w_free_ancestor = graph_traits
::null_vertex(); v_free_ancestor = graph_traits
::null_vertex(); // We now need to distinguish between the case that // w_prime and v_prime share an ancestor under the // "parent" relation, in which case we've found a // blossom and should shrink it, or the case that // w_prime and v_prime both have distinct ancestors that // are free, in which case we've found an alternating // path between those two ancestors. ++timestamp; while (nearest_common_ancestor == graph_traits
::null_vertex() && (v_free_ancestor == graph_traits
::null_vertex() || w_free_ancestor == graph_traits
::null_vertex() ) ) { ancestor_of_w[w_up] = timestamp; ancestor_of_v[v_up] = timestamp; if (w_free_ancestor == graph_traits
::null_vertex()) w_up = parent(w_up); if (v_free_ancestor == graph_traits
::null_vertex()) v_up = parent(v_up); if (mate[v_up] == graph_traits
::null_vertex()) v_free_ancestor = v_up; if (mate[w_up] == graph_traits
::null_vertex()) w_free_ancestor = w_up; if (ancestor_of_w[v_up] == timestamp) nearest_common_ancestor = v_up; else if (ancestor_of_v[w_up] == timestamp) nearest_common_ancestor = w_up; else if (v_free_ancestor == w_free_ancestor && v_free_ancestor != graph_traits
::null_vertex()) nearest_common_ancestor = v_up; } if (nearest_common_ancestor == graph_traits
::null_vertex()) found_alternating_path = true; //to break out of the loop else { //shrink the blossom link_and_set_bridges(w_prime, nearest_common_ancestor, std::make_pair(w,v)); link_and_set_bridges(v_prime, nearest_common_ancestor, std::make_pair(v,w)); } } } if (!found_alternating_path) return false; // retrieve the augmenting path and put it in aug_path reversed_retrieve_augmenting_path(v, v_free_ancestor); retrieve_augmenting_path(w, w_free_ancestor); // augment the matching along aug_path vertex_descriptor_t a,b; while (!aug_path.empty()) { a = aug_path.front(); aug_path.pop_front(); b = aug_path.front(); aug_path.pop_front(); mate[a] = b; mate[b] = a; } return true; } template
void get_current_matching(PropertyMap pm) { vertex_iterator_t vi,vi_end; for(tie(vi,vi_end) = vertices(g); vi != vi_end; ++vi) put(pm, *vi, mate[*vi]); } template
void get_vertex_state_map(PropertyMap pm) { vertex_iterator_t vi,vi_end; for(tie(vi,vi_end) = vertices(g); vi != vi_end; ++vi) put(pm, *vi, vertex_state[origin[ds.find_set(*vi)]]); } private: vertex_descriptor_t parent(vertex_descriptor_t x) { if (vertex_state[x] == graph::detail::V_EVEN && mate[x] != graph_traits
::null_vertex()) return mate[x]; else if (vertex_state[x] == graph::detail::V_ODD) return origin[ds.find_set(pred[x])]; else return x; } void link_and_set_bridges(vertex_descriptor_t x, vertex_descriptor_t stop_vertex, vertex_pair_t the_bridge) { for(vertex_descriptor_t v = x; v != stop_vertex; v = parent(v)) { ds.union_set(v, stop_vertex); origin[ds.find_set(stop_vertex)] = stop_vertex; if (vertex_state[v] == graph::detail::V_ODD) { bridge[v] = the_bridge; out_edge_iterator_t oei, oei_end; for(tie(oei, oei_end) = out_edges(v,g); oei != oei_end; ++oei) even_edges.push_back(*oei); } } } // Since none of the STL containers support both constant-time // concatenation and reversal, the process of expanding an // augmenting path once we know one exists is a little more // complicated than it has to be. If we know the path is from v to // w, then the augmenting path is recursively defined as: // // path(v,w) = [v], if v = w // = concat([v, mate[v]], path(pred[mate[v]], w), // if v != w and vertex_state[v] == graph::detail::V_EVEN // = concat([v], reverse(path(x,mate[v])), path(y,w)), // if v != w, vertex_state[v] == graph::detail::V_ODD, and bridge[v] = (x,y) // // These next two mutually recursive functions implement this definition. void retrieve_augmenting_path(vertex_descriptor_t v, vertex_descriptor_t w) { if (v == w) aug_path.push_back(v); else if (vertex_state[v] == graph::detail::V_EVEN) { aug_path.push_back(v); aug_path.push_back(mate[v]); retrieve_augmenting_path(pred[mate[v]], w); } else //vertex_state[v] == graph::detail::V_ODD { aug_path.push_back(v); reversed_retrieve_augmenting_path(bridge[v].first, mate[v]); retrieve_augmenting_path(bridge[v].second, w); } } void reversed_retrieve_augmenting_path(vertex_descriptor_t v, vertex_descriptor_t w) { if (v == w) aug_path.push_back(v); else if (vertex_state[v] == graph::detail::V_EVEN) { reversed_retrieve_augmenting_path(pred[mate[v]], w); aug_path.push_back(mate[v]); aug_path.push_back(v); } else //vertex_state[v] == graph::detail::V_ODD { reversed_retrieve_augmenting_path(bridge[v].second, w); retrieve_augmenting_path(bridge[v].first, mate[v]); aug_path.push_back(v); } } //private data members const Graph& g; VertexIndexMap vm; v_size_t n_vertices; //storage for the property maps below std::vector
mate_vector; std::vector
ancestor_of_v_vector; std::vector
ancestor_of_w_vector; std::vector
vertex_state_vector; std::vector
origin_vector; std::vector
pred_vector; std::vector
bridge_vector; std::vector
ds_parent_vector; std::vector
ds_rank_vector; //iterator property maps vertex_to_vertex_map_t mate; vertex_to_esize_map_t ancestor_of_v; vertex_to_esize_map_t ancestor_of_w; vertex_to_int_map_t vertex_state; vertex_to_vertex_map_t origin; vertex_to_vertex_map_t pred; vertex_to_vertex_pair_map_t bridge; vertex_to_vertex_map_t ds_parent_map; vertex_to_vsize_map_t ds_rank_map; vertex_list_t aug_path; edge_list_t even_edges; disjoint_sets< vertex_to_vsize_map_t, vertex_to_vertex_map_t > ds; }; //*************************************************************************** //*************************************************************************** // Initial Matching Functors //*************************************************************************** //*************************************************************************** template
struct greedy_matching { typedef typename graph_traits< Graph >::vertex_descriptor vertex_descriptor_t; typedef typename graph_traits< Graph >::vertex_iterator vertex_iterator_t; typedef typename graph_traits< Graph >::edge_descriptor edge_descriptor_t; typedef typename graph_traits< Graph >::edge_iterator edge_iterator_t; static void find_matching(const Graph& g, MateMap mate) { vertex_iterator_t vi, vi_end; for(tie(vi,vi_end) = vertices(g); vi != vi_end; ++vi) put(mate, *vi, graph_traits
::null_vertex()); edge_iterator_t ei, ei_end; for( tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) { edge_descriptor_t e = *ei; vertex_descriptor_t u = source(e,g); vertex_descriptor_t v = target(e,g); if (get(mate,u) == get(mate,v)) //only way equality can hold is if // mate[u] == mate[v] == null_vertex { put(mate,u,v); put(mate,v,u); } } } }; template
struct extra_greedy_matching { // The "extra greedy matching" is formed by repeating the // following procedure as many times as possible: Choose the // unmatched vertex v of minimum non-zero degree. Choose the // neighbor w of v which is unmatched and has minimum degree over // all of v's neighbors. Add (u,v) to the matching. Ties for // either choice are broken arbitrarily. This procedure takes time // O(m log n), where m is the number of edges in the graph and n // is the number of vertices. typedef typename graph_traits< Graph >::vertex_descriptor vertex_descriptor_t; typedef typename graph_traits< Graph >::vertex_iterator vertex_iterator_t; typedef typename graph_traits< Graph >::edge_descriptor edge_descriptor_t; typedef typename graph_traits< Graph >::edge_iterator edge_iterator_t; typedef std::pair
vertex_pair_t; struct select_first { inline static vertex_descriptor_t select_vertex(const vertex_pair_t p) {return p.first;} }; struct select_second { inline static vertex_descriptor_t select_vertex(const vertex_pair_t p) {return p.second;} }; template
class less_than_by_degree { public: less_than_by_degree(const Graph& g): m_g(g) {} bool operator() (const vertex_pair_t x, const vertex_pair_t y) { return out_degree(PairSelector::select_vertex(x), m_g) < out_degree(PairSelector::select_vertex(y), m_g); } private: const Graph& m_g; }; static void find_matching(const Graph& g, MateMap mate) { typedef std::vector
> directed_edges_vector_t; directed_edges_vector_t edge_list; vertex_iterator_t vi, vi_end; for(tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) put(mate, *vi, graph_traits
::null_vertex()); edge_iterator_t ei, ei_end; for(tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) { edge_descriptor_t e = *ei; vertex_descriptor_t u = source(e,g); vertex_descriptor_t v = target(e,g); edge_list.push_back(std::make_pair(u,v)); edge_list.push_back(std::make_pair(v,u)); } //sort the edges by the degree of the target, then (using a //stable sort) by degree of the source std::sort(edge_list.begin(), edge_list.end(), less_than_by_degree
(g)); std::stable_sort(edge_list.begin(), edge_list.end(), less_than_by_degree
(g)); //construct the extra greedy matching for(typename directed_edges_vector_t::const_iterator itr = edge_list.begin(); itr != edge_list.end(); ++itr) { if (get(mate,itr->first) == get(mate,itr->second)) //only way equality can hold is if mate[itr->first] == mate[itr->second] == null_vertex { put(mate, itr->first, itr->second); put(mate, itr->second, itr->first); } } } }; template
struct empty_matching { typedef typename graph_traits< Graph >::vertex_iterator vertex_iterator_t; static void find_matching(const Graph& g, MateMap mate) { vertex_iterator_t vi, vi_end; for(tie(vi,vi_end) = vertices(g); vi != vi_end; ++vi) put(mate, *vi, graph_traits
::null_vertex()); } }; //*************************************************************************** //*************************************************************************** // Matching Verifiers //*************************************************************************** //*************************************************************************** namespace detail { template
class odd_components_counter : public dfs_visitor<> // This depth-first search visitor will count the number of connected // components with an odd number of vertices. It's used by // maximum_matching_verifier. { public: odd_components_counter(SizeType& c_count): m_count(c_count) { m_count = 0; } template
void start_vertex(Vertex v, Graph&) { m_parity = false; } template
void discover_vertex(Vertex u, Graph&) { m_parity = !m_parity; m_parity ? ++m_count : --m_count; } protected: SizeType& m_count; private: bool m_parity; }; }//namespace detail template
struct no_matching_verifier { inline static bool verify_matching(const Graph& g, MateMap mate, VertexIndexMap vm) { return true;} }; template
struct maximum_cardinality_matching_verifier { template
struct map_vertex_to_ { typedef boost::iterator_property_map
::iterator, VertexIndexMap> type; }; typedef typename graph_traits
::vertex_descriptor vertex_descriptor_t; typedef typename graph_traits
::vertices_size_type v_size_t; typedef typename graph_traits
::vertex_iterator vertex_iterator_t; typedef typename map_vertex_to_
::type vertex_to_int_map_t; typedef typename map_vertex_to_
::type vertex_to_vertex_map_t; template
struct non_odd_vertex { //this predicate is used to create a filtered graph that //excludes vertices labeled "graph::detail::V_ODD" non_odd_vertex() : vertex_state(0) { } non_odd_vertex(VertexStateMap* arg_vertex_state) : vertex_state(arg_vertex_state) { } template
bool operator()(const Vertex& v) const { BOOST_ASSERT(vertex_state); return get(*vertex_state, v) != graph::detail::V_ODD; } VertexStateMap* vertex_state; }; static bool verify_matching(const Graph& g, MateMap mate, VertexIndexMap vm) { //For any graph G, let o(G) be the number of connected //components in G of odd size. For a subset S of G's vertex set //V(G), let (G - S) represent the subgraph of G induced by //removing all vertices in S from G. Let M(G) be the size of the //maximum cardinality matching in G. Then the Tutte-Berge //formula guarantees that // // 2 * M(G) = min ( |V(G)| + |U| + o(G - U) ) // //where the minimum is taken over all subsets U of //V(G). Edmonds' algorithm finds a set U that achieves the //minimum in the above formula, namely the vertices labeled //"ODD." This function runs one iteration of Edmonds' algorithm //to find U, then verifies that the size of the matching given //by mate satisfies the Tutte-Berge formula. //first, make sure it's a valid matching if (!is_a_matching(g,mate,vm)) return false; //We'll try to augment the matching once. This serves two //purposes: first, if we find some augmenting path, the matching //is obviously non-maximum. Second, running edmonds' algorithm //on a graph with no augmenting path will create the //Edmonds-Gallai decomposition that we need as a certificate of //maximality - we can get it by looking at the vertex_state map //that results. edmonds_augmenting_path_finder
augmentor(g,mate,vm); if (augmentor.augment_matching()) return false; std::vector
vertex_state_vector(num_vertices(g)); vertex_to_int_map_t vertex_state(vertex_state_vector.begin(), vm); augmentor.get_vertex_state_map(vertex_state); //count the number of graph::detail::V_ODD vertices v_size_t num_odd_vertices = 0; vertex_iterator_t vi, vi_end; for(tie(vi,vi_end) = vertices(g); vi != vi_end; ++vi) if (vertex_state[*vi] == graph::detail::V_ODD) ++num_odd_vertices; //count the number of connected components with odd cardinality //in the graph without graph::detail::V_ODD vertices non_odd_vertex
filter(&vertex_state); filtered_graph
> fg(g, keep_all(), filter); v_size_t num_odd_components; detail::odd_components_counter
occ(num_odd_components); depth_first_search(fg, visitor(occ).vertex_index_map(vm)); if (2 * matching_size(g,mate,vm) == num_vertices(g) + num_odd_vertices - num_odd_components) return true; else return false; } }; template
class AugmentingPathFinder, template
class InitialMatchingFinder, template
class MatchingVerifier> bool matching(const Graph& g, MateMap mate, VertexIndexMap vm) { InitialMatchingFinder
::find_matching(g,mate); AugmentingPathFinder
augmentor(g,mate,vm); bool not_maximum_yet = true; while(not_maximum_yet) { not_maximum_yet = augmentor.augment_matching(); } augmentor.get_current_matching(mate); return MatchingVerifier
::verify_matching(g,mate,vm); } template
inline bool checked_edmonds_maximum_cardinality_matching(const Graph& g, MateMap mate, VertexIndexMap vm) { return matching < Graph, MateMap, VertexIndexMap, edmonds_augmenting_path_finder, extra_greedy_matching, maximum_cardinality_matching_verifier> (g, mate, vm); } template
inline bool checked_edmonds_maximum_cardinality_matching(const Graph& g, MateMap mate) { return checked_edmonds_maximum_cardinality_matching(g, mate, get(vertex_index,g)); } template
inline void edmonds_maximum_cardinality_matching(const Graph& g, MateMap mate, VertexIndexMap vm) { matching < Graph, MateMap, VertexIndexMap, edmonds_augmenting_path_finder, extra_greedy_matching, no_matching_verifier> (g, mate, vm); } template
inline void edmonds_maximum_cardinality_matching(const Graph& g, MateMap mate) { edmonds_maximum_cardinality_matching(g, mate, get(vertex_index,g)); } }//namespace boost #endif //BOOST_GRAPH_MAXIMUM_CARDINALITY_MATCHING_HPP
max_cardinality_matching.hpp
Page URL
File URL
Prev
60/95
Next
Download
( 29 KB )
Note: The DriveHQ service banners will NOT be displayed if the file owner is a paid member.
Comments
Total ratings:
0
Average rating:
Not Rated
Would you like to comment?
Join DriveHQ
for a free account, or
Logon
if you are already a member.