mirror of
https://github.com/boostorg/graph.git
synced 2025-05-10 15:34:00 +00:00
Name VERTEX_STATE
to anonymous enum; change brute-force verification to pre-computed answers comparison
This commit is contained in:
parent
650291caf6
commit
4f937d1617
@ -27,7 +27,7 @@
|
|||||||
namespace boost
|
namespace boost
|
||||||
{
|
{
|
||||||
namespace graph { namespace detail {
|
namespace graph { namespace detail {
|
||||||
enum { V_EVEN, V_ODD, V_UNREACHED };
|
enum VERTEX_STATE { V_EVEN, V_ODD, V_UNREACHED };
|
||||||
} } // end namespace graph::detail
|
} } // end namespace graph::detail
|
||||||
|
|
||||||
template <typename Graph, typename MateMap, typename VertexIndexMap>
|
template <typename Graph, typename MateMap, typename VertexIndexMap>
|
||||||
|
@ -54,7 +54,7 @@ namespace boost
|
|||||||
{
|
{
|
||||||
typedef boost::iterator_property_map<typename std::vector<T>::iterator, VertexIndexMap> type;
|
typedef boost::iterator_property_map<typename std::vector<T>::iterator, VertexIndexMap> type;
|
||||||
};
|
};
|
||||||
typedef unsigned short vertex_state_t;
|
typedef typename graph::detail::VERTEX_STATE vertex_state_t;
|
||||||
typedef typename graph_traits<Graph>::vertex_iterator vertex_iterator_t;
|
typedef typename graph_traits<Graph>::vertex_iterator vertex_iterator_t;
|
||||||
typedef typename graph_traits<Graph>::vertex_descriptor vertex_descriptor_t;
|
typedef typename graph_traits<Graph>::vertex_descriptor vertex_descriptor_t;
|
||||||
typedef typename std::vector<vertex_descriptor_t>::const_iterator vertex_vec_iter_t;
|
typedef typename std::vector<vertex_descriptor_t>::const_iterator vertex_vec_iter_t;
|
||||||
@ -77,8 +77,10 @@ namespace boost
|
|||||||
|
|
||||||
typedef boost::shared_ptr<blossom> blossom_ptr_t;
|
typedef boost::shared_ptr<blossom> blossom_ptr_t;
|
||||||
std::vector<blossom_ptr_t> sub_blossoms;
|
std::vector<blossom_ptr_t> sub_blossoms;
|
||||||
edge_property_t dual_var = 0;
|
edge_property_t dual_var;
|
||||||
blossom_ptr_t father = blossom_ptr_t();
|
blossom_ptr_t father;
|
||||||
|
|
||||||
|
blossom() : dual_var(0), father(blossom_ptr_t()) {}
|
||||||
|
|
||||||
// get the base vertex of a blossom by recursively getting
|
// get the base vertex of a blossom by recursively getting
|
||||||
// its base sub-blossom, which is always the first one in
|
// its base sub-blossom, which is always the first one in
|
||||||
@ -123,7 +125,6 @@ namespace boost
|
|||||||
class trivial_blossom : public blossom
|
class trivial_blossom : public blossom
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
trivial_blossom(vertex_descriptor_t v) : trivial_vertex(v) {}
|
trivial_blossom(vertex_descriptor_t v) : trivial_vertex(v) {}
|
||||||
virtual vertex_descriptor_t get_base() const
|
virtual vertex_descriptor_t get_base() const
|
||||||
{
|
{
|
||||||
|
50000
test/weighted_matching.dat
Normal file
50000
test/weighted_matching.dat
Normal file
File diff suppressed because it is too large
Load Diff
@ -10,35 +10,20 @@
|
|||||||
#include <boost/graph/max_cardinality_matching.hpp>
|
#include <boost/graph/max_cardinality_matching.hpp>
|
||||||
#include <boost/graph/maximum_weighted_matching.hpp>
|
#include <boost/graph/maximum_weighted_matching.hpp>
|
||||||
|
|
||||||
#include <iostream> // for std::cout
|
#include <iostream>
|
||||||
#include <boost/property_map/vector_property_map.hpp>
|
#include <fstream>
|
||||||
|
#include <sstream>
|
||||||
#include <boost/graph/adjacency_list.hpp>
|
#include <boost/graph/adjacency_list.hpp>
|
||||||
#include <boost/graph/adjacency_matrix.hpp>
|
#include <boost/graph/adjacency_matrix.hpp>
|
||||||
#include <boost/graph/random.hpp>
|
|
||||||
#include <ctime>
|
|
||||||
#include <boost/random.hpp>
|
|
||||||
#include <boost/test/minimal.hpp>
|
#include <boost/test/minimal.hpp>
|
||||||
|
|
||||||
using namespace boost;
|
using namespace boost;
|
||||||
|
|
||||||
typedef property<edge_weight_t, float, property<edge_index_t, int> > EdgeProperty;
|
typedef property<edge_weight_t, float, property<edge_index_t, int> > EdgeProperty;
|
||||||
|
|
||||||
typedef adjacency_list<vecS,
|
typedef adjacency_list<vecS, vecS, undirectedS, property<vertex_index_t,int>, EdgeProperty> undirected_graph;
|
||||||
vecS,
|
typedef adjacency_list<listS, listS, undirectedS, property<vertex_index_t,int>, EdgeProperty> undirected_list_graph;
|
||||||
undirectedS,
|
typedef adjacency_matrix<undirectedS, property<vertex_index_t,int>, EdgeProperty> undirected_adjacency_matrix_graph;
|
||||||
property<vertex_index_t,int>,
|
|
||||||
EdgeProperty> undirected_graph;
|
|
||||||
|
|
||||||
typedef adjacency_list<listS,
|
|
||||||
listS,
|
|
||||||
undirectedS,
|
|
||||||
property<vertex_index_t,int>,
|
|
||||||
EdgeProperty> undirected_list_graph;
|
|
||||||
|
|
||||||
typedef adjacency_matrix<undirectedS,
|
|
||||||
property<vertex_index_t,int>,
|
|
||||||
EdgeProperty> undirected_adjacency_matrix_graph;
|
|
||||||
|
|
||||||
|
|
||||||
template <typename Graph>
|
template <typename Graph>
|
||||||
struct vertex_index_installer
|
struct vertex_index_installer
|
||||||
@ -46,7 +31,6 @@ struct vertex_index_installer
|
|||||||
static void install(Graph&) {}
|
static void install(Graph&) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
struct vertex_index_installer<undirected_list_graph>
|
struct vertex_index_installer<undirected_list_graph>
|
||||||
{
|
{
|
||||||
@ -73,100 +57,82 @@ void print_graph(const Graph& g)
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename Graph>
|
template <typename Graph>
|
||||||
void weighted_matching_test(typename graph_traits<Graph>::vertices_size_type num_v,
|
void weighted_matching_test(const Graph& g,
|
||||||
typename graph_traits<Graph>::edges_size_type num_e,
|
typename property_traits<typename property_map<Graph, edge_weight_t>::type>::value_type answer)
|
||||||
const std::string& graph_name,
|
|
||||||
boost::mt19937& generator)
|
|
||||||
{
|
{
|
||||||
typedef typename property_map<Graph,vertex_index_t>::type vertex_index_map_t;
|
typedef typename property_map<Graph,vertex_index_t>::type vertex_index_map_t;
|
||||||
typedef vector_property_map< typename graph_traits<Graph>::vertex_descriptor, vertex_index_map_t > mate_t;
|
typedef vector_property_map< typename graph_traits<Graph>::vertex_descriptor, vertex_index_map_t > mate_t;
|
||||||
typedef typename graph_traits<Graph>::vertex_iterator vertex_iterator_t;
|
mate_t mate(num_vertices(g));
|
||||||
typedef typename graph_traits<Graph>::vertex_descriptor vertex_descriptor_t;
|
maximum_weighted_matching(g, mate);
|
||||||
|
bool same_result = (matching_weight_sum(g, mate) == answer);
|
||||||
boost::uniform_int<> distribution(0, num_v-1);
|
|
||||||
boost::variate_generator<boost::mt19937&, boost::uniform_int<> > rand_num(generator, distribution);
|
|
||||||
|
|
||||||
num_e = std::min(num_e, num_v*num_v);
|
|
||||||
typename graph_traits<Graph>::edges_size_type num_edges = 0;
|
|
||||||
bool success;
|
|
||||||
|
|
||||||
Graph g(num_v);
|
|
||||||
vertex_index_installer<Graph>::install(g);
|
|
||||||
|
|
||||||
while (num_edges < num_e)
|
|
||||||
{
|
|
||||||
vertex_descriptor_t u = random_vertex(g, rand_num);
|
|
||||||
vertex_descriptor_t v = random_vertex(g, rand_num);
|
|
||||||
if (u != v)
|
|
||||||
{
|
|
||||||
if (!edge(u,v,g).second)
|
|
||||||
boost::tie(tuples::ignore, success) = add_edge(u, v, EdgeProperty(distribution(generator)), g);
|
|
||||||
else
|
|
||||||
success = false;
|
|
||||||
|
|
||||||
if (success)
|
|
||||||
++num_edges;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//print_graph(g);
|
|
||||||
|
|
||||||
mate_t mate1(num_v), mate2(num_v);
|
|
||||||
|
|
||||||
maximum_weighted_matching(g, mate1);
|
|
||||||
brute_force_maximum_weighted_matching(g, mate2);
|
|
||||||
|
|
||||||
bool same_result = (matching_weight_sum(g, mate1) == matching_weight_sum(g, mate2));
|
|
||||||
BOOST_CHECK(same_result);
|
BOOST_CHECK(same_result);
|
||||||
if (!same_result)
|
if (!same_result)
|
||||||
{
|
{
|
||||||
std::cout << std::endl << "Found a weighted matching of weight sum " << matching_weight_sum(g, mate1) << std::endl
|
mate_t max_mate(num_vertices(g));
|
||||||
<< "While brute-force search found a weighted matching of weight sum " << matching_weight_sum(g, mate2) << std::endl;
|
brute_force_maximum_weighted_matching(g, max_mate);
|
||||||
|
|
||||||
|
std::cout << std::endl << "Found a weighted matching of weight sum " << matching_weight_sum(g, mate) << std::endl
|
||||||
|
<< "While brute-force search found a weighted matching of weight sum " << matching_weight_sum(g, max_mate) << std::endl;
|
||||||
|
|
||||||
|
typedef typename graph_traits<Graph>::vertex_iterator vertex_iterator_t;
|
||||||
vertex_iterator_t vi, vi_end;
|
vertex_iterator_t vi, vi_end;
|
||||||
|
|
||||||
print_graph(g);
|
print_graph(g);
|
||||||
|
|
||||||
std::cout << std::endl << "The algorithmic matching is:" << std::endl;
|
std::cout << std::endl << "The algorithmic matching is:" << std::endl;
|
||||||
for (boost::tie(vi,vi_end) = vertices(g); vi != vi_end; ++vi)
|
for (boost::tie(vi,vi_end) = vertices(g); vi != vi_end; ++vi)
|
||||||
if (mate1[*vi] != graph_traits<Graph>::null_vertex() && *vi < mate1[*vi])
|
if (mate[*vi] != graph_traits<Graph>::null_vertex() && *vi < mate[*vi])
|
||||||
std::cout << "{" << *vi << ", " << mate1[*vi] << "}" << std::endl;
|
std::cout << "{" << *vi << ", " << mate[*vi] << "}" << std::endl;
|
||||||
|
|
||||||
std::cout << std::endl << "The brute-force matching is:" << std::endl;
|
std::cout << std::endl << "The brute-force matching is:" << std::endl;
|
||||||
for (boost::tie(vi,vi_end) = vertices(g); vi != vi_end; ++vi)
|
for (boost::tie(vi,vi_end) = vertices(g); vi != vi_end; ++vi)
|
||||||
if (mate2[*vi] != graph_traits<Graph>::null_vertex() && *vi < mate2[*vi])
|
if (max_mate[*vi] != graph_traits<Graph>::null_vertex() && *vi < max_mate[*vi])
|
||||||
std::cout << "{" << *vi << ", " << mate2[*vi] << "}" << std::endl;
|
std::cout << "{" << *vi << ", " << max_mate[*vi] << "}" << std::endl;
|
||||||
|
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename Graph>
|
||||||
|
Graph make_graph(typename graph_traits<Graph>::vertices_size_type num_v,
|
||||||
|
typename graph_traits<Graph>::edges_size_type num_e,
|
||||||
|
std::deque<std::size_t> input_edges)
|
||||||
|
{
|
||||||
|
Graph g(num_v);
|
||||||
|
vertex_index_installer<Graph>::install(g);
|
||||||
|
for (std::size_t i = 0; i < num_e; ++i)
|
||||||
|
{
|
||||||
|
std::size_t src_v, tgt_v, edge_weight;
|
||||||
|
src_v = input_edges.front();
|
||||||
|
input_edges.pop_front();
|
||||||
|
tgt_v = input_edges.front();
|
||||||
|
input_edges.pop_front();
|
||||||
|
edge_weight = input_edges.front();
|
||||||
|
input_edges.pop_front();
|
||||||
|
add_edge(vertex(src_v, g), vertex(tgt_v, g), EdgeProperty(edge_weight), g);
|
||||||
|
}
|
||||||
|
return g;
|
||||||
|
}
|
||||||
|
|
||||||
int test_main(int, char*[])
|
int test_main(int, char*[])
|
||||||
{
|
{
|
||||||
// this test may take quite a while because of the brute-force verifier,
|
std::ifstream in_file("weighted_matching.dat");
|
||||||
// you can also lower the max_num_v and/or max_num_e
|
std::string line;
|
||||||
|
while (std::getline(in_file, line))
|
||||||
std::size_t max_num_v = 16;
|
|
||||||
std::size_t max_num_e = 24;
|
|
||||||
std::size_t batch_size = 16;
|
|
||||||
|
|
||||||
boost::mt19937 generator(static_cast<unsigned int>(std::time(0)));
|
|
||||||
|
|
||||||
for (std::size_t num_v = 1; num_v <= max_num_v; ++num_v)
|
|
||||||
{
|
{
|
||||||
for (std::size_t num_e = num_v-1; num_e <= std::min(max_num_e,num_v*(num_v-1)/2); ++num_e)
|
std::istringstream in_graph(line);
|
||||||
{
|
std::size_t answer, num_v, num_e;
|
||||||
for (std::size_t batch = 0; batch < batch_size; ++batch)
|
in_graph >> answer >> num_v >> num_e;
|
||||||
{
|
|
||||||
weighted_matching_test<undirected_graph>(num_v, num_e, "adjacency_list (using vectors)", generator);
|
std::deque<std::size_t> input_edges;
|
||||||
weighted_matching_test<undirected_list_graph>(num_v, num_e, "adjacency_list (using lists)", generator);
|
std::size_t i;
|
||||||
weighted_matching_test<undirected_adjacency_matrix_graph>(num_v, num_e, "adjacency_matrix", generator);
|
while (in_graph >> i)
|
||||||
}
|
input_edges.push_back(i);
|
||||||
}
|
|
||||||
|
weighted_matching_test(make_graph<undirected_graph>(num_v, num_e, input_edges), answer);
|
||||||
|
weighted_matching_test(make_graph<undirected_list_graph>(num_v, num_e, input_edges), answer);
|
||||||
|
weighted_matching_test(make_graph<undirected_adjacency_matrix_graph>(num_v, num_e, input_edges), answer);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user