diff --git a/components.c b/components.c index 9e549ba36b9a2d8698952f508815929e8c49b0ff..3f019baa3e1d435882d8cb6a5c45e747886bcfbe 100644 --- a/components.c +++ b/components.c @@ -39,7 +39,25 @@ void allocSearchConnectedComponents(Graph g) { // Search connected components of the subgraph delimited by V // verif is just used to verify for each vertex that it is in the current set (useless for greedy search) -int searchConnectedComponents(SET V, int S[], int n, Graph g) { + + +void compExploreBFSOrderedNeighbors(int num, int nbNiS[],Graph g) { + while (last != first) { + int e = *first; + first = first+1; + if (first == queue+g->n) first = queue; + for (int *p = g->lists[e]; p < g->lists[e]+nbNiS[e]; p ++) { + if (iComp[*p] == NONE) { + iComp[*p] = num; + compSizes[num]++; + *last++ = *p; + if (last == queue + g->n) last = queue; + } + } + } +} + +int searchConnectedComponents(int S[], int n, int nbNiS[], Graph g) { int nbComp = 0; int nbNodes = 0; @@ -56,7 +74,7 @@ int searchConnectedComponents(SET V, int S[], int n, Graph g) { //firstOfComp[nbComp] = S[i]; first = last = queue; *last++ = S[i]; - compExploreBFS(nbComp, V, S, n, g, 1); + compExploreBFSOrderedNeighbors(nbComp, nbNiS, g); if (compSizes[nbComp] > sizeCompMax) sizeCompMax = compSizes[nbComp]; nbNodes += compSizes[nbComp]; nbComp++; @@ -66,7 +84,33 @@ int searchConnectedComponents(SET V, int S[], int n, Graph g) { return nbComp; } +#ifdef NOTDEF +int searchConnectedComponents(SET V, int S[], int n, Graph g) { + + int nbComp = 0; + int nbNodes = 0; + sizeCompMax = 0; + for (int i = 0; i < n; i++) + iComp[S[i]] = NONE; + + // Call BFS exploration from each node of S[] + for (int i = 0; i < n; i++) { + if (iComp[S[i]] == NONE) { + iComp[S[i]] = nbComp; + compSizes[nbComp] = 1; + //firstOfComp[nbComp] = S[i]; + first = last = queue; + *last++ = S[i]; + compExploreBFS(nbComp, V, S, n, g, 1); + if (compSizes[nbComp] > sizeCompMax) sizeCompMax = compSizes[nbComp]; + nbNodes += compSizes[nbComp]; + nbComp++; + if (nbNodes == n) break; + } + } + return nbComp; +} void compExploreBFS(int num, SET V, int S[], int n, Graph g, int verif) { while (last != first) { @@ -86,7 +130,7 @@ void compExploreBFS(int num, SET V, int S[], int n, Graph g, int verif) { } } } - +#endif // Special version for separators: the neighbors of each vertex are ordered so as that those in S @@ -228,29 +272,6 @@ int searchConnectedComponentsGreedy(SET V, Heap heap, Graph g, int removedVertex -int nbCCE = 0; - -void compExplore(int u, int num, SET V, int S[], int n, Graph g, int depth) { - LIST q = g->adj[u]; - int nbNeighbors = 0; - nbCCE ++; - - //if (nbCCE >= 2011872) printf("depth=%d n=%d u=%d size=%d\n", depth, n, u, compSizes[num]); - - while (q != NULL) { - nbNeighbors ++; - if (nbNeighbors > g->nadj[u]) {printf("too many neighbors !\n"); exit(0);} - if ((isInSet(q->val, V, S, n)) && (iComp[q->val] == NONE)) { //((IN(q->val, V)) && (iComp[q->val] == NONE)) { - iComp[q->val] = num; - compSizes[num] ++; - compExplore(q->val, num, V, S, n, g, depth+1); - } - q = q->suiv; - } -} - - - // // utils // diff --git a/components.h b/components.h index 75c9307bebb3c14c0521432b2a9b6067338f380b..0b13d52ed63c212af7d41147ffd9e03b46240923 100644 --- a/components.h +++ b/components.h @@ -20,9 +20,9 @@ extern int sizeCompMax; void allocSearchConnectedComponents(Graph g); -int searchConnectedComponents(SET V, int S[], int n, Graph g); +//int searchConnectedComponents(SET V, int S[], int n, Graph g); +int searchConnectedComponents(int S[], int n, int nbNiS[], Graph g); int searchConnectedComponentsGreedy(SET V, Heap heap, Graph g, int removedVertex); -void compExplore(int u, int num, SET V, int S[], int n, Graph g, int depth); void compExploreBFS(int num, SET V, int S[], int n, Graph g, int verif); int searchConnectedComponentsInHeap(Heap H, int nbNiS[], Graph g); void sortListByComponent(int S[], int n, int nbComp, int sizes[]); diff --git a/decompose.c b/decompose.c index 556d28fd7abd30a1186d760642a0c72d5d98a7a7..9a768bc5abee2beac568167cb7530c1e5ffbe630 100644 --- a/decompose.c +++ b/decompose.c @@ -261,8 +261,6 @@ Node decompose(int *S, int n, int pos[], int depth, Graph g, int hmax, int conne if (trace) printf("[%d] call %d n=%d \n", depth, nbCallsDecompose, n); - assert(depth <= g->n); - if (stopSearch) return NULL; if (n == 0) return NULL; if (hmax <= 0) return NULL; @@ -276,17 +274,27 @@ Node decompose(int *S, int n, int pos[], int depth, Graph g, int hmax, int conne return greedyDecompose(conHeap, depth, g, hmax, 1); } - SET set = NULL; - if (n > 105) { - if (theSets[depth] == NULL) reAllocSets(100, g); - set = makeSet(S, n, theSets[depth]); + if (0) { + SET set = NULL; + if (n > 105) { + if (theSets[depth] == NULL) reAllocSets(100, g); + set = makeSet(S, n, theSets[depth]); + } else + Introsort(S, S, S + n - 1); + } + + int nbEdges = initializeNbNeighbors(S, n, pos, g); // place S neighbors first in lists + + if (2*nbEdges == n*(n-1)) { + markRemoved(S, n, pos); + return makeSingleBranch(S, n, NULL, g); } - else - Introsort(S, S, S + n - 1); // Search connected components - if (depth > 0) { - int nbComp = searchConnectedComponents(set, S, n, g); + if ( ! connected) { //(depth > 0) + //int nbComp = searchConnectedComponents(set, S, n, g); + int nbComp = searchConnectedComponents(S, n, nbNeighborsInS, g); + if (stopSearch) return NULL; if (nbComp > 1) { if (trace) printf("components: %d ", nbComp); @@ -294,23 +302,10 @@ Node decompose(int *S, int n, int pos[], int depth, Graph g, int hmax, int conne } } - int nbEdges = initializeNbNeighbors(set, S, n, pos, g); // for searchSeparator() - - if (2*nbEdges == n*(n-1)) { - markRemoved(S, n, pos); - return makeSingleBranch(S, n, NULL, g); - } - - //searchSeparator(S, n, set, g, separator, (n < 20) ? 1 : nbRunsSeparation, (n < 20) ? 1 : nbFlushes, NULL, 0); - searchSeparator(S, n, set, g, separator, nbRunsSeparation, nbFlushes, depth); + searchSeparator(S, n, g, separator, nbRunsSeparation, nbFlushes, depth); if (stopSearch) return NULL; - if (0) { - improveSeparation(separator, g, 0); // Seg fault with 100 runs "./treedepth -file ../public/heur_007.gr " - printf("improve :: %d %d %d\n", separator->B->n, separator->C->n, separator->A->n); - } - //root = makeSingleBranchWithDisconnectedVertices(separator->C->val, separator->C->n, separator->nbABDV, g); Node root = makeSingleBranch(separator->C->val, separator->C->n, nbNInABCopy, g); @@ -322,11 +317,6 @@ Node decompose(int *S, int n, int pos[], int depth, Graph g, int hmax, int conne int nC = separator->C->n; Node A, B; - if (0) { for (int i = 0; i < depth; i ++) printf(" "); printf("%d %d %d\n", 1000*nA/n, 1000*nB/n, 1000*nC/n); } - - assert(nC > 0); // Indeed, the subgraph is connected here. - - int *listA = S; int *listB = S+nA; // no need for S after here diff --git a/graph.c b/graph.c index 88fd461dcae597698b40ceccc88f449d5f9bc373..ba06d94f97bc905878bbc859d640737ec03806ee 100644 --- a/graph.c +++ b/graph.c @@ -142,19 +142,6 @@ int nbNeighborsInHeap(int u, Heap F, Graph g) { } -int nbNeighborsInList(int u, SET V, int *S, int n, Graph g) { - LIST p = g->adj[u]; - int nbN = 0; - - while (p != NULL) { - if (isInSet(p->val, V, S, n)) { - nbN ++; - } - p = p->suiv; - } - return nbN; -} - int hasNoNeighborInSet(int vertex, SET V, Graph g) { for (int *p = g->lists[vertex]; *p != NONE; p ++) if (IN(*p, V)) return 0; diff --git a/graph.h b/graph.h index a425598cdb1ef3a9cad2203d29512cc36496064e..9cc785cde8f9793c29a047a42ca9b7eb08869ba5 100644 --- a/graph.h +++ b/graph.h @@ -53,7 +53,6 @@ int areNeighbours(int u, int v, Graph g); void printGraph(Graph g); int nbNeighborsInHeap(int u, Heap F, Graph g); int nbVerticeInHeap(int list[], int n, Heap F, Graph g); -int nbNeighborsInList(int u, SET V, int *S, int n, Graph g); int hasNoNeighborInSet(int vertex, SET V, Graph g); int hasNeighborsInSubtree(int vertex, SET V, Graph g); int haveSameNeighbors(int u, int v, Graph g); diff --git a/separator.c b/separator.c index 835fba6ce6dad1fb763db0018b28fda536cc8877..74a7751ee04afc294c6028f235c943d040ea598e 100644 --- a/separator.c +++ b/separator.c @@ -73,6 +73,9 @@ int sizeMax; // Connected components int *component; +int computeComponents = 0; // to detect components during separation and use it for evaluation +Components AComp, BComp; + // // Warning: the preliminary call to initializeNbNeighbors() place first in the lists of neighbors @@ -85,7 +88,7 @@ int *nbSearches; int *sumSizes; #endif -int searchSeparator(int *S, int n, SET V, Graph g, Separator theSeparator, int nTries, int nFlushes, int depth) { +int searchSeparator(int *S, int n, Graph g, Separator theSeparator, int nTries, int nFlushes, int depth) { #ifdef STATS_SEPARATION if (timesSep == NULL) { @@ -130,9 +133,9 @@ int searchSeparator(int *S, int n, SET V, Graph g, Separator theSeparator, int n randomizePriorities(S, n, g); - initSeparator(V, S, n, g, sep); + initSeparator(S, n, g, sep); - separe(S, n, V, g, sep, nFlushes, modeEvalSeparator); + separe(S, n, g, sep, nFlushes, modeEvalSeparator); if ((stopSearch) || ((clock()-start)/CLOCKS_PER_SEC > maxTimeSeparation/(depth+1))) break; } @@ -207,7 +210,7 @@ int chooseFirstVertex(int *S, int n, Graph g) { -int separe(int *S, int n, SET V, Graph g, Separator s, int nbFlushs, int mode) { +int separe(int *S, int n, Graph g, Separator s, int nbFlushs, int mode) { int firstVertex; @@ -232,10 +235,15 @@ int separe(int *S, int n, SET V, Graph g, Separator s, int nbFlushs, int mode) { firstVertex = (i > 0) ? NONE : chooseFirstVertex(S, n, g); } + if (computeComponents) { + if (i == 0) AComp->size = AComp->maxsize = 0; + else initializeComponents(AComp, A, g); + } + heapSetCompare(C, compareCVerticesFlushBtoA); makeHeap(C); - flushBtoA(A, B, C, V, S, n, mode, firstVertex, g); + flushBtoA(A, B, C, S, n, mode, firstVertex, g); if (stopSearch) break; @@ -248,10 +256,12 @@ int separe(int *S, int n, SET V, Graph g, Separator s, int nbFlushs, int mode) { else makeHeap(A); + if (computeComponents) initializeComponents(BComp, B, g); + heapSetCompare(C, compareCVerticesFlushAtoB); makeHeap(C); - flushAtoB(A, B, C, V, S, n, mode, g); + flushAtoB(A, B, C, S, n, mode, g); if (stopSearch) break; } @@ -269,6 +279,9 @@ double evalSep(int nA, int nB, int nC, int mA, int mB, int mode, int direction) // Should consider here the particular cases (B->n=0, C->n=0,...) int min = (nA > nB) ? nB : nA; + + if (mode == EVAL_CARD) return ((double) (min) / (nC+1)); // modified 1/05 + int max = (nA > nB) ? nA : nB; int delta = max-min; int maxE = (mA > mB) ? mA : mB; @@ -297,8 +310,6 @@ double evalSep(int nA, int nB, int nC, int mA, int mB, int mode, int direction) return ((rab - deltaSqrt) / (1+nC)); } - if (mode == EVAL_CARD) return ((double) (min) / (nC+1)); // modified 1/05 - if (mode == EVAL_LEVEL_DENSITY) { // evaluate the cost to place vertices of C and the smallest among A and B // evaluating the number of vertices of these sets per level @@ -413,7 +424,7 @@ int chooseEltInA(Heap A) { int testSourceConnected = 0; int thresholdConComponents = 13; -void flushBtoA(Heap A, Heap B, Heap C, SET V, int S[], int n, int mode, int seed, Graph g) { +void flushBtoA(Heap A, Heap B, Heap C, int S[], int n, int mode, int seed, Graph g) { int e = NONE; int bestASize = NONE; @@ -444,15 +455,16 @@ void flushBtoA(Heap A, Heap B, Heap C, SET V, int S[], int n, int mode, int seed else if (useMinPartitions == 2) minheapJustRemove(e, B, nbNeighborsInB); else heapRemove(e, B); nbEdgesInB = nbEdgesInB-nbNeighborsInB[e]; - decreaseNbNeighborsInB(e, B, C, V, S, n, g); + decreaseNbNeighborsInB(e, B, C, g); } // insert e in A + if (computeComponents) createNewAComponent(e, AComp); heapJustAdd(e, A); - increaseNbNeighborsInA(e, C, V, S, n, g); + increaseNbNeighborsInA(e, C, A, g); // move e neighbors which are in B to C - removeNeighborsFromB(e, A, B, C, V, S, n, g); + removeNeighborsFromB(e, A, B, C, g); if (A->n >= sizeMax) break; @@ -470,7 +482,7 @@ void flushBtoA(Heap A, Heap B, Heap C, SET V, int S[], int n, int mode, int seed } } - double e = evalSep(A->n, nB, C->n, nbEdgesInA, nEB, mode, FLUSH_B_A); + double e = evalSep(computeComponents ? AComp->maxsize : A->n, nB, C->n, nbEdgesInA, nEB, mode, FLUSH_B_A); if ((bestIsUninitialized) || (e > bestEval)) { // There can be vertices in C with no neighbor in B @@ -485,7 +497,8 @@ void flushBtoA(Heap A, Heap B, Heap C, SET V, int S[], int n, int mode, int seed } } if ((bestIsUninitialized) && (A->n < n)) { - if (1) pourCintoA(A, nbNeighborsInB, nbNeighborsInA, &nbEdgesInA, C, g, 1); + if (computeComponents) pourCintoPart(A, AComp, nbNeighborsInB, nbNeighborsInA, &nbEdgesInA, C, g, 1); + else pourCintoA(A, nbNeighborsInB, nbNeighborsInA, &nbEdgesInA, C, g, 1); bestIsUninitialized = 0; bestEval = e; copySeparator(sep, bestSep); @@ -500,7 +513,7 @@ void flushBtoA(Heap A, Heap B, Heap C, SET V, int S[], int n, int mode, int seed -void flushAtoB(Heap A, Heap B, Heap C, SET V, int S[], int n, int mode, Graph g) { +void flushAtoB(Heap A, Heap B, Heap C, int S[], int n, int mode, Graph g) { int e = NONE; int bestBSize = NONE; @@ -525,15 +538,16 @@ void flushAtoB(Heap A, Heap B, Heap C, SET V, int S[], int n, int mode, Graph g) else if (useMinPartitions == 2) minheapJustRemove(e, A, nbNeighborsInA); else heapRemove(e, A); nbEdgesInA -= nbNeighborsInA[e]; - decreaseNbNeighborsInA(e, A, C, V, S, n, g); + decreaseNbNeighborsInA(e, A, C, g); } // insert e in B heapJustAdd(e, B); - increaseNbNeighborsInB(e, C, V, S, n, g); + if (computeComponents) createNewAComponent(e, BComp); + increaseNbNeighborsInB(e, C, B, g); // move e neighbors which are in A to C - removeNeighborsFromA(e, A, B, C, V, S, n, g); + removeNeighborsFromA(e, A, B, C, g); if (B->n >= sizeMax) break; @@ -551,10 +565,11 @@ void flushAtoB(Heap A, Heap B, Heap C, SET V, int S[], int n, int mode, Graph g) } } - double e = evalSep(nA, B->n, C->n, nEA, nbEdgesInB, mode, FLUSH_A_B); + double e = evalSep(nA, computeComponents ? BComp->maxsize : B->n, C->n, nEA, nbEdgesInB, mode, FLUSH_A_B); if ((bestIsUninitialized) || (e > bestEval)) { - if (1) pourCintoA(B, nbNeighborsInA, nbNeighborsInB, &nbEdgesInB, C, g, 1); + if (computeComponents) pourCintoPart(B, BComp, nbNeighborsInA, nbNeighborsInB, &nbEdgesInB, C, g, 1); + else pourCintoA(B, nbNeighborsInA, nbNeighborsInB, &nbEdgesInB, C, g, 1); bestIsUninitialized = 0; bestEval = e; if (separatorJustMemorizeReceptorSize && (g->n >= separatorJustMemoSizeMin)) { @@ -566,7 +581,6 @@ void flushAtoB(Heap A, Heap B, Heap C, SET V, int S[], int n, int mode, Graph g) } } if ((separatorJustMemorizeReceptorSize) && (bestBSize != NONE)) { - int nB = B->n; copySeparator(sep, bestSep); builtBestSeparator(bestSep->B, bestSep->A, bestSep->C, nbNeighborsInB, nbNeighborsInA, bestBSize, g); } @@ -616,7 +630,7 @@ void builtBestSeparator(Heap dest, Heap src, Heap C, int nbNdest[], int nbNsrc[] // FlushBtoA() :: e has been moved to A. e neighbors which are in B must be moved to C. -void removeNeighborsFromB(int e, Heap A, Heap B, Heap C, SET V, int *S, int n, Graph g) { +void removeNeighborsFromB(int e, Heap A, Heap B, Heap C, Graph g) { int nbToThrow = 0; for (int *p = g->lists[e]; p-g->lists[e] < nbNeighborsInS[e]; p ++) { //(*p != NONE) : useless, first neighbors are in S @@ -634,7 +648,7 @@ void removeNeighborsFromB(int e, Heap A, Heap B, Heap C, SET V, int *S, int n, G heapInsert(*p, C); nbEdgesInB -= nbNeighborsInB[*p]; - decreaseNbNeighborsInB(*p, B, C, V, S, n, g); + decreaseNbNeighborsInB(*p, B, C, g); } } @@ -646,15 +660,16 @@ void removeNeighborsFromB(int e, Heap A, Heap B, Heap C, SET V, int *S, int n, G if ((C->ind[*p] != NONE) && (nbNeighborsInB[*p] == 0)) { heapRemove(*p, C); heapJustAdd(*p, A); + if (computeComponents) createNewAComponent(*p, AComp); nbEdgesInA += nbNeighborsInA[*p]; - increaseNbNeighborsInA(*p, C, V, S, n, g); + increaseNbNeighborsInA(*p, C, A, g); } } } -void removeNeighborsFromA(int e, Heap A, Heap B, Heap C, SET V, int *S, int n, Graph g) { +void removeNeighborsFromA(int e, Heap A, Heap B, Heap C, Graph g) { int movesToB = 0; for (int *p = g->lists[e]; p-g->lists[e] < nbNeighborsInS[e]; p ++) { if (A->ind[*p] != NONE) { @@ -671,7 +686,7 @@ void removeNeighborsFromA(int e, Heap A, Heap B, Heap C, SET V, int *S, int n, G heapInsert(*p, C); nbEdgesInA -= nbNeighborsInA[*p]; - decreaseNbNeighborsInA(*p, A, C, V, S, n, g); + decreaseNbNeighborsInA(*p, A, C, g); } } @@ -682,8 +697,9 @@ void removeNeighborsFromA(int e, Heap A, Heap B, Heap C, SET V, int *S, int n, G if ((C->ind[*p] != NONE) && (nbNeighborsInA[*p] == 0)) { heapRemove(*p, C); heapJustAdd(*p, B); + if (computeComponents) createNewAComponent(*p, BComp); nbEdgesInB += nbNeighborsInB[*p]; - increaseNbNeighborsInB(*p, C, V, S, n, g); + increaseNbNeighborsInB(*p, C, B, g); } } } @@ -853,6 +869,29 @@ int compareCVerticesFlushAtoB(int a, int b) { // Dust separator: for vertices of C that have no neighbor in A or B // +void pourCintoPart(Heap dest, Components ABC, int *nbNFrom, int *nbNTo, int *nbEdges, Heap C, Graph g, int justAdd) { + // move isolated vertices from C to A or B + for (int i = 0; i < C->n; i++) { + int e = C->val[i]; + if (nbNFrom[e] == 0) { + heapRemove(e, C); + if (justAdd) + heapJustAdd(e, dest); + else + heapInsert(e, dest); + + if (computeComponents) createNewAComponent(e, ABC); + + *nbEdges = *nbEdges + nbNTo[e]; + for (int *p = g->lists[e]; p < g->lists[e]+nbNeighborsInS[e]; p ++) { + nbNTo[*p]++; + if (computeComponents) if (dest->ind[*p] != NONE) + updateComponents(e, *p, ABC, g); + } + } + } +} + void pourCintoA(Heap A, int nbNFrom[], int nbNTo[], int *nbEdges, Heap C, Graph g, int justAdd) { for (int i = 0; i < C->n; i++) { int e = C->val[i]; @@ -1100,6 +1139,22 @@ void allocSeparation(Graph g) { priorities = malloc(g->n * sizeof(int)); verticesToThrow = malloc(g->n * sizeof(int)); + + if (computeComponents) { + AComp = malloc(sizeof(struct components)); + BComp = malloc(sizeof(struct components)); + + AComp->fathers = malloc(g->n * sizeof(int)); + AComp->sizes = malloc(g->n * sizeof(int)); + AComp->edges = malloc(g->n * sizeof(int)); + AComp->roots = malloc(g->n * sizeof(int)); + AComp->comp = malloc(g->n * sizeof(int)); + BComp->fathers = malloc(g->n * sizeof(int)); + BComp->sizes = malloc(g->n * sizeof(int)); + BComp->edges = malloc(g->n * sizeof(int)); + BComp->roots = malloc(g->n * sizeof(int)); + BComp->comp = malloc(g->n * sizeof(int)); + } } @@ -1130,7 +1185,7 @@ void recoverNbNeighbors(int S[], int n) { -int initializeNbNeighbors(SET V, int S[], int n, int pos[], Graph g) { +int initializeNbNeighbors(int S[], int n, int pos[], Graph g) { nbEdgesInS = 0; minDegree = n+1; maxDegree = -1; @@ -1159,7 +1214,7 @@ int initializeNbNeighbors(SET V, int S[], int n, int pos[], Graph g) { -void initSeparator(SET V, int *S, int n, Graph g, Separator s) { +void initSeparator(int *S, int n, Graph g, Separator s) { resetHeap(s->A); resetHeap(s->B); @@ -1177,6 +1232,11 @@ void initSeparator(SET V, int *S, int n, Graph g, Separator s) { } recoverNbNeighbors(S, n); + + if (computeComponents) { + AComp->size = 0; + BComp->size = 0; + } } @@ -1228,7 +1288,7 @@ void printSeparator(Separator s) { int nbCallsdecreaseNbNeighborsInB = 0; // Only for flushBtoA stage. u has been removed from B => decrease the number of neighbors in B for all B neighbors, // Neighbors have been ordered so that those in S[] occur first in the list -void decreaseNbNeighborsInB(int u, Heap B, Heap C, SET V, int S[], int n, Graph g) { +void decreaseNbNeighborsInB(int u, Heap B, Heap C, Graph g) { int nb = 0; for (int * p = g->lists[u]; *p != NONE; p ++) { @@ -1248,12 +1308,15 @@ void decreaseNbNeighborsInB(int u, Heap B, Heap C, SET V, int S[], int n, Graph // Only for flushAtoB(). u has been inserted in B (for flushAtoB) -void increaseNbNeighborsInB(int u, Heap C, SET V, int S[], int n, Graph g) { +void increaseNbNeighborsInB(int u, Heap C, Heap B, Graph g) { int nb = 0; for (int *pp = g->lists[u]; *pp != NONE; pp ++) { nbNeighborsInB[*pp] ++; if (C->ind[*pp] != NONE) heapBubbleUp(C->ind[*pp], C); + else if ((computeComponents) && (B->ind[*pp] != NONE)) { + updateComponents(u, *pp, BComp, g); + } if ( ++ nb == nbNeighborsInS[u]) break; } } @@ -1261,7 +1324,7 @@ void increaseNbNeighborsInB(int u, Heap C, SET V, int S[], int n, Graph g) { // for flushAtoB -void decreaseNbNeighborsInA(int u, Heap A, Heap C, SET V, int S[], int n, Graph g) { +void decreaseNbNeighborsInA(int u, Heap A, Heap C, Graph g) { int nb = 0; for (int *p = g->lists[u]; *p != NONE; p ++) { nbNeighborsInA[*p] --; @@ -1275,22 +1338,23 @@ void decreaseNbNeighborsInA(int u, Heap A, Heap C, SET V, int S[], int n, Graph heapBubbleUp(C->ind[*p], C); if ( ++ nb == nbNeighborsInS[u]) break; } - return; } // for flushBtoA -void increaseNbNeighborsInA(int u, Heap C, SET V, int S[], int n, Graph g) { +void increaseNbNeighborsInA(int u, Heap C, Heap A, Graph g) { int nb = 0; for (int *pp = g->lists[u]; *pp != NONE; pp ++) { nbNeighborsInA[*pp] ++; if (C->ind[*pp] != NONE) heapBubbleUp(C->ind[*pp], C); + else if (computeComponents) if (A->ind[*pp] != NONE) { + updateComponents(u, *pp, AComp, g); + } // It is useless to consider u neighbors which are in B, there is none if ( ++ nb == nbNeighborsInS[u]) break; // first neighbors are those in S[] } - return; } @@ -1327,5 +1391,142 @@ void randomizePriorities(int S[], int n, Graph g) { +// +// A and B components during separation, utilies. +// + +int verifyHeapComponents(Heap H, Components C, Graph g) { + int *father = C->fathers; + int *component = C->comp; + int *size = C->sizes; + int *root = C->roots; + int nbComp = C->size; + int nb[nbComp], nbC = 0; + for (int i = 0; i < nbComp; i ++) { + nb[i] = 0; + if (father[root[i]] != NONE) printf("father of root %d is not NONE\n", root[i]); + } + for (int i = 0; i < H->n; i ++) { + int e = H->val[i]; + if (father[e] == NONE) nbC ++; + if ((father[e] == NONE) && ((component[e] >= nbComp) || (root[component[e]] != e))) + printf("problem %d should be root of comp %d\n", e, component[e]); + } + if (nbC != nbComp) printf("find %d components, %d given\n", nbC, nbComp); + return 1; +} + + + +// Initialize ABComponents given components calculated with a BFS +int initializeComponents(Components C, Heap H, Graph g) { + + C->size = searchConnectedComponentsInHeap(H, nbNeighborsInS, g); + + for (int i = 0; i < C->size; i ++) + C->sizes[i] = 0; + + C->maxedges = 0; + for (int i = 0; i < H->n; i ++) { + int comp = iComp[H->val[i]]; + C->comp[H->val[i]] = comp; // useless, only the root needs its component + C->sizes[comp] ++; + if (C->sizes[comp] == 1) { + C->roots[comp] = H->val[i]; + C->fathers[H->val[i]] = NONE; + C->edges[comp] = compNbEdges[comp]; + if (compNbEdges[comp] > C->maxedges) C->maxedges = compNbEdges[comp]; + } + else + C->fathers[H->val[i]] = C->roots[comp]; + } + + C->maxsize = 0; + for (int i = 0; i < C->size; i ++) + if (C->sizes[i] > C->maxsize) + C->maxsize = C->sizes[i]; + + //verifyHeapComponents(H, C, g); + return C->size; +} + + + +int getABComponent(int u, int *father) { + int uu = u, tmp; + while (father[u] != NONE) u = father[u]; + while (uu != u) { tmp = father[uu]; father[uu] = u; uu = tmp; } + return u; +} + +int callUC = 0; +int updateComponents(int u, int v, Components C, Graph g) { +// int *father, int *component, int *size, int *root, int nbComp, Graph g) { +// Add edge (u,v), merge components if different. + + callUC++; + if ((v == 109) && (C->fathers[v] == 109)) + printf("OUYE %d\n", callUC); + + int ru = getABComponent(u, C->fathers); + int rv = getABComponent(v, C->fathers); + + if (ru != rv) { + // merge components + int compu = C->comp[ru]; + int compv = C->comp[rv]; + if (C->sizes[compu] > C->sizes[compv]) { + C->sizes[compu] += C->sizes[compv]; + C->edges[compu] += C->edges[compv]+1; + if (C->edges[compu] > C->maxedges) C->maxedges = C->edges[compu]; + C->fathers[rv] = ru; + if (C->sizes[compu] > C->maxsize) C->maxsize = C->sizes[compu]; + C->size --; + if (compv != C->size) { + // must swap last component and compv + int lastroot = C->roots[C->size]; + C->roots[compv] = lastroot; + C->sizes[compv] = C->sizes[C->size]; + C->comp[lastroot] = compv; + } + } + else { + C->sizes[compv] += C->sizes[compu]; + C->edges[compv] += C->edges[compu]+1; + if (C->edges[compv] > C->maxedges) C->maxedges = C->edges[compv]; + C->fathers[ru] = rv; + if (C->sizes[compv] > C->maxsize) C->maxsize = C->sizes[compv]; + C->size --; + if (compu != C->size) { + // must swap last component and compu + int lastroot = C->roots[C->size]; + C->roots[compu] = lastroot; + C->sizes[compu] = C->sizes[C->size]; + C->comp[lastroot] = compu; + } + } + } + else { + C->edges[C->comp[ru]] ++; + if (C->edges[C->comp[ru]] > C->maxedges) C->maxedges = C->edges[C->comp[ru]]; + } + return C->size; +} + + +void createNewAComponent(int e, Components C) { + C->fathers[e] = NONE; + C->sizes[C->size] = 1; + C->edges[C->size] = 0; + if (C->maxsize == 0) C->maxsize = 1; + C->comp[e] = C->size; + C->roots[C->size] = e; + C->size ++; +} + + + + + diff --git a/separator.h b/separator.h index 4127677d016d9dbffc920136b9a332fbf2c955ec..b5ef327861156c3ba8a9cd80ef685229ce5be0ff 100644 --- a/separator.h +++ b/separator.h @@ -45,8 +45,24 @@ struct separator { +typedef struct components * Components; +struct components { + int *fathers; + int *sizes; + int *edges; + int *roots; + int *comp; + int size; + int maxsize; + int maxedges; +}; + + + extern int *nbNeighborsInA; extern int *nbNeighborsInB; +extern int * nbNeighborsInS; + extern int nbEdgesInA, nbEdgesInB; extern int * nbNInABCopy; @@ -58,21 +74,22 @@ extern int nbCallsSepare; double evalSep(int nA, int nB, int nC, int mA, int mB, int mode, int direction); -int searchSeparator(int *S, int n, SET V, Graph g, Separator theSeparator, int nTries, int nFlushes, int depth); -int separe(int *S, int n, SET V, Graph g, Separator s, int nbFlushs, int mode); -void flushBtoA(Heap A, Heap B, Heap C, SET V, int S[], int n, int mode, int seed, Graph g); -void flushAtoB(Heap A, Heap B, Heap C, SET V, int S[], int n, int mode, Graph g); +int searchSeparator(int *S, int n, Graph g, Separator theSeparator, int nTries, int nFlushes, int depth); +int separe(int *S, int n, Graph g, Separator s, int nbFlushs, int mode); +void flushBtoA(Heap A, Heap B, Heap C, int S[], int n, int mode, int seed, Graph g); +void flushAtoB(Heap A, Heap B, Heap C, int S[], int n, int mode, Graph g); void builtBestSeparator(Heap dest, Heap src, Heap C, int nbNdest[], int nbNsrc[], int size, Graph g); -void removeNeighborsFromA(int e, Heap A, Heap B, Heap C, SET V, int *S, int n, Graph g); -void removeNeighborsFromB(int e, Heap A, Heap B, Heap C, SET V, int *S, int n, Graph g); +void removeNeighborsFromA(int e, Heap A, Heap B, Heap C, Graph g); +void removeNeighborsFromB(int e, Heap A, Heap B, Heap C, Graph g); int isSmallerNeighborsInB(int a, int b); int isSmallerNeighborsInA(int a, int b); int compareCVerticesFlushBtoA(int a, int b); int compareCVerticesFlushAtoB(int a, int b); +void pourCintoPart(Heap dest, Components ABC, int *nbNFrom, int *nbNTo, int *nbEdges, Heap C, Graph g, int justAdd); void pourCintoA(Heap A, int nbNFrom[], int nbNTo[], int *nbEdges, Heap C, Graph g, int justAdd); void allocSeparation(Graph g); @@ -88,23 +105,31 @@ int searchMoveBC(Separator s, Graph g, int movesCA[], int *the); void makeMove(int v, Heap source, Heap dest); Separator newSeparator(int size, Graph g); -int initializeNbNeighbors(SET V, int S[], int n, int pos[], Graph g); +int initializeNbNeighbors(int S[], int n, int pos[], Graph g); void recoverNbNeighbors(int S[], int n); -void initSeparator(SET V, int *S, int n, Graph g, Separator s); +void initSeparator(int *S, int n, Graph g, Separator s); //void removeFromB(int v, Separator s); //void removeFromC(int v, Separator s); //void addInC(int v, Separator s); void printSeparator(Separator s); int verifySeparator(int *S, int n, Separator s); -void decreaseNbNeighborsInB(int u, Heap B, Heap C, SET V, int S[], int n, Graph g); -void decreaseNbNeighborsInA(int u, Heap A, Heap C, SET V, int S[], int n, Graph g); -void increaseNbNeighborsInA(int u, Heap C, SET V, int S[], int n, Graph g); -void increaseNbNeighborsInB(int u, Heap C, SET V, int S[], int n, Graph g); +void decreaseNbNeighborsInB(int u, Heap B, Heap C, Graph g); +void decreaseNbNeighborsInA(int u, Heap A, Heap C, Graph g); +void increaseNbNeighborsInA(int u, Heap C, Heap A, Graph g); +void increaseNbNeighborsInB(int u, Heap C, Heap B, Graph g); int verifyNbNeighbors(Heap A, Heap B, Heap C, SET V, int S[], int n, Graph g); void initializePriorities(Graph g); void randomizePriorities(int S[], int n, Graph g); +// A/B components +int verifyHeapComponents(Heap H, Components C, Graph g); +int initializeComponents(Components C, Heap H, Graph g); + +int updateComponents(int u, int v, Components C, Graph g); + +void createNewAComponent(int e, Components C); + #endif //SRC_SEPARATOR_H diff --git a/tree.c b/tree.c index 0e5752ac703746d232f5f38b4f7a6d9f4a4dd14d..5921b611843eb346c083cde8c66aefe372718467 100644 --- a/tree.c +++ b/tree.c @@ -120,7 +120,8 @@ int nbNeighborsAbove(Node node, Graph g) { Node p = node->father; while (p != NULL) { - if (isInSet(p->vertex, NULL, N, nN)) + //if (isInSet(p->vertex, NULL, N, nN)) + if (isInList(p->vertex, N, nN)) nb ++; p = p->father; } diff --git a/utils.c b/utils.c index d1af18499a29c153e57f1b21ad205034bd3e1a94..45939a125022b00454f8e4d3abe3b68e8ba87b44 100644 --- a/utils.c +++ b/utils.c @@ -113,30 +113,6 @@ int nbInListWithThisValue(int val, int *S, int n, int *values) { -// search in set, either a SET of a sorted list -int isInSet(int v, SET S, int T[], int n) { - - if (S != NULL) { - return IN(v, S); - } - - if (n == 0) return 0; - - int l = 0; - int r = n; - // l <= pos < r - while (l+1 < r) { - int m = (l+r)/2; - if (v >= T[m]) - l = m; - else - r = m; - } - // l+1=r and l <= pos < r - return (v == T[l]); -} - - // search v in the list, int isInList(int v, int T[], int n) { diff --git a/utils.h b/utils.h index ce264fced94fc1fed6081fd00cacc0023ac32a61..d6401b117efbd036505ec538c3ab28a1df82f65c 100644 --- a/utils.h +++ b/utils.h @@ -21,7 +21,6 @@ int packListLeft(int num, int S[], int n, int C[]); void copyListLeft(int S[], int start, int size); int nbInListWithThisValue(int num, int *S, int n, int *values); -int isInSet(int v, SET S, int T[], int n); int isInList(int v, int T[], int n); void swap(int arr[], int i, int j);