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