From bcba5cda051bc21faeaf46ca681aa9038fc63d78 Mon Sep 17 00:00:00 2001 From: Jeremy Siek Date: Mon, 18 Sep 2000 08:24:47 +0000 Subject: [PATCH] pending stuff from Boost Graph Library [SVN r7704] --- .gitattributes | 96 +++++++ .../boost/pending/detail/disjoint_sets.hpp | 83 +++++++ include/boost/pending/disjoint_sets.hpp | 235 ++++++++++++++++++ 3 files changed, 414 insertions(+) create mode 100644 .gitattributes create mode 100644 include/boost/pending/detail/disjoint_sets.hpp create mode 100644 include/boost/pending/disjoint_sets.hpp diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..3e84d7c --- /dev/null +++ b/.gitattributes @@ -0,0 +1,96 @@ +* text=auto !eol svneol=native#text/plain +*.gitattributes text svneol=native#text/plain + +# Scriptish formats +*.bat text svneol=native#text/plain +*.bsh text svneol=native#text/x-beanshell +*.cgi text svneol=native#text/plain +*.cmd text svneol=native#text/plain +*.js text svneol=native#text/javascript +*.php text svneol=native#text/x-php +*.pl text svneol=native#text/x-perl +*.pm text svneol=native#text/x-perl +*.py text svneol=native#text/x-python +*.sh eol=lf svneol=LF#text/x-sh +configure eol=lf svneol=LF#text/x-sh + +# Image formats +*.bmp binary svneol=unset#image/bmp +*.gif binary svneol=unset#image/gif +*.ico binary svneol=unset#image/ico +*.jpeg binary svneol=unset#image/jpeg +*.jpg binary svneol=unset#image/jpeg +*.png binary svneol=unset#image/png +*.tif binary svneol=unset#image/tiff +*.tiff binary svneol=unset#image/tiff +*.svg text svneol=native#image/svg%2Bxml + +# Data formats +*.pdf binary svneol=unset#application/pdf +*.avi binary svneol=unset#video/avi +*.doc binary svneol=unset#application/msword +*.dsp text svneol=crlf#text/plain +*.dsw text svneol=crlf#text/plain +*.eps binary svneol=unset#application/postscript +*.gz binary svneol=unset#application/gzip +*.mov binary svneol=unset#video/quicktime +*.mp3 binary svneol=unset#audio/mpeg +*.ppt binary svneol=unset#application/vnd.ms-powerpoint +*.ps binary svneol=unset#application/postscript +*.psd binary svneol=unset#application/photoshop +*.rdf binary svneol=unset#text/rdf +*.rss text svneol=unset#text/xml +*.rtf binary svneol=unset#text/rtf +*.sln text svneol=native#text/plain +*.swf binary svneol=unset#application/x-shockwave-flash +*.tgz binary svneol=unset#application/gzip +*.vcproj text svneol=native#text/xml +*.vcxproj text svneol=native#text/xml +*.vsprops text svneol=native#text/xml +*.wav binary svneol=unset#audio/wav +*.xls binary svneol=unset#application/vnd.ms-excel +*.zip binary svneol=unset#application/zip + +# Text formats +.htaccess text svneol=native#text/plain +*.bbk text svneol=native#text/xml +*.cmake text svneol=native#text/plain +*.css text svneol=native#text/css +*.dtd text svneol=native#text/xml +*.htm text svneol=native#text/html +*.html text svneol=native#text/html +*.ini text svneol=native#text/plain +*.log text svneol=native#text/plain +*.mak text svneol=native#text/plain +*.qbk text svneol=native#text/plain +*.rst text svneol=native#text/plain +*.sql text svneol=native#text/x-sql +*.txt text svneol=native#text/plain +*.xhtml text svneol=native#text/xhtml%2Bxml +*.xml text svneol=native#text/xml +*.xsd text svneol=native#text/xml +*.xsl text svneol=native#text/xml +*.xslt text svneol=native#text/xml +*.xul text svneol=native#text/xul +*.yml text svneol=native#text/plain +boost-no-inspect text svneol=native#text/plain +CHANGES text svneol=native#text/plain +COPYING text svneol=native#text/plain +INSTALL text svneol=native#text/plain +Jamfile text svneol=native#text/plain +Jamroot text svneol=native#text/plain +Jamfile.v2 text svneol=native#text/plain +Jamrules text svneol=native#text/plain +Makefile* text svneol=native#text/plain +README text svneol=native#text/plain +TODO text svneol=native#text/plain + +# Code formats +*.c text svneol=native#text/plain +*.cpp text svneol=native#text/plain +*.h text svneol=native#text/plain +*.hpp text svneol=native#text/plain +*.ipp text svneol=native#text/plain +*.tpp text svneol=native#text/plain +*.jam text svneol=native#text/plain +*.java text svneol=native#text/plain diff --git a/include/boost/pending/detail/disjoint_sets.hpp b/include/boost/pending/detail/disjoint_sets.hpp new file mode 100644 index 0000000..61042b0 --- /dev/null +++ b/include/boost/pending/detail/disjoint_sets.hpp @@ -0,0 +1,83 @@ +#ifndef BOOST_DETAIL_DISJOINT_SETS_HPP +#define BOOST_DETAIL_DISJOINT_SETS_HPP + +namespace boost { + +namespace detail { + +template +Vertex +find_representative_with_path_halving(ParentPA p, Vertex v) +{ + Vertex parent = get(p, v); + Vertex grandparent = get(p, parent); + while (parent != grandparent) { + put(p, v, grandparent); + v = grandparent; + parent = get(p, v); + grandparent = get(p, parent); + } + return parent; +} + +template +Vertex +find_representative_with_full_compression(ParentPA parent, Vertex v) +{ + Vertex old = v; + Vertex ancestor = get(parent, v); + while (ancestor != v) { + v = ancestor; + ancestor = get(parent, v); + } + v = parent[old]; + while (ancestor != v) { + put(parent, old, ancestor); + old = v; + v = get(parent, old); + } + return ancestor; +} + +/* the postcondition of link sets is: + component_representative(i) == component_representative(j) + */ +template +inline void +link_sets(ParentPA p, RankPA rank, Vertex i, Vertex j, + ComponentRepresentative comp_rep) +{ + i = comp_rep(p, i); + j = comp_rep(p, j); + if (i == j) return; + if (get(rank, i) > get(rank, j)) + put(p, j, i); + else { + put(p, i, j); + if (get(rank, i) == get(rank, j)) + ++at(rank, j); + } +} + +// normalize components has the following postcondidition: +// i >= p[i] +// that is, the representative is the node with the smallest index in its class +// as its precondition it it assumes that the node container is compressed + +template +inline void +normalize_node(ParentPA p, Vertex i) +{ + if (i > get(p,i) || get(p, get(p,i)) != get(p,i)) + put(p,i, get(p, get(p,i))); + else { + put(p, get(p,i), i); + put(p, i, i); + } +} + + } // namespace detail +} // namespace boost + +#endif // BOOST_DETAIL_DISJOINT_SETS_HPP diff --git a/include/boost/pending/disjoint_sets.hpp b/include/boost/pending/disjoint_sets.hpp new file mode 100644 index 0000000..37b6488 --- /dev/null +++ b/include/boost/pending/disjoint_sets.hpp @@ -0,0 +1,235 @@ +// +//======================================================================= +// Copyright 1997, 1998, 1999, 2000 University of Notre Dame. +// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek +// +// This file is part of the Generic Graph Component Library +// +// You should have received a copy of the License Agreement for the +// Generic Graph Component Library along with the software; see the +// file LICENSE. If not, contact Office of Research, University of Notre +// Dame, Notre Dame, IN 46556. +// +// Permission to modify the code and to distribute modified code is +// granted, provided the text of this NOTICE is retained, a notice that +// the code was modified is included with the above COPYRIGHT NOTICE and +// with the COPYRIGHT NOTICE in the LICENSE file, and that the LICENSE +// file is distributed with the modified code. +// +// LICENSOR MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED. +// By way of example, but not limitation, Licensor MAKES NO +// REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY +// PARTICULAR PURPOSE OR THAT THE USE OF THE LICENSED SOFTWARE COMPONENTS +// OR DOCUMENTATION WILL NOT INFRINGE ANY PATENTS, COPYRIGHTS, TRADEMARKS +// OR OTHER RIGHTS. +//======================================================================= +// +#ifndef BOOST_DISJOINT_SETS_HPP +#define BOOST_DISJOINT_SETS_HPP + +#include +#include + +namespace boost { + + struct representative_with_path_halving { + template + Vertex operator()(ParentPA p, Vertex v) { + return detail::find_representative_with_path_halving(pc, v); + } + }; + + struct representative_with_full_path_compression { + template + Vertex operator()(ParentPA p, Vertex v){ + return detail::find_representative_with_full_compression(p, v); + } + }; + + // This is a generalized functor to provide disjoint sets operations + // with "union by rank" and "path compression". A disjoint-set data + // structure maintains a collection S={S1, S2, ..., Sk} of disjoint + // sets. Each set is identified by a representative, which is some + // member of of the set. Sets are represented by rooted trees. Two + // heuristics: "union by rank" and "path compression" are used to + // speed up the operations. + + // Disjoint Set requires two vertex properties for internal use. A + // RankPA and a ParentPA. The RankPA must map Vertex to some Integral type + // (preferably the size_type associated with Vertex). The ParentPA + // must map Vertex to Vertex. + template + class disjoint_sets { + typedef disjoint_sets self; + + inline disjoint_sets() {} + public: + inline disjoint_sets(RankPA r, ParentPA p) + : rank(r), parent(p) {} + + inline disjoint_sets(const self& c) + : rank(c.rank), parent(c.parent) {} + + // Make Set -- Create a singleton set containing vertex x + template + inline void make_set(Element x) + { + put(parent, x, x); + typedef typename property_traits::value_type R; + put(rank, x, R()); + } + + // Link - union the two sets represented by vertex x and y + template + inline void link(Element x, Element y) + { + detail::link_sets(parent, rank, x, y, rep); + } + + // Union-Set - union the two sets containing vertex x and y + template + inline void union_set(Element x, Element y) + { + link(find_set(x), find_set(y)); + } + + // Find-Set - returns the Element representative of the set + // containing Element x and applies path compression. + template + inline Element find_set(Element x) + { + return rep(parent, x); + } + + template + inline std::size_t count_sets(ElementIterator first, ElementIterator last) + { + std::size_t count = 0; + for ( ; first != last; ++first) + if (get(parent, *first) == *first) + ++count; + return count; + } + + template + inline void normalize_sets(ElementIterator first, ElementIterator last) + { + for (; first != last; ++first) + detail::normalize_node(parent, *first); + } + + template + inline void compress_sets(ElementIterator first, ElementIterator last) + { + for (; first != last; ++first) + detail::find_representative_with_full_compression(parent, *first); + } + protected: + RankPA rank; + ParentPA parent; + FindCompress rep; + }; + + + + + template + class disjoint_sets_with_storage + { + typedef typename property_traits::value_type Index; + typedef std::vector ParentContainer; + typedef std::vector RankContainer; + public: + typedef typename ParentContainer::size_type size_type; + + disjoint_sets_with_storage(size_type n = 0, + ID id_ = ID(), + InverseID inv = InverseID()) + : id(id_), id_to_vertex(inv), rank(n, 0), parent(n) + { + for (Index i = 0; i < n; ++i) + parent[i] = i; + } + // note this is not normally needed + template + inline void + make_set(Element x) { + parent[x] = x; + rank[x] = 0; + } + template + inline void + link(Element x, Element y) + { + extend_sets(x,y); + detail::link_sets(parent.begin(), rank.begin(), + get(id,x), get(id,y), rep); + } + template + inline void + union_set(Element x, Element y) { + Element rx = find_set(x); + Element ry = find_set(y); + link(rx, ry); + } + template + inline Element find_set(Element x) { + return id_to_vertex[rep(parent.begin(), get(id,x))]; + } + + template + inline std::size_t count_sets(ElementIterator first, ElementIterator last) + { + std::size_t count = 0; + for ( ; first != last; ++first) + if (parent[*first] == *first) + ++count; + return count; + } + + template + inline void normalize_sets(ElementIterator first, ElementIterator last) + { + for (; first != last; ++first) + detail::normalize_node(parent.begin(), *first); + } + + template + inline void compress_sets(ElementIterator first, ElementIterator last) + { + for (; first != last; ++first) + detail::find_representative_with_full_compression(parent.begin(), + *first); + } + + const ParentContainer& parents() { return parent; } + + protected: + + template + inline void + extend_sets(Element x, Element y) + { + Index needed = get(id,x) > get(id,y) ? get(id,x) + 1 : get(id,y) + 1; + if (needed > parent.size()) { + rank.insert(rank.end(), needed - rank.size(), 0); + for (Index k = parent.size(); k < needed; ++k) + parent.push_back(k); + } + } + + ID id; + InverseID id_to_vertex; + RankContainer rank; + ParentContainer parent; + FindCompress rep; + }; + +} // namespace boost + +#endif // BOOST_DISJOINT_SETS_HPP