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

plcompact.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 "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    // move only if it resolves ALL overlaps
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; // only makes sense when "existsOverlaps"
00126    ShiftRotateDecision decision; // initialized
00127    for (int i = 0; i < ShiftBlock::DIR_NUM; i++)
00128    {
00129       // if overlap occurs
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    // -----try rotating the block if no move works so far-----
00142    if (existsOverlaps && !success)
00143    {
00144       // temporarily change the info
00145       swap(_widths[currBlk], _heights[currBlk]);
00146       double orig_xloc = _xloc[currBlk];
00147       double orig_yloc = _yloc[currBlk];
00148 
00149       // apply the same procedures to find moves
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          // if overlap occurs
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       // special case when "rotating" helps already
00172       if (!existsOverlaps)
00173       {
00174          decision.rotate = true;
00175          decision.shiftDir = ShiftBlock::EAST;
00176          decision.shiftExtent = 0;
00177          
00178          success = true;
00179       }
00180 
00181       // restore the global details even when succeed
00182       swap(_widths[currBlk], _heights[currBlk]);
00183       _xloc[currBlk] = orig_xloc;
00184       _yloc[currBlk] = orig_yloc;
00185    }
00186 
00187    // move towards the direction that needs least fix
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; // "f" ==> exists unresolvable overlap (not converse)
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    // LEFT-edge
00285    _xStart[_blocknum] = NEG_INFTY;
00286    _xEnd[_blocknum] = left_bound;
00287    _yStart[_blocknum] = NEG_INFTY;
00288    _yEnd[_blocknum] = INFTY;
00289 
00290    // BOTTOM-edge
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    // RIGHT-edge
00297    _xStart[_blocknum+2] = right_bound;
00298    _xEnd[_blocknum+2] = INFTY;
00299    _yStart[_blocknum+2] = NEG_INFTY;
00300    _yEnd[_blocknum+2] = INFTY;
00301       
00302    // TOP-edge
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    // -----initialize the output-----
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    // -----determine the overlap's and/or shiftRange-----
00324    for (int tempBlk = 0; tempBlk < _blocknum+4; tempBlk++)
00325    {
00326       // printf("-----tempBlk %d-----\n", tempBlk);
00327       if (tempBlk != currBlk)
00328       {
00329          if (_xStart[tempBlk] < _xEnd[currBlk] - _epsilon &&
00330              _xStart[currBlk] < _xEnd[tempBlk] - _epsilon)
00331          {
00332             // horizontal overlap, relevant for dir's N and S
00333             if (_yStart[tempBlk] < _yEnd[currBlk] - _epsilon &&
00334                 _yStart[currBlk] < _yEnd[tempBlk] - _epsilon)
00335             {
00336                // real overlaps, "shiftRange(Min/Max)" must be +ve
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                // handle "overlap(Min/Max)"
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                // cout << "here -1- real overlap" << endl;
00372             }
00373             else if (_yStart[tempBlk] < _yEnd[currBlk] - _epsilon) 
00374             {
00375                // "tempBlk" below "currBlk"
00376                shiftinfo[SOUTH].shiftRangeMax =
00377                   min(shiftinfo[SOUTH].shiftRangeMax,
00378                       max(_yStart[currBlk]-_yEnd[tempBlk], 0.0));
00379                // cout << "here -2- tempBlk below currBlk" << endl;
00380             }
00381             else
00382             {
00383                // "tempBlk" above "currBlk"
00384                shiftinfo[NORTH].shiftRangeMax =
00385                   min(shiftinfo[NORTH].shiftRangeMax,
00386                       max(_yStart[tempBlk]-_yEnd[currBlk], 0.0));
00387                // cout << "here -3- tempBlk above currBlk" << endl;
00388             }
00389          }
00390          else if (_yStart[tempBlk] < _yEnd[currBlk] - _epsilon &&
00391                   _yStart[currBlk] < _yEnd[tempBlk] - _epsilon)
00392          {
00393             // vertical overlap, but not horizontal
00394             if (_xStart[tempBlk] < _xEnd[currBlk] - _epsilon)
00395             {
00396                // "tempBlk" left of "currBlk"
00397                shiftinfo[EAST].shiftRangeMax =
00398                   min(shiftinfo[EAST].shiftRangeMax,
00399                       max(_xStart[currBlk]-_xEnd[tempBlk], 0.0));
00400                // cout << "here -4- tempBlk left of currBlk" << endl;
00401             }
00402             else
00403             {
00404                // "tempBlk" right of "currBlk"
00405                shiftinfo[WEST].shiftRangeMax =
00406                   min(shiftinfo[WEST].shiftRangeMax,
00407                       max(_xStart[tempBlk]-_xEnd[currBlk], 0.0));
00408                // cout << "here -5- tempBlk right of currBlk" << endl;
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    

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