opBinTree.H

00001 
00002 /*
00003   This file is part of Aleph system
00004 
00005   Copyright (c) 2002, 2003, 2004, 2005, 2006
00006   UNIVERSITY LOS ANDES (ULA) Merida - REPÚBLICA BOLIVARIANA DE VENEZUELA  
00007 
00008   - Center of Studies in Microelectronics & Distributed Systems (CEMISID) 
00009   - ULA Computer Science Department
00010   - FUNDACITE Mérida - Ministerio de Ciencia y Tecnología
00011 
00012   PERMISSION TO USE, COPY, MODIFY AND DISTRIBUTE THIS SOFTWARE AND ITS
00013   DOCUMENTATION IS HEREBY GRANTED, PROVIDED THAT BOTH THE COPYRIGHT
00014   NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES OF THE
00015   SOFTWARE, DERIVATIVE WORKS OR MODIFIED VERSIONS, AND ANY PORTIONS
00016   THEREOF, AND THAT BOTH NOTICES APPEAR IN SUPPORTING DOCUMENTATION.
00017 
00018   Aleph is distributed in the hope that it will be useful, but WITHOUT
00019   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
00020   or FITNESS FOR A PARTICULAR PURPOSE.
00021 
00022   UNIVERSIDAD DE LOS ANDES requests users of this software to return to 
00023 
00024   Leandro Leon
00025   CEMISID 
00026   Ed La Hechicera 
00027   3er piso, ala sur
00028   Facultad de Ingenieria 
00029   Universidad de Los Andes 
00030   Merida - REPÚBLICA BOLIVARIANA DE VENEZUELA    or
00031 
00032   lrleon@ula.ve
00033 
00034   any improvements or extensions that they make and grant Universidad 
00035   de Los Andes (ULA) the rights to redistribute these changes. 
00036 
00037   Aleph is (or was) granted by: 
00038   - Consejo de Desarrollo Cientifico, Humanistico, Tecnico de la ULA 
00039     (CDCHT)
00040   - Fundacite Mérida
00041 */
00042 
00043 
00044 # ifndef OPBINTREE_H 
00045 # define OPBINTREE_H
00046 
00047 # include <tpl_dynArray.H>
00048 
00049 namespace Aleph {
00050 
00051 # define COST(i,j) (cost[(i)*(n+1) + (j)])
00052 # define TREE(i,j) (tree[(i)*(n+1) + (j)])
00053 
00054 static inline double sum_p(double p[], const int & i, const int & j);
00055 
00056     static inline int 
00057 min_index(DynArray <double>&, const int &, const int &, const int &);
00058 
00059     static inline 
00060 void compute_optimal_costs(DynArray <double> & cost, 
00061                            double              p[], 
00062                            const int &         n, 
00063                            DynArray <int>    & tree)
00064 {
00065   int i, j, k;
00066   for (i = 1; i <= n; ++i)
00067     {
00068       COST(i, i - 1) = 0;
00069       TREE(i, i) = i;
00070     }
00071   for (i = 0; i < n; ++i)
00072     for (j = 1; j <= n - i; ++j)
00073       {
00074         k          = j + i;
00075         TREE(j, k) = min_index(cost, j, k, n);
00076         COST(j, k) = sum_p(p, j, k) + 
00077                      COST(j, TREE(j, k) - 1) + COST(TREE(j, k) + 1, k);
00078       }
00079 }
00080 static inline double sum_p(double p[], const int & i, const int & j)
00081 {
00082   double sum = 0.0;
00083 
00084   for (int k = i - 1; k < j; ++k)
00085     sum += p[k];
00086 
00087   return sum;
00088 }
00089 static inline int min_index(DynArray <double>& cost, 
00090                             const int & j, const int & k, const int & n)
00091 {
00092   int ret_val;
00093   double min_sum = 1e32;
00094   double sum;
00095   
00096   for (int i = j; i <= k; ++i)
00097     {
00098       sum = COST(j, i - 1) + COST(i + 1, k);
00099 
00100       if (sum < min_sum)
00101         {
00102           min_sum = sum;
00103           ret_val = i;
00104         }
00105     }
00106 
00107   return ret_val;
00108 }
00109     template<class Node, typename Key> static inline
00110 Node * compute_tree(Key keys[], DynArray<int>& tree, 
00111                     const int & n, const int & i, cons int & j)
00112 {
00113   if (i > j)
00114     return Node::NullPtr;
00115 
00116   Node * root = new Node (keys[TREE(i, j) - 1]);
00117 
00118   LLINK(root) = compute_tree <Node, Key>(keys, tree, n, i, TREE(i, j) - 1);
00119   RLINK(root) = compute_tree <Node, Key>(keys, tree, n, TREE(i, j) + 1, j);
00120 
00121   return root;
00122 }
00141     template <class Node, typename Key>
00142 Node * build_optimal_tree(Key keys[], double p[], const int & n)
00143 {
00144   DynArray <int> tree((n + 1)*(n + 1));
00145   DynArray <double> cost((n + 1)*(n + 1));
00146  
00147   compute_optimal_costs(cost, p, n, tree);
00148 
00149   return compute_tree<Node, Key> (keys, tree, n, 1, n);
00150 }
00151 
00152 
00153 # undef COST
00154 # undef TREE
00155 } // end namespace Aleph
00156 # endif // OPBINTREE_H
00157 

Leandro R. León