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

btree.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 
00036 
00037 #include "btree.h"
00038 
00039 #include <iostream>
00040 #include <fstream>
00041 #include <string>
00042 #include <cmath>
00043 #include <float.h>
00044 #include <vector>
00045 #include <algorithm>
00046 using namespace std;
00047 using namespace basepacking_h;
00048 
00049 const int BTree::UNDEFINED = Dimension::UNDEFINED;
00050 // ========================================================
00051 BTree::BTree(const HardBlockInfoType& blockinfo)
00052    : tree(in_tree),
00053      contour(in_contour),
00054      NUM_BLOCKS(blockinfo.blocknum()),
00055      in_blockinfo(blockinfo),
00056      in_tree(blockinfo.blocknum()+2),
00057      in_contour(blockinfo.blocknum()+2),
00058      
00059      in_xloc(blockinfo.blocknum()+2, UNDEFINED),
00060      in_yloc(blockinfo.blocknum()+2, UNDEFINED),
00061      in_width(blockinfo.blocknum()+2, UNDEFINED),
00062      in_height(blockinfo.blocknum()+2, UNDEFINED),
00063      
00064      in_blockArea(blockinfo.blockArea()),
00065      in_totalArea(0),
00066      in_totalWidth(0),
00067      in_totalHeight(0),
00068 
00069      TOLERANCE(0)
00070 {
00071    int vec_size = NUM_BLOCKS+2;
00072    for (int i = 0; i < vec_size; i++)
00073    {
00074       in_tree[i].parent = UNDEFINED;
00075       in_tree[i].left = UNDEFINED;
00076       in_tree[i].right = UNDEFINED;
00077       in_tree[i].block_index = i;
00078       in_tree[i].orient = UNDEFINED;
00079 
00080       in_contour[i].next = UNDEFINED;
00081       in_contour[i].prev = UNDEFINED;
00082       in_contour[i].begin = UNDEFINED;
00083       in_contour[i].end = UNDEFINED;
00084       in_contour[i].CTL = UNDEFINED;
00085    }
00086 
00087    in_contour[NUM_BLOCKS].next = NUM_BLOCKS+1;
00088    in_contour[NUM_BLOCKS].prev = UNDEFINED;
00089    in_contour[NUM_BLOCKS].begin = 0;
00090    in_contour[NUM_BLOCKS].end = 0;
00091    in_contour[NUM_BLOCKS].CTL = Dimension::INFTY;
00092 
00093    in_xloc[NUM_BLOCKS] = 0;
00094    in_yloc[NUM_BLOCKS] = 0;
00095    in_width[NUM_BLOCKS] = 0;
00096    in_height[NUM_BLOCKS] = Dimension::INFTY;
00097    
00098    in_contour[NUM_BLOCKS+1].next = UNDEFINED;
00099    in_contour[NUM_BLOCKS+1].prev = NUM_BLOCKS;
00100    in_contour[NUM_BLOCKS+1].begin = 0;
00101    in_contour[NUM_BLOCKS+1].end = Dimension::INFTY;
00102    in_contour[NUM_BLOCKS+1].CTL = 0;
00103 
00104    in_xloc[NUM_BLOCKS+1] = 0;
00105    in_yloc[NUM_BLOCKS+1] = 0;
00106    in_width[NUM_BLOCKS+1] = Dimension::INFTY;
00107    in_height[NUM_BLOCKS+1] = 0;
00108 }
00109 // --------------------------------------------------------
00110 BTree::BTree(const HardBlockInfoType& blockinfo,
00111              double nTolerance)
00112    : tree(in_tree),
00113      contour(in_contour),
00114      NUM_BLOCKS(blockinfo.blocknum()),
00115      in_blockinfo(blockinfo),
00116      in_tree(blockinfo.blocknum()+2),
00117      in_contour(blockinfo.blocknum()+2),
00118      
00119      in_xloc(blockinfo.blocknum()+2, UNDEFINED),
00120      in_yloc(blockinfo.blocknum()+2, UNDEFINED),
00121      in_width(blockinfo.blocknum()+2, UNDEFINED),
00122      in_height(blockinfo.blocknum()+2, UNDEFINED),
00123      
00124      in_blockArea(blockinfo.blockArea()),
00125      in_totalArea(0),
00126      in_totalWidth(0),
00127      in_totalHeight(0),
00128 
00129      TOLERANCE(nTolerance)
00130 {
00131    int vec_size = NUM_BLOCKS+2;
00132    for (int i = 0; i < vec_size; i++)
00133    {
00134       in_tree[i].parent = UNDEFINED;
00135       in_tree[i].left = UNDEFINED;
00136       in_tree[i].right = UNDEFINED;
00137       in_tree[i].block_index = i;
00138       in_tree[i].orient = UNDEFINED;
00139 
00140       in_contour[i].next = UNDEFINED;
00141       in_contour[i].prev = UNDEFINED;
00142       in_contour[i].begin = UNDEFINED;
00143       in_contour[i].end = UNDEFINED;
00144       in_contour[i].CTL = UNDEFINED;
00145    }
00146 
00147    in_contour[NUM_BLOCKS].next = NUM_BLOCKS+1;
00148    in_contour[NUM_BLOCKS].prev = UNDEFINED;
00149    in_contour[NUM_BLOCKS].begin = 0;
00150    in_contour[NUM_BLOCKS].end = 0;
00151    in_contour[NUM_BLOCKS].CTL = Dimension::INFTY;
00152 
00153    in_xloc[NUM_BLOCKS] = 0;
00154    in_yloc[NUM_BLOCKS] = 0;
00155    in_width[NUM_BLOCKS] = 0;
00156    in_height[NUM_BLOCKS] = Dimension::INFTY;
00157    
00158    in_contour[NUM_BLOCKS+1].next = UNDEFINED;
00159    in_contour[NUM_BLOCKS+1].prev = NUM_BLOCKS;
00160    in_contour[NUM_BLOCKS+1].begin = 0;
00161    in_contour[NUM_BLOCKS+1].end = Dimension::INFTY;
00162    in_contour[NUM_BLOCKS+1].CTL = 0;
00163 
00164    in_xloc[NUM_BLOCKS+1] = 0;
00165    in_yloc[NUM_BLOCKS+1] = 0;
00166    in_width[NUM_BLOCKS+1] = Dimension::INFTY;
00167    in_height[NUM_BLOCKS+1] = 0;
00168 }
00169 // --------------------------------------------------------
00170 void BTree::evaluate(const vector<BTreeNode>& ntree)
00171 {
00172    if (ntree.size() != in_tree.size())
00173    {
00174       cout << "ERROR: size of btree's doesn't match." << endl;
00175       exit(1);
00176    }
00177 
00178    in_tree = ntree;
00179    contour_evaluate();
00180 }  
00181 // --------------------------------------------------------
00182 void BTree::evaluate(const vector<int>& tree_bits,
00183                      const vector<int>& perm,
00184                      const vector<int>& orient)
00185 {
00186    if (int(perm.size()) != NUM_BLOCKS)
00187    {
00188       cout << "ERROR: the permutation length doesn't match with "
00189            << "size of the tree." << endl;
00190       exit(1);
00191    }
00192    bits2tree(tree_bits, perm, orient, in_tree);
00193 //   OutputBTree(cout, in_tree);
00194    contour_evaluate();
00195 }
00196 // --------------------------------------------------------
00197 void BTree::bits2tree(const vector<int>& tree_bits,
00198                        const vector<int>& perm,
00199                        const vector<int>& orient,
00200                        vector<BTreeNode>& ntree)
00201 {
00202    int perm_size = perm.size();
00203    ntree.resize(perm_size+2);
00204    clean_tree(ntree);
00205 
00206    int treePtr = perm_size;
00207    int bitsPtr = 0;
00208 
00209    int lastAct = -1;
00210    for (int i = 0; i < perm_size; i++)
00211    {
00212       int currAct = tree_bits[bitsPtr];
00213       while (currAct == 1)
00214       {
00215          // move up a level/sibling
00216          if (lastAct == 1)
00217             treePtr = ntree[treePtr].parent;
00218 
00219          // move among siblings
00220          while (ntree[treePtr].right != UNDEFINED)
00221             treePtr = ntree[treePtr].parent;
00222          bitsPtr++;
00223          lastAct = 1;
00224          currAct = tree_bits[bitsPtr];
00225       }
00226 
00227       if (lastAct != 1)
00228          ntree[treePtr].left = perm[i];
00229       else // lastAct == 1
00230          ntree[treePtr].right = perm[i];
00231       
00232       ntree[perm[i]].parent = treePtr;
00233       ntree[perm[i]].block_index = perm[i];
00234       ntree[perm[i]].orient = orient[i];
00235 
00236       treePtr = perm[i];
00237       lastAct = 0;
00238       bitsPtr++;
00239    }         
00240 }
00241 // --------------------------------------------------------
00242 void BTree::swap(int indexOne,
00243                  int indexTwo)
00244 {
00245    int indexOne_left = in_tree[indexOne].left;
00246    int indexOne_right = in_tree[indexOne].right;
00247    int indexOne_parent = in_tree[indexOne].parent;
00248 
00249    int indexTwo_left = in_tree[indexTwo].left;
00250    int indexTwo_right = in_tree[indexTwo].right;
00251    int indexTwo_parent = in_tree[indexTwo].parent;
00252 
00253    if (indexOne == indexTwo_parent)
00254       swap_parent_child(indexOne, (indexTwo == in_tree[indexOne].left));
00255    else if (indexTwo == indexOne_parent)
00256       swap_parent_child(indexTwo, (indexOne == in_tree[indexTwo].left));
00257    else
00258    {
00259       // update around indexOne
00260       in_tree[indexOne].parent = indexTwo_parent;
00261       in_tree[indexOne].left = indexTwo_left;
00262       in_tree[indexOne].right = indexTwo_right;
00263 
00264       if (indexOne == in_tree[indexOne_parent].left)
00265          in_tree[indexOne_parent].left = indexTwo;
00266       else
00267          in_tree[indexOne_parent].right = indexTwo;
00268 
00269       if (indexOne_left != UNDEFINED)
00270          in_tree[indexOne_left].parent = indexTwo;
00271       
00272       if (indexOne_right != UNDEFINED)
00273          in_tree[indexOne_right].parent = indexTwo;
00274       
00275       // update around indexTwo
00276       in_tree[indexTwo].parent = indexOne_parent;
00277       in_tree[indexTwo].left = indexOne_left;
00278       in_tree[indexTwo].right = indexOne_right;
00279       
00280       if (indexTwo == in_tree[indexTwo_parent].left)
00281          in_tree[indexTwo_parent].left = indexOne;
00282       else
00283          in_tree[indexTwo_parent].right = indexOne;
00284       
00285       if (indexTwo_left != UNDEFINED)
00286          in_tree[indexTwo_left].parent = indexOne;
00287       
00288       if (indexTwo_right != UNDEFINED)
00289          in_tree[indexTwo_right].parent = indexOne;
00290    }
00291    contour_evaluate();   
00292 }
00293 // --------------------------------------------------------
00294 void BTree::swap_parent_child(int parent,
00295                               bool isLeft)
00296 {
00297    int parent_parent = in_tree[parent].parent;
00298    int parent_left = in_tree[parent].left;
00299    int parent_right = in_tree[parent].right;
00300 
00301    int child = (isLeft)? in_tree[parent].left : in_tree[parent].right;
00302    int child_left = in_tree[child].left;
00303    int child_right = in_tree[child].right;
00304 
00305    if (isLeft)
00306    {
00307       in_tree[parent].parent = child;
00308       in_tree[parent].left = child_left;
00309       in_tree[parent].right = child_right;
00310 
00311       if (parent == in_tree[parent_parent].left)
00312          in_tree[parent_parent].left = child;
00313       else
00314          in_tree[parent_parent].right = child;
00315 
00316       if (parent_right != UNDEFINED)
00317          in_tree[parent_right].parent = child;
00318 
00319       in_tree[child].parent = parent_parent;
00320       in_tree[child].left = parent;
00321       in_tree[child].right = parent_right;
00322 
00323       if (child_left != UNDEFINED)
00324          in_tree[child_left].parent = parent;
00325 
00326       if (child_right != UNDEFINED)
00327          in_tree[child_right].parent = parent;
00328    }
00329    else
00330    {
00331       in_tree[parent].parent = child;
00332       in_tree[parent].left = child_left;
00333       in_tree[parent].right = child_right;
00334 
00335       if (parent == in_tree[parent_parent].left)
00336          in_tree[parent_parent].left = child;
00337       else
00338          in_tree[parent_parent].right = child;
00339 
00340       if (parent_left != UNDEFINED)
00341          in_tree[parent_left].parent = child;
00342 
00343       in_tree[child].parent = parent_parent;
00344       in_tree[child].left = parent_left;
00345       in_tree[child].right = parent;
00346 
00347       if (child_left != UNDEFINED)
00348          in_tree[child_left].parent = parent;
00349 
00350       if (child_right != UNDEFINED)
00351          in_tree[child_right].parent = parent;
00352    }
00353 }
00354 // --------------------------------------------------------
00355 void BTree::move(int index,
00356                  int target,
00357                  bool leftChild)
00358 {
00359    int index_parent = in_tree[index].parent;
00360    int index_left = in_tree[index].left;
00361    int index_right = in_tree[index].right;
00362 
00363    // remove "index" from the tree
00364    if ((index_left != UNDEFINED) && (index_right != UNDEFINED))
00365       remove_left_up_right_down(index);
00366    else if (index_left != UNDEFINED)
00367    {
00368       in_tree[index_left].parent = index_parent;
00369       if (index == in_tree[index_parent].left)
00370          in_tree[index_parent].left = index_left;
00371       else
00372          in_tree[index_parent].right = index_left;
00373    }
00374    else if (index_right != UNDEFINED)
00375    {
00376       in_tree[index_right].parent = index_parent;
00377       if (index == in_tree[index_parent].left)
00378          in_tree[index_parent].left = index_right;
00379       else
00380          in_tree[index_parent].right = index_right;
00381    }
00382    else
00383    {
00384       if (index == in_tree[index_parent].left)
00385          in_tree[index_parent].left = UNDEFINED;
00386       else
00387          in_tree[index_parent].right = UNDEFINED;
00388    }
00389 
00390    int target_left = in_tree[target].left;
00391    int target_right = in_tree[target].right;
00392    
00393    // add "index" to the required location
00394    if (leftChild)
00395    {
00396       in_tree[target].left = index;
00397       if (target_left != UNDEFINED)
00398          in_tree[target_left].parent = index;
00399          
00400       in_tree[index].parent = target;
00401       in_tree[index].left = target_left;
00402       in_tree[index].right = UNDEFINED;
00403    }
00404    else
00405    {
00406       in_tree[target].right = index;
00407       if (target_right != UNDEFINED)
00408          in_tree[target_right].parent = index;
00409 
00410       in_tree[index].parent = target;
00411       in_tree[index].left = UNDEFINED;
00412       in_tree[index].right = target_right;
00413    }
00414    
00415    contour_evaluate();
00416 }
00417 // --------------------------------------------------------
00418 void BTree::remove_left_up_right_down(int index)
00419 {
00420    int index_parent = in_tree[index].parent;
00421    int index_left = in_tree[index].left;
00422    int index_right = in_tree[index].right;
00423 
00424    in_tree[index_left].parent = index_parent;
00425    if (index == in_tree[index_parent].left)
00426       in_tree[index_parent].left = index_left;
00427    else
00428       in_tree[index_parent].right = index_left;
00429 
00430    int ptr = index_left;
00431    while (in_tree[ptr].right != UNDEFINED)
00432       ptr = in_tree[ptr].right;
00433 
00434    in_tree[ptr].right = index_right;
00435    in_tree[index_right].parent = ptr;
00436 }
00437 // --------------------------------------------------------
00438 void BTree::contour_evaluate() // assume the tree is set
00439 {
00440    clean_contour(in_contour);
00441    
00442    int tree_prev = NUM_BLOCKS;
00443    int tree_curr = in_tree[NUM_BLOCKS].left; // start with first block
00444    while (tree_curr != NUM_BLOCKS) // until reach the root again
00445    {
00446 //      cout << "tree_curr: " << tree_curr << endl;
00447       if (tree_prev == in_tree[tree_curr].parent)
00448       {
00449          contour_add_block(tree_curr);
00450          tree_prev = tree_curr;
00451          if (in_tree[tree_curr].left != UNDEFINED)
00452             tree_curr = in_tree[tree_curr].left;
00453          else if (in_tree[tree_curr].right != UNDEFINED)
00454             tree_curr = in_tree[tree_curr].right;
00455          else
00456             tree_curr = in_tree[tree_curr].parent;
00457       }
00458       else if (tree_prev == in_tree[tree_curr].left)
00459       {
00460          tree_prev = tree_curr;
00461          if (in_tree[tree_curr].right != UNDEFINED)
00462             tree_curr = in_tree[tree_curr].right;
00463          else
00464             tree_curr = in_tree[tree_curr].parent;
00465       }
00466       else
00467       {
00468          tree_prev = tree_curr;
00469          tree_curr = in_tree[tree_curr].parent;
00470       }
00471    }
00472    in_totalWidth = in_contour[NUM_BLOCKS+1].begin;
00473 
00474    int contour_ptr = in_contour[NUM_BLOCKS].next;
00475    in_totalHeight = 0;
00476    while (contour_ptr != NUM_BLOCKS+1)
00477    {
00478       in_totalHeight = max(in_totalHeight, in_contour[contour_ptr].CTL);
00479       contour_ptr = in_contour[contour_ptr].next;
00480    }
00481    in_totalArea = in_totalWidth * in_totalHeight;
00482 }
00483 // --------------------------------------------------------
00484 void BTree::contour_add_block(const int tree_ptr)
00485 {
00486    int tree_parent = in_tree[tree_ptr].parent;
00487    double maxCTL = -1;
00488    int contour_ptr = UNDEFINED;
00489    int contour_prev = UNDEFINED;
00490    
00491    if (tree_ptr == in_tree[in_tree[tree_ptr].parent].left)
00492    {
00493       in_contour[tree_ptr].begin = in_contour[tree_parent].end;
00494       contour_ptr = in_contour[tree_parent].next;
00495    }
00496    else
00497    {
00498       in_contour[tree_ptr].begin = in_contour[tree_parent].begin;
00499       contour_ptr = tree_parent;
00500    }
00501    contour_prev = in_contour[contour_ptr].prev; // begins of cPtr/tPtr match
00502    maxCTL = in_contour[contour_ptr].CTL;
00503 
00504    int block = in_tree[tree_ptr].block_index;
00505    int theta = in_tree[tree_ptr].orient;
00506    in_contour[tree_ptr].end =
00507       in_contour[tree_ptr].begin + in_blockinfo[block].width[theta];
00508 
00509    while (in_contour[contour_ptr].end <=
00510           in_contour[tree_ptr].end + TOLERANCE)
00511    {
00512       maxCTL = max(maxCTL, in_contour[contour_ptr].CTL);
00513       contour_ptr = in_contour[contour_ptr].next;
00514    }
00515 
00516    if (in_contour[contour_ptr].begin + TOLERANCE < in_contour[tree_ptr].end)
00517       maxCTL = max(maxCTL, in_contour[contour_ptr].CTL);
00518    
00519    in_xloc[tree_ptr] = in_contour[tree_ptr].begin;
00520    in_yloc[tree_ptr] = maxCTL;
00521    in_width[tree_ptr] = in_blockinfo[block].width[theta];
00522    in_height[tree_ptr] = in_blockinfo[block].height[theta];
00523       
00524    in_contour[tree_ptr].CTL =  maxCTL + in_blockinfo[block].height[theta];
00525    in_contour[tree_ptr].next = contour_ptr;
00526    in_contour[contour_ptr].prev = tree_ptr;
00527    in_contour[contour_ptr].begin = in_contour[tree_ptr].end;
00528 
00529    in_contour[tree_ptr].prev = contour_prev;
00530    in_contour[contour_prev].next = tree_ptr;
00531    in_contour[tree_ptr].begin = in_contour[contour_prev].end;
00532 }
00533 // --------------------------------------------------------
00534 void BTree::save_bbb(const string& filename) const
00535 {
00536    ofstream outfile;
00537    outfile.open(filename.c_str());
00538    if (!outfile.good())
00539    {
00540       cout << "ERROR: cannot open file" << filename << endl;
00541       exit(1);
00542    }
00543 
00544    outfile.setf(ios::fixed);
00545    outfile.precision(3);
00546 
00547    outfile << in_totalWidth << endl;
00548    outfile << in_totalHeight << endl;
00549    outfile << NUM_BLOCKS << endl;
00550    for (int i = 0; i < NUM_BLOCKS; i++)
00551       outfile << in_width[i] << " " << in_height[i] << endl;
00552    outfile << endl;
00553 
00554    for (int i = 0; i < NUM_BLOCKS; i++)
00555       outfile << in_xloc[i] << " " << in_yloc[i] << endl;
00556    outfile << endl;
00557 }
00558 // --------------------------------------------------------
00559       
00560 
00561    

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