75void Miaig::create(
int nIns,
int nOuts,
int nObjsAlloc) {
91 _data->
vOrder = Vi_Alloc(1000);
92 _data->
vOrderF = Vi_Alloc(1000);
94 _data->
vTfo = Vi_Alloc(1000);
108 if (pName == NULL || pName[0] ==
'\0') {
109 _data->pName = strdup(
"rewire_miaig");
111 _data->pName = strdup(pName);
118 printf(
"\nAIG printout:\n");
123 printf(
"Node%d {", i);
139 int *pCopy = (
int *)
calloc(
sizeof(
int), Gia_ManObjNum(pGia));
142 create(Gia_ManPiNum(pGia), Gia_ManPoNum(pGia), Gia_ManObjNum(pGia));
144 pCopy[0] = Gia_ObjId(pGia, Gia_ManConst0(pGia));
151 appendFanin(pCopy[i], Rw_Lit2LitV(pCopy, Gia_Obj2Lit(pGia, Gia_ObjChild1(pObj))));
152 appendFanin(pCopy[i], Rw_Lit2LitV(pCopy, Gia_Obj2Lit(pGia, Gia_ObjChild0(pObj))));
161 int *pCopy = (
int *)
calloc(
sizeof(
int), Mini_AigNodeNum(pMiniAig));
162 create(Mini_AigPiNum(pMiniAig), Mini_AigPoNum(pMiniAig), Mini_AigNodeNum(pMiniAig));
169 appendFanin(pCopy[i], Rw_Lit2LitV(pCopy, Mini_AigNodeFanin0(pMiniAig, i)));
170 appendFanin(pCopy[i], Rw_Lit2LitV(pCopy, Mini_AigNodeFanin1(pMiniAig, i)));
181 pGia->
pName = Abc_UtilStrsav(_data->pName);
185 objCopy(i) = Gia_ManAppendCi(pGia);
190 objCopy(i) = Rw_Lit2LitL(_data->pCopy, iLit);
198 Gia_ManAppendCo(pGia, Rw_Lit2LitL(_data->pCopy, iLit));
211 objCopy(i) = Mini_AigCreatePi(pMini);
216 objCopy(i) = Rw_Lit2LitL(_data->pCopy, iLit);
218 objCopy(i) = Mini_AigAnd(pMini,
objCopy(i), Rw_Lit2LitL(_data->pCopy, iLit));
223 Mini_AigCreatePo(pMini, Rw_Lit2LitL(_data->pCopy, iLit));
231 if (_data->pNtkMapped && fMapped) {
234 Abc_NtkSetName(pNtk, Abc_UtilStrsav(_data->pName));
245 p->size = Vec_IntSize(v);
246 p->cap = Vec_IntCap(v);
247 p->ptr = Vec_IntArray(v);
255 assert(Gia_ManCoNum(pExc) ==
nOuts() || Gia_ManCoNum(pExc) == 1);
256 if (Gia_ManCoNum(pExc) !=
nOuts() && Gia_ManCoNum(pExc) == 1) {
257 printf(
"[Warning] The external careset has only a single output that will be applied to all other outputs.\n");
263 Exc.initializeTruth();
264 for (i = 0; i <
nOuts(); ++i) {
273 if (!reset && _data->nTransistor)
return _data->nTransistor;
276 Abc_Ntk_t *pNtkMapped = NULL, *pNtkMappedTemp = NULL;
277 if (nMappedMode == 0) {
281 }
else if (nMappedMode == 1) {
285 }
else if (nMappedMode == 2) {
293 pNtkMapped = pNtkMappedTemp;
307 return _data->nTransistor = area;
311void Miaig::topoCollect_rec(
int iObj) {
316 Vi_PushOrder(_data->
vOrder, iObj);
321vi *Miaig::topoCollect(
void) {
324 Vi_Shrink(_data->
vOrder, 0);
333int Miaig::initializeLevels_rec(
int iObj) {
339 level = Abc_MaxInt(initializeLevels_rec(
Rw_Lit2Var(iLit)), level);
344void Miaig::initializeLevels(
void) {
345 if (_data->pLevel)
return;
346 _data->pLevel = (
int *)
malloc(
sizeof(
int) *
nObjs());
361void Miaig::initializeDists(
void) {
362 if (_data->pDist)
return;
363 _data->pDist = (
int *)
malloc(
sizeof(
int) *
nObjs());
366void Miaig::markDistanceN_rec(
int iObj,
int n,
int limit) {
374 markDistanceN_rec(
Rw_Lit2Var(iLit), n + 1, limit);
377void Miaig::markDistanceN(
int iObj,
int n) {
380 markDistanceN_rec(iObj, 0, n);
381 for (i = 0; i < n; ++i) {
384 int minDist =
nObjs();
389 if (minDist !=
nObjs()) {
390 markDistanceN_rec(j, minDist + 1, n);
396void Miaig::markCritical(
void) {
401 if (
objLevel(iObj) != maxRequire)
continue;
402 markCritical_rec(iObj);
406void Miaig::markCritical_rec(
int iObj) {
444void Miaig::initializeRefs(
void) {
451void Miaig::verifyRefs(
void) {
455 for (i = 0; i <
nObjs(); i++)
457 printf(
"Ref count of node %d is incorrect (%d).\n", i,
objRef(i));
462void Miaig::markDfs_rec(
int iObj) {
471int Miaig::markDfs(
void) {
503 if (_data->pNtkMapped && fMapped)
504 pNew._data->
pNtkMapped = Vi_Dup(_data->pNtkMapped);
510void Miaig::dupDfs_rec(
Miaig &pNew,
int iObj) {
545void Miaig::reduceFanins(
vi *v) {
549 if (Vi_Read(v, 0) == 0) {
553 while (Vi_Read(v, 0) == 1)
555 if (Vi_Size(v) == 0) {
561 int i, iLit, iPrev = Vi_Read(v, 0);
563 if ((iPrev ^ iLit) == 1) {
574int Miaig::hashTwo(
int l0,
int l1,
int TableSize) {
580 return Key % TableSize;
583int *Miaig::hashLookup(
int *pTable,
int l0,
int l1,
int TableSize) {
584 int Key = hashTwo(l0, l1, TableSize);
585 for (; pTable[3 * Key]; Key = (Key + 1) % TableSize)
586 if (pTable[3 * Key] == l0 && pTable[3 * Key + 1] == l1)
587 return pTable + 3 * Key + 2;
588 assert(pTable[3 * Key] == 0);
589 assert(pTable[3 * Key + 1] == 0);
590 assert(pTable[3 * Key + 2] == 0);
591 pTable[3 * Key] = l0;
592 pTable[3 * Key + 1] = l1;
593 return pTable + 3 * Key + 2;
597int Miaig::buildNode(
int l0,
int l1,
int fCprop,
int fStrash) {
599 if (l0 == 0 || l1 == 0 || (l0 ^ l1) == 1)
return 0;
600 if (l0 == l1 || l1 == 1)
return l0;
601 if (l0 == 1)
return l1;
605 pPlace = hashLookup(_data->pTable,
Rw_MinInt(l0, l1),
Rw_MaxInt(l0, l1), _data->TableSize);
615int Miaig::buildNodeBalance_rec(
Miaig &pNew,
vi *vFanins,
int begin,
int end,
int fCprop,
int fStrash) {
616 int length = end - begin + 1;
618 return Rw_Lit2LitL(_data->pCopy, Vi_Read(vFanins, begin));
619 }
else if (length == 2) {
620 return pNew.buildNode(Rw_Lit2LitL(_data->pCopy, Vi_Read(vFanins, begin)), Rw_Lit2LitL(_data->pCopy, Vi_Read(vFanins, end)), fCprop, fStrash);
622 int middle = begin + length / 2;
623 int iLit0 = buildNodeBalance_rec(pNew, vFanins, begin, middle - 1, fCprop, fStrash);
624 int iLit1 = buildNodeBalance_rec(pNew, vFanins, middle, end, fCprop, fStrash);
625 return pNew.buildNode(iLit0, iLit1, fCprop, fStrash);
628int Miaig::buildNodeBalance(
Miaig &pNew,
vi *vFanins,
int fCprop,
int fStrash) {
629 return buildNodeBalance_rec(pNew, vFanins, 0, Vi_Size(vFanins) - 1, fCprop, fStrash);
632int Miaig::buildNodeCascade(
Miaig &pNew,
vi *vFanins,
int fCprop,
int fStrash) {
634 for (
int i = 0; i < Vi_Size(vFanins); ++i) {
636 iLit = Rw_Lit2LitL(_data->pCopy, Vi_Read(vFanins, i));
638 iLit = pNew.buildNode(iLit, Rw_Lit2LitL(_data->pCopy, Vi_Read(vFanins, i)), fCprop, fStrash);
667int *Miaig::createStops(
void) {
668 int i, *pStop = (
int *)
calloc(
sizeof(
int),
nObjs());
683void Miaig::collectSuper_rec(
int iLit,
int *pStop,
vi *vSuper) {
685 Vi_Push(vSuper, Rw_Lit2LitL(_data->pCopy, iLit));
695 int *pStop = createStops();
697 vi *vArray = Vi_Alloc(100);
698 assert(nFaninMax_ >= 2 && nGrowth >= 1);
706 Vi_Shrink(vArray, 0);
707 collectSuper_rec(
objFanin0(i), pStop, vArray);
708 collectSuper_rec(
objFanin1(i), pStop, vArray);
709 assert(Vi_Size(vArray) > 1);
710 reduceFanins(vArray);
711 assert(Vi_Size(vArray) > 0);
712 if (Vi_Size(vArray) == 1)
713 objCopy(i) = Vi_Read(vArray, 0);
715 int nFaninMaxLocal = 2 + (
Random_Num(0) % (nFaninMax_ - 1));
716 int nGrowthLocal = 1 + (
Random_Num(0) % nGrowth);
717 assert(nFaninMaxLocal >= 2 && nFaninMaxLocal <= nFaninMax_);
718 assert(nGrowthLocal >= 1 && nGrowthLocal <= nGrowth);
720 if (Vi_Size(vArray) > nFaninMaxLocal)
721 Vi_Randomize(vArray);
723 while (Vi_Size(vArray) > nFaninMaxLocal) {
727 vFanins->
cap = nFaninMaxLocal + nGrowthLocal;
728 vFanins->
ptr = (
int *)
malloc(
sizeof(
int) * vFanins->
cap);
731 assert(Vi_Space(vFanins) == nGrowthLocal);
732 for (k = 0; k < nFaninMaxLocal; k++)
740 vFanins->
cap = Vi_Size(vArray) + nGrowthLocal;
741 vFanins->
ptr = (
int *)
malloc(
sizeof(
int) * vFanins->
cap);
744 assert(Vi_Space(vFanins) == nGrowthLocal);
756void Miaig::truthSimNode(
int i) {
765word *Miaig::truthSimNodeSubset(
int i,
int m) {
766 int k, iLit, Counter = 0;
776 assert(Counter == Tt_BitCount16(m));
780word *Miaig::truthSimNodeSubset2(
int i,
vi *vFanins,
int nFanins) {
789void Miaig::initializeTruth(
void) {
791 if (_data->pTruths[0])
794 _data->pTruths[1] = _data->pTruths[0] + 1 *
nWords() *
nObjs();
795 _data->pTruths[2] = _data->pTruths[0] + 2 *
nWords() *
nObjs();
798 float MemMB = 8.0 *
nWords() * (3 *
nObjs() + 2) / (1 << 20);
800 printf(
"Allocated %d truth tables of %d-variable functions (%.2f MB),\n", 3 *
nObjs() + 2,
nIns(), MemMB);
812void Miaig::truthUpdate(
vi *vTfo,
word *pExc,
int fCheck) {
813 int i, iTemp, nFails = 0;
819 printf(
"Verification failed at output %d.\n", iTemp - (
nObjs() -
nOuts())), nFails++;
825 printf(
"Verification failed at output %d.\n", iTemp - (
nObjs() -
nOuts())), nFails++;
829 if (fCheck && nFails)
830 printf(
"Verification failed for %d outputs after updating node %d.\n", nFails, Vi_Read(vTfo, 0));
833int Miaig::computeTfo_rec(
int iObj) {
834 int k, iLit,
Value = 0;
843 if (Value) Vi_Push(_data->vTfo, iObj);
847vi *Miaig::computeTfo(
int iObj) {
852 Vi_Fill(_data->vTfo, 1, iObj);
863word *Miaig::computeCareSet(
int iObj,
word *pExc) {
864 vi *vTfo = computeTfo(iObj);
867 Tt_Clear(_data->pCare,
nWords());
885void Miaig::addPair(
vi *vPair,
int iFan1,
int iFan2) {
887 int i, *pArray = Vi_Array(vPair);
888 assert(Vi_Size(vPair) % 3 == 0);
889 for (i = 0; i < Vi_Size(vPair); i += 3)
890 if (pArray[i] == iFan1 && pArray[i + 1] == iFan2)
892 if (i == Vi_Size(vPair)) {
893 Vi_Push(vPair, iFan1);
894 Vi_Push(vPair, iFan2);
896 pArray = Vi_Array(vPair);
902int Miaig::findPair(
vi *vPair) {
903 int iBest = -1, BestCost = 0;
904 int i, *pArray = Vi_Array(vPair);
905 assert(Vi_Size(vPair) % 3 == 0);
906 for (i = 0; i < Vi_Size(vPair); i += 3)
907 if (BestCost < pArray[i + 2]) {
908 BestCost = pArray[i + 2];
916int Miaig::updateFanins(
vi *vFans,
int iFan1,
int iFan2,
int iLit) {
917 int f1, f2, iFan1_, iFan2_;
923 Vi_Push(vFans, iLit);
930void Miaig::extractBest(
vi *vPairs) {
932 int Counter = 0, *pArray = Vi_Array(vPairs);
933 int iBest = findPair(vPairs);
940 Counter += updateFanins(
objFanins(i), pArray[iBest], pArray[iBest + 1],
Rw_Var2Lit(iObj, 0));
941 assert(Counter == pArray[iBest + 2]);
946 vi *vPairs = Vi_Alloc(30);
947 int i, f1, f2, iFan1, iFan2;
953 if (Tt_GetBit(pRowFan1, iFan2)) addPair(vPairs, iFan1, iFan2);
954 else Tt_SetBit(pRowFan1, iFan2);
962int Miaig::findShared(
int nNewNodesMax) {
975 for (i = 0; i < nNewNodesMax; i++) {
976 memset(pSto, 0, nBytesAll);
978 vPairs = findPairs(pSto,
nWords);
980 if (Vi_Size(vPairs) > 0)
982 int Size = Vi_Size(vPairs);
991int Miaig::checkConst(
int iObj,
word *pCare,
word *pExc,
int fCheck,
int fVerbose) {
993 if (!Tt_IntersectC(pCare, pFunc, 0,
nWords())) {
997 truthUpdate(_data->vTfo, pExc, fCheck);
998 if (fVerbose) printf(
"Detected Const0 at node %d.\n", iObj);
1001 if (!Tt_IntersectC(pCare, pFunc, 1,
nWords())) {
1005 truthUpdate(_data->vTfo, pExc, fCheck);
1006 if (fVerbose) printf(
"Detected Const1 at node %d.\n", iObj);
1012int Miaig::expandOne(
int iObj,
int nAddedMax,
int nDist,
int nExpandableLevel,
word *pExc,
int fCheck,
int fVerbose) {
1013 int i, k, n, iLit, nAdded = 0;
1014 word *pCare = computeCareSet(iObj, pExc);
1022 Tt_Sharp(pOnset, pCare, 0,
nWords());
1024 Vi_Shrink(_data->vOrderF, 0);
1025 if (nDist) markDistanceN(iObj, nDist);
1030 Vi_Push(_data->vOrderF, i);
1032 Vi_Randomize(_data->vOrderF);
1034 int *pOrderF = Vi_Array(_data->vOrderF);
1035 std::stable_sort(pOrderF, pOrderF + Vi_Size(_data->vOrderF), [&](
int a,
int b) {
1036 return objLevel(Rw_Lit2Var(a)) > objLevel(Rw_Lit2Var(b));
1038 std::stable_sort(pOrderF, pOrderF + Vi_Size(_data->vOrderF), [&](
int a,
int b) {
1039 if (objLevel(Rw_Lit2Var(a)) == 0 || objLevel(Rw_Lit2Var(b)) == 0) {
1047 assert(objTravId(i) != nTravIds());
1049 for (n = 0; n < 2; n++)
1050 if (!Tt_IntersectC(pOnset, objTruth(i, 0), !n,
nWords())) {
1051 if (fVerbose) printf(
"Adding node %d fanin %d\n", iObj,
Rw_Var2Lit(i, n));
1057 if (nAdded == nAddedMax)
1061 truthUpdate(_data->vTfo, pExc, fCheck);
1066int Miaig::reduceOne(
int iObj,
int fOnlyConst,
int fOnlyBuffer,
int fHeuristic,
word *pExc,
int fCheck,
int fVerbose) {
1067 int n, k, iLit, nFans = objFaninNum(iObj);
1068 word *pCare = computeCareSet(iObj, pExc);
1069 if (checkConst(iObj, pCare, pExc, fCheck, fVerbose))
1076 word *pFunc = objTruth(iObj, 0);
1079 if (Tt_EqualOnCare(pCare, pFunc, _data->pProd,
nWords())) {
1081 Vi_Fill(objFanins(iObj), 1, iLit);
1083 truthUpdate(_data->vTfo, pExc, fCheck);
1084 if (fVerbose) printf(
"Reducing node %d fanin count from %d to %d.\n", iObj, nFans, objFaninNum(iObj));
1090 Vi_Shrink(_data->vOrderF, 0);
1092 Vi_Push(_data->vOrderF, iLit);
1093 Vi_Randomize(_data->vOrderF);
1096 int *pOrderF = Vi_Array(_data->vOrderF);
1097 std::stable_sort(pOrderF, pOrderF + Vi_Size(_data->vOrderF), [&](
int a,
int b) {
1098 return objLevel(Rw_Lit2Var(a)) < objLevel(Rw_Lit2Var(b));
1100 std::stable_sort(pOrderF, pOrderF + Vi_Size(_data->vOrderF), [&](
int a,
int b) {
1101 if (objLevel(Rw_Lit2Var(a)) == 0 || objLevel(Rw_Lit2Var(b)) == 0) {
1108 assert(Vi_Size(_data->vOrderF) == nFans);
1110 for (n = Vi_Size(_data->vOrderF) - 1; n >= 0; n--) {
1111 int iFanin = Vi_Drop(_data->vOrderF, n);
1112 word *pProd = truthSimNodeSubset2(iObj, _data->vOrderF, Vi_Size(_data->vOrderF));
1113 if (!Tt_EqualOnCare(pCare, pFunc, pProd,
nWords()))
1114 Vi_Push(_data->vOrderF, iFanin);
1116 assert(Vi_Size(_data->vOrderF) >= 1);
1118 if (Vi_Size(_data->vOrderF) < nFans) {
1120 Vi_Shrink(objFanins(iObj), 0);
1122 Vi_PushOrder(objFanins(iObj), iLit);
1124 truthUpdate(_data->vTfo, pExc, fCheck);
1125 if (fVerbose) printf(
"Reducing node %d fanin count from %d to %d.\n", iObj, nFans, objFaninNum(iObj));
1126 return nFans - Vi_Size(_data->vOrderF);
1131int Miaig::expandThenReduceOne(
int iNode,
int nFaninAddLimit,
int nDist,
int nExpandableLevel,
word *pExc,
int fCheck,
int fVerbose) {
1132 expandOne(iNode, std::min(Vi_Space(objFanins(iNode)), nFaninAddLimit), nDist, nExpandableLevel, pExc, fCheck, fVerbose);
1133 reduceOne(iNode, 0, 0, 0, pExc, fCheck, fVerbose);
1137vi *Miaig::createRandomOrder(
void) {
1139 Vi_Shrink(_data->vOrder, 0);
1141 Vi_Push(_data->vOrder, i);
1142 Vi_Randomize(_data->vOrder);
1143 return _data->vOrder;
1147 int i, iNode, nAdded = 0;
1148 assert(nFaninAddLimitAll > 0);
1149 vi *vOrder = createRandomOrder();
1154 if (nDist) initializeDists();
1156 nAdded += expandOne(iNode, std::min(Vi_Space(
objFanins(iNode)), nFaninAddLimitAll - nAdded), nDist, nExpandableLevel, pExc, fCheck, fVerbose);
1157 if (nAdded >= nFaninAddLimitAll)
1160 assert(nAdded <= nFaninAddLimitAll);
1161 if (fCheck) verifyRefs();
1168 int nNewNodes = pCopy.findShared(nNewNodesMax);
1172 pCopy.
nObjs() -= nNewNodes;
1174 pCopy.
nObjs() += nNewNodes;
1180 vi *vOrder = topoCollect();
1187 reduceOne(iNode, 0, 0, 1, pExc, fCheck, fVerbose);
1188 if (fCheck) verifyRefs();
1195 vi *vOrder = topoCollect();
1200 if (nDist) initializeDists();
1202 expandThenReduceOne(iNode, nFaninAddLimit, nDist, nExpandableLevel, pExc, fCheck, fVerbose);
1204 if (fCheck) verifyRefs();
1205 return dupDfs().dupStrash(1, 1, 1);
1210 Miaig pNew =
expand(nFaninAddLimitAll, nDist, nExpandableLevel, pExc, fCheck, nVerbose);
1212 pNew = pNew.
share(nDivs == -1 ? pNew.
nObjs() : nDivs);
1214 pNew = pNew.
reduce(pExc, fCheck, nVerbose);
1224 if (pBests.size() < nBestSave) {
1225 pBests.push_back(pNew);
1228 pBests[iNum] = pNew;
1233 return pBests[
Random_Num(0) % pBests.size()];
1238 return (pBests[iNum] == pExcept) ? pBests[(iNum + 1) % pBests.size()] : pBests[iNum];
1241Miaig Miaig::rewire(
int nIters,
float levelGrowRatio,
int nExpands,
int nGrowth,
int nDivs,
int nFaninMax,
int nTimeOut,
int nMode,
int nMappedMode,
int nDist,
int fCheck,
Gia_ChMan_t *pChMan,
int nVerbose) {
1242 const int nRootSave = 8;
1243 const int nBestSave = 4;
1244 int nRestart = 5000;
1245 std::vector<Miaig> pRoots = {this->
dup(0)};
1246 std::vector<Miaig> pBests = {this->
dup(0)};
Miaig pInit = pBests[0];
1247 iword clkStart = Time_Clock();
1249 Miaig pRoot = pRoots[0];
1250 Miaig pBest = this->
dup(0);
int improved = 0;
1252 int maxLevel = levelGrowRatio != 0 ? this->
countLevel() * levelGrowRatio : 0;
1253 int nExpandableLevel = maxLevel ? maxLevel - this->
countLevel() : 0;
1254 int fMapped = nMode > 0;
1255 word *pExc = _data->pExc;
1257 float PrevBest = ((&pBest)->*Miaig_ObjectiveFunction)(1, nMappedMode);
1258 int iterNotImproveAfterRestart = 0;
1259 if (nVerbose && maxLevel) printf(
"Max level : %5d\n", maxLevel);
1260 if (nVerbose) printf(
"Initial target : %5g (AND2 = %5g Level = %3d)\n", PrevBest, this->
countAnd2(1), this->countLevel());
1261 for (
int i = 0; nIters ? i < nIters : 1; i++) {
1262 if (nVerbose) printf(
"\rIteration %7d(%zu) : %5g -> ", i + 1, pBests.size(), ((&pRoot)->*Miaig_ObjectiveFunction)(0, nMappedMode));
1263 if (nTimeOut && nTimeOut < 1.0 * (Time_Clock() - clkStart) / CLOCKS_PER_SEC)
break;
1264 if (PrevBest == 0)
break;
1265 pNew = pRoot.
dupMulti(nFaninMax, nGrowth);
1268 pNew = pNew.
expandThenReduce(nGrowth, nDist, nExpandableLevel, pExc, fCheck, nVerbose > 1);
1270 pNew = pNew.
expandShareReduce(nExpands, nDivs, nDist, nExpandableLevel, pExc, fCheck, nVerbose > 1);
1272 ++iterNotImproveAfterRestart;
1274 float rootTarget = ((&pRoot)->*Miaig_ObjectiveFunction)(0, nMappedMode);
1275 float newTarget = ((&pNew)->*Miaig_ObjectiveFunction)(1, nMappedMode);
1276 if (maxLevel ? pNew.
countLevel() > maxLevel : 0) {
1277 }
else if (PrevBest > newTarget) {
1278 if (nVerbose) printf(
"%5g (AND2 = %5g Level = %3d) ", newTarget, pNew.
countAnd2(), pNew.
countLevel());
1279 if (nVerbose) Time_PrintEndl(
"Elapsed time", Time_Clock() - clkStart);
1280 PrevBest = newTarget;
1281 pBests = {pNew.
dup(0), pNew.
dup(0)};
1282 pBest = pNew.
dup(0, fMapped), improved = 1;
1283 iterNotImproveAfterRestart = 0;
1284 }
else if (PrevBest == newTarget) {
1288 if (maxLevel ? pNew.
countLevel() > maxLevel : 0) {
1289 }
else if (rootTarget < newTarget) {
1290 if (iterNotImproveAfterRestart > nRestart) {
1291 pNew =
randomRead(pBests).dupMulti(nFaninMax, nGrowth);
1292 pNew = pNew.
expand(nExpands, nDist, nExpandableLevel, pExc, fCheck, nVerbose > 1);
1293 pNew = pNew.
share(nDivs == -1 ? pNew.
nObjs() : nDivs);
1296 iterNotImproveAfterRestart = 0;
1297 }
else if (rootTarget * 1.05 > newTarget) {
1300 }
else if (rootTarget == newTarget) {
1307 if (nVerbose) Time_PrintEndl(
"Total solving time", Time_Clock() - clkStart);