00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
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
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
00216 if (lastAct == 1)
00217 treePtr = ntree[treePtr].parent;
00218
00219
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
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
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
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
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
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()
00439 {
00440 clean_contour(in_contour);
00441
00442 int tree_prev = NUM_BLOCKS;
00443 int tree_curr = in_tree[NUM_BLOCKS].left;
00444 while (tree_curr != NUM_BLOCKS)
00445 {
00446
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;
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