PARP Research Group University of Murcia, Spain


src/qvmath/qvdisjointset.cpp

Go to the documentation of this file.
00001 /*
00002  *      Copyright (C) 2007, 2008. 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 <qvdefines.h>
00026 #include <QVDisjointSet>
00027 
00028 QVDisjointSet::QVDisjointSet(uInt numElements): cols(0), rows(0), elements(numElements)
00029         {
00030         Q_ASSERT_X(numElements > 0, "QVDisjointSet", "Number of elements equals 0 in constructor");
00031         allocData();
00032         makeSet();
00033         }
00034 
00035 QVDisjointSet::QVDisjointSet(uInt cols, uInt rows): cols(cols), rows(rows), elements(cols*rows)
00036         {
00037         Q_ASSERT_X(cols > 0, "QVDisjointSet", "Number of columns equals 0 in constructor");
00038         Q_ASSERT_X(rows > 0, "QVDisjointSet", "Number of rows equals 0 in constructor");
00039         allocData();
00040         makeSet();
00041         }
00042 
00043 QVDisjointSet::QVDisjointSet(const QVGenericImage &image): cols(image.getCols()), rows(image.getRows()), elements(cols*rows)
00044         {
00045         Q_ASSERT_X(cols > 0, "QVDisjointSet", "Number of columns equals 0 in constructor");
00046         Q_ASSERT_X(rows > 0, "QVDisjointSet", "Number of rows equals 0 in constructor");
00047         allocData();
00048         makeSet();
00049         }
00050 
00051 QVDisjointSet::~QVDisjointSet()
00052         {
00053         Q_ASSERT_X(parent != 0, "~QVDisjointSet", "Parent array not allocated");
00054         Q_ASSERT_X(rank != 0, "~QVDisjointSet", "Rank array not allocated");
00055         freeData();
00056         }
00057 
00058 const uInt QVDisjointSet::unify(uInt index1, uInt index2)
00059         {
00060         Q_ASSERT_X(index1 < elements, "QVDisjointSet::unify", "First index exceeds number of elements");
00061         Q_ASSERT_X(index2 < elements, "QVDisjointSet::unify", "Second index exceeds number of elements");
00062 
00063         // Trivial case: elements are the same.
00064         if ( index1 == index2 )
00065                 return index1;
00066 
00067         uInt root1 = find(index1), root2 = find(index2);
00068 
00069         // Trivial case: elements belong to the same set.
00070         if ( root1 == root2 )
00071                 return root1;
00072 
00073         // Addon to union-find algorithm to keep count of number of sets with constant cost
00074         sets--;
00075 
00076         Q_ASSERT_X(sets > 0 , "QVDisjointSet::unify", "Number of sets reached 0");
00077         
00078         if (rank[root1] > rank[root2])
00079                 {
00080                 uInt temp = root1;
00081                 root1 = root2;
00082                 root2 = temp;
00083                 }
00084 
00085         Q_ASSERT_X(rank[root1] == MIN(rank[root1], rank[root2]), "QVDisjointSet::unify", "first root is minimal");
00086         Q_ASSERT_X(rank[root2] == MAX(rank[root1], rank[root2]), "QVDisjointSet::unify", "first root is maximal");
00087 
00088         if (rank[root1] == rank[root2])
00089                 rank[root2] = rank[root2] +1;
00090 
00091         parent[root1] = root2;
00092 
00093         // Addon to union-find algorithm to keep count of cardinality of sets with constant cost
00094         count[root2] += count[root1];
00095 
00096         Q_ASSERT_X(find(index1) == find(index2) , "QVDisjointSet::unify", "Parent for indexes don't coincide, after unify");
00097         Q_ASSERT_X(root2 == find(index1) , "QVDisjointSet::unify", "Root2 is not the root for elements.");
00098 
00099         return root2;
00100         }
00101 
00102 void QVDisjointSet::makeSet()
00103         {
00104         sets = elements;
00105         for (uInt index = 0; index < elements; index++)
00106                 { 
00107                 rank[index] = 0;
00108                 count[index] = 1;
00109                 parent[index] = index;
00110                 }
00111         }
00112 
00113 void QVDisjointSet::allocData()
00114         {
00115         parent = new uInt[elements];
00116         rank = new uInt[elements];
00117         count = new uInt[elements];
00118         }
00119 
00120 void QVDisjointSet::freeData()
00121         {
00122         delete parent;
00123         delete rank;
00124         delete count;
00125         }
00126 



QVision framework. PARP research group, copyright 2007, 2008.