minstcutboost.hxx

Go to the documentation of this file.
00001 #pragma once
00002 #ifndef OPENGM_MINSTCUTBOOST_HXX
00003 #define OPENGM_MINSTCUTBOOST_HXX
00004 
00005 #ifndef BOOST_DISABLE_ASSERTS
00006 #define BOOST_DISABLE_ASSERTS
00007 #define USED_BOOST_DISABLE_ASSERTS
00008 #endif  
00009 
00010 #include <queue>
00011 #include <cassert>
00012 
00013 #include <boost/graph/graph_traits.hpp>
00014 #include <boost/graph/one_bit_color_map.hpp>
00015 #include <boost/property_map/property_map.hpp>
00016 #include <boost/typeof/typeof.hpp>
00017 
00018 #include <boost/graph/adjacency_list.hpp>
00019 #include <boost/graph/edmonds_karp_max_flow.hpp>
00020 #include <boost/graph/push_relabel_max_flow.hpp>
00021 #include <boost/graph/boykov_kolmogorov_max_flow.hpp>
00022 
00023 namespace opengm {
00024 
00025    enum BoostMaxFlowAlgorithm {
00026       PUSH_RELABEL, EDMONDS_KARP, KOLMOGOROV
00027    };
00028 
00030    template<class NType, class VType, BoostMaxFlowAlgorithm mfalg>
00031    class MinSTCutBoost {
00032    public:
00033       // Type-Definitions
00034       typedef NType node_type;
00035       typedef VType ValueType;
00036       typedef boost::vecS OutEdgeList;
00037       typedef boost::vecS VertexList;
00038       typedef boost::adjacency_list_traits<OutEdgeList, VertexList, boost::directedS> graph_traits;
00039       typedef graph_traits::edge_descriptor edge_descriptor;
00040       typedef graph_traits::vertex_descriptor vertex_descriptor;
00041 
00043       struct Edge {
00044          Edge() : capacity(ValueType()), residual(ValueType()), reverse(edge_descriptor()) 
00045             {}
00046          ValueType capacity;
00047          ValueType residual;
00048          edge_descriptor reverse;
00049       };
00051 
00052       typedef boost::adjacency_list<OutEdgeList, VertexList, boost::directedS, size_t, Edge> graph_type;
00053       typedef typename boost::graph_traits<graph_type>::edge_iterator edge_iterator;
00054       typedef typename boost::graph_traits<graph_type>::out_edge_iterator out_edge_iterator;
00055 
00056       // Methods
00057       MinSTCutBoost();
00058       MinSTCutBoost(size_t numberOfNodes, size_t numberOfEdges);
00059       void addEdge(node_type, node_type, ValueType);
00060       void calculateCut(std::vector<bool>&);
00061 
00062    private:
00063       // Members
00064       graph_type graph_;
00065       size_t numberOfNodes_;
00066       size_t numberOfEdges_;
00067       static const NType S = 0;
00068       static const NType T = 1;
00069    };
00070 
00071    //*********************
00072    //** Implementation  **
00073    //*********************
00074 
00075    template<class NType, class VType, BoostMaxFlowAlgorithm mfalg>
00076    MinSTCutBoost<NType, VType, mfalg>::MinSTCutBoost() {
00077       numberOfNodes_ = 2;
00078       numberOfEdges_ = 0;
00079    }
00080 
00081    template<class NType, class VType, BoostMaxFlowAlgorithm mfalg>
00082    MinSTCutBoost<NType, VType, mfalg>::MinSTCutBoost(size_t numberOfNodes, size_t numberOfEdges) {
00083       numberOfNodes_ = numberOfNodes;
00084       numberOfEdges_ = numberOfEdges;
00085       graph_ = graph_type(numberOfNodes_);
00086       //std::cout << "#nodes : " << numberOfNodes_ << std::endl;
00087    }
00088 
00089    template<class NType, class VType, BoostMaxFlowAlgorithm mfalg>
00090    void MinSTCutBoost<NType, VType, mfalg>::addEdge(node_type n1, node_type n2, ValueType cost) {
00091       assert(n1 < numberOfNodes_);
00092       assert(n2 < numberOfNodes_);
00093       assert(cost >= 0);
00094       std::pair<edge_descriptor, bool> e = add_edge(n1, n2, graph_);
00095       std::pair<edge_descriptor, bool> er = add_edge(n2, n1, graph_);
00096       graph_[e.first].capacity += cost;
00097       graph_[e.first].reverse = er.first;
00098       graph_[er.first].reverse = e.first;
00099       //std::cout << n1 << "->" << n2 << " : " << cost << std::endl;
00100    }
00101 
00102    template<class NType, class VType, BoostMaxFlowAlgorithm mfalg>
00103    void MinSTCutBoost<NType, VType, mfalg>::calculateCut(std::vector<bool>& segmentation) {
00104       if (mfalg == KOLMOGOROV) {//Kolmogorov
00105          std::vector<boost::default_color_type> color(num_vertices(graph_));
00106          std::vector<edge_descriptor> pred(num_vertices(graph_));
00107          std::vector<vertex_descriptor> dist(num_vertices(graph_));
00108          boykov_kolmogorov_max_flow(graph_,
00109             get(&Edge::capacity, graph_),
00110             get(&Edge::residual, graph_),
00111             get(&Edge::reverse, graph_),
00112             &pred[0],
00113             &color[0],
00114             &dist[0],
00115             get(boost::vertex_index, graph_),
00116             S, T
00117             );
00118          // find (s,t)-cut set
00119          segmentation.resize(num_vertices(graph_));
00120          for (size_t j = 2; j < num_vertices(graph_); ++j) {
00121             if (color[j] == boost::black_color || color[j] == boost::gray_color) {
00122                segmentation[j] = false;
00123             } else if (color[j] == boost::white_color) {
00124                segmentation[j] = true;
00125             }
00126          }
00127       } 
00128       else if (mfalg == PUSH_RELABEL) {// PushRelable
00129 
00130          push_relabel_max_flow(graph_, S, T,
00131             get(&Edge::capacity, graph_),
00132             get(&Edge::residual, graph_),
00133             get(&Edge::reverse, graph_),
00134             get(boost::vertex_index_t(), graph_)
00135             );
00136          // find (s,t)-cut set 
00137          segmentation.resize(num_vertices(graph_), true);
00138          segmentation[S] = false; // source
00139          segmentation[T] = false; // sink
00140          typedef typename boost::property_map<graph_type, boost::vertex_index_t>::type VertexIndexMap;
00141          VertexIndexMap vertexIndexMap = get(boost::vertex_index, graph_);
00142          std::queue<vertex_descriptor> q;
00143          q.push(*(vertices(graph_).first)); // source
00144          while (!q.empty()) {
00145             out_edge_iterator current, end;
00146             tie(current, end) = out_edges(q.front(), graph_);
00147             q.pop();
00148             while (current != end) {
00149                if (graph_[*current].residual > 0) {
00150                   vertex_descriptor v = target(*current, graph_);
00151                   if (vertexIndexMap[v] > 1 && segmentation[vertexIndexMap[v]] == true) {
00152                      segmentation[vertexIndexMap[v]] = false;
00153                      q.push(v);
00154                   }
00155                }
00156                ++current;
00157             }
00158          }
00159       } 
00160       else if (mfalg == EDMONDS_KARP) {//EdmondsKarp
00161          std::vector<boost::default_color_type> color(num_vertices(graph_));
00162          std::vector<edge_descriptor> pred(num_vertices(graph_));
00163          edmonds_karp_max_flow(graph_, S, T,
00164             get(&Edge::capacity, graph_),
00165             get(&Edge::residual, graph_),
00166             get(&Edge::reverse, graph_),
00167             &color[0], &pred[0]
00168             );
00169          // find (s,t)-cut set
00170          segmentation.resize(num_vertices(graph_));
00171          for (size_t j = 2; j < num_vertices(graph_); ++j) {
00172             if (color[j] == boost::black_color) {
00173                segmentation[j] = false;
00174             } else if (color[j] == boost::white_color) {
00175                segmentation[j] = true;
00176             } else {
00177                throw std::runtime_error("At least one vertex is labeled neither black nor white.");
00178             }
00179          }
00180       } 
00181       else {//UNKNOWN MaxFlowalgorithm
00182          throw std::runtime_error("Unknown MaxFlow-algorithm in MinSTCutBoost.hxx");
00183       }
00184       return;
00185    }
00186 
00187 } // namespace opengm
00188 
00189 #ifdef USED_BOOST_DISABLE_ASSERTS
00190 #undef BOOST_DISABLE_ASSERTS
00191 #undef USED_BOOST_DISABLE_ASSERTS
00192 #endif 
00193 
00194 
00195 #endif // #ifndef OPENGM_MINSTCUTBOOST_HXX
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
Generated on Mon Jun 17 16:31:04 2013 for OpenGM by  doxygen 1.6.3