graph/test/min_cost_max_flow_utils.hpp
Maël Valais 589584b4e4 Fix #11374 and #12038: issues with find_flow_cost(), bundled properties and named parameters (#61)
* trac 11374: find_flow_cost() not working with bundled properties.

When using bundled for Weight and Cost properties, find_flow_cost() coudln't work because the properties had been "hard coded" instead of using generic types.

Fixes https://svn.boost.org/trac/boost/ticket/11374

* trac 12038: max-flow algorithms not working with named parameters.

The named parameter "Capacity" was not working. I just had to reverse the order of get_param_type parameters.

Here are the max-flow algorithms that are curretly not working with the named parameter "Capacity":
- edmonds_karp_max_flow,
- push_relabel_max_flow,
- boykov_kolmogorov_max_flow.

Fixes https://svn.boost.org/trac/boost/ticket/12038

* trac 11374: find_flow_cost() not working with named parameters and bundled properties at the same time.

When using bundled properties as well as named parameters, there was an error.

What happened is that the "named parameters" version of find_flow_cost() was not using a generic return value, hence the error.

Also, the return value_type was using edge_capacity_value instead of edge_weight_value (which is the type of a flow cost).

I fixed it using the trick used for edmonds_karp_max_flow(): add `edge_weight_value` to named_function_params.hpp.

* Unit test find_flow_cost() with bundled properties & named params.

-> unit tests for trac 11374

I used the existing min_cost_max_flow_utils.hpp, but I had to make the graph of getSampleGraph() more generic.

In the first place, I wanted to make a compile-only test but I also made
the test runnable so we check that
- find_flow_cost works() correctly with bundled properties
- successive_shortest_path_nonnegative_weights() also works with bundled properties

To run this test, this is a bit painful...
I had to run the entire graph-related tests.
- I commented the other tests except for graph in ./status/Jamfile.v2
- in this same dir, I ran `../b2`

One issue though: csr_graph_test seems to be broken on my boost copy, I may have an issue with updating the submodules or something...

* Unit test edmond_karp_max_flow with named params & bundled properties.

-> unit tests for trac 12038

As the previous commit, I rely on min_cost_max_flow_utils.hpp.

And I also made a runnable test instead of a simple "compile-time" test.

* Indented with 2 spaces instead of tabs

Thanks for the patch!
2016-07-16 16:18:35 -06:00

146 lines
4.8 KiB
C++

//=======================================================================
// Copyright 2013 University of Warsaw.
// Authors: Piotr Wygocki
//
// 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 SAMPLE_GRAPH_UNDIRECTED_HPP
#define SAMPLE_GRAPH_UNDIRECTED_HPP
#include <iostream>
#include <cstdlib>
#include <boost/graph/adjacency_list.hpp>
namespace boost {
struct SampleGraph {
typedef adjacency_list_traits < vecS, vecS, directedS > Traits;
typedef adjacency_list < vecS, vecS, directedS, no_property,
property < edge_capacity_t, long,
property < edge_residual_capacity_t, long,
property < edge_reverse_t, Traits::edge_descriptor,
property <edge_weight_t, long>
>
>
> > Graph;
typedef property_map < Graph, edge_capacity_t >::type Capacity;
typedef property_map < Graph, edge_residual_capacity_t >::type ResidualCapacity;
typedef property_map < Graph, edge_weight_t >::type Weight;
typedef property_map < Graph, edge_reverse_t>::type Reversed;
typedef boost::graph_traits<Graph>::vertices_size_type size_type;
typedef Traits::vertex_descriptor vertex_descriptor;
template <class Graph, class Weight, class Capacity, class Reversed, class ResidualCapacity>
class EdgeAdder {
public:
EdgeAdder(Graph& g, Weight& w, Capacity& c, Reversed& rev
, ResidualCapacity&) : m_g(g), m_w(w), m_cap(c), m_rev(rev) {}
void addEdge(vertex_descriptor v, vertex_descriptor w, long weight, long capacity) {
Traits::edge_descriptor e,f;
e = add(v, w, weight, capacity);
f = add(w, v, -weight, 0);
m_rev[e] = f;
m_rev[f] = e;
}
private:
Traits::edge_descriptor add(vertex_descriptor v, vertex_descriptor w
, long weight, long capacity)
{
bool b;
Traits::edge_descriptor e;
boost::tie(e, b) = add_edge(vertex(v, m_g), vertex(w, m_g), m_g);
if (!b) {
std::cerr << "Edge between " << v << " and " << w << " already exists." << std::endl;
std::abort();
}
m_cap[e] = capacity;
m_w[e] = weight;
return e;
}
Graph & m_g;
Weight & m_w;
Capacity & m_cap;
Reversed & m_rev;
};
static void getSampleGraph(Graph &g, vertex_descriptor & s, vertex_descriptor & t) {
Capacity capacity = get(edge_capacity, g);
Reversed rev = get(edge_reverse, g);
ResidualCapacity residual_capacity = get(edge_residual_capacity, g);
Weight weight = get(edge_weight, g);
getSampleGraph(g,s,t,capacity,residual_capacity,weight,rev);
}
template <class Graph, class Weight, class Capacity, class Reversed, class ResidualCapacity>
static void
getSampleGraph(Graph &g, vertex_descriptor & s, vertex_descriptor & t,
Capacity capacity, ResidualCapacity residual_capacity, Weight weight, Reversed rev) {
size_type N(6);
for(size_type i = 0; i < N; ++i){
add_vertex(g);
}
s = 0;
t = 5;
EdgeAdder<Graph, Weight, Capacity, Reversed, ResidualCapacity> ea(g, weight, capacity, rev, residual_capacity);
ea.addEdge(0, 1, 4 ,2);
ea.addEdge(0, 2, 2 ,2);
ea.addEdge(1, 3, 2 ,2);
ea.addEdge(1, 4, 1 ,1);
ea.addEdge(2, 3, 1 ,1);
ea.addEdge(2, 4, 1 ,1);
ea.addEdge(3, 5, 4 ,20);
ea.addEdge(4, 5, 2 ,20);
}
static void getSampleGraph2(Graph &g, vertex_descriptor & s, vertex_descriptor & t) {
const boost::graph_traits<Graph>::vertices_size_type N(5);
typedef property_map < Graph, edge_reverse_t >::type Reversed;
for(size_type i = 0; i < N; ++i){
add_vertex(g);
}
Capacity capacity = get(edge_capacity, g);
Reversed rev = get(edge_reverse, g);
ResidualCapacity residual_capacity = get(edge_residual_capacity, g);
Weight weight = get(edge_weight, g);
s = 0;
t = 4;
EdgeAdder<Graph, Weight, Capacity, Reversed, ResidualCapacity> ea(g, weight, capacity, rev, residual_capacity);
ea.addEdge(0, 1, 4 ,2);
ea.addEdge(0, 2, 2 ,2);
ea.addEdge(1, 2, 2 ,2);
ea.addEdge(2, 3, 1 ,1);
ea.addEdge(2, 4, 1 ,1);
ea.addEdge(3, 4, 1 ,1);
ea.addEdge(1, 0, 2 ,2);
ea.addEdge(2, 0, 1 ,1);
ea.addEdge(2, 1, 5 ,2);
ea.addEdge(3, 2, 1 ,1);
ea.addEdge(4, 2, 2 ,2);
ea.addEdge(4, 3, 1 ,3);
}
};
} //boost
#endif /* SAMPLE_GRAPH_UNDIRECTED_HPP */