227TEST_CASE_METHOD(Fixture_object_diamond_with_hole,
"Breadth first visit and search",
"[breadth]" ){
228 GIVEN(
"A diamond object with graph properties" ){
229 using Graph = FixtureObject ;
230 using vertex_descriptor = boost::graph_traits<Graph>::vertex_descriptor ;
231 using vertex_iterator = boost::graph_traits<Graph>::vertex_iterator ;
234 using StdColorMap = std::map< vertex_descriptor, boost::default_color_type > ;
235 StdColorMap colorMap;
236 boost::associative_property_map< StdColorMap > propColorMap( colorMap );
238 using StdDistanceMap = std::map< vertex_descriptor, uint64_t > ;
239 StdDistanceMap distanceMap;
240 boost::associative_property_map< StdDistanceMap > propDistanceMap( distanceMap );
241 boost::queue< vertex_descriptor > Q;
243 vertex_descriptor start {
Point{ 0, 0, 3 } };
245 THEN(
"Test IncidenceGraph interface with breadth_first_search" ){
246 using PredecessorMap = std::map< vertex_descriptor, vertex_descriptor > ;
247 PredecessorMap predecessorMap;
248 boost::associative_property_map< PredecessorMap >
249 propPredecessorMap( predecessorMap );
251 boost::breadth_first_search(
255 boost::make_bfs_visitor( boost::record_predecessors( propPredecessorMap, boost::on_tree_edge() ) ),
259 INFO(
"predecessorMap" );
260 INFO(
"starting point: " << *( obj_fixture.begin() ) );
262 for(
auto && v : predecessorMap){
264 INFO( v.first <<
" : " << v.second );
267 CHECK((visited + 1) == obj_fixture.size());
270 THEN(
"Test IncidenceGraph interface with breadth_first_visit" ){
272 trace.
beginBlock (
"Testing IncidenceGraph interface with breadth_first_visit..." );
273 boost::breadth_first_visit
277 boost::make_bfs_visitor( boost::record_distances( propDistanceMap, boost::on_tree_edge() ) ),
282 vertex_descriptor furthest = start;
284 for ( std::pair<vertex_iterator, vertex_iterator>
285 vp =
boost::vertices( obj_fixture ); vp.first != vp.second; ++vp.first, ++nbV )
287 uint64_t d = boost::get( propDistanceMap, *vp.first );
291 furthest = *vp.first;
295 REQUIRE( nbV == obj_fixture.size() );
296 trace.
info() <<
"- Start: d[ " << start <<
" ] = " << boost::get( propDistanceMap, start) << std::endl;
297 trace.
info() <<
"- Furthest: d[ " << furthest <<
" ] = " << maxD << std::endl;
301 THEN(
"Test Wagner Stoer min-cut"){
303 using vertices_size_type = boost::graph_traits<Graph>::vertices_size_type ;
304 using edge_descriptor = boost::graph_traits<Graph>::edge_descriptor ;
306 trace.
beginBlock (
"Testing UndirectedGraph interface with Wagner-Stoer min cut ..." );
308 using weight_type = double ;
309 using StdWeightMap = std::map< edge_descriptor, weight_type > ;
310 StdWeightMap weightMap;
311 boost::associative_property_map< StdWeightMap > propWeightMap( weightMap );
312 using StdVertexIndexMap = std::map< vertex_descriptor, vertices_size_type > ;
313 StdVertexIndexMap vertexIndexMap;
314 boost::associative_property_map< StdVertexIndexMap > propVertexIndexMap( vertexIndexMap );
315 vertices_size_type idxV = 0;
319 vp.first != vp.second; ++vp.first, ++idxV )
321 vertex_descriptor v1 = *vp.first;
322 vertexIndexMap[ v1 ] = idxV;
324 ve.first != ve.second; ++ve.first )
329 weight_type weight = (
330 (v1[2] == Approx(0) && v2[2] != Approx(0) ) ||
331 (v2[2] == Approx(0) && v1[2] != Approx(0) )
333 weightMap[ *ve.first ] = weight;
334 weightMap[ obj_fixture.opposite( *ve.first ) ] = weight;
339 using StdParityMap = std::map< vertex_descriptor, bool > ;
340 StdParityMap parityMap;
341 boost::associative_property_map< StdParityMap > propParityMap( parityMap );
343 weight_type total_weight =
344 boost::stoer_wagner_min_cut
347 boost::parity_map( propParityMap )
348 .vertex_index_map( propVertexIndexMap )
350 INFO(
"- total weight = " << total_weight);
354 vp.first != vp.second; ++vp.first, ++idxV )
356 vertex_descriptor v1 = *vp.first;
357 if ( parityMap[ v1 ] ) ++nb1;
360 trace.
info() <<
"parityMap: True components: " << nb1 <<
" False: " << nb0 << std::endl;
361 trace.
info() <<
"- parity[ " << start <<
" ] = " << parityMap[ start ] << std::endl;
362 trace.
info() <<
"- parity[ " << furthest <<
" ] = " << parityMap[ furthest ] << std::endl;
363 CHECK( parityMap[start] != parityMap[furthest]);
364 CHECK( total_weight < 1.0);
368 THEN(
"Test Boykov-Kolmogorov max flow"){
370 using edge_iterator = boost::graph_traits<Graph>::edge_iterator ;
371 trace.
beginBlock (
"Testing EdgeListGraph and IncidenceGraph interfaces with Boykov-Kolmogorov max flow ..." );
372 using capacity_type = double ;
374 using StdEdgeCapacityMap = std::map< edge_descriptor, weight_type > ;
375 StdEdgeCapacityMap edgeCapacityMap;
376 boost::associative_property_map< StdEdgeCapacityMap > propEdgeCapacityMap( edgeCapacityMap );
378 using StdEdgeResidualCapacityMap = std::map< edge_descriptor, weight_type > ;
379 StdEdgeResidualCapacityMap edgeResidualCapacityMap;
380 boost::associative_property_map< StdEdgeResidualCapacityMap > propEdgeResidualCapacityMap( edgeResidualCapacityMap );
382 using StdReversedEdgeMap = std::map< edge_descriptor, edge_descriptor > ;
383 StdReversedEdgeMap reversedEdgeMap;
384 boost::associative_property_map< StdReversedEdgeMap > propReversedEdgeMap( reversedEdgeMap );
386 using StdPredecessorMap = std::map< vertex_descriptor, edge_descriptor > ;
387 StdPredecessorMap predecessorMap;
388 boost::associative_property_map< StdPredecessorMap > propPredecessorMap( predecessorMap );
393 for ( std::pair<edge_iterator, edge_iterator>
394 ve =
boost::edges( obj_fixture ); ve.first != ve.second; ++ve.first, ++nbEdges )
396 edge_descriptor e = *ve.first;
397 edge_descriptor rev_e = obj_fixture.opposite( e );
404 capacity_type capacity = (
405 (v1[2] == Approx(0) && v2[2] != Approx(0) ) ||
406 (v2[2] == Approx(0) && v1[2] != Approx(0) )
408 edgeCapacityMap[ e ] = capacity;
409 edgeCapacityMap[ obj_fixture.opposite( e ) ] = capacity;
410 reversedEdgeMap[ e ] = obj_fixture.opposite( e );
411 reversedEdgeMap[ obj_fixture.opposite( e ) ] = e;
414 trace.
info() <<
"- nb edges = " << nbEdges << std::endl;
417 capacity_type max_flow =
418 boost::boykov_kolmogorov_max_flow
420 propEdgeCapacityMap, propEdgeResidualCapacityMap,
421 propReversedEdgeMap, propPredecessorMap, propColorMap, propDistanceMap, propVertexIndexMap,
423 trace.
info() <<
"- max flow = " << max_flow << std::endl;
424 CHECK(abs(max_flow) == Approx(total_weight));
433 GIVEN(
"A diamond object with graph properties and an isolated vertex" ){
434 using Graph = FixtureObject ;
435 using vertex_descriptor = boost::graph_traits<Graph>::vertex_descriptor ;
436 using edge_descriptor = boost::graph_traits<Graph>::edge_descriptor ;
437 using vertices_size_type = boost::graph_traits<Graph>::vertices_size_type ;
440 obj_fixture.pointSet().insertNew(FixtureObject::Point(0,0,7));
442 THEN(
"VertexListGraph interface with connected_components" ){
445 using StdColorMap = std::map< vertex_descriptor, boost::default_color_type > ;
446 StdColorMap colorMap;
447 boost::associative_property_map< StdColorMap > propColorMap( colorMap );
449 using StdComponentMap = std::map< vertex_descriptor, vertices_size_type > ;
450 StdComponentMap componentMap;
451 boost::associative_property_map< StdComponentMap > propComponentMap( componentMap );
452 vertices_size_type nbComp =
453 boost::connected_components
456 boost::color_map( propColorMap )
460 THEN(
"Filter graph and get components" ){
461 using ComponentGraph =
462 boost::filtered_graph<
464 function<bool(edge_descriptor)>,
465 function<bool(vertex_descriptor)>
467 auto &g = obj_fixture;
469 std::vector<ComponentGraph> component_graphs;
471 for (
size_t i = 0; i < nbComp; i++)
472 component_graphs.emplace_back(g,
473 [componentMap,i,&g](edge_descriptor e) {
474 return componentMap.at(boost::source(e,g) )==i
475 || componentMap.at(boost::target(e,g))==i;
477 [componentMap,i](vertex_descriptor v) {
478 return componentMap.at(v)==i;
482 CHECK( component_graphs.size() == 2);
483 std::vector<FixtureObject> obj_components;
485 FixtureObject obj_copy(obj_fixture);
486 obj_copy.pointSet().clear();
489 for (
auto && c : component_graphs){
490 obj_components.push_back(obj_copy);
491 for (
auto && vp =
boost::vertices(c); vp.first != vp.second ; ++vp.first){
492 obj_components.back().pointSet().insertNew(*vp.first);
503 GIVEN(
"A diamond object with graph properties" ){
504 using Graph = FixtureObject ;
505 using vertex_descriptor = boost::graph_traits<Graph>::vertex_descriptor ;
506 using vertices_size_type = boost::graph_traits<Graph>::vertices_size_type ;
507 THEN(
"Test copy_graph"){
509 using StdVertexIndexMap = std::map< vertex_descriptor, vertices_size_type > ;
510 StdVertexIndexMap vertexIndexMap;
511 boost::associative_property_map< StdVertexIndexMap > propVertexIndexMap( vertexIndexMap );
512 using BGraph = boost::adjacency_list< boost::vecS, boost::vecS, boost::undirectedS, VertexProperties > ;
514 boost::copy_graph( obj_fixture, bG,
515 boost::vertex_copy( my_vertex_copier<Graph,BGraph,StdVertexIndexMap>( obj_fixture, bG, vertexIndexMap ) )
516 .edge_copy( my_edge_copier<Graph,BGraph>( obj_fixture, bG ) )
517 .vertex_index_map( propVertexIndexMap )
519 using vertex_descriptor_2 = boost::graph_traits< BGraph >::vertex_descriptor ;
520 using vertex_iterator_2 = boost::graph_traits< BGraph >::vertex_iterator ;
521 using GraphVertexPositionMap = boost::property_map< BGraph, vertex_position_t>::type ;
522 GraphVertexPositionMap vertexPos( boost::get( vertex_position_t(), bG) );
523 for ( std::pair<vertex_iterator_2, vertex_iterator_2>
526 vertex_descriptor_2 v1 = *vp.first;
527 vertex_position pos = boost::get( vertexPos, v1 );
529 INFO(
"after copy: Boost graph has " << num_vertices( bG ) <<
" vertices.");