Main Page | Namespace List | Class Hierarchy | Compound List | File List | Namespace Members | Compound Members | File Members

pltobtree.cxx

Go to the documentation of this file.
00001 /**************************************************************************
00002 ***    
00003 *** Copyright (c) 1995-2000 Regents of the University of California,
00004 ***               Andrew E. Caldwell, Andrew B. Kahng and Igor L. Markov
00005 *** Copyright (c) 2000-2004 Regents of the University of Michigan,
00006 ***               Saurabh N. Adya, Jarrod A. Roy and Igor L. Markov
00007 ***
00008 ***  Contact author(s): abk@cs.ucsd.edu, imarkov@umich.edu
00009 ***  Original Affiliation:   UCLA, Computer Science Department,
00010 ***                          Los Angeles, CA 90095-1596 USA
00011 ***
00012 ***  Permission is hereby granted, free of charge, to any person obtaining 
00013 ***  a copy of this software and associated documentation files (the
00014 ***  "Software"), to deal in the Software without restriction, including
00015 ***  without limitation 
00016 ***  the rights to use, copy, modify, merge, publish, distribute, sublicense, 
00017 ***  and/or sell copies of the Software, and to permit persons to whom the 
00018 ***  Software is furnished to do so, subject to the following conditions:
00019 ***
00020 ***  The above copyright notice and this permission notice shall be included
00021 ***  in all copies or substantial portions of the Software.
00022 ***
00023 *** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 
00024 *** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
00025 *** OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 
00026 *** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
00027 *** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT
00028 *** OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
00029 *** THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00030 ***
00031 ***
00032 ***************************************************************************/
00033 
00034 
00035 #include "pltobtree.h"
00036 #include "plsptobtree.h"
00037 
00038 #include "debug.h"
00039 
00040 #include <math.h>
00041 #include <vector>
00042 #include <list>
00043 #include <algorithm>
00044 #include <cfloat>
00045 using namespace std;
00046 
00047 const double Pl2BTree::INFTY = basepacking_h::Dimension::INFTY;
00048 const int Pl2BTree::UNDEFINED = basepacking_h::Dimension::UNDEFINED;
00049 const double Pl2BTree::EPSILON_ACCURACY = basepacking_h::Dimension::EPSILON_ACCURACY;
00050 double Pl2BTree::BuildTreeRecord::_epsilon = 0;
00051 // --------------------------------------------------------
00052 void Pl2BTree::heuristic_build_tree()
00053 {
00054    BuildTreeRecord::_epsilon = _epsilon;
00055 
00056    // -----initialize the list-----
00057    vector<BuildTreeRecord> treeRecord(_blocknum+1);
00058    for (int i = 0; i < _blocknum; i++)
00059    {
00060       treeRecord[i].parent = _blocknum;      // set as the LEFT-edge initially
00061       treeRecord[i].treeLocIndex = i;
00062       treeRecord[i].distance = _xloc[i]; // set as its xloc initially
00063 
00064       treeRecord[i].xStart = _xloc[i];
00065       treeRecord[i].xEnd = _xloc[i] + _widths[i];
00066       treeRecord[i].yStart = _yloc[i];
00067       treeRecord[i].yEnd = _yloc[i] + _heights[i];
00068       treeRecord[i].used = false;      
00069    }
00070    treeRecord[_blocknum].parent = UNDEFINED;
00071    treeRecord[_blocknum].treeLocIndex = _blocknum;
00072    treeRecord[_blocknum].distance = 0;
00073 
00074    treeRecord[_blocknum].xStart = 0;
00075    treeRecord[_blocknum].xEnd = 0;
00076    treeRecord[_blocknum].yStart = 0;
00077    treeRecord[_blocknum].yEnd = INFTY;
00078    treeRecord[_blocknum].used = true;
00079 
00080    // determine the real (otree) parent of each node, maybe unchanged
00081    for (int i = 0; i < _blocknum; i++)
00082    {
00083       double minDistance = treeRecord[i].distance;
00084       for (int j = 0; j < _blocknum; j++)
00085       {
00086          if (i != j)
00087          {
00088             // if overlap in y-span occurs (compact to the left)
00089             if (treeRecord[i].yEnd > treeRecord[j].yStart + _epsilon &&
00090                 treeRecord[j].yEnd > treeRecord[i].yStart + _epsilon)
00091             {
00092                double tempDistance =
00093                   BuildTreeRecord::getDistance(treeRecord[i],
00094                                                treeRecord[j]);
00095 
00096                // break ties
00097                if (tempDistance < minDistance)
00098                {
00099                   treeRecord[i].parent = j;
00100                   minDistance = tempDistance;
00101                }
00102             }
00103          }
00104       }
00105    }
00106    
00107    for (int treeNodeCount = 0; treeNodeCount < _blocknum; treeNodeCount++)
00108    {
00109       // -----add a block to the B*-Tree-----
00110       vector<BuildTreeRecord>::iterator min_ptr =
00111          min_element(treeRecord.begin(),
00112                      treeRecord.end(),
00113                      ValidCriterion(treeRecord));
00114 
00115       build_tree_add_block(*min_ptr);
00116       min_ptr->used = true;
00117 
00118       // -----update the rest of the list-----
00119       int currBlock = min_ptr->treeLocIndex;      
00120       for (int tempBlock = 0; tempBlock < _blocknum; tempBlock++)
00121          if (!treeRecord[tempBlock].used)
00122          {
00123             // determine the distance of removed block from this block
00124             double tempDistance =
00125                BuildTreeRecord::getDistance(treeRecord[tempBlock],
00126                                             treeRecord[currBlock]);
00127             
00128             // determine whether to update and update if necessary
00129             treeRecord[tempBlock].distance =
00130                min(treeRecord[tempBlock].distance, tempDistance);
00131          }
00132 
00133 //       OutputBTree(cout, _btree);
00134 //       cin.get();
00135    } // end while (!treeRecord.empty)
00136 }
00137 // --------------------------------------------------------
00138 void Pl2BTree::build_tree_add_block(const Pl2BTree::BuildTreeRecord& btr)
00139 {
00140 //    printf("block %d added with block %d as its otree-parent\n",
00141 //           btr.treeLocIndex, btr.parent);
00142    
00143    int currBlock = btr.treeLocIndex;
00144    int otree_parent = btr.parent;
00145    if (_btree[otree_parent].left == UNDEFINED)
00146    {
00147       _btree[otree_parent].left = currBlock;
00148       _btree[currBlock].parent = otree_parent;
00149    }
00150    else
00151    {
00152       int tree_prev = otree_parent;
00153       int tree_curr = _btree[otree_parent].left;
00154       while ((tree_curr != UNDEFINED) &&
00155              (_yloc[tree_curr] < _yloc[currBlock]))
00156       {
00157          tree_prev = tree_curr;
00158          tree_curr = _btree[tree_curr].right;
00159       }
00160 
00161 //       printf("tree_curr: %d tree_prev: %d\n", tree_curr, tree_prev);
00162 //       printf("YLOC: tree_curr: %.2lf currBlock: %.2lf tree_prev: %.2lf\n",
00163 //              (tree_curr != UNDEFINED)? _yloc[tree_curr] : -1,
00164 //              _yloc[currBlock], _yloc[tree_prev]);
00165       
00166       if ((tree_curr != UNDEFINED) &&
00167           (tree_curr == _btree[tree_prev].left))
00168          _btree[tree_prev].left = currBlock;
00169       else
00170          _btree[tree_prev].right = currBlock;
00171       _btree[currBlock].parent = tree_prev;
00172 
00173       _btree[currBlock].right = tree_curr; // possibly UNDEFINED
00174       if (tree_curr != UNDEFINED)
00175          _btree[tree_curr].parent = currBlock;
00176    }
00177 }
00178 // --------------------------------------------------------
00179 double Pl2BTree::BuildTreeRecord::getDistance(const BuildTreeRecord& btr1, 
00180                                               const BuildTreeRecord& btr2) 
00181 {
00182    double tempDistance = btr1.xStart - btr2.xEnd;// tempXlocStart - currXlocEnd;
00183 
00184    if (btr1.yEnd < btr2.yStart + _epsilon || // only count if y-spans overlap
00185        btr2.yEnd < btr1.yStart + _epsilon)
00186       tempDistance = INFTY;
00187    
00188    else if (tempDistance < -1*_epsilon) // horizontal overlap? not necessary
00189    {
00190       if (btr2.xStart < btr1.xEnd - _epsilon) // horizontal overlap
00191       {
00192          if ((btr1.yEnd > btr2.yStart + _epsilon) &&
00193              (btr1.yStart < btr2.yEnd - _epsilon))
00194             tempDistance = 0;      // real overlap, push it horizontally
00195          else
00196             tempDistance = INFTY;  // no overlap, treat it as no-edge
00197       }
00198       else
00199          tempDistance = INFTY;
00200    }
00201    
00202    return max(tempDistance, 0.0);
00203 }
00204 // --------------------------------------------------------
00205 bool Pl2BTree::BuildTreeRecord::operator <(const BuildTreeRecord& btr) const
00206 {
00207    double difference = distance - btr.distance;
00208    if (fabs(difference) < _epsilon)
00209    {
00210       if (xEnd < btr.xStart + _epsilon) // break ties by x-span (L > R)
00211          return true;
00212       else if (btr.xEnd < xStart + _epsilon)
00213          return false;
00214          
00215       if (yEnd < btr.yStart + _epsilon) // break ties by y-span (T > B)
00216          return true;
00217       else if (btr.yEnd < yStart + _epsilon)
00218          return false;
00219       else
00220          return false;                  // two blocks overlap, whatever
00221    }
00222    else
00223       return difference < 0;
00224 }
00225 // --------------------------------------------------------
00226 bool Pl2BTree::ValidCriterion::operator ()(const BuildTreeRecord& btr1,
00227                                            const BuildTreeRecord& btr2) const
00228 {
00229    if (btr1.used)
00230       return false;
00231    
00232    else if (btr2.used) // btr1 is not used
00233       return true;
00234       
00235    else if (!btr_vec[btr1.parent].used)
00236       return false;
00237 
00238    else if (!btr_vec[btr2.parent].used) // parent of btr1 is used
00239       return true;
00240    
00241    else
00242       return btr1 < btr2;
00243 }
00244 // --------------------------------------------------------
00245 void Pl2BTree::TCG_build_tree()
00246 {
00247    vector< vector<bool> > TCGMatrixVert(_blocknum, vector<bool>(_blocknum, false));
00248    vector< vector<bool> > TCGMatrixHoriz(TCGMatrixVert);
00249 
00250    //set up the immediate constraints
00251    for(int i = 0; i < _blocknum; ++i)
00252    {
00253       for(int j = 0; j <= i; ++j)
00254       {
00255          double horizOverlap = 0;
00256          double vertOverlap = 0;
00257          unsigned vertOverlapDir = 0;
00258          unsigned horizOverlapDir = 0;
00259                   
00260          if (i == j)
00261          {
00262             TCGMatrixHoriz[i][j] = true;
00263             TCGMatrixVert[i][j] = true;
00264             continue;
00265          }
00266 
00267          // i != j
00268          TCGMatrixHoriz[i][j] = false;
00269          TCGMatrixVert[i][j] = false;
00270          TCGMatrixHoriz[j][i] = false;
00271          TCGMatrixVert[j][i] = false;
00272          
00273          double iXStart = _xloc[i];
00274          double iXEnd = _xloc[i] + _widths[i];
00275          double jXStart = _xloc[j];
00276          double jXEnd = _xloc[j] + _widths[j];
00277 
00278          double iYStart = _yloc[i];
00279          double iYEnd = _yloc[i] + _heights[i];
00280          double jYStart = _yloc[j];
00281          double jYEnd = _yloc[j] + _heights[j];
00282 
00283          // horizontal constraint
00284          if (jYStart < iYEnd - _epsilon && iYStart < jYEnd - _epsilon)
00285          {         
00286             if (jYStart < iYStart && jYEnd < iYEnd)
00287             {
00288                vertOverlap = jYEnd - iYStart; // lower overlap (j lower i)
00289                vertOverlapDir = 0; 
00290             }
00291             else if (jYStart > iYStart) // (jYEnd <= iYEnd)
00292             {
00293                vertOverlap = jYEnd - jYStart; // inner overlap (j inner i)
00294                if (iYEnd-jYEnd > jYStart-iYStart)
00295                   vertOverlapDir = 0;
00296                else
00297                   vertOverlapDir = 1;
00298             }
00299             else if (jYEnd > iYEnd) // (jYStart <= iYstart)
00300             {
00301                vertOverlap = iYEnd - jYStart; // upper overlap (j upper i)
00302                vertOverlapDir = 1;
00303             }
00304             else // (jYStart <= iYStart && jYEnd > iYEnd)
00305             {
00306                vertOverlap = iYEnd - iYStart; // outer overlap (j outer i)
00307                if(jYEnd-iYEnd > iYStart-jYStart)
00308                   vertOverlapDir = 1;
00309                else
00310                   vertOverlapDir = 0;
00311             }
00312          }
00313          else
00314             TCGMatrixHoriz[i][j] = false;  // no overlap         
00315 
00316          // vertical constraint
00317          if (jXStart < iXEnd - _epsilon && iXStart < jXEnd - _epsilon)
00318          {            
00319             if (jXStart < iXStart && jXEnd < iXEnd)
00320             {
00321                horizOverlap = jXEnd - iXStart; // left overlap (j left i)
00322                horizOverlapDir = 0; 
00323             }
00324             else if (jXEnd < iXEnd) // (jXStart >= iXStart) 
00325             {
00326                horizOverlap = jXEnd - jXStart; // inner overlap (j inner i)
00327                if (iXEnd-jXEnd > jXStart-iXStart)
00328                   horizOverlapDir = 0;
00329                else
00330                   horizOverlapDir = 1;
00331             }
00332             else if (jXStart > iXStart) // (jXEnd >= iXEnd)
00333             {
00334                horizOverlap = iXEnd - jXStart;  // right overlap (j right i)
00335                horizOverlapDir = 1;
00336             }
00337             else //  (jXStart < iXStart) && (jXEnd >= iXEnd) 
00338             {
00339                horizOverlap = iXEnd - iXStart;  // outer overlap (j out i)
00340                if (jXEnd-iXEnd  > iXStart-jXStart )
00341                   horizOverlapDir = 1;
00342                else
00343                   horizOverlapDir = 0;
00344             }
00345          }
00346          else
00347             TCGMatrixVert[i][j] = false;    // no overlap
00348 
00349          // determine edge in TCG's
00350          if (vertOverlap != 0 && horizOverlap == 0)
00351          {
00352             if (iXStart <= jXStart)
00353                TCGMatrixHoriz[i][j] = true;
00354             else
00355                TCGMatrixHoriz[j][i] = true;
00356          }
00357          else if (horizOverlap != 0 && vertOverlap == 0)
00358          {
00359             if (iYStart <= jYStart)
00360                TCGMatrixVert[i][j] = true;
00361             else
00362                TCGMatrixVert[j][i] = true;
00363          }
00364          // overlapping
00365          else if (horizOverlap != 0 && vertOverlap != 0)
00366          {
00367             if (vertOverlap >= horizOverlap)
00368             {
00369                if (horizOverlapDir == 1)
00370                   TCGMatrixHoriz[i][j] = true;
00371                else
00372                   TCGMatrixHoriz[j][i] = true;
00373             }
00374             else
00375             {
00376                if (vertOverlapDir == 1)
00377                   TCGMatrixVert[i][j] = true;
00378                else
00379                   TCGMatrixVert[j][i] = true;
00380             }
00381          }
00382       }
00383    }
00384     
00385   //floyd marshal to find transitive closure
00386   //TCG_FM(TCGMatrixHoriz, TCGMatrixVert);
00387 
00388   // dynamic programming DFS algo to find transitive closure
00389   TCG_DP(TCGMatrixHoriz);
00390   TCG_DP(TCGMatrixVert);
00391 
00392   // find ties and break them
00393   for(int i = 0; i < _blocknum; ++i)
00394   {
00395      for(int j = 0; j < _blocknum; ++j)
00396      {
00397         if (i == j)
00398            continue;
00399         
00400         if (TCGMatrixHoriz[i][j] && TCGMatrixHoriz[j][i])
00401         {
00402            cout << "ERROR in TCG 1 "<<i<<"\t"<<j<<endl;
00403         }
00404         
00405         if (TCGMatrixVert[i][j] && TCGMatrixVert[j][i])
00406         {
00407            cout<<"ERROR in TCG 2 "<<i<<"\t"<<j<<endl;
00408 
00409         }
00410 
00411         unsigned ctr = 0;
00412         if(TCGMatrixHoriz[i][j])
00413            ++ctr;
00414         if(TCGMatrixHoriz[j][i])
00415            ++ctr;
00416         if(TCGMatrixVert[i][j])
00417            ++ctr;
00418         if(TCGMatrixVert[j][i])
00419            ++ctr;
00420 
00421         if(ctr > 1)
00422         {
00423            unsigned dir = rand()%2;
00424            if(dir == 0) // H constraint
00425            {
00426               TCGMatrixVert[i][j] = false;
00427               TCGMatrixVert[j][i] = false;
00428            }
00429            else // V constraint
00430            {
00431               TCGMatrixHoriz[i][j] = false;
00432               TCGMatrixHoriz[j][i] = false;
00433            }
00434         }
00435           
00436         // no constraint between the blocks
00437         if (!TCGMatrixHoriz[i][j] && !TCGMatrixHoriz[j][i] &&
00438             !TCGMatrixVert[i][j] && !TCGMatrixVert[j][i])
00439         {
00440            TCGMatrixHoriz[i][j] = (_xloc[i] < _xloc[j]);
00441         }
00442      }
00443   }
00444   
00445   // get the sequence pair now
00446   for(int i = 0; i < _blocknum; ++i)
00447   {
00448      _XX[i] = i;
00449      _YY[i] = i;
00450   }  
00451   sort(_XX.begin(), _XX.end(), SPXRelation(TCGMatrixHoriz, TCGMatrixVert));
00452   sort(_YY.begin(), _YY.end(), SPYRelation(TCGMatrixHoriz, TCGMatrixVert));
00453 
00454   PlSP2BTree plsp2btree(_xloc, _yloc, _widths, _heights, _XX, _YY);
00455   _btree = plsp2btree.btree();
00456 }
00457 // --------------------------------------------------------
00458 void Pl2BTree::TCG_DP(vector< vector <bool> >& TCGMatrix)
00459 {
00460    vector< vector <bool> > adjMatrix(TCGMatrix);
00461    vector<int> pre(_blocknum, UNDEFINED);
00462    
00463    for(int i = 0; i < _blocknum; ++i)
00464       fill(TCGMatrix[i].begin(), TCGMatrix[i].end(), false);
00465    
00466    _count = 0;
00467    for(int i = 0; i < _blocknum; ++i)
00468       if(pre[i] == -1)
00469          TCGDfs(TCGMatrix, adjMatrix, i, pre);
00470 }
00471 // --------------------------------------------------------
00472 void Pl2BTree::TCGDfs(vector< vector <bool> >& TCGMatrix, 
00473                       const vector< vector <bool> >& adjMatrix,
00474                       int v,
00475                       vector<int>& pre)
00476 {
00477   pre[v] = _count;
00478   _count++;
00479   for (int u = 0; u < _blocknum; ++u)
00480   {
00481      if (adjMatrix[v][u])
00482      {
00483         TCGMatrix[v][u] = true;
00484         if (pre[u] > pre[v]) // taken care of already
00485            continue;
00486          
00487         if (pre[u] == UNDEFINED)
00488            TCGDfs(TCGMatrix, adjMatrix, u, pre);
00489          
00490         for (int i = 0; i < _blocknum; ++i)
00491            if (TCGMatrix[u][i])
00492               TCGMatrix[v][i] = true;
00493      }
00494   }
00495 }
00496 // --------------------------------------------------------

Generated on Mon Apr 25 01:09:25 2005 for Parquete by doxygen 1.3.2