00001
00019 #include "fxuInt.h"
00020
00024
00025 #define MAX_SIZE_LOOKAHEAD 20
00026
00027 static int Fxu_MatrixFindComplement( Fxu_Matrix * p, int iVar );
00028
00029 static Fxu_Double * Fxu_MatrixFindComplementSingle( Fxu_Matrix * p, Fxu_Single * pSingle );
00030 static Fxu_Single * Fxu_MatrixFindComplementDouble2( Fxu_Matrix * p, Fxu_Double * pDouble );
00031 static Fxu_Double * Fxu_MatrixFindComplementDouble4( Fxu_Matrix * p, Fxu_Double * pDouble );
00032
00033 Fxu_Double * Fxu_MatrixFindDouble( Fxu_Matrix * p,
00034 int piVarsC1[], int piVarsC2[], int nVarsC1, int nVarsC2 );
00035 void Fxu_MatrixGetDoubleVars( Fxu_Matrix * p, Fxu_Double * pDouble,
00036 int piVarsC1[], int piVarsC2[], int * pnVarsC1, int * pnVarsC2 );
00037
00038
00042
00054 int Fxu_Select( Fxu_Matrix * p, Fxu_Single ** ppSingle, Fxu_Double ** ppDouble )
00055 {
00056
00057 Fxu_Single * pSingles[MAX_SIZE_LOOKAHEAD];
00058 Fxu_Double * pDoubles[MAX_SIZE_LOOKAHEAD];
00059
00060 Fxu_Double * pSCompl[MAX_SIZE_LOOKAHEAD];
00061 Fxu_Single * pDComplS[MAX_SIZE_LOOKAHEAD];
00062 Fxu_Double * pDComplD[MAX_SIZE_LOOKAHEAD];
00063 Fxu_Pair * pPair;
00064 int nSingles;
00065 int nDoubles;
00066 int i;
00067 int WeightBest;
00068 int WeightCur;
00069 int iNum, fBestS;
00070
00071
00072 for ( nSingles = 0; nSingles < MAX_SIZE_LOOKAHEAD; nSingles++ )
00073 {
00074 pSingles[nSingles] = Fxu_HeapSingleGetMax( p->pHeapSingle );
00075 if ( pSingles[nSingles] == NULL )
00076 break;
00077 }
00078
00079 for ( i = 0; i < nSingles; i++ )
00080 if ( pSingles[i] )
00081 Fxu_HeapSingleInsert( p->pHeapSingle, pSingles[i] );
00082
00083
00084
00085 for ( nDoubles = 0; nDoubles < MAX_SIZE_LOOKAHEAD; nDoubles++ )
00086 {
00087 pDoubles[nDoubles] = Fxu_HeapDoubleGetMax( p->pHeapDouble );
00088 if ( pDoubles[nDoubles] == NULL )
00089 break;
00090 }
00091
00092 for ( i = 0; i < nDoubles; i++ )
00093 if ( pDoubles[i] )
00094 Fxu_HeapDoubleInsert( p->pHeapDouble, pDoubles[i] );
00095
00096
00097 for ( i = 0; i < nSingles; i++ )
00098 if ( pSingles[i] )
00099 pSCompl[i] = Fxu_MatrixFindComplementSingle( p, pSingles[i] );
00100
00101
00102 for ( i = 0; i < nDoubles; i++ )
00103 if ( pDoubles[i] )
00104 {
00105 pPair = pDoubles[i]->lPairs.pHead;
00106 if ( pPair->nLits1 == 1 && pPair->nLits2 == 1 )
00107 {
00108 pDComplS[i] = Fxu_MatrixFindComplementDouble2( p, pDoubles[i] );
00109 pDComplD[i] = NULL;
00110 }
00111
00112
00113
00114
00115
00116 else
00117 {
00118 pDComplS[i] = NULL;
00119 pDComplD[i] = NULL;
00120 }
00121 }
00122
00123
00124 WeightBest = -1;
00125 for ( i = 0; i < nSingles; i++ )
00126 {
00127 WeightCur = pSingles[i]->Weight;
00128 if ( pSCompl[i] )
00129 {
00130
00131 WeightCur += pSCompl[i]->Weight;
00132
00133 pPair = pSCompl[i]->lPairs.pHead;
00134 WeightCur += pPair->nLits1 + pPair->nLits2;
00135 }
00136 if ( WeightBest < WeightCur )
00137 {
00138 WeightBest = WeightCur;
00139 *ppSingle = pSingles[i];
00140 *ppDouble = pSCompl[i];
00141 fBestS = 1;
00142 iNum = i;
00143 }
00144 }
00145 for ( i = 0; i < nDoubles; i++ )
00146 {
00147 WeightCur = pDoubles[i]->Weight;
00148 if ( pDComplS[i] )
00149 {
00150
00151 WeightCur += pDComplS[i]->Weight;
00152
00153 pPair = pDoubles[i]->lPairs.pHead;
00154 WeightCur += pPair->nLits1 + pPair->nLits2;
00155 }
00156 if ( WeightBest < WeightCur )
00157 {
00158 WeightBest = WeightCur;
00159 *ppSingle = pDComplS[i];
00160 *ppDouble = pDoubles[i];
00161 fBestS = 0;
00162 iNum = i;
00163 }
00164 }
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204 return WeightBest;
00205 }
00206
00207
00219 Fxu_Double * Fxu_MatrixFindComplementSingle( Fxu_Matrix * p, Fxu_Single * pSingle )
00220 {
00221
00222 int iVar1, iVar2;
00223 int iVar1C, iVar2C;
00224
00225 iVar1 = pSingle->pVar1->iVar;
00226 iVar2 = pSingle->pVar2->iVar;
00227 iVar1C = Fxu_MatrixFindComplement( p, iVar1 );
00228 iVar2C = Fxu_MatrixFindComplement( p, iVar2 );
00229 if ( iVar1C == -1 || iVar2C == -1 )
00230 return NULL;
00231 assert( iVar1C < iVar2C );
00232 return Fxu_MatrixFindDouble( p, &iVar1C, &iVar2C, 1, 1 );
00233 }
00234
00246 Fxu_Single * Fxu_MatrixFindComplementDouble2( Fxu_Matrix * p, Fxu_Double * pDouble )
00247 {
00248
00249 int piVarsC1[10], piVarsC2[10];
00250 int nVarsC1, nVarsC2;
00251 int iVar1, iVar2, iVarTemp;
00252 int iVar1C, iVar2C;
00253 Fxu_Single * pSingle;
00254
00255
00256 Fxu_MatrixGetDoubleVars( p, pDouble, piVarsC1, piVarsC2, &nVarsC1, &nVarsC2 );
00257 assert( nVarsC1 == 1 );
00258 assert( nVarsC2 == 1 );
00259 iVar1 = piVarsC1[0];
00260 iVar2 = piVarsC2[0];
00261 assert( iVar1 < iVar2 );
00262
00263 iVar1C = Fxu_MatrixFindComplement( p, iVar1 );
00264 iVar2C = Fxu_MatrixFindComplement( p, iVar2 );
00265 if ( iVar1C == -1 || iVar2C == -1 )
00266 return NULL;
00267
00268
00269
00270 if ( iVar1C > iVar2C )
00271 {
00272 iVarTemp = iVar1C;
00273 iVar1C = iVar2C;
00274 iVar2C = iVarTemp;
00275 }
00276
00277 Fxu_MatrixForEachSingle( p, pSingle )
00278 if ( pSingle->pVar1->iVar == iVar1C && pSingle->pVar2->iVar == iVar2C )
00279 return pSingle;
00280 return NULL;
00281 }
00282
00294 Fxu_Double * Fxu_MatrixFindComplementDouble4( Fxu_Matrix * p, Fxu_Double * pDouble )
00295 {
00296
00297 int piVarsC1[10], piVarsC2[10];
00298 int nVarsC1, nVarsC2;
00299 int iVar11, iVar12, iVar21, iVar22;
00300 int iVar11C, iVar12C, iVar21C, iVar22C;
00301 int RetValue;
00302
00303
00304 Fxu_MatrixGetDoubleVars( p, pDouble, piVarsC1, piVarsC2, &nVarsC1, &nVarsC2 );
00305 assert( nVarsC1 == 2 && nVarsC2 == 2 );
00306
00307 iVar11 = piVarsC1[0];
00308 iVar12 = piVarsC1[1];
00309 iVar21 = piVarsC2[0];
00310 iVar22 = piVarsC2[1];
00311 assert( iVar11 < iVar21 );
00312
00313 iVar11C = Fxu_MatrixFindComplement( p, iVar11 );
00314 iVar12C = Fxu_MatrixFindComplement( p, iVar12 );
00315 iVar21C = Fxu_MatrixFindComplement( p, iVar21 );
00316 iVar22C = Fxu_MatrixFindComplement( p, iVar22 );
00317 if ( iVar11C == -1 || iVar12C == -1 || iVar21C == -1 || iVar22C == -1 )
00318 return NULL;
00319 if ( iVar11C != iVar21 || iVar12C != iVar22 ||
00320 iVar21C != iVar11 || iVar22C != iVar12 )
00321 return NULL;
00322
00323
00324
00325
00326 RetValue = piVarsC1[1];
00327 piVarsC1[1] = piVarsC2[1];
00328 piVarsC2[1] = RetValue;
00329
00330 return Fxu_MatrixFindDouble( p, piVarsC1, piVarsC2, 2, 2 );
00331 }
00332
00333
00345 int Fxu_MatrixFindComplement( Fxu_Matrix * p, int iVar )
00346 {
00347 return iVar ^ 1;
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386 }
00387
00388
00400 void Fxu_MatrixGetDoubleVars( Fxu_Matrix * p, Fxu_Double * pDouble,
00401 int piVarsC1[], int piVarsC2[], int * pnVarsC1, int * pnVarsC2 )
00402 {
00403 Fxu_Pair * pPair;
00404 Fxu_Lit * pLit1, * pLit2;
00405 int nLits1, nLits2;
00406
00407
00408 pPair = pDouble->lPairs.pHead;
00409
00410 nLits1 = 0;
00411 nLits2 = 0;
00412 pLit1 = pPair->pCube1->lLits.pHead;
00413 pLit2 = pPair->pCube2->lLits.pHead;
00414 while ( 1 )
00415 {
00416 if ( pLit1 && pLit2 )
00417 {
00418 if ( pLit1->iVar == pLit2->iVar )
00419 {
00420 pLit1 = pLit1->pHNext;
00421 pLit2 = pLit2->pHNext;
00422 }
00423 else if ( pLit1->iVar < pLit2->iVar )
00424 {
00425 piVarsC1[nLits1++] = pLit1->iVar;
00426 pLit1 = pLit1->pHNext;
00427 }
00428 else
00429 {
00430 piVarsC2[nLits2++] = pLit2->iVar;
00431 pLit2 = pLit2->pHNext;
00432 }
00433 }
00434 else if ( pLit1 && !pLit2 )
00435 {
00436 piVarsC1[nLits1++] = pLit1->iVar;
00437 pLit1 = pLit1->pHNext;
00438 }
00439 else if ( !pLit1 && pLit2 )
00440 {
00441 piVarsC2[nLits2++] = pLit2->iVar;
00442 pLit2 = pLit2->pHNext;
00443 }
00444 else
00445 break;
00446 }
00447 *pnVarsC1 = nLits1;
00448 *pnVarsC2 = nLits2;
00449 }
00450
00451
00463 Fxu_Double * Fxu_MatrixFindDouble( Fxu_Matrix * p,
00464 int piVarsC1[], int piVarsC2[], int nVarsC1, int nVarsC2 )
00465 {
00466 int piVarsC1_[100], piVarsC2_[100];
00467 int nVarsC1_, nVarsC2_, i;
00468 Fxu_Double * pDouble;
00469 Fxu_Pair * pPair;
00470 unsigned Key;
00471
00472 assert( nVarsC1 > 0 );
00473 assert( nVarsC2 > 0 );
00474 assert( piVarsC1[0] < piVarsC2[0] );
00475
00476
00477 Key = Fxu_PairHashKeyArray( p, piVarsC1, piVarsC2, nVarsC1, nVarsC2 );
00478
00479
00480 Key %= p->nTableSize;
00481 Fxu_TableForEachDouble( p, Key, pDouble )
00482 {
00483 pPair = pDouble->lPairs.pHead;
00484 if ( pPair->nLits1 != nVarsC1 )
00485 continue;
00486 if ( pPair->nLits2 != nVarsC2 )
00487 continue;
00488
00489 Fxu_MatrixGetDoubleVars( p, pDouble, piVarsC1_, piVarsC2_, &nVarsC1_, &nVarsC2_ );
00490
00491 for ( i = 0; i < nVarsC1; i++ )
00492 if ( piVarsC1[i] != piVarsC1_[i] )
00493 break;
00494 if ( i != nVarsC1 )
00495 continue;
00496
00497 for ( i = 0; i < nVarsC2; i++ )
00498 if ( piVarsC2[i] != piVarsC2_[i] )
00499 break;
00500 if ( i != nVarsC2 )
00501 continue;
00502 return pDouble;
00503 }
00504 return NULL;
00505 }
00506
00507
00508
00509
00510
00522 int Fxu_SelectSCD( Fxu_Matrix * p, int WeightLimit, Fxu_Var ** ppVar1, Fxu_Var ** ppVar2 )
00523 {
00524
00525 Fxu_Var * pVar1;
00526 Fxu_Var * pVar2, * pVarTemp;
00527 Fxu_Lit * pLitV, * pLitH;
00528 int Coin;
00529 int CounterAll;
00530 int CounterTest;
00531 int WeightCur;
00532 int WeightBest;
00533
00534 CounterAll = 0;
00535 CounterTest = 0;
00536
00537 WeightBest = -10;
00538
00539
00540 Fxu_MatrixForEachVariable( p, pVar1 )
00541 {
00542
00543 Fxu_MatrixRingVarsStart( p );
00544
00545
00546 for ( pLitV = pVar1->lLits.pHead; pLitV; pLitV = pLitV->pVNext )
00547 {
00548
00549 for ( pLitH = pLitV->pHNext; pLitH; pLitH = pLitH->pHNext )
00550 {
00551
00552 pVar2 = pLitH->pVar;
00553 CounterAll++;
00554
00555 if ( pVar2->pOrder )
00556 continue;
00557
00558
00559
00560
00561 Fxu_MatrixRingVarsAdd( p, pVar2 );
00562 }
00563 }
00564
00565 Fxu_MatrixRingVarsStop( p );
00566
00567
00568 Fxu_MatrixForEachVarInRing( p, pVar2 )
00569 {
00570 CounterTest++;
00571
00572
00573 Coin = Fxu_SingleCountCoincidence( p, pVar1, pVar2 );
00574 assert( Coin > 0 );
00575
00576
00577 WeightCur = Coin - 2;
00578
00579
00580 if ( WeightBest < WeightCur )
00581 {
00582 WeightBest = WeightCur;
00583 *ppVar1 = pVar1;
00584 *ppVar2 = pVar2;
00585 }
00586 }
00587
00588 Fxu_MatrixForEachVarInRingSafe( p, pVar2, pVarTemp )
00589 pVar2->pOrder = NULL;
00590 Fxu_MatrixRingVarsReset( p );
00591 }
00592
00593
00594
00595 return WeightBest;
00596 }
00597
00598
00602
00603