From ec0533df87d4d49fff9f43474b204d353cf13e96 Mon Sep 17 00:00:00 2001 From: stephgc <stephane.grandcolas@univ-amu.fr> Date: Sat, 30 May 2020 20:55:21 +0200 Subject: [PATCH] sga 29/05 --- Licence.txt | 20 ++++ components.c | 73 +++++--------- components.h | 4 +- decompose.c | 48 +++++---- graph.c | 13 +++ graph.h | 1 + separator.c | 271 +++++++-------------------------------------------- separator.h | 49 +++------- tree.c | 3 +- utils.c | 24 +++++ utils.h | 1 + 11 files changed, 164 insertions(+), 343 deletions(-) create mode 100644 Licence.txt diff --git a/Licence.txt b/Licence.txt new file mode 100644 index 0000000..096ff14 --- /dev/null +++ b/Licence.txt @@ -0,0 +1,20 @@ +Copyright (c) 2020 Sephane Grandcolas + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/components.c b/components.c index 3f019ba..9e549ba 100644 --- a/components.c +++ b/components.c @@ -39,52 +39,6 @@ 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) - - -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; - 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]; - compExploreBFSOrderedNeighbors(nbComp, nbNiS, g); - if (compSizes[nbComp] > sizeCompMax) sizeCompMax = compSizes[nbComp]; - nbNodes += compSizes[nbComp]; - nbComp++; - if (nbNodes == n) break; - } - } - return nbComp; -} - -#ifdef NOTDEF int searchConnectedComponents(SET V, int S[], int n, Graph g) { int nbComp = 0; @@ -112,6 +66,8 @@ int searchConnectedComponents(SET V, int S[], int n, Graph g) { return nbComp; } + + void compExploreBFS(int num, SET V, int S[], int n, Graph g, int verif) { while (last != first) { int *p = g->lists[*first]; @@ -130,7 +86,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 @@ -272,6 +228,29 @@ 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 0b13d52..75c9307 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(int S[], int n, int nbNiS[], Graph g); +int searchConnectedComponents(SET V, int S[], int n, 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 9a768bc..556d28f 100644 --- a/decompose.c +++ b/decompose.c @@ -261,6 +261,8 @@ 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; @@ -274,27 +276,17 @@ Node decompose(int *S, int n, int pos[], int depth, Graph g, int hmax, int conne return greedyDecompose(conHeap, depth, g, hmax, 1); } - 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); + 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); // Search connected components - if ( ! connected) { //(depth > 0) - //int nbComp = searchConnectedComponents(set, S, n, g); - int nbComp = searchConnectedComponents(S, n, nbNeighborsInS, g); - + if (depth > 0) { + int nbComp = searchConnectedComponents(set, S, n, g); if (stopSearch) return NULL; if (nbComp > 1) { if (trace) printf("components: %d ", nbComp); @@ -302,10 +294,23 @@ Node decompose(int *S, int n, int pos[], int depth, Graph g, int hmax, int conne } } - searchSeparator(S, n, g, separator, nbRunsSeparation, nbFlushes, depth); + 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); 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); @@ -317,6 +322,11 @@ 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 ba06d94..88fd461 100644 --- a/graph.c +++ b/graph.c @@ -142,6 +142,19 @@ 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 9cc785c..a425598 100644 --- a/graph.h +++ b/graph.h @@ -53,6 +53,7 @@ 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 74a7751..835fba6 100644 --- a/separator.c +++ b/separator.c @@ -73,9 +73,6 @@ 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 @@ -88,7 +85,7 @@ int *nbSearches; int *sumSizes; #endif -int searchSeparator(int *S, int n, Graph g, Separator theSeparator, int nTries, int nFlushes, int depth) { +int searchSeparator(int *S, int n, SET V, Graph g, Separator theSeparator, int nTries, int nFlushes, int depth) { #ifdef STATS_SEPARATION if (timesSep == NULL) { @@ -133,9 +130,9 @@ int searchSeparator(int *S, int n, Graph g, Separator theSeparator, int nTries, randomizePriorities(S, n, g); - initSeparator(S, n, g, sep); + initSeparator(V, S, n, g, sep); - separe(S, n, g, sep, nFlushes, modeEvalSeparator); + separe(S, n, V, g, sep, nFlushes, modeEvalSeparator); if ((stopSearch) || ((clock()-start)/CLOCKS_PER_SEC > maxTimeSeparation/(depth+1))) break; } @@ -210,7 +207,7 @@ int chooseFirstVertex(int *S, int n, Graph g) { -int separe(int *S, int n, Graph g, Separator s, int nbFlushs, int mode) { +int separe(int *S, int n, SET V, Graph g, Separator s, int nbFlushs, int mode) { int firstVertex; @@ -235,15 +232,10 @@ int separe(int *S, int n, 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, S, n, mode, firstVertex, g); + flushBtoA(A, B, C, V, S, n, mode, firstVertex, g); if (stopSearch) break; @@ -256,12 +248,10 @@ int separe(int *S, int n, 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, S, n, mode, g); + flushAtoB(A, B, C, V, S, n, mode, g); if (stopSearch) break; } @@ -279,9 +269,6 @@ 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; @@ -310,6 +297,8 @@ 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 @@ -424,7 +413,7 @@ int chooseEltInA(Heap A) { int testSourceConnected = 0; int thresholdConComponents = 13; -void flushBtoA(Heap A, Heap B, Heap C, int S[], int n, int mode, int seed, Graph g) { +void flushBtoA(Heap A, Heap B, Heap C, SET V, int S[], int n, int mode, int seed, Graph g) { int e = NONE; int bestASize = NONE; @@ -455,16 +444,15 @@ void flushBtoA(Heap A, Heap B, Heap C, int S[], int n, int mode, int seed, Graph else if (useMinPartitions == 2) minheapJustRemove(e, B, nbNeighborsInB); else heapRemove(e, B); nbEdgesInB = nbEdgesInB-nbNeighborsInB[e]; - decreaseNbNeighborsInB(e, B, C, g); + decreaseNbNeighborsInB(e, B, C, V, S, n, g); } // insert e in A - if (computeComponents) createNewAComponent(e, AComp); heapJustAdd(e, A); - increaseNbNeighborsInA(e, C, A, g); + increaseNbNeighborsInA(e, C, V, S, n, g); // move e neighbors which are in B to C - removeNeighborsFromB(e, A, B, C, g); + removeNeighborsFromB(e, A, B, C, V, S, n, g); if (A->n >= sizeMax) break; @@ -482,7 +470,7 @@ void flushBtoA(Heap A, Heap B, Heap C, int S[], int n, int mode, int seed, Graph } } - double e = evalSep(computeComponents ? AComp->maxsize : A->n, nB, C->n, nbEdgesInA, nEB, mode, FLUSH_B_A); + double e = evalSep(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 @@ -497,8 +485,7 @@ void flushBtoA(Heap A, Heap B, Heap C, int S[], int n, int mode, int seed, Graph } } if ((bestIsUninitialized) && (A->n < n)) { - if (computeComponents) pourCintoPart(A, AComp, nbNeighborsInB, nbNeighborsInA, &nbEdgesInA, C, g, 1); - else pourCintoA(A, nbNeighborsInB, nbNeighborsInA, &nbEdgesInA, C, g, 1); + if (1) pourCintoA(A, nbNeighborsInB, nbNeighborsInA, &nbEdgesInA, C, g, 1); bestIsUninitialized = 0; bestEval = e; copySeparator(sep, bestSep); @@ -513,7 +500,7 @@ void flushBtoA(Heap A, Heap B, Heap C, int S[], int n, int mode, int seed, Graph -void flushAtoB(Heap A, Heap B, Heap C, int S[], int n, int mode, Graph g) { +void flushAtoB(Heap A, Heap B, Heap C, SET V, int S[], int n, int mode, Graph g) { int e = NONE; int bestBSize = NONE; @@ -538,16 +525,15 @@ void flushAtoB(Heap A, Heap B, Heap C, 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, g); + decreaseNbNeighborsInA(e, A, C, V, S, n, g); } // insert e in B heapJustAdd(e, B); - if (computeComponents) createNewAComponent(e, BComp); - increaseNbNeighborsInB(e, C, B, g); + increaseNbNeighborsInB(e, C, V, S, n, g); // move e neighbors which are in A to C - removeNeighborsFromA(e, A, B, C, g); + removeNeighborsFromA(e, A, B, C, V, S, n, g); if (B->n >= sizeMax) break; @@ -565,11 +551,10 @@ void flushAtoB(Heap A, Heap B, Heap C, int S[], int n, int mode, Graph g) { } } - double e = evalSep(nA, computeComponents ? BComp->maxsize : B->n, C->n, nEA, nbEdgesInB, mode, FLUSH_A_B); + double e = evalSep(nA, B->n, C->n, nEA, nbEdgesInB, mode, FLUSH_A_B); if ((bestIsUninitialized) || (e > bestEval)) { - if (computeComponents) pourCintoPart(B, BComp, nbNeighborsInA, nbNeighborsInB, &nbEdgesInB, C, g, 1); - else pourCintoA(B, nbNeighborsInA, nbNeighborsInB, &nbEdgesInB, C, g, 1); + if (1) pourCintoA(B, nbNeighborsInA, nbNeighborsInB, &nbEdgesInB, C, g, 1); bestIsUninitialized = 0; bestEval = e; if (separatorJustMemorizeReceptorSize && (g->n >= separatorJustMemoSizeMin)) { @@ -581,6 +566,7 @@ void flushAtoB(Heap A, Heap B, Heap C, 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); } @@ -630,7 +616,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, Graph g) { +void removeNeighborsFromB(int e, Heap A, Heap B, Heap C, SET V, int *S, int n, 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 @@ -648,7 +634,7 @@ void removeNeighborsFromB(int e, Heap A, Heap B, Heap C, Graph g) { heapInsert(*p, C); nbEdgesInB -= nbNeighborsInB[*p]; - decreaseNbNeighborsInB(*p, B, C, g); + decreaseNbNeighborsInB(*p, B, C, V, S, n, g); } } @@ -660,16 +646,15 @@ void removeNeighborsFromB(int e, Heap A, Heap B, Heap C, Graph 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, A, g); + increaseNbNeighborsInA(*p, C, V, S, n, g); } } } -void removeNeighborsFromA(int e, Heap A, Heap B, Heap C, Graph g) { +void removeNeighborsFromA(int e, Heap A, Heap B, Heap C, SET V, int *S, int n, Graph g) { int movesToB = 0; for (int *p = g->lists[e]; p-g->lists[e] < nbNeighborsInS[e]; p ++) { if (A->ind[*p] != NONE) { @@ -686,7 +671,7 @@ void removeNeighborsFromA(int e, Heap A, Heap B, Heap C, Graph g) { heapInsert(*p, C); nbEdgesInA -= nbNeighborsInA[*p]; - decreaseNbNeighborsInA(*p, A, C, g); + decreaseNbNeighborsInA(*p, A, C, V, S, n, g); } } @@ -697,9 +682,8 @@ void removeNeighborsFromA(int e, Heap A, Heap B, Heap C, Graph 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, B, g); + increaseNbNeighborsInB(*p, C, V, S, n, g); } } } @@ -869,29 +853,6 @@ 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]; @@ -1139,22 +1100,6 @@ 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)); - } } @@ -1185,7 +1130,7 @@ void recoverNbNeighbors(int S[], int n) { -int initializeNbNeighbors(int S[], int n, int pos[], Graph g) { +int initializeNbNeighbors(SET V, int S[], int n, int pos[], Graph g) { nbEdgesInS = 0; minDegree = n+1; maxDegree = -1; @@ -1214,7 +1159,7 @@ int initializeNbNeighbors(int S[], int n, int pos[], Graph g) { -void initSeparator(int *S, int n, Graph g, Separator s) { +void initSeparator(SET V, int *S, int n, Graph g, Separator s) { resetHeap(s->A); resetHeap(s->B); @@ -1232,11 +1177,6 @@ void initSeparator(int *S, int n, Graph g, Separator s) { } recoverNbNeighbors(S, n); - - if (computeComponents) { - AComp->size = 0; - BComp->size = 0; - } } @@ -1288,7 +1228,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, Graph g) { +void decreaseNbNeighborsInB(int u, Heap B, Heap C, SET V, int S[], int n, Graph g) { int nb = 0; for (int * p = g->lists[u]; *p != NONE; p ++) { @@ -1308,15 +1248,12 @@ void decreaseNbNeighborsInB(int u, Heap B, Heap C, Graph g) { // Only for flushAtoB(). u has been inserted in B (for flushAtoB) -void increaseNbNeighborsInB(int u, Heap C, Heap B, Graph g) { +void increaseNbNeighborsInB(int u, Heap C, SET V, int S[], int n, 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; } } @@ -1324,7 +1261,7 @@ void increaseNbNeighborsInB(int u, Heap C, Heap B, Graph g) { // for flushAtoB -void decreaseNbNeighborsInA(int u, Heap A, Heap C, Graph g) { +void decreaseNbNeighborsInA(int u, Heap A, Heap C, SET V, int S[], int n, Graph g) { int nb = 0; for (int *p = g->lists[u]; *p != NONE; p ++) { nbNeighborsInA[*p] --; @@ -1338,23 +1275,22 @@ void decreaseNbNeighborsInA(int u, Heap A, Heap C, Graph g) { heapBubbleUp(C->ind[*p], C); if ( ++ nb == nbNeighborsInS[u]) break; } + return; } // for flushBtoA -void increaseNbNeighborsInA(int u, Heap C, Heap A, Graph g) { +void increaseNbNeighborsInA(int u, Heap C, SET V, int S[], int n, 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; } @@ -1391,142 +1327,5 @@ 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 b5ef327..4127677 100644 --- a/separator.h +++ b/separator.h @@ -45,24 +45,8 @@ 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; @@ -74,22 +58,21 @@ 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, 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); +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); 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, Graph g); -void removeNeighborsFromB(int e, Heap A, Heap B, Heap C, 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); 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); @@ -105,31 +88,23 @@ 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(int S[], int n, int pos[], Graph g); +int initializeNbNeighbors(SET V, int S[], int n, int pos[], Graph g); void recoverNbNeighbors(int S[], int n); -void initSeparator(int *S, int n, Graph g, Separator s); +void initSeparator(SET V, 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, 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); +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); 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 5921b61..0e5752a 100644 --- a/tree.c +++ b/tree.c @@ -120,8 +120,7 @@ int nbNeighborsAbove(Node node, Graph g) { Node p = node->father; while (p != NULL) { - //if (isInSet(p->vertex, NULL, N, nN)) - if (isInList(p->vertex, N, nN)) + if (isInSet(p->vertex, NULL, N, nN)) nb ++; p = p->father; } diff --git a/utils.c b/utils.c index 45939a1..d1af184 100644 --- a/utils.c +++ b/utils.c @@ -113,6 +113,30 @@ 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 d6401b1..ce264fc 100644 --- a/utils.h +++ b/utils.h @@ -21,6 +21,7 @@ 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); -- GitLab