src/qvdta/qvdisjointset.cpp

Go to the documentation of this file.
00001 /*
00002  *      Copyright (C) 2007. PARP Research Group.
00003  *      <http://perception.inf.um.es>
00004  *      University of Murcia, Spain.
00005  *
00006  *      This file is part of the QVision library.
00007  *
00008  *      QVision is free software: you can redistribute it and/or modify
00009  *      it under the terms of the GNU Lesser General Public License as
00010  *      published by the Free Software Foundation, version 3 of the License.
00011  *
00012  *      QVision is distributed in the hope that it will be useful,
00013  *      but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  *      GNU Lesser General Public License for more details.
00016  *
00017  *      You should have received a copy of the GNU Lesser General Public
00018  *      License along with QVision. If not, see <http://www.gnu.org/licenses/>.
00019  */
00020 
00024 
00025 #include <qvdta/qvdisjointset.h>
00026 #define MIN(X,Y)        (((X)>(Y))?(Y):(X))
00027 #define MAX(X,Y)        (((X)>(Y))?(X):(Y))
00028 
00029 namespace qvdta
00030 {
00031 QVDisjointSet::QVDisjointSet(uInt numElements): elements(numElements), cols(0), rows(0)
00032         {
00033         Q_ASSERT_X(numElements > 0, "QVDisjointSet", "Number of elements equals 0 in constructor");
00034         allocData();
00035         makeSet();
00036         }
00037 
00038 QVDisjointSet::QVDisjointSet(uInt cols, uInt rows): elements(cols*rows), cols(cols), rows(rows)
00039         {
00040         Q_ASSERT_X(cols > 0, "QVDisjointSet", "Number of columns equals 0 in constructor");
00041         Q_ASSERT_X(rows > 0, "QVDisjointSet", "Number of rows equals 0 in constructor");
00042         allocData();
00043         makeSet();
00044         }
00045 
00046 QVDisjointSet::QVDisjointSet(QVGenericImage &image): elements(cols*rows), cols(image.getCols()), rows(image.getRows())
00047         {
00048         Q_ASSERT_X(cols > 0, "QVDisjointSet", "Number of columns equals 0 in constructor");
00049         Q_ASSERT_X(rows > 0, "QVDisjointSet", "Number of rows equals 0 in constructor");
00050         allocData();
00051         makeSet();
00052         }
00053 
00054 QVDisjointSet::~QVDisjointSet()
00055         {
00056         Q_ASSERT_X(parent != 0, "~QVDisjointSet", "Parent array not allocated");
00057         Q_ASSERT_X(rank != 0, "~QVDisjointSet", "Rank array not allocated");
00058         freeData();
00059         }
00060 
00061 uInt QVDisjointSet::unify(uInt index1, uInt index2)
00062         {
00063         Q_ASSERT_X(index1 < elements, "QVDisjointSet::unify", "First index exceeds number of elements");
00064         Q_ASSERT_X(index2 < elements, "QVDisjointSet::unify", "Second index exceeds number of elements");
00065 
00066         uInt root1 = find(index1), root2 = find(index2);
00067 
00068         // Trivial cases
00069         if ( (index1 == index2) || (root1 == root2) )
00070                 return root1;
00071 
00072         // Addon to union-find algorithm to keep count of number of sets with constant cost
00073         sets--;
00074 
00075         Q_ASSERT_X(sets > 0 , "QVDisjointSet::unify", "Number of sets reached 0");
00076         
00077         if (rank[root1] > rank[root2])
00078                 {
00079                 uInt temp = root1;
00080                 root1 = root2;
00081                 root2 = temp;
00082                 }
00083 
00084         Q_ASSERT_X(rank[root1] == MIN(rank[root1], rank[root2]) ,
00085                 "QVDisjointSet::unify", "first root is minimal");
00086         Q_ASSERT_X(rank[root2] == MAX(rank[root1], rank[root2]) ,
00087                 "QVDisjointSet::unify", "first root is maximal");
00088 
00089         if (rank[root1] == rank[root2])
00090                 rank[root2] = rank[root2] +1;
00091 
00092         parent[root1] = root2;
00093         count[root2] += count[root1];
00094 
00095         Q_ASSERT_X(find(index1) == find(index2) , "QVDisjointSet::unify",
00096                 "Parent for indexes don't coincide, after unify");
00097 
00098         return find(index1);
00099         }
00100 
00101 void QVDisjointSet::makeSet()
00102         {
00103         sets = elements;
00104         for (uInt index = 0; index < elements; index++)
00105                 { 
00106                 rank[index] = 0;
00107                 count[index] = 1;
00108                 parent[index] = index;
00109                 }
00110         }
00111 
00112 void QVDisjointSet::allocData()
00113         {
00114         parent = new uInt[elements];
00115         rank = new uInt[elements];
00116         count = new uInt[elements];
00117         }
00118 
00119 void QVDisjointSet::freeData()
00120         {
00121         delete parent;
00122         delete rank;
00123         delete count;
00124         }
00125 
00126 }

Generated on Thu Dec 13 13:06:26 2007 for QVision by  doxygen 1.5.3