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 #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
00057 vector<BuildTreeRecord> treeRecord(_blocknum+1);
00058 for (int i = 0; i < _blocknum; i++)
00059 {
00060 treeRecord[i].parent = _blocknum;
00061 treeRecord[i].treeLocIndex = i;
00062 treeRecord[i].distance = _xloc[i];
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
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
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
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
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
00119 int currBlock = min_ptr->treeLocIndex;
00120 for (int tempBlock = 0; tempBlock < _blocknum; tempBlock++)
00121 if (!treeRecord[tempBlock].used)
00122 {
00123
00124 double tempDistance =
00125 BuildTreeRecord::getDistance(treeRecord[tempBlock],
00126 treeRecord[currBlock]);
00127
00128
00129 treeRecord[tempBlock].distance =
00130 min(treeRecord[tempBlock].distance, tempDistance);
00131 }
00132
00133
00134
00135 }
00136 }
00137
00138 void Pl2BTree::build_tree_add_block(const Pl2BTree::BuildTreeRecord& btr)
00139 {
00140
00141
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
00162
00163
00164
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;
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;
00183
00184 if (btr1.yEnd < btr2.yStart + _epsilon ||
00185 btr2.yEnd < btr1.yStart + _epsilon)
00186 tempDistance = INFTY;
00187
00188 else if (tempDistance < -1*_epsilon)
00189 {
00190 if (btr2.xStart < btr1.xEnd - _epsilon)
00191 {
00192 if ((btr1.yEnd > btr2.yStart + _epsilon) &&
00193 (btr1.yStart < btr2.yEnd - _epsilon))
00194 tempDistance = 0;
00195 else
00196 tempDistance = INFTY;
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)
00211 return true;
00212 else if (btr.xEnd < xStart + _epsilon)
00213 return false;
00214
00215 if (yEnd < btr.yStart + _epsilon)
00216 return true;
00217 else if (btr.yEnd < yStart + _epsilon)
00218 return false;
00219 else
00220 return false;
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)
00233 return true;
00234
00235 else if (!btr_vec[btr1.parent].used)
00236 return false;
00237
00238 else if (!btr_vec[btr2.parent].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
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
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
00284 if (jYStart < iYEnd - _epsilon && iYStart < jYEnd - _epsilon)
00285 {
00286 if (jYStart < iYStart && jYEnd < iYEnd)
00287 {
00288 vertOverlap = jYEnd - iYStart;
00289 vertOverlapDir = 0;
00290 }
00291 else if (jYStart > iYStart)
00292 {
00293 vertOverlap = jYEnd - jYStart;
00294 if (iYEnd-jYEnd > jYStart-iYStart)
00295 vertOverlapDir = 0;
00296 else
00297 vertOverlapDir = 1;
00298 }
00299 else if (jYEnd > iYEnd)
00300 {
00301 vertOverlap = iYEnd - jYStart;
00302 vertOverlapDir = 1;
00303 }
00304 else
00305 {
00306 vertOverlap = iYEnd - iYStart;
00307 if(jYEnd-iYEnd > iYStart-jYStart)
00308 vertOverlapDir = 1;
00309 else
00310 vertOverlapDir = 0;
00311 }
00312 }
00313 else
00314 TCGMatrixHoriz[i][j] = false;
00315
00316
00317 if (jXStart < iXEnd - _epsilon && iXStart < jXEnd - _epsilon)
00318 {
00319 if (jXStart < iXStart && jXEnd < iXEnd)
00320 {
00321 horizOverlap = jXEnd - iXStart;
00322 horizOverlapDir = 0;
00323 }
00324 else if (jXEnd < iXEnd)
00325 {
00326 horizOverlap = jXEnd - jXStart;
00327 if (iXEnd-jXEnd > jXStart-iXStart)
00328 horizOverlapDir = 0;
00329 else
00330 horizOverlapDir = 1;
00331 }
00332 else if (jXStart > iXStart)
00333 {
00334 horizOverlap = iXEnd - jXStart;
00335 horizOverlapDir = 1;
00336 }
00337 else
00338 {
00339 horizOverlap = iXEnd - iXStart;
00340 if (jXEnd-iXEnd > iXStart-jXStart )
00341 horizOverlapDir = 1;
00342 else
00343 horizOverlapDir = 0;
00344 }
00345 }
00346 else
00347 TCGMatrixVert[i][j] = false;
00348
00349
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
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
00386
00387
00388
00389 TCG_DP(TCGMatrixHoriz);
00390 TCG_DP(TCGMatrixVert);
00391
00392
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)
00425 {
00426 TCGMatrixVert[i][j] = false;
00427 TCGMatrixVert[j][i] = false;
00428 }
00429 else
00430 {
00431 TCGMatrixHoriz[i][j] = false;
00432 TCGMatrixHoriz[j][i] = false;
00433 }
00434 }
00435
00436
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
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])
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