227 {
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 ;
232
233
234 using StdColorMap = std::map< vertex_descriptor, boost::default_color_type > ;
235 StdColorMap colorMap;
236 boost::associative_property_map< StdColorMap > propColorMap( colorMap );
237
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;
242
243 vertex_descriptor start {
Point{ 0, 0, 3 } };
244
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 );
250
251 boost::breadth_first_search(
252 obj_fixture,
253 start,
254 Q,
255 boost::make_bfs_visitor( boost::record_predecessors( propPredecessorMap, boost::on_tree_edge() ) ),
256 propColorMap
257 );
258
259 INFO( "predecessorMap" );
260 INFO( "starting point: " << *( obj_fixture.begin() ) );
261 size_t visited{0};
262 for(auto && v : predecessorMap){
263 ++visited;
264 INFO( v.first << " : " << v.second );
265 }
266
267 CHECK((visited + 1) == obj_fixture.size());
268 }
269
270 THEN( "Test IncidenceGraph interface with breadth_first_visit" ){
271
272 trace.
beginBlock (
"Testing IncidenceGraph interface with breadth_first_visit..." );
273 boost::breadth_first_visit
274 ( obj_fixture,
275 start,
276 Q,
277 boost::make_bfs_visitor( boost::record_distances( propDistanceMap, boost::on_tree_edge() ) ),
278 propColorMap
279 );
280
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 )
286 {
287 uint64_t d = boost::get( propDistanceMap, *vp.first );
288 if ( d > maxD )
289 {
290 maxD = d;
291 furthest = *vp.first;
292 }
293 }
294
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;
298 CHECK( maxD == 6 );
300
301 THEN( "Test Wagner Stoer min-cut"){
302
303 using vertices_size_type = boost::graph_traits<Graph>::vertices_size_type ;
304 using edge_descriptor = boost::graph_traits<Graph>::edge_descriptor ;
305
306 trace.
beginBlock (
"Testing UndirectedGraph interface with Wagner-Stoer min cut ..." );
307
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;
316
317
319 vp.first != vp.second; ++vp.first, ++idxV )
320 {
321 vertex_descriptor v1 = *vp.first;
322 vertexIndexMap[ v1 ] = idxV;
324 ve.first != ve.second; ++ve.first )
325 {
327 if ( v1 < v2 )
328 {
329 weight_type weight = (
330 (v1[2] == Approx(0) && v2[2] != Approx(0) ) ||
331 (v2[2] == Approx(0) && v1[2] != Approx(0) )
332 ) ? 0.01 : 1.0;
333 weightMap[ *ve.first ] = weight;
334 weightMap[ obj_fixture.opposite( *ve.first ) ] = weight;
335 }
336 }
337 }
338
339 using StdParityMap = std::map< vertex_descriptor, bool > ;
340 StdParityMap parityMap;
341 boost::associative_property_map< StdParityMap > propParityMap( parityMap );
342
343 weight_type total_weight =
344 boost::stoer_wagner_min_cut
345 ( obj_fixture,
346 propWeightMap,
347 boost::parity_map( propParityMap )
348 .vertex_index_map( propVertexIndexMap )
349 );
350 INFO( "- total weight = " << total_weight);
354 vp.first != vp.second; ++vp.first, ++idxV )
355 {
356 vertex_descriptor v1 = *vp.first;
357 if ( parityMap[ v1 ] ) ++nb1;
358 else ++nb0;
359 }
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);
365
367
368 THEN( "Test Boykov-Kolmogorov max flow"){
369
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 ;
373
374 using StdEdgeCapacityMap = std::map< edge_descriptor, weight_type > ;
375 StdEdgeCapacityMap edgeCapacityMap;
376 boost::associative_property_map< StdEdgeCapacityMap > propEdgeCapacityMap( edgeCapacityMap );
377
378 using StdEdgeResidualCapacityMap = std::map< edge_descriptor, weight_type > ;
379 StdEdgeResidualCapacityMap edgeResidualCapacityMap;
380 boost::associative_property_map< StdEdgeResidualCapacityMap > propEdgeResidualCapacityMap( edgeResidualCapacityMap );
381
382 using StdReversedEdgeMap = std::map< edge_descriptor, edge_descriptor > ;
383 StdReversedEdgeMap reversedEdgeMap;
384 boost::associative_property_map< StdReversedEdgeMap > propReversedEdgeMap( reversedEdgeMap );
385
386 using StdPredecessorMap = std::map< vertex_descriptor, edge_descriptor > ;
387 StdPredecessorMap predecessorMap;
388 boost::associative_property_map< StdPredecessorMap > propPredecessorMap( predecessorMap );
389
391
392
393 for ( std::pair<edge_iterator, edge_iterator>
394 ve =
boost::edges( obj_fixture ); ve.first != ve.second; ++ve.first, ++nbEdges )
395 {
396 edge_descriptor e = *ve.first;
397 edge_descriptor rev_e = obj_fixture.opposite( e );
402 if ( v1 < v2 )
403 {
404 capacity_type capacity = (
405 (v1[2] == Approx(0) && v2[2] != Approx(0) ) ||
406 (v2[2] == Approx(0) && v1[2] != Approx(0) )
407 ) ? 0.01 : 1.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;
412 }
413 }
414 trace.
info() <<
"- nb edges = " << nbEdges << std::endl;
415 distanceMap.clear();
416 colorMap.clear();
417 capacity_type max_flow =
418 boost::boykov_kolmogorov_max_flow
419 ( obj_fixture,
420 propEdgeCapacityMap, propEdgeResidualCapacityMap,
421 propReversedEdgeMap, propPredecessorMap, propColorMap, propDistanceMap, propVertexIndexMap,
422 start, furthest );
423 trace.
info() <<
"- max flow = " << max_flow << std::endl;
424 CHECK(
abs(max_flow) == Approx(total_weight));
426 }
427 }
428 }
429 }
430}
void beginBlock(const std::string &keyword="")
boost::uint64_t uint64_t
unsigned 64-bit integer.
graph_traits< DGtal::DigitalSurface< TDigitalSurfaceContainer > >::vertex_descriptor source(typename graph_traits< DGtal::DigitalSurface< TDigitalSurfaceContainer > >::edge_descriptor edge, const DGtal::DigitalSurface< TDigitalSurfaceContainer > &digSurf)
graph_traits< DGtal::DigitalSurface< TDigitalSurfaceContainer > >::vertex_descriptor target(typename graph_traits< DGtal::DigitalSurface< TDigitalSurfaceContainer > >::edge_descriptor edge, const DGtal::DigitalSurface< TDigitalSurfaceContainer > &digSurf)