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 "plcompact.h"
00036 #include "basepacking.h"
00037
00038 #include <stdio.h>
00039 #include <math.h>
00040 #include <iostream>
00041 #include <algorithm>
00042 #include <cfloat>
00043 using namespace std;
00044
00045 const double ShiftLegalizer::INFTY = basepacking_h::Dimension::INFTY;
00046 const int ShiftLegalizer::UNDEFINED = basepacking_h::Dimension::UNDEFINED;
00047
00048 const double ShiftBlock::INFTY = basepacking_h::Dimension::INFTY;
00049 const double ShiftBlock::NEG_INFTY = -1 * ShiftBlock::INFTY;
00050 const int ShiftBlock::UNDEFINED = basepacking_h::Dimension::UNDEFINED;
00051
00052 ShiftLegalizer::ShiftLegalizer(const vector<double>& n_xloc,
00053 const vector<double>& n_yloc,
00054 const vector<double>& n_widths,
00055 const vector<double>& n_heights,
00056 double left_bound,
00057 double right_bound,
00058 double top_bound,
00059 double bottom_bound)
00060 : _blocknum(n_xloc.size()),
00061 _xloc(n_xloc),
00062 _yloc(n_yloc),
00063 _widths(n_widths),
00064 _heights(n_heights),
00065 _epsilon(ShiftBlock::INFTY),
00066 _leftBound(left_bound),
00067 _rightBound(right_bound),
00068 _topBound(top_bound),
00069 _bottomBound(bottom_bound)
00070 {
00071 for (int i = 0; i < _blocknum; i++)
00072 _epsilon = min(_epsilon, min(_widths[i], _heights[i]));
00073
00074 _epsilon /= basepacking_h::Dimension::EPSILON_ACCURACY;
00075 }
00076
00077 bool ShiftLegalizer::legalizeAll(ShiftLegalizer::AlgoType algo,
00078 const vector<int>& checkBlks,
00079 vector<int>& badBlks)
00080 {
00081 switch (algo)
00082 {
00083 case NAIVE:
00084 return naiveLegalize(checkBlks, badBlks);
00085
00086 default:
00087 cout << "ERROR: invalid algo specified in ShiftLegalizer::legalizeAll()"
00088 << endl;
00089 exit(1);
00090 break;
00091 }
00092 }
00093
00094 bool ShiftLegalizer::naiveLegalize(const vector<int>& checkBlks,
00095 vector<int>& badBlks)
00096 {
00097 int checkBlkNum = checkBlks.size();
00098 bool success = true;
00099
00100 for (int i = 0; i < checkBlkNum; i++)
00101 putBlockIntoCore(i);
00102
00103 for (int i = 0; i < checkBlkNum; i++)
00104 {
00105 bool thisSuccess = legalizeBlock(checkBlks[i]);
00106 if (!thisSuccess)
00107 badBlks.push_back(checkBlks[i]);
00108 success = success && thisSuccess;
00109 }
00110 return success;
00111 }
00112
00113 bool ShiftLegalizer::legalizeBlock(int currBlk)
00114 {
00115 printf("-----Block %d-----\n", currBlk);
00116
00117
00118 ShiftBlock shift_block(_xloc, _yloc, _widths, _heights,
00119 _leftBound, _rightBound,
00120 _topBound, _bottomBound);
00121 vector<ShiftBlock::ShiftInfo> shiftinfo;
00122 shift_block(currBlk, shiftinfo);
00123
00124 bool existsOverlaps = false;
00125 bool success = false;
00126 ShiftRotateDecision decision;
00127 for (int i = 0; i < ShiftBlock::DIR_NUM; i++)
00128 {
00129
00130 if (fabs(shiftinfo[i].shiftRangeMin) > _epsilon)
00131 {
00132 bool tempSuccess = shiftDecider(ShiftBlock::Directions(i),
00133 shiftinfo, decision);
00134
00135 decision.rotate = false;
00136 success = success || tempSuccess;
00137 existsOverlaps = true;
00138 }
00139 }
00140
00141
00142 if (existsOverlaps && !success)
00143 {
00144
00145 swap(_widths[currBlk], _heights[currBlk]);
00146 double orig_xloc = _xloc[currBlk];
00147 double orig_yloc = _yloc[currBlk];
00148
00149
00150 ShiftBlock shift_block_rotated(_xloc, _yloc, _widths, _heights,
00151 _leftBound, _rightBound,
00152 _topBound, _bottomBound);
00153 vector<ShiftBlock::ShiftInfo> shiftinfo_rotated;
00154 shift_block_rotated(currBlk, shiftinfo_rotated);
00155
00156 existsOverlaps = false;
00157 for (int i = 0; i < ShiftBlock::DIR_NUM; i++)
00158 {
00159
00160 if (fabs(shiftinfo_rotated[i].shiftRangeMin) > _epsilon)
00161 {
00162 bool tempSuccess = shiftDecider(ShiftBlock::Directions(i),
00163 shiftinfo_rotated, decision);
00164
00165 decision.rotate = true;
00166 success = success || tempSuccess;
00167 existsOverlaps = true;
00168 }
00169 }
00170
00171
00172 if (!existsOverlaps)
00173 {
00174 decision.rotate = true;
00175 decision.shiftDir = ShiftBlock::EAST;
00176 decision.shiftExtent = 0;
00177
00178 success = true;
00179 }
00180
00181
00182 swap(_widths[currBlk], _heights[currBlk]);
00183 _xloc[currBlk] = orig_xloc;
00184 _yloc[currBlk] = orig_yloc;
00185 }
00186
00187
00188 if (decision.shiftDir != UNDEFINED)
00189 {
00190 adjustBlock(currBlk, decision);
00191 return true;
00192 }
00193 else if (!existsOverlaps)
00194 return true;
00195 else
00196 return false;
00197 }
00198
00199 bool ShiftLegalizer::shiftDecider(
00200 ShiftBlock::Directions currDir,
00201 const vector<ShiftBlock::ShiftInfo>& shiftinfo,
00202 ShiftRotateDecision& decision) const
00203 {
00204 if (shiftinfo[currDir].shiftRangeMin <
00205 shiftinfo[currDir].shiftRangeMax + _epsilon)
00206 {
00207 if (shiftinfo[currDir].shiftRangeMin < decision.shiftExtent)
00208 {
00209 decision.shiftDir = currDir;
00210 decision.shiftExtent = shiftinfo[currDir].shiftRangeMin;
00211 }
00212 return true;
00213 }
00214 else
00215 return false;
00216 }
00217
00218 void ShiftLegalizer::adjustBlock(int currBlk,
00219 const ShiftRotateDecision& decision)
00220 {
00221 if (decision.rotate)
00222 swap(_widths[currBlk], _heights[currBlk]);
00223
00224 switch (decision.shiftDir)
00225 {
00226 case ShiftBlock::NORTH:
00227 _yloc[currBlk] += decision.shiftExtent;
00228 break;
00229
00230 case ShiftBlock::EAST:
00231 _xloc[currBlk] -= decision.shiftExtent;
00232 break;
00233
00234 case ShiftBlock::SOUTH:
00235 _yloc[currBlk] -= decision.shiftExtent;
00236 break;
00237
00238 case ShiftBlock::WEST:
00239 _xloc[currBlk] += decision.shiftExtent;
00240 break;
00241
00242 default:
00243 cout << "ERROR: invalid direction specified in moveblock()"
00244 << endl;
00245 exit(1);
00246 }
00247 }
00248
00249 void ShiftLegalizer::putBlockIntoCore(int currBlk)
00250 {
00251 _xloc[currBlk] = max(_xloc[currBlk], _leftBound);
00252 _xloc[currBlk] = min(_xloc[currBlk], _rightBound-_widths[currBlk]);
00253
00254 _yloc[currBlk] = max(_yloc[currBlk], _bottomBound);
00255 _yloc[currBlk] = min(_yloc[currBlk], _topBound-_heights[currBlk]);
00256 }
00257
00258 ShiftBlock::ShiftBlock(const vector<double>& xloc,
00259 const vector<double>& yloc,
00260 const vector<double>& widths,
00261 const vector<double>& heights,
00262 double left_bound,
00263 double right_bound,
00264 double top_bound,
00265 double bottom_bound)
00266 : _blocknum(xloc.size()),
00267 _xStart(_blocknum+4),
00268 _xEnd(_blocknum+4),
00269 _yStart(_blocknum+4),
00270 _yEnd(_blocknum+4),
00271 _epsilon(INFTY)
00272 {
00273 for (int i = 0; i < _blocknum; i++)
00274 {
00275 _xStart[i] = xloc[i];
00276 _xEnd[i] = xloc[i] + widths[i];
00277 _yStart[i] = yloc[i];
00278 _yEnd[i] = yloc[i] + heights[i];
00279
00280 _epsilon = min(_epsilon, min(widths[i], heights[i]));
00281 }
00282 _epsilon /= basepacking_h::Dimension::EPSILON_ACCURACY;
00283
00284
00285 _xStart[_blocknum] = NEG_INFTY;
00286 _xEnd[_blocknum] = left_bound;
00287 _yStart[_blocknum] = NEG_INFTY;
00288 _yEnd[_blocknum] = INFTY;
00289
00290
00291 _xStart[_blocknum+1] = NEG_INFTY;
00292 _xEnd[_blocknum+1] = INFTY;
00293 _yStart[_blocknum+1] = NEG_INFTY;
00294 _yEnd[_blocknum+1] = bottom_bound;
00295
00296
00297 _xStart[_blocknum+2] = right_bound;
00298 _xEnd[_blocknum+2] = INFTY;
00299 _yStart[_blocknum+2] = NEG_INFTY;
00300 _yEnd[_blocknum+2] = INFTY;
00301
00302
00303 _xStart[_blocknum+3] = NEG_INFTY;
00304 _xEnd[_blocknum+3] = INFTY;
00305 _yStart[_blocknum+3] = top_bound;
00306 _yEnd[_blocknum+3] = INFTY;
00307 }
00308
00309 void ShiftBlock::operator ()(int currBlk,
00310 vector<ShiftInfo>& shiftinfo) const
00311 {
00312
00313 shiftinfo.resize(DIR_NUM);
00314 for (int i = 0; i < int(DIR_NUM); i++)
00315 {
00316 Directions currDir = Directions(i);
00317 shiftinfo[currDir].shiftRangeMin = 0;
00318 shiftinfo[currDir].shiftRangeMax = INFTY;
00319 shiftinfo[currDir].overlapMin = INFTY;
00320 shiftinfo[currDir].overlapMax = 0;
00321 }
00322
00323
00324 for (int tempBlk = 0; tempBlk < _blocknum+4; tempBlk++)
00325 {
00326
00327 if (tempBlk != currBlk)
00328 {
00329 if (_xStart[tempBlk] < _xEnd[currBlk] - _epsilon &&
00330 _xStart[currBlk] < _xEnd[tempBlk] - _epsilon)
00331 {
00332
00333 if (_yStart[tempBlk] < _yEnd[currBlk] - _epsilon &&
00334 _yStart[currBlk] < _yEnd[tempBlk] - _epsilon)
00335 {
00336
00337 shiftinfo[NORTH].shiftRangeMin =
00338 max(shiftinfo[NORTH].shiftRangeMin,
00339 _yEnd[tempBlk] - _yStart[currBlk]);
00340
00341 shiftinfo[SOUTH].shiftRangeMin =
00342 max(shiftinfo[SOUTH].shiftRangeMin,
00343 _yEnd[currBlk] - _yStart[tempBlk]);
00344
00345 shiftinfo[EAST].shiftRangeMin =
00346 max(shiftinfo[EAST].shiftRangeMin,
00347 _xEnd[currBlk] - _xStart[tempBlk]);
00348
00349 shiftinfo[WEST].shiftRangeMin =
00350 max(shiftinfo[WEST].shiftRangeMin,
00351 _xEnd[tempBlk] - _xStart[currBlk]);
00352
00353
00354 shiftinfo[NORTH].overlapMin =
00355 min(shiftinfo[NORTH].overlapMin, _xStart[tempBlk]);
00356
00357 shiftinfo[NORTH].overlapMax =
00358 max(shiftinfo[NORTH].overlapMax, _xEnd[tempBlk]);
00359
00360 shiftinfo[SOUTH].overlapMin = shiftinfo[NORTH].overlapMin;
00361 shiftinfo[SOUTH].overlapMax = shiftinfo[NORTH].overlapMax;
00362
00363 shiftinfo[EAST].overlapMin =
00364 min(shiftinfo[EAST].overlapMin, _yStart[tempBlk]);
00365
00366 shiftinfo[EAST].overlapMax =
00367 max(shiftinfo[EAST].overlapMax, _yEnd[tempBlk]);
00368
00369 shiftinfo[WEST].overlapMin = shiftinfo[EAST].overlapMin;
00370 shiftinfo[WEST].overlapMax = shiftinfo[EAST].overlapMax;
00371
00372 }
00373 else if (_yStart[tempBlk] < _yEnd[currBlk] - _epsilon)
00374 {
00375
00376 shiftinfo[SOUTH].shiftRangeMax =
00377 min(shiftinfo[SOUTH].shiftRangeMax,
00378 max(_yStart[currBlk]-_yEnd[tempBlk], 0.0));
00379
00380 }
00381 else
00382 {
00383
00384 shiftinfo[NORTH].shiftRangeMax =
00385 min(shiftinfo[NORTH].shiftRangeMax,
00386 max(_yStart[tempBlk]-_yEnd[currBlk], 0.0));
00387
00388 }
00389 }
00390 else if (_yStart[tempBlk] < _yEnd[currBlk] - _epsilon &&
00391 _yStart[currBlk] < _yEnd[tempBlk] - _epsilon)
00392 {
00393
00394 if (_xStart[tempBlk] < _xEnd[currBlk] - _epsilon)
00395 {
00396
00397 shiftinfo[EAST].shiftRangeMax =
00398 min(shiftinfo[EAST].shiftRangeMax,
00399 max(_xStart[currBlk]-_xEnd[tempBlk], 0.0));
00400
00401 }
00402 else
00403 {
00404
00405 shiftinfo[WEST].shiftRangeMax =
00406 min(shiftinfo[WEST].shiftRangeMax,
00407 max(_xStart[tempBlk]-_xEnd[currBlk], 0.0));
00408
00409 }
00410 }
00411 }
00412 }
00413 }
00414
00415 void OutputShiftInfo(ostream& outs,
00416 const vector<ShiftBlock::ShiftInfo>& shiftinfo)
00417 {
00418 outs << "NORTH: " << endl;
00419 outs << "shiftRangeMin: "
00420 << shiftinfo[ShiftBlock::NORTH].shiftRangeMin << endl;
00421 outs << "shiftRangeMax: "
00422 << shiftinfo[ShiftBlock::NORTH].shiftRangeMax << endl;
00423 outs << "overlapMin: "
00424 << shiftinfo[ShiftBlock::NORTH].overlapMin << endl;
00425 outs << "overlapMax: "
00426 << shiftinfo[ShiftBlock::NORTH].overlapMax << endl;
00427 outs << endl;
00428
00429 outs << "EAST: " << endl;
00430 outs << "shiftRangeMin: "
00431 << shiftinfo[ShiftBlock::EAST].shiftRangeMin << endl;
00432 outs << "shiftRangeMax: "
00433 << shiftinfo[ShiftBlock::EAST].shiftRangeMax << endl;
00434 outs << "overlapMin: "
00435 << shiftinfo[ShiftBlock::EAST].overlapMin << endl;
00436 outs << "overlapMax: "
00437 << shiftinfo[ShiftBlock::EAST].overlapMax << endl;
00438 outs << endl;
00439
00440 outs << "SOUTH: " << endl;
00441 outs << "shiftRangeMin: "
00442 << shiftinfo[ShiftBlock::SOUTH].shiftRangeMin << endl;
00443 outs << "shiftRangeMax: "
00444 << shiftinfo[ShiftBlock::SOUTH].shiftRangeMax << endl;
00445 outs << "overlapMin: "
00446 << shiftinfo[ShiftBlock::SOUTH].overlapMin << endl;
00447 outs << "overlapMax: "
00448 << shiftinfo[ShiftBlock::SOUTH].overlapMax << endl;
00449 outs << endl;
00450
00451 outs << "WEST: " << endl;
00452 outs << "shiftRangeMin: "
00453 << shiftinfo[ShiftBlock::WEST].shiftRangeMin << endl;
00454 outs << "shiftRangeMax: "
00455 << shiftinfo[ShiftBlock::WEST].shiftRangeMax << endl;
00456 outs << "overlapMin: "
00457 << shiftinfo[ShiftBlock::WEST].overlapMin << endl;
00458 outs << "overlapMax: "
00459 << shiftinfo[ShiftBlock::WEST].overlapMax << endl;
00460 outs << endl;
00461 outs << "--------" << endl;
00462 }
00463
00464
00465
00466
00467