diff DEPENDENCIES/generic/include/boost/graph/bipartite.hpp @ 16:2665513ce2d3

Add boost headers
author Chris Cannam
date Tue, 05 Aug 2014 11:11:38 +0100
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DEPENDENCIES/generic/include/boost/graph/bipartite.hpp	Tue Aug 05 11:11:38 2014 +0100
@@ -0,0 +1,381 @@
+/**
+ *
+ * Copyright (c) 2010 Matthias Walter (xammy@xammy.homelinux.net)
+ *
+ * Authors: Matthias Walter
+ *
+ * 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 BOOST_GRAPH_BIPARTITE_HPP
+#define BOOST_GRAPH_BIPARTITE_HPP
+
+#include <utility>
+#include <vector>
+#include <exception>
+#include <boost/graph/properties.hpp>
+#include <boost/graph/adjacency_list.hpp>
+#include <boost/graph/depth_first_search.hpp>
+#include <boost/graph/one_bit_color_map.hpp>
+#include <boost/bind.hpp>
+
+namespace boost {
+
+  namespace detail {
+
+    /**
+     * The bipartite_visitor_error is thrown if an edge cannot be colored.
+     * The witnesses are the edges incident vertices.
+     */
+
+    template <typename Vertex>
+    struct bipartite_visitor_error: std::exception
+    {
+      std::pair <Vertex, Vertex> witnesses;
+
+      bipartite_visitor_error (Vertex a, Vertex b) :
+        witnesses (a, b)
+      {
+
+      }
+
+      const char* what () const throw ()
+      {
+        return "Graph is not bipartite.";
+      }
+    };
+
+    /**
+     * Functor which colors edges to be non-monochromatic.
+     */
+
+    template <typename PartitionMap>
+    struct bipartition_colorize
+    {
+      typedef on_tree_edge event_filter;
+
+      bipartition_colorize (PartitionMap partition_map) :
+        partition_map_ (partition_map)
+      {
+
+      }
+
+      template <typename Edge, typename Graph>
+      void operator() (Edge e, const Graph& g)
+      {
+        typedef typename graph_traits <Graph>::vertex_descriptor vertex_descriptor_t;
+        typedef color_traits <typename property_traits <PartitionMap>::value_type> color_traits;
+
+        vertex_descriptor_t source_vertex = source (e, g);
+        vertex_descriptor_t target_vertex = target (e, g);
+        if (get (partition_map_, source_vertex) == color_traits::white ())
+          put (partition_map_, target_vertex, color_traits::black ());
+        else
+          put (partition_map_, target_vertex, color_traits::white ());
+      }
+
+    private:
+      PartitionMap partition_map_;
+    };
+
+    /**
+     * Creates a bipartition_colorize functor which colors edges
+     * to be non-monochromatic.
+     *
+     * @param partition_map Color map for the bipartition
+     * @return The functor.
+     */
+
+    template <typename PartitionMap>
+    inline bipartition_colorize <PartitionMap> colorize_bipartition (PartitionMap partition_map)
+    {
+      return bipartition_colorize <PartitionMap> (partition_map);
+    }
+
+    /**
+     * Functor which tests an edge to be monochromatic.
+     */
+
+    template <typename PartitionMap>
+    struct bipartition_check
+    {
+      typedef on_back_edge event_filter;
+
+      bipartition_check (PartitionMap partition_map) :
+        partition_map_ (partition_map)
+      {
+
+      }
+
+      template <typename Edge, typename Graph>
+      void operator() (Edge e, const Graph& g)
+      {
+        typedef typename graph_traits <Graph>::vertex_descriptor vertex_descriptor_t;
+
+        vertex_descriptor_t source_vertex = source (e, g);
+        vertex_descriptor_t target_vertex = target (e, g);
+        if (get (partition_map_, source_vertex) == get (partition_map_, target_vertex))
+          throw bipartite_visitor_error <vertex_descriptor_t> (source_vertex, target_vertex);
+      }
+
+    private:
+      PartitionMap partition_map_;
+    };
+
+    /**
+     * Creates a bipartition_check functor which raises an error if a
+     * monochromatic edge is found.
+     *
+     * @param partition_map The map for a bipartition.
+     * @return The functor.
+     */
+
+    template <typename PartitionMap>
+    inline bipartition_check <PartitionMap> check_bipartition (PartitionMap partition_map)
+    {
+      return bipartition_check <PartitionMap> (partition_map);
+    }
+
+    /**
+     * Find the beginning of a common suffix of two sequences
+     * 
+     * @param sequence1 Pair of bidirectional iterators defining the first sequence.
+     * @param sequence2 Pair of bidirectional iterators defining the second sequence.
+     * @return Pair of iterators pointing to the beginning of the common suffix.
+     */
+
+    template <typename BiDirectionalIterator1, typename BiDirectionalIterator2>
+    inline std::pair <BiDirectionalIterator1, BiDirectionalIterator2> reverse_mismatch (std::pair <
+        BiDirectionalIterator1, BiDirectionalIterator1> sequence1, std::pair <BiDirectionalIterator2,
+        BiDirectionalIterator2> sequence2)
+    {
+      if (sequence1.first == sequence1.second || sequence2.first == sequence2.second)
+        return std::make_pair (sequence1.first, sequence2.first);
+
+      BiDirectionalIterator1 iter1 = sequence1.second;
+      BiDirectionalIterator2 iter2 = sequence2.second;
+
+      while (true)
+      {
+        --iter1;
+        --iter2;
+        if (*iter1 != *iter2)
+        {
+          ++iter1;
+          ++iter2;
+          break;
+        }
+        if (iter1 == sequence1.first)
+          break;
+        if (iter2 == sequence2.first)
+          break;
+      }
+
+      return std::make_pair (iter1, iter2);
+    }
+
+  }
+
+  /**
+   * Checks a given graph for bipartiteness and fills the given color map with
+   * white and black according to the bipartition. If the graph is not
+   * bipartite, the contents of the color map are undefined. Runs in linear
+   * time in the size of the graph, if access to the property maps is in
+   * constant time.
+   *
+   * @param graph The given graph.
+   * @param index_map An index map associating vertices with an index.
+   * @param partition_map A color map to fill with the bipartition.
+   * @return true if and only if the given graph is bipartite.
+   */
+
+  template <typename Graph, typename IndexMap, typename PartitionMap>
+  bool is_bipartite (const Graph& graph, const IndexMap index_map, PartitionMap partition_map)
+  {
+    /// General types and variables
+    typedef typename property_traits <PartitionMap>::value_type partition_color_t;
+    typedef typename graph_traits <Graph>::vertex_descriptor vertex_descriptor_t;
+
+    /// Declare dfs visitor
+    //    detail::empty_recorder recorder;
+    //    typedef detail::bipartite_visitor <PartitionMap, detail::empty_recorder> dfs_visitor_t;
+    //    dfs_visitor_t dfs_visitor (partition_map, recorder);
+
+
+    /// Call dfs
+    try
+    {
+      depth_first_search (graph, vertex_index_map (index_map).visitor (make_dfs_visitor (std::make_pair (
+          detail::colorize_bipartition (partition_map), std::make_pair (detail::check_bipartition (partition_map),
+              put_property (partition_map, color_traits <partition_color_t>::white (), on_start_vertex ()))))));
+    }
+    catch (detail::bipartite_visitor_error <vertex_descriptor_t> error)
+    {
+      return false;
+    }
+
+    return true;
+  }
+
+  /**
+   * Checks a given graph for bipartiteness.
+   *
+   * @param graph The given graph.
+   * @param index_map An index map associating vertices with an index.
+   * @return true if and only if the given graph is bipartite.
+   */
+
+  template <typename Graph, typename IndexMap>
+  bool is_bipartite (const Graph& graph, const IndexMap index_map)
+  {
+    typedef one_bit_color_map <IndexMap> partition_map_t;
+    partition_map_t partition_map (num_vertices (graph), index_map);
+
+    return is_bipartite (graph, index_map, partition_map);
+  }
+
+  /**
+   * Checks a given graph for bipartiteness. The graph must
+   * have an internal vertex_index property. Runs in linear time in the
+   * size of the graph, if access to the property maps is in constant time.
+   *
+   * @param graph The given graph.
+   * @return true if and only if the given graph is bipartite.
+   */
+
+  template <typename Graph>
+  bool is_bipartite (const Graph& graph)
+  {
+    return is_bipartite (graph, get (vertex_index, graph));
+  }
+
+  /**
+   * Checks a given graph for bipartiteness and fills a given color map with
+   * white and black according to the bipartition. If the graph is not
+   * bipartite, a sequence of vertices, producing an odd-cycle, is written to
+   * the output iterator. The final iterator value is returned. Runs in linear
+   * time in the size of the graph, if access to the property maps is in
+   * constant time.
+   *
+   * @param graph The given graph.
+   * @param index_map An index map associating vertices with an index.
+   * @param partition_map A color map to fill with the bipartition.
+   * @param result An iterator to write the odd-cycle vertices to.
+   * @return The final iterator value after writing.
+   */
+
+  template <typename Graph, typename IndexMap, typename PartitionMap, typename OutputIterator>
+  OutputIterator find_odd_cycle (const Graph& graph, const IndexMap index_map, PartitionMap partition_map,
+      OutputIterator result)
+  {
+    /// General types and variables
+    typedef typename property_traits <PartitionMap>::value_type partition_color_t;
+    typedef typename graph_traits <Graph>::vertex_descriptor vertex_descriptor_t;
+    typedef typename graph_traits <Graph>::vertex_iterator vertex_iterator_t;
+    vertex_iterator_t vertex_iter, vertex_end;
+
+    /// Declare predecessor map
+    typedef std::vector <vertex_descriptor_t> predecessors_t;
+    typedef iterator_property_map <typename predecessors_t::iterator, IndexMap, vertex_descriptor_t,
+        vertex_descriptor_t&> predecessor_map_t;
+
+    predecessors_t predecessors (num_vertices (graph), graph_traits <Graph>::null_vertex ());
+    predecessor_map_t predecessor_map (predecessors.begin (), index_map);
+
+    /// Initialize predecessor map
+    for (boost::tie (vertex_iter, vertex_end) = vertices (graph); vertex_iter != vertex_end; ++vertex_iter)
+    {
+      put (predecessor_map, *vertex_iter, *vertex_iter);
+    }
+
+    /// Call dfs
+    try
+    {
+      depth_first_search (graph, vertex_index_map (index_map).visitor (make_dfs_visitor (std::make_pair (
+          detail::colorize_bipartition (partition_map), std::make_pair (detail::check_bipartition (partition_map),
+              std::make_pair (put_property (partition_map, color_traits <partition_color_t>::white (),
+                  on_start_vertex ()), record_predecessors (predecessor_map, on_tree_edge ())))))));
+    }
+    catch (detail::bipartite_visitor_error <vertex_descriptor_t> error)
+    {
+      typedef std::vector <vertex_descriptor_t> path_t;
+
+      path_t path1, path2;
+      vertex_descriptor_t next, current;
+
+      /// First path
+      next = error.witnesses.first;
+      do
+      {
+        current = next;
+        path1.push_back (current);
+        next = predecessor_map[current];
+      }
+      while (current != next);
+
+      /// Second path
+      next = error.witnesses.second;
+      do
+      {
+        current = next;
+        path2.push_back (current);
+        next = predecessor_map[current];
+      }
+      while (current != next);
+
+      /// Find beginning of common suffix
+      std::pair <typename path_t::iterator, typename path_t::iterator> mismatch = detail::reverse_mismatch (
+          std::make_pair (path1.begin (), path1.end ()), std::make_pair (path2.begin (), path2.end ()));
+
+      /// Copy the odd-length cycle
+      result = std::copy (path1.begin (), mismatch.first + 1, result);
+      return std::reverse_copy (path2.begin (), mismatch.second, result);
+    }
+
+    return result;
+  }
+
+  /**
+   * Checks a given graph for bipartiteness. If the graph is not bipartite, a
+   * sequence of vertices, producing an odd-cycle, is written to the output
+   * iterator. The final iterator value is returned. Runs in linear time in the
+   * size of the graph, if access to the property maps is in constant time.
+   *
+   * @param graph The given graph.
+   * @param index_map An index map associating vertices with an index.
+   * @param result An iterator to write the odd-cycle vertices to.
+   * @return The final iterator value after writing.
+   */
+
+  template <typename Graph, typename IndexMap, typename OutputIterator>
+  OutputIterator find_odd_cycle (const Graph& graph, const IndexMap index_map, OutputIterator result)
+  {
+    typedef one_bit_color_map <IndexMap> partition_map_t;
+    partition_map_t partition_map (num_vertices (graph), index_map);
+
+    return find_odd_cycle (graph, index_map, partition_map, result);
+  }
+
+  /**
+   * Checks a given graph for bipartiteness. If the graph is not bipartite, a
+   * sequence of vertices, producing an odd-cycle, is written to the output
+   * iterator. The final iterator value is returned. The graph must have an
+   * internal vertex_index property. Runs in linear time in the size of the
+   * graph, if access to the property maps is in constant time.
+   *
+   * @param graph The given graph.
+   * @param result An iterator to write the odd-cycle vertices to.
+   * @return The final iterator value after writing.
+   */
+
+  template <typename Graph, typename OutputIterator>
+  OutputIterator find_odd_cycle (const Graph& graph, OutputIterator result)
+  {
+    return find_odd_cycle (graph, get (vertex_index, graph), result);
+  }
+}
+
+#endif /// BOOST_GRAPH_BIPARTITE_HPP