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
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047 #include "FPcommon.h"
00048 #include "PlToSP.h"
00049 #include "Annealer.h"
00050 #include "CommandLine.h"
00051 #include "ABKCommon/infolines.h"
00052 #include "VoltageIsland.h"
00053
00054 using namespace parquetfp;
00055
00056 #define VANILLA
00057
00058 Annealer::Annealer(const Command_Line *const params,
00059 DB *const db)
00060 : BaseAnnealer(params, db),
00061 _sp(new SeqPair(_db->getNumNodes())),
00062 _spEval(new SPeval(_db->getNodes()->getNodeHeights(),
00063 _db->getNodes()->getNodeWidths(),
00064 _params->useFastSP))
00065 {}
00066
00067 Annealer::~Annealer()
00068 {
00069 if(_sp != NULL) delete _sp;
00070 if(_spEval != NULL) delete _spEval;
00071 }
00072
00073 void Annealer::compactSoln()
00074 {
00075 eval();
00076 double currArea = getXSize() * getYSize();
00077 double lastArea = currArea;
00078
00079 bool whichDir = false;
00080 evalCompact(whichDir);
00081 do
00082 {
00083 whichDir = !whichDir;
00084 takeSPfromDB();
00085 evalCompact(whichDir);
00086
00087 lastArea = currArea;
00088 currArea = getXSize() * getYSize();
00089 if(_params->verb.forMajStats > 0)
00090 cout << "area: " << lastArea << " -> " << currArea << endl;
00091 }
00092 while(int(currArea) < int(lastArea));
00093 }
00094
00095 void Annealer::takePlfromDB()
00096 {
00097 takeSPfromDB();
00098 eval();
00099 }
00100
00101 void Annealer::takeSPfromDB()
00102 {
00103 vector<double> heights = _db->getNodeHeights();
00104 vector<double> widths = _db->getNodeWidths();
00105 vector<double> xloc = _db->getXLocs();
00106 vector<double> yloc = _db->getYLocs();
00107
00108 PL2SP_ALGO useAlgo = TCG_ALGO;
00109 Pl2SP pl2sp(xloc, yloc, widths, heights, useAlgo);
00110 _sp->putX(pl2sp.getXSP());
00111 _sp->putY(pl2sp.getYSP());
00112 _spEval->changeWidths(widths);
00113 _spEval->changeHeights(heights);
00114 }
00115
00116 bool Annealer::go()
00117 {
00118 MaxMem::update("Parquet before annealing");
00119
00120 Timer T;
00121 T.stop();
00122 T.start(0.0);
00123 anneal();
00124 T.stop();
00125
00126 annealTime += T.getUserTime();
00127
00128 _spEval->evaluate(_sp->getX(), _sp->getY());
00129 _db->updatePlacement(_spEval->xloc, _spEval->yloc);
00130
00131 if(_params->softBlocks)
00132 {
00133
00134 packSoftBlocks(100);
00135 _spEval->evaluate(_sp->getX(), _sp->getY());
00136 _db->updatePlacement(_spEval->xloc, _spEval->yloc);
00137 }
00138 _spEval->evalSlacks(_sp->getX(), _sp->getY());
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151 _db->updateSlacks(_spEval->xSlacks, _spEval->ySlacks);
00152
00153 SolutionInfo currSoln;
00154 currSoln.area = _spEval->xSize*_spEval->ySize;
00155 currSoln.width = _spEval->xSize;
00156 currSoln.height = _spEval->ySize;
00157 currSoln.HPWL = _db->evalHPWL();
00158 printResults(T, currSoln);
00159
00160 return true;
00161 }
00162
00163 void Annealer::updatePlacement(void)
00164 {
00165 _db->updatePlacement(_spEval->xloc, _spEval->yloc);
00166 }
00167
00168 void Annealer::eval(void)
00169 {
00170 _spEval->evaluate(_sp->getX(), _sp->getY());
00171 _db->updatePlacement(_spEval->xloc, _spEval->yloc);
00172 }
00173
00174 void Annealer::evalSlacks(void)
00175 {
00176 _spEval->evalSlacks(_sp->getX(), _sp->getY());
00177 _db->updateSlacks(_spEval->xSlacks, _spEval->ySlacks);
00178 }
00179
00180 void Annealer::evalCompact(bool whichDir)
00181 {
00182 _spEval->evaluateCompact(_sp->getX(), _sp->getY(), whichDir);
00183 _db->updatePlacement(_spEval->xloc, _spEval->yloc);
00184 }
00185
00186 void Annealer::anneal()
00187 {
00188 bool budgetTime = _params->budgetTime;
00189 double seconds = _params->seconds;
00190
00191 vector<unsigned> tempX, tempY;
00192
00193 bool minWL = _params->minWL;
00194 double wireWeight = _params->wireWeight;
00195 double areaWeight = _params->areaWeight;
00196 double ARWeight = 1 - areaWeight - wireWeight;
00197 if(ARWeight < 0)
00198 ARWeight = 0;
00199
00200 double tempArea = 0;
00201 double tempHeight = 0;
00202 double tempWidth = 0;
00203 double tempAR=0;
00204 double bestHPWL = 1e100;
00205 double bestArea = 1e100;
00206 double currArea = 1e100;
00207 double deltaArea = 0, deltaAR, delta;
00208 double blocksArea = _db->getNodesArea();
00209 double currHeight = 1;
00210 double currWidth = 1;
00211 double currTime = _params->startTime;
00212 double size = _sp->getX().size();
00213 double alpha = 0, r;
00214 double reqdAR = _params->reqdAR, currAR;
00215 int move = 0, count=0, ran;
00216 unsigned timeChangeCtr = 0;
00217 unsigned indexOrient = 0, moveSelect, iter, masterMoveSel=0;
00218 parquetfp::ORIENT newOrient = N;
00219 parquetfp::ORIENT oldOrient = N;
00220 double oldWidth=0, oldHeight=0, newWidth=0, newHeight=0;
00221 bool moveAccepted=0;
00222
00223 const double reqdArea = blocksArea * (1+(_params->maxWS/100.0));
00224 const double reqdWidth = sqrt(reqdArea*reqdAR);
00225 const double reqdHeight = reqdWidth/reqdAR;
00226
00227 bool brokeFromLoop;
00228
00229 double tempHPWL=1e100;
00230 double currHPWL=1e100;
00231 double deltaHPWL=0;
00232
00233 unsigned numNodes = _db->getNumNodes();
00234 bool updatedBestSoln=false;
00235 Point dummy;
00236 dummy.x=0;
00237 dummy.y=0;
00238 vector<Point> bestSolnPl(numNodes, dummy);
00239 vector<parquetfp::ORIENT> bestSolnOrient(numNodes, N);
00240 vector<double> bestSolnWidth(numNodes, 0);
00241 vector<double> bestSolnHeight(numNodes, 0);
00242 vector<unsigned> bestXSP(numNodes, 0);
00243 vector<unsigned> bestYSP(numNodes, 0);
00244
00245
00246
00247 Timer looptm;
00248 looptm.stop();
00249 double unit=0, total=seconds, percent=1;
00250 unsigned moves=2000;
00251
00252 while(currTime>_params->timeCool || budgetTime)
00253 {
00254 brokeFromLoop = 0;
00255 iter=0;
00256 do
00257 {
00258 if (budgetTime)
00259 {
00260 if (count==0)
00261 {
00262 looptm.start(0.0);
00263 }
00264 else if (count==1000)
00265 {
00266 looptm.stop();
00267 unit=looptm.getUserTime()/1000;
00268 if(unit == 0)
00269 {
00270 unit = 10e-6;
00271 }
00272 seconds-=looptm.getUserTime();
00273 if(_params->verb.forMajStats > 0)
00274 cout<<int(seconds/unit)<<" moves left with "<<
00275 unit*1000000<<" micro seconds per move.\n";
00276 moves=unsigned(seconds/unit/125.0);
00277 }
00278 else if (count > 1000)
00279 {
00280 seconds-=unit;
00281 if (seconds <= 0)
00282 {
00283 brokeFromLoop=1;
00284 break;
00285
00286 }
00287 }
00288 }
00289 else
00290 {
00291 if (count==0)
00292 {
00293 looptm.start(0.0);
00294 }
00295 else if (count==1000)
00296 {
00297 looptm.stop();
00298 unit=looptm.getUserTime()/1000;
00299 if(unit == 0)
00300 {
00301 unit = 10e-6;
00302 }
00303 if(_params->verb.forMajStats > 0)
00304 cout << (unit*1000000) << " micro seconds per move." << endl;
00305 }
00306 }
00307
00308 ++count;
00309 ++iter;
00310
00311 tempX = _sp->getX();
00312 tempY = _sp->getY();
00313
00314
00315
00316
00317 if(_params->softBlocks && currTime < 30)
00318 masterMoveSel = rand()%1000;
00319 moveSelect = rand()%1000;
00320
00321 currAR = currWidth/currHeight;
00322 move = -1;
00323
00324 #ifdef VANILLA
00325 if(_params->softBlocks && masterMoveSel > 990)
00326 move = packSoftBlocks(2);
00327 else if(_params->softBlocks && masterMoveSel > 930)
00328 move = makeSoftBlMove(tempX, tempY, indexOrient, newWidth,
00329 newHeight);
00330 else if(((reqdAR-currAR)/reqdAR > 0.00005 ||
00331 (currAR-reqdAR)/reqdAR > 0.00005) &&
00332 (timeChangeCtr%4)==0 && reqdAR != -9999)
00333 move = makeARMove(tempX, tempY, currAR);
00334 else if(moveSelect < 150 && minWL == 1 && reqdAR != -9999)
00335 move = makeARWLMove(tempX, tempY, currAR);
00336 else if(moveSelect < 300 && minWL == 1)
00337 move = makeHPWLMove(tempX, tempY);
00338 else if(moveSelect < 500)
00339 move = makeMoveOrient(indexOrient, oldOrient, newOrient);
00340 else
00341 move = makeMove(tempX, tempY);
00342 #else
00343 if(_params->softBlocks && masterMoveSel > 470)
00344 move = packSoftBlocks(2);
00345 else if(_params->softBlocks && masterMoveSel > 400)
00346 move = makeSoftBlMove(tempX, tempY, indexOrient, newWidth,
00347 newHeight);
00348 else if(((reqdAR-currAR)/reqdAR > 0.00007 ||
00349 (currAR-reqdAR)/reqdAR >0.00005)
00350 && (timeChangeCtr%2)==0 && reqdAR != -9999)
00351 move = makeARMove(tempX, tempY, currAR);
00352 else if(moveSelect < 150 && minWL == 1 && reqdAR != -9999)
00353 move = makeARWLMove(tempX, tempY, currAR);
00354 else if(moveSelect < 300 && minWL == 1)
00355 move = makeHPWLMove(tempX, tempY);
00356 else if(moveSelect < 400)
00357 move = makeMoveSlacks(tempX, tempY);
00358 else if(moveSelect < 600)
00359 move = makeMoveSlacksOrient(tempX, tempY, indexOrient, oldOrient,
00360 newOrient);
00361 else if(moveSelect < 700)
00362 move = makeMoveOrient(indexOrient, oldOrient, newOrient);
00363 else
00364 move = makeMove(tempX, tempY);
00365 #endif
00366
00367
00368 if(move == 10)
00369 {
00370 if(oldOrient%2 != newOrient%2)
00371 _spEval->changeOrient(indexOrient);
00372
00373 if(minWL)
00374 _db->getNodes()->changeOrient(indexOrient, newOrient,
00375 *(_db->getNets()));
00376 }
00377 if(move == 11)
00378 {
00379 oldHeight = _db->getNodes()->getNodeHeight(indexOrient);
00380 oldWidth = _db->getNodes()->getNodeWidth(indexOrient);
00381 _spEval->changeNodeWidth(indexOrient, newWidth);
00382 _spEval->changeNodeHeight(indexOrient, newHeight);
00383 }
00384
00385 _spEval->evaluate(tempX, tempY);
00386 tempHeight = _spEval->ySize;
00387 tempWidth = _spEval->xSize;
00388 tempArea = tempHeight*tempWidth;
00389 tempAR = tempWidth/tempHeight;
00390
00391
00392
00393 if(currTime>30)
00394 deltaArea=((tempArea-currArea)*1.2*_params->timeInit)/blocksArea;
00395 else
00396 deltaArea=((tempArea-currArea)*1.5*_params->timeInit)/blocksArea;
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409 delta = deltaArea;
00410
00411 _db->updatePlacement(_spEval->xloc, _spEval->yloc);
00412 if(minWL)
00413 {
00414 tempHPWL = _db->evalHPWL();
00415
00416 if(currHPWL == 0)
00417 deltaHPWL = 0;
00418 else
00419 {
00420 if(currTime>30)
00421 deltaHPWL=((tempHPWL-currHPWL)*1.2*_params->timeInit)/currHPWL;
00422 else
00423 deltaHPWL=((tempHPWL-currHPWL)*1.5*_params->timeInit)/currHPWL;
00424 }
00425 }
00426
00427 if(reqdAR != -9999)
00428 {
00429 if(currTime>30)
00430 deltaAR = ((tempAR - reqdAR)*(tempAR - reqdAR) - (currAR - reqdAR)*(currAR - reqdAR))*10*_params->timeInit;
00431 else
00432 deltaAR = ((tempAR - reqdAR)*(tempAR - reqdAR) - (currAR - reqdAR)*(currAR - reqdAR))*10*_params->timeInit;
00433
00434
00435 if(minWL)
00436 delta = areaWeight*deltaArea + wireWeight*deltaHPWL +
00437 ARWeight*deltaAR;
00438 else
00439 delta = (areaWeight+wireWeight/2.0)*deltaArea +
00440 (ARWeight+wireWeight/2.0)*deltaAR;
00441 }
00442 else if(minWL)
00443 {
00444 delta = (areaWeight+ARWeight/2.0)*deltaArea +
00445 (wireWeight+ARWeight/2.0)*deltaHPWL;
00446 }
00447 else
00448 delta = deltaArea;
00449
00450 if(delta<0 || move == -1)
00451 moveAccepted = 1;
00452 else if(currTime>_params->timeCool)
00453
00454 {
00455 ran=rand()%10000;
00456 r=double(ran)/9999.0;
00457 if(r<exp(-1*delta/currTime))
00458 moveAccepted = 1;
00459 else
00460 moveAccepted = 0;
00461 }
00462 else
00463 moveAccepted = 0;
00464
00465
00466
00467 if(moveAccepted)
00468 {
00469 currHeight=tempHeight;
00470 currWidth=tempWidth;
00471 currArea=tempArea;
00472 currHPWL=tempHPWL;
00473 _sp->putX(tempX);
00474 _sp->putY(tempY);
00475
00476 if(move == 10)
00477 _db->getNodes()->changeOrient(indexOrient, newOrient,
00478 *(_db->getNets()));
00479 else if(move == 11)
00480 {
00481 _db->getNodes()->putNodeWidth(indexOrient, newWidth);
00482 _db->getNodes()->putNodeHeight(indexOrient, newHeight);
00483 }
00484 }
00485 else
00486 {
00487 if(move == 10)
00488 {
00489 if(oldOrient%2 != newOrient%2)
00490 _spEval->changeOrient(indexOrient);
00491
00492 if(minWL)
00493 _db->getNodes()->changeOrient(indexOrient, oldOrient,
00494 *(_db->getNets()));
00495 }
00496 else if(move == 11)
00497 {
00498 _spEval->changeNodeWidth(indexOrient, oldWidth);
00499 _spEval->changeNodeHeight(indexOrient, oldHeight);
00500 }
00501 }
00502
00503
00504
00505 bool saveSolnInBestCopy=false;
00506 if(moveAccepted)
00507 {
00508 double oldCurrArea = currArea;
00509 double oldCurrWidth = currWidth;
00510 double oldCurrHeight = currHeight;
00511
00512 if(reqdAR != -9999)
00513 {
00514 if(_params->solveTop && _params->dontClusterMacros)
00515 {
00516 double tempXSize = _db->getXSizeWMacroOnly();
00517 double tempYSize = _db->getYSizeWMacroOnly();
00518 if(tempXSize > 1e-5 && tempYSize > 1e-5)
00519 {
00520 currArea = tempXSize*tempYSize;
00521 currHeight = tempYSize;
00522 currWidth = tempXSize;
00523 }
00524 }
00525
00526 if(minWL)
00527 {
00528 if(currArea <= reqdArea && currHeight <= reqdHeight &&
00529 currWidth <= reqdWidth && bestHPWL > currHPWL)
00530 {
00531 bestHPWL = currHPWL;
00532 bestArea = currArea;
00533 updatedBestSoln = true;
00534 saveSolnInBestCopy = true;
00535 }
00536 }
00537 else
00538 {
00539 if(currArea <= reqdArea && currHeight <= reqdHeight &&
00540 currWidth <= reqdWidth && bestArea > currArea)
00541 {
00542 bestHPWL = currHPWL;
00543 bestArea = currArea;
00544 updatedBestSoln = true;
00545 saveSolnInBestCopy = true;
00546 }
00547 }
00548 }
00549 else
00550 {
00551 if(minWL)
00552 {
00553 if(currArea <= bestArea && currHPWL <= bestHPWL)
00554 {
00555 bestHPWL = currHPWL;
00556 bestArea = currArea;
00557 updatedBestSoln = true;
00558 saveSolnInBestCopy = true;
00559 }
00560 }
00561 else
00562 {
00563 if(currArea <= bestArea)
00564 {
00565 bestHPWL = currHPWL;
00566 bestArea = currArea;
00567 updatedBestSoln = true;
00568 saveSolnInBestCopy = true;
00569 }
00570 }
00571 }
00572 if(saveSolnInBestCopy)
00573 {
00574 itNode node;
00575 unsigned nodeId=0;
00576 for(node = _db->getNodes()->nodesBegin(); node != _db->getNodes()->nodesEnd(); ++node)
00577 {
00578 bestSolnPl[nodeId].x = node->getX();
00579 bestSolnPl[nodeId].y = node->getY();
00580 bestSolnOrient[nodeId] = node->getOrient();
00581 bestSolnWidth[nodeId] = node->getWidth();
00582 bestSolnHeight[nodeId] = node->getHeight();
00583 bestXSP[nodeId] = (_sp->getX())[nodeId];
00584 bestYSP[nodeId] = (_sp->getY())[nodeId];
00585 ++nodeId;
00586 }
00587 }
00588
00589 if(minWL)
00590 {
00591 if(reqdAR != -9999 && currTime < 0.5 && updatedBestSoln)
00592 {
00593 brokeFromLoop = 1;
00594 if(_params->verb.forMajStats > 0)
00595 cout<<"Fixed-outline FPing SUCCESS"<<endl;
00596 break;
00597
00598 }
00599 }
00600 else
00601 {
00602 if(updatedBestSoln && reqdAR != -9999)
00603 {
00604 brokeFromLoop = 1;
00605 if(_params->verb.forMajStats > 0)
00606 cout<<"Fixed-outline FPing SUCCESS"<<endl;
00607 break;
00608
00609 }
00610 }
00611
00612 if(reqdAR != -9999 && _params->solveTop && _params->dontClusterMacros)
00613 {
00614 currArea = oldCurrArea;
00615 currWidth = oldCurrWidth;
00616 currHeight = oldCurrHeight;
00617 }
00618 }
00619
00620 if (iter>=moves && budgetTime)
00621 break;
00622 }
00623 while(iter<size*4 || budgetTime);
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646
00647 ++timeChangeCtr;
00648
00649 if (budgetTime)
00650 {
00651 percent=seconds/total;
00652
00653 if(percent<.066666 && percent>.033333)
00654 alpha=0.9;
00655 else if(percent<.033333 && percent>.016666)
00656 alpha=0.95;
00657 else if(percent<.016666 && percent>.006666)
00658 alpha=0.96;
00659 else if(percent<.006666 && percent>.000333)
00660 alpha=0.8;
00661 else if(percent<.000333 && percent>.000003)
00662 alpha=0.98;
00663 else
00664 alpha=0.85;
00665 }
00666 else
00667 {
00668 if(currTime<2000 && currTime>1000)
00669 alpha=0.95;
00670 else if(currTime<1000 && currTime>500)
00671 alpha=0.95;
00672 else if(currTime<500 && currTime>200)
00673 alpha=0.96;
00674 else if(currTime<200 && currTime>10)
00675 alpha=0.96;
00676 else if(currTime<15 && currTime>0.1)
00677 alpha=0.98;
00678 else
00679 alpha=0.95;
00680 }
00681 currTime = alpha*currTime;
00682
00683 if(brokeFromLoop == 1)
00684 break;
00685
00686
00687 }
00688
00689 if(updatedBestSoln)
00690 {
00691 itNode node;
00692 unsigned nodeId=0;
00693 for(node = _db->getNodes()->nodesBegin(); node != _db->getNodes()->nodesEnd(); ++node)
00694 {
00695 node->putX(bestSolnPl[nodeId].x);
00696 node->putY(bestSolnPl[nodeId].y);
00697 node->changeOrient(bestSolnOrient[nodeId], *(_db->getNets()));
00698 node->putWidth(bestSolnWidth[nodeId]);
00699 node->putHeight(bestSolnHeight[nodeId]);
00700
00701 _spEval->changeNodeWidth(nodeId, bestSolnWidth[nodeId]);
00702 _spEval->changeNodeHeight(nodeId, bestSolnHeight[nodeId]);
00703 ++nodeId;
00704 }
00705
00706 _sp->putX(bestXSP);
00707 _sp->putY(bestYSP);
00708 }
00709
00710 if(_params->verb.forActions > 0)
00711 cout << "NumMoves attempted: " << count << endl;
00712
00713 _sp->printX();
00714 _sp->printY();
00715
00716 tempX = _sp->getX();
00717 tempY = _sp->getY();
00718
00719 SetOfVoltages tempVdds;
00720
00721
00722 for(unsigned i=0;i<(_sp->getSize()-1);i++)
00723 {
00724
00725 if(_db->getNodes()->getNode(tempX[i]).getVoltage() == _db->getNodes()->getNode(tempX[i+1]).getVoltage())
00726 {
00727 cout << "Node " << tempX[i] << " can be voltage island with " << tempX[i+1] << endl;
00728 tempVdds.addVdd(_db->getNodes()->getNode(tempX[i+1]).getVoltage());
00729
00730
00731
00732
00733
00734
00735 tempVdds.getIslandsAtVdd(_db->getNodes()->getNode(tempX[i+1]).getVoltage()).newIsland(tempX[i],tempX[i+1]);
00736
00737 }
00738 if(_db->getNodes()->getNode(tempY[i]).getVoltage() == _db->getNodes()->getNode(tempY[i+1]).getVoltage())
00739 {
00740 cout << "Node " << tempY[i] << " can be voltage island with " << tempY[i+1] << endl;
00741 tempVdds.addVdd(_db->getNodes()->getNode(tempY[i+1]).getVoltage());
00742
00743
00744
00745
00746
00747
00748
00749 tempVdds.getIslandsAtVdd(_db->getNodes()->getNode(tempY[i+1]).getVoltage()).newIsland(tempY[i],tempY[i+1]);
00750 }
00751 }
00752
00753
00754
00755
00756 for(unsigned i = 0; i < tempVdds.voltageislands.size(); i++){
00757 cout << "Voltage Islands: " << tempVdds.voltageislands[i].voltage << endl;
00758 }
00759
00760
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770
00771 }
00772
00773
00774 void Annealer::sortSlacks(vector<Point>& sortedXSlacks,
00775 vector<Point>& sortedYSlacks)
00776 {
00777 sortedXSlacks.erase(sortedXSlacks.begin(), sortedXSlacks.end());
00778 sortedYSlacks.erase(sortedYSlacks.begin(), sortedYSlacks.end());
00779 Point tempPoint;
00780
00781 for(unsigned i=0;i<_spEval->xSlacks.size();++i)
00782 {
00783 tempPoint.x = _spEval->xSlacks[i];
00784 tempPoint.y = i;
00785 sortedXSlacks.push_back(tempPoint);
00786 tempPoint.x = _spEval->ySlacks[i];
00787 tempPoint.y = i;
00788 sortedYSlacks.push_back(tempPoint);
00789 }
00790 std::sort(sortedXSlacks.begin(),sortedXSlacks.end(),sort_slacks());
00791 std::sort(sortedYSlacks.begin(),sortedYSlacks.end(),sort_slacks());
00792 }
00793
00794
00795 int Annealer::makeMove(vector<unsigned>& A, vector<unsigned>& B)
00796 {
00797 int elem1,elem2,i=0,voltage1=0,voltage2=0;
00798 int size = A.size();
00799 if(size == 1)
00800 return -1;
00801
00802 unsigned temporary;
00803 int moverand = rand()%1000;
00804 int movedir;
00805
00806 elem1=rand()%size;
00807 elem2=rand()%size;
00808
00809
00810
00811
00812
00813
00814
00815
00816
00817
00818
00819 std::vector<unsigned>::iterator itb;
00820
00821 moverand=rand()%600;
00822
00823 if(moverand<75)
00824 {
00825 temporary=A[elem1];
00826 A[elem1]=A[elem2];
00827 A[elem2]=temporary;
00828 return 1;
00829 }
00830 else if(moverand>75 && moverand<150)
00831 {
00832 temporary=B[elem1];
00833 B[elem1]=B[elem2];
00834 B[elem2]=temporary;
00835 return 2;
00836 }
00837 else if(moverand>150 && moverand<200)
00838 {
00839 temporary=A[elem1];
00840 A[elem1]=A[elem2];
00841 A[elem2]=temporary;
00842 elem1=rand()%size;
00843 elem2=rand()%size;
00844 temporary=B[elem1];
00845 B[elem1]=B[elem2];
00846 B[elem2]=temporary;
00847 return 3;
00848 }
00849 else if(moverand>200 && moverand<400)
00850 {
00851 movedir=rand()%100;
00852 if(movedir<50)
00853 {
00854 i=0;
00855 for(itb=A.begin();i!=elem1;++itb,++i)
00856 { }
00857 temporary=*itb;
00858 A.erase(itb);
00859 i=0;
00860 for(itb=A.begin();i!=elem2;++itb,++i)
00861 { }
00862 A.insert(itb,1,temporary);
00863 }
00864 else
00865 {
00866 i=0;
00867 for(itb=B.begin();i!=elem1;++itb,++i)
00868 { }
00869 temporary=*itb;
00870 B.erase(itb);
00871 i=0;
00872 for(itb=B.begin();i!=elem2;++itb,++i)
00873 {
00874 }
00875 B.insert(itb,1,temporary);
00876 }
00877 return 4;
00878 }
00879 else if(moverand>400 && moverand<600)
00880 {
00881 elem2=rand()%(int(ceil(size/4.0)));
00882 movedir=rand()%100;
00883 if(movedir<50)
00884 {
00885 if((elem1-elem2)<0)
00886 elem2=elem1+elem2;
00887 else
00888 elem2=elem1-elem2;
00889 }
00890 else
00891 {
00892 if((elem1+elem2)>size-1)
00893 elem2=elem1-elem2;
00894 else
00895 elem2=elem1+elem2;
00896 }
00897 if(moverand<500)
00898 {
00899 temporary=A[elem1];
00900 A[elem1]=A[elem2];
00901 A[elem2]=temporary;
00902 }
00903 else
00904 {
00905 temporary=B[elem1];
00906 B[elem1]=B[elem2];
00907 B[elem2]=temporary;
00908 }
00909 return 5;
00910 }
00911 return -1;
00912 }
00913
00914 int Annealer::makeMoveOrient(unsigned& index, parquetfp::ORIENT& oldOrient,
00915 parquetfp::ORIENT& newOrient)
00916 {
00917
00918 index = rand()%_sp->getSize();
00919 Node& node = _db->getNodes()->getNode(index);
00920 if(node.isOrientFixed())
00921 return -1;
00922
00923 oldOrient = node.getOrient();
00924 newOrient = parquetfp::ORIENT(rand()%8);
00925
00926 return 10;
00927 }
00928
00929 int Annealer::makeMoveSlacksOrient(vector<unsigned>& A, vector<unsigned>& B,
00930 unsigned& index, parquetfp::ORIENT& oldOrient, parquetfp::ORIENT& newOrient)
00931 {
00932 unsigned size = A.size();
00933 _spEval->evalSlacks(A, B);
00934
00935 sortSlacks(sortedXSlacks, sortedYSlacks);
00936 unsigned elem1=0;
00937 unsigned movedir = rand()%100;
00938 index = elem1;
00939 if(movedir<50)
00940 {
00941 for(unsigned i=0;i<size;++i)
00942 {
00943 elem1 = unsigned(sortedXSlacks[i].y);
00944 if(_db->getNodes()->getNodeWidth(elem1) >
00945 _db->getNodes()->getNodeHeight(elem1))
00946 break;
00947 }
00948 index = elem1;
00949 }
00950 else
00951 {
00952 for(unsigned i=0;i<size;++i)
00953 {
00954 elem1 = unsigned(sortedYSlacks[i].y);
00955 if(_db->getNodes()->getNodeHeight(elem1) >
00956 _db->getNodes()->getNodeWidth(elem1))
00957 break;
00958 }
00959 index = elem1;
00960 }
00961
00962 Node& node = _db->getNodes()->getNode(index);
00963 if(node.isOrientFixed())
00964 return -1;
00965
00966 oldOrient = node.getOrient();
00967 unsigned r = rand()%4;
00968
00969 if(oldOrient%2 == 0)
00970 newOrient = parquetfp::ORIENT(2*r+1);
00971 else
00972 newOrient = parquetfp::ORIENT(2*r);
00973
00974 return 10;
00975 }
00976
00977
00978 int Annealer::makeMoveSlacks(vector<unsigned>& A, vector<unsigned>& B)
00979 {
00980 unsigned size = A.size();
00981 if(size == 1)
00982 return -1;
00983
00984 _spEval->evalSlacks(A, B);
00985
00986 sortSlacks(sortedXSlacks, sortedYSlacks);
00987
00988 std::vector<unsigned>::iterator itb;
00989 unsigned temporary;
00990 unsigned elem1, elem2;
00991 unsigned movedir = rand()%100;
00992 unsigned choseElem1=rand()%int(ceil(size/5.0));
00993 unsigned choseElem2=size-rand()%int(ceil(size/5.0))-1;
00994 if(movedir<50)
00995 {
00996 elem1 = unsigned(sortedXSlacks[choseElem1].y);
00997 for(itb=A.begin();(*itb)!=elem1;++itb)
00998 { }
00999 temporary=*itb;
01000 A.erase(itb);
01001
01002 elem2=unsigned(sortedXSlacks[choseElem2].y);
01003 for(itb=A.begin();(*itb)!=elem2;++itb)
01004 { }
01005 A.insert(itb,1,temporary);
01006
01007 for(itb=B.begin();(*itb)!=elem1;++itb)
01008 { }
01009 temporary=*itb;
01010 B.erase(itb);
01011
01012 for(itb=B.begin();(*itb)!=elem2;++itb)
01013 { }
01014 B.insert(itb,1,temporary);
01015 }
01016 else
01017 {
01018 elem1 = unsigned(sortedYSlacks[choseElem1].y);
01019 for(itb=A.begin();(*itb)!=elem1;++itb)
01020 { }
01021 temporary=*itb;
01022 A.erase(itb);
01023
01024 elem2=unsigned(sortedYSlacks[choseElem2].y);
01025 for(itb=A.begin();(*itb)!=elem2;++itb)
01026 { }
01027 A.insert(itb,1,temporary);
01028
01029
01030 for(itb=B.begin();(*itb)!=elem1;++itb)
01031 { }
01032 temporary=*itb;
01033 B.erase(itb);
01034
01035 for(itb=B.begin();(*itb)!=elem2;++itb)
01036 { }
01037 B.insert(itb,1,temporary);
01038 }
01039 return 6;
01040 }
01041
01042 int Annealer::makeARMove(vector<unsigned>& A, vector<unsigned>& B,
01043 double currAR)
01044 {
01045 unsigned size = A.size();
01046 if(size == 1)
01047 return -1;
01048
01049 unsigned direction, temp;
01050 _spEval->evalSlacks(A, B);
01051
01052 sortSlacks(sortedXSlacks, sortedYSlacks);
01053
01054 std::vector<unsigned>::iterator itb;
01055 unsigned chooseElem1=0;
01056 unsigned elem1=0;
01057 unsigned chooseElem2=0;
01058 unsigned elem2=0;
01059 unsigned temporary=0;
01060
01061 bool HVDir=0;
01062 if(currAR > 1.0*_params->reqdAR)
01063
01064 HVDir = 0;
01065 else
01066 HVDir = 1;
01067
01068 chooseElem1=rand()%int(ceil(size/5.0));
01069 chooseElem2=size-rand()%int(ceil(size/5.0))-1;
01070
01071 if(HVDir == 0)
01072 {
01073 elem1 = unsigned(sortedXSlacks[chooseElem1].y);
01074 elem2 = unsigned(sortedXSlacks[chooseElem2].y);
01075 }
01076 else
01077 {
01078 elem1 = unsigned(sortedYSlacks[chooseElem1].y);
01079 elem2 = unsigned(sortedYSlacks[chooseElem2].y);
01080 }
01081
01082 temp = rand() % 2;
01083 if(HVDir == 0)
01084 {
01085 if(temp == 0)
01086 direction = 0;
01087 else
01088 direction = 3;
01089 }
01090 else
01091 {
01092 if(temp == 0)
01093 direction = 1;
01094 else
01095 direction = 2;
01096 }
01097
01098 for(itb=A.begin();(*itb)!=unsigned(elem1);++itb)
01099 { }
01100 temporary=*itb;
01101 A.erase(itb);
01102
01103 for(itb=A.begin();(*itb)!=unsigned(elem2);++itb)
01104 { }
01105 switch(direction)
01106 {
01107 case 0:
01108 case 1:
01109 break;
01110 case 2:
01111 case 3:
01112 ++itb;
01113 break;
01114 }
01115 A.insert(itb,1,temporary);
01116
01117
01118 for(itb=B.begin();(*itb)!=unsigned(elem1);++itb)
01119 { }
01120 temporary=*itb;
01121 B.erase(itb);
01122
01123 for(itb=B.begin();(*itb)!=unsigned(elem2);++itb)
01124 { }
01125 switch(direction)
01126 {
01127 case 0:
01128 case 2:
01129 break;
01130 case 1:
01131 case 3:
01132 ++itb;
01133 break;
01134 }
01135
01136 B.insert(itb,1,temporary);
01137
01138 return 7;
01139 }
01140
01141 int Annealer::makeSoftBlMove(const vector<unsigned>& A,
01142 const vector<unsigned>& B,
01143 unsigned &index,
01144 double &newWidth, double &newHeight)
01145 {
01146 unsigned size = A.size();
01147 _spEval->evalSlacks(A, B);
01148
01149 sortSlacks(sortedXSlacks, sortedYSlacks);
01150 unsigned elem1=0;
01151 double minAR, maxAR, currAR;
01152 unsigned movedir = rand()%100;
01153 double maxWidth, maxHeight;
01154 index = elem1;
01155 bool brokeFromLoop=0;
01156
01157 if(movedir<50)
01158 {
01159 for(unsigned i=0;i<size;++i)
01160 {
01161 elem1 = unsigned(sortedXSlacks[i].y);
01162 Node& node = _db->getNodes()->getNode(elem1);
01163 minAR = node.getminAR();
01164 maxAR = node.getmaxAR();
01165 currAR = node.getWidth()/node.getHeight();
01166
01167 if(_spEval->ySlacks[elem1] > 0 && minAR != maxAR && currAR > minAR)
01168 {
01169 brokeFromLoop = 1;
01170 break;
01171 }
01172 }
01173 index = elem1;
01174 }
01175
01176 if(movedir >= 50 || brokeFromLoop == 0)
01177 {
01178 for(unsigned i=0;i<size;++i)
01179 {
01180 elem1 = unsigned(sortedYSlacks[i].y);
01181 Node& node = _db->getNodes()->getNode(elem1);
01182 minAR = node.getminAR();
01183 maxAR = node.getmaxAR();
01184 currAR = node.getWidth()/node.getHeight();
01185
01186 if(_spEval->xSlacks[elem1] > 0 && minAR != maxAR && currAR < maxAR)
01187 break;
01188 }
01189 index = elem1;
01190 }
01191
01192 Node& node = _db->getNodes()->getNode(index);
01193 double origHeight = node.getHeight();
01194 double origWidth = node.getWidth();
01195 currAR = origWidth/origHeight;
01196 double area = node.getArea();
01197
01198 if(node.getminAR() > node.getmaxAR())
01199 {
01200 minAR = node.getmaxAR();
01201 maxAR = node.getminAR();
01202 }
01203 else
01204 {
01205 minAR = node.getminAR();
01206 maxAR = node.getmaxAR();
01207 }
01208
01209 if(node.getOrient()%2 == 0)
01210 {
01211 maxHeight = sqrt(area/minAR);
01212 maxWidth = sqrt(area*maxAR);
01213 }
01214 else
01215 {
01216 maxHeight = sqrt(area*maxAR);
01217 maxWidth = sqrt(area/minAR);
01218 }
01219
01220 double absSlackX = _spEval->xSlacks[index]*_spEval->xSize/100;
01221 double absSlackY = _spEval->ySlacks[index]*_spEval->ySize/100;
01222
01223 newHeight = origHeight;
01224 newWidth = origWidth;
01225
01226 if(absSlackX > absSlackY)
01227 {
01228 if(currAR < maxAR)
01229 {
01230 newWidth = origWidth + absSlackX;
01231 if(newWidth > maxWidth)
01232 newWidth = maxWidth;
01233 newHeight = area/newWidth;
01234 }
01235 }
01236 else
01237 {
01238 if(currAR > minAR)
01239 {
01240 newHeight = origHeight + absSlackY;
01241 if(newHeight > maxHeight)
01242 newHeight = maxHeight;
01243 newWidth = area/newHeight;
01244 }
01245 }
01246
01247 if(minAR == maxAR)
01248 {
01249 newHeight = origHeight;
01250 newWidth = origWidth;
01251 }
01252
01253 return 11;
01254 }
01255
01256 int Annealer::makeIndexSoftBlMove(const vector<unsigned>& A,
01257 const vector<unsigned>& B,
01258 unsigned index,
01259 double &newWidth, double &newHeight)
01260 {
01261 _spEval->evalSlacks(A, B);
01262
01263
01264 double minAR, maxAR, currAR;
01265 double maxWidth, maxHeight;
01266
01267 Node& node = _db->getNodes()->getNode(index);
01268 double origHeight = node.getHeight();
01269 double origWidth = node.getWidth();
01270 currAR = origWidth/origHeight;
01271 double area = node.getArea();
01272
01273 if(node.getminAR() > node.getmaxAR())
01274 {
01275 minAR = node.getmaxAR();
01276 maxAR = node.getminAR();
01277 }
01278 else
01279 {
01280 minAR = node.getminAR();
01281 maxAR = node.getmaxAR();
01282 }
01283
01284 if(node.getOrient()%2 == 0)
01285 {
01286 maxHeight = sqrt(area/minAR);
01287 maxWidth = sqrt(area*maxAR);
01288 }
01289 else
01290 {
01291 maxHeight = sqrt(area*maxAR);
01292 maxWidth = sqrt(area/minAR);
01293 }
01294
01295 double absSlackX = _spEval->xSlacks[index]*_spEval->xSize/100;
01296 double absSlackY = _spEval->ySlacks[index]*_spEval->ySize/100;
01297
01298 newHeight = origHeight;
01299 newWidth = origWidth;
01300
01301 if(absSlackX > absSlackY)
01302 {
01303 newWidth = origWidth + absSlackX;
01304 if(newWidth > maxWidth)
01305 newWidth = maxWidth;
01306 newHeight = area/newWidth;
01307
01308 }
01309 else
01310 {
01311 newHeight = origHeight + absSlackY;
01312 if(newHeight > maxHeight)
01313 newHeight = maxHeight;
01314 newWidth = area/newHeight;
01315 }
01316
01317 if(fabs(minAR-maxAR) < 0.0000001)
01318 {
01319 newHeight = origHeight;
01320 newWidth = origWidth;
01321 }
01322
01323 return 11;
01324 }
01325
01326 int Annealer::packSoftBlocks(unsigned numIter)
01327 {
01328 unsigned index;
01329 double origHeight, origWidth;
01330 double newHeight, newWidth;
01331 double oldArea;
01332 double newArea;
01333 double change=-1;
01334
01335 unsigned size = (_sp->getX()).size();
01336
01337 _spEval->evaluate(_sp->getX(), _sp->getY());
01338 oldArea = _spEval->ySize * _spEval->xSize;
01339 unsigned iter = 0;
01340 while(iter < numIter)
01341 {
01342 ++iter;
01343
01344 _spEval->evalSlacks(_sp->getX(), _sp->getY());
01345 sortSlacks(sortedXSlacks, sortedYSlacks);
01346
01347 for(unsigned i = 0; i<size; ++i)
01348 {
01349 if(numIter%2 == 0)
01350 index = unsigned(sortedXSlacks[i].y);
01351 else
01352 index = unsigned(sortedYSlacks[i].y);
01353
01354 origHeight = _db->getNodes()->getNodeHeight(index);
01355 origWidth = _db->getNodes()->getNodeWidth(index);
01356
01357 makeIndexSoftBlMove(_sp->getX(), _sp->getY(), index, newWidth, newHeight);
01358 _spEval->changeNodeWidth(index, newWidth);
01359 _spEval->changeNodeHeight(index, newHeight);
01360 _spEval->evaluate(_sp->getX(), _sp->getY());
01361
01362 newArea = _spEval->ySize * _spEval->xSize;
01363 change = newArea-oldArea;
01364 if(change > 1)
01365 {
01366 _spEval->changeNodeWidth(index, origWidth);
01367 _spEval->changeNodeHeight(index, origHeight);
01368 }
01369 else
01370 {
01371 _db->getNodes()->putNodeWidth(index, newWidth);
01372 _db->getNodes()->putNodeHeight(index, newHeight);
01373 oldArea = newArea;
01374 }
01375 }
01376 }
01377 return -1;
01378 }
01379
01380 int Annealer::makeHPWLMove(vector<unsigned>& A, vector<unsigned>& B)
01381 {
01382
01383 int size = A.size();
01384
01385 if(size == 1)
01386 return -1;
01387
01388 int i, j, temp, direction;
01389 int elem1,elem2;
01390
01391 elem1=rand()%size;
01392 int searchRadiusNum = int(ceil(size/5.0));
01393 double searchRadius;
01394 double distance;
01395 double xDist;
01396 double yDist;
01397
01398 std::vector<unsigned>::iterator itb;
01399 int temporary;
01400
01401 vector<bool> seenBlocks;
01402 seenBlocks.resize(size);
01403
01404 double unitRadiusSize;
01405
01406 vector<int> searchBlocks;
01407
01408 vector<double>& xloc = _spEval->xloc;
01409 vector<double>& yloc = _spEval->yloc;
01410
01411
01412 _spEval->evaluate(A, B);
01413
01414
01415 if(_spEval->xSize > _spEval->ySize)
01416 unitRadiusSize = _spEval->xSize;
01417 else
01418 unitRadiusSize = _spEval->ySize;
01419
01420 unitRadiusSize /= sqrt(double(size));
01421
01422 Point idealLoc = _analSolve->getOptLoc(elem1, _spEval->xloc, _spEval->yloc);
01423
01424
01425 fill(seenBlocks.begin(), seenBlocks.end(), 0);
01426 searchRadius = 0;
01427 for(i=0; i<searchRadiusNum; ++i)
01428 {
01429 searchRadius += unitRadiusSize;
01430 for(j = 0; j<size; ++j)
01431 {
01432 if(seenBlocks[j] == 0 && j != elem1)
01433 {
01434 xDist = xloc[j]-idealLoc.x;
01435 yDist = yloc[j]-idealLoc.y;
01436 distance = sqrt(xDist*xDist + yDist*yDist);
01437 if(distance < searchRadius)
01438 {
01439 seenBlocks[j] = 1;
01440 searchBlocks.push_back(j);
01441 if(searchBlocks.size() >= unsigned(searchRadiusNum))
01442 break;
01443 continue;
01444 }
01445 }
01446 }
01447 if(searchBlocks.size() >= unsigned(searchRadiusNum))
01448 break;
01449 }
01450
01451 if(searchBlocks.size() != 0)
01452 {
01453 temp = rand() % searchBlocks.size();
01454 elem2 = searchBlocks[temp];
01455 }
01456 else
01457 {
01458 do
01459 elem2 = rand() % size;
01460 while(elem2 == elem1);
01461 }
01462
01463 if(elem1 == elem2)
01464 return -1;
01465
01466 direction = rand() % 4;
01467
01468
01469 for(itb=A.begin();(*itb)!=unsigned(elem1);++itb)
01470 { }
01471 temporary=*itb;
01472 A.erase(itb);
01473
01474 for(itb=A.begin();(*itb)!=unsigned(elem2);++itb)
01475 { }
01476 switch(direction)
01477 {
01478 case 0:
01479 case 1:
01480 break;
01481 case 2:
01482 case 3:
01483 ++itb;
01484 break;
01485 }
01486 A.insert(itb,1,temporary);
01487
01488
01489 for(itb=B.begin();(*itb)!=unsigned(elem1);++itb)
01490 { }
01491 temporary=*itb;
01492 B.erase(itb);
01493
01494 for(itb=B.begin();(*itb)!=unsigned(elem2);++itb)
01495 { }
01496 switch(direction)
01497 {
01498 case 0:
01499 case 2:
01500 break;
01501 case 1:
01502 case 3:
01503 ++itb;
01504 break;
01505 }
01506
01507 B.insert(itb,1,temporary);
01508 return 12;
01509
01510 return -1;
01511 }
01512
01513 int Annealer::makeARWLMove(vector<unsigned>& A, vector<unsigned>& B,
01514 double currAR)
01515 {
01516 unsigned size = A.size();
01517
01518 if(size == 1)
01519 return -1;
01520
01521 std::vector<unsigned>::iterator itb;
01522 unsigned chooseElem1=0;
01523 unsigned elem1=0;
01524 unsigned elem2=0;
01525 unsigned temporary=0;
01526 unsigned i, j, direction, temp;
01527 double maxSlack;
01528 unsigned searchRadiusNum = unsigned(ceil(size/5.0));
01529 double searchRadius;
01530 double distance;
01531 double xDist;
01532 double yDist;
01533
01534 vector<bool> seenBlocks;
01535 seenBlocks.resize(size);
01536 double unitRadiusSize;
01537
01538 vector<int> searchBlocks;
01539
01540 vector<double>& xloc = _spEval->xloc;
01541 vector<double>& yloc = _spEval->yloc;
01542
01543 _spEval->evalSlacks(A, B);
01544
01545 sortSlacks(sortedXSlacks, sortedYSlacks);
01546
01547 _spEval->evaluate(A, B);
01548
01549
01550 bool HVDir=0;
01551 if(currAR > _params->reqdAR)
01552
01553 HVDir = 0;
01554 else
01555 HVDir = 1;
01556
01557 chooseElem1=rand()%int(ceil(size/5.0));
01558
01559 if(HVDir == 0)
01560 elem1 = unsigned(sortedXSlacks[chooseElem1].y);
01561 else
01562 elem1 = unsigned(sortedYSlacks[chooseElem1].y);
01563
01564 if(_spEval->xSize > _spEval->ySize)
01565 unitRadiusSize = _spEval->xSize;
01566 else
01567 unitRadiusSize = _spEval->ySize;
01568 unitRadiusSize /= sqrt(double(size));
01569
01570 Point idealLoc = _analSolve->getOptLoc(elem1, xloc, yloc);
01571
01572
01573 fill(seenBlocks.begin(), seenBlocks.end(), 0);
01574 searchRadius = 0;
01575 for(i=0; i<searchRadiusNum; ++i)
01576 {
01577 searchRadius += unitRadiusSize;
01578 for(j = 0; j<size; ++j)
01579 {
01580 if(seenBlocks[j] == 0 && j != elem1)
01581 {
01582 xDist = xloc[j]-idealLoc.x;
01583 yDist = yloc[j]-idealLoc.y;
01584 distance = sqrt(xDist*xDist + yDist*yDist);
01585 if(distance < searchRadius)
01586 {
01587 seenBlocks[j] = 1;
01588 searchBlocks.push_back(j);
01589 if(searchBlocks.size() >= unsigned(searchRadiusNum))
01590 break;
01591 continue;
01592 }
01593 }
01594 }
01595 if(searchBlocks.size() >= unsigned(searchRadiusNum))
01596 break;
01597 }
01598
01599 maxSlack = -1e100;
01600 if(HVDir == 0)
01601 {
01602 for(i=0; i<searchBlocks.size(); ++i)
01603 {
01604 if(_spEval->xSlacks[searchBlocks[i]] > maxSlack)
01605 {
01606 maxSlack = _spEval->xSlacks[searchBlocks[i]];
01607 elem2 = searchBlocks[i];
01608 }
01609 }
01610 }
01611 else
01612 {
01613 for(i=0; i<searchBlocks.size(); ++i)
01614 {
01615 if(_spEval->ySlacks[searchBlocks[i]] > maxSlack)
01616 {
01617 maxSlack = _spEval->ySlacks[searchBlocks[i]];
01618 elem2 = searchBlocks[i];
01619 }
01620 }
01621 }
01622
01623 if(searchBlocks.size() == 0)
01624 do
01625 elem2 = rand() % size;
01626 while(elem2 == elem1);
01627
01628 temp = rand() % 2;
01629 if(HVDir == 0)
01630 {
01631 if(temp == 0)
01632 direction = 0;
01633 else
01634 direction = 3;
01635 }
01636 else
01637 {
01638 if(temp == 0)
01639 direction = 1;
01640 else
01641 direction = 2;
01642 }
01643
01644 for(itb=A.begin();(*itb)!=unsigned(elem1);++itb)
01645 { }
01646 temporary=*itb;
01647 A.erase(itb);
01648
01649 for(itb=A.begin();(*itb)!=unsigned(elem2);++itb)
01650 { }
01651 switch(direction)
01652 {
01653 case 0:
01654 case 1:
01655 break;
01656 case 2:
01657 case 3:
01658 ++itb;
01659 break;
01660 }
01661 A.insert(itb,1,temporary);
01662
01663
01664 for(itb=B.begin();(*itb)!=unsigned(elem1);++itb)
01665 { }
01666 temporary=*itb;
01667 B.erase(itb);
01668
01669 for(itb=B.begin();(*itb)!=unsigned(elem2);++itb)
01670 { }
01671 switch(direction)
01672 {
01673 case 0:
01674 case 2:
01675 break;
01676 case 1:
01677 case 3:
01678 ++itb;
01679 break;
01680 }
01681
01682 B.insert(itb,1,temporary);
01683
01684 return 13;
01685 }
01686
01687
01688 double Annealer::getXSize(void)
01689 {
01690 return _spEval->xSize;
01691 }
01692
01693
01694 double Annealer::getYSize(void)
01695 {
01696 return _spEval->ySize;
01697 }
01698