Skip to content
Snippets Groups Projects
Commit 7dd30722 authored by stephgc's avatar stephgc
Browse files

sga 29/05

parent d927c13c
Branches
No related tags found
No related merge requests found
......@@ -17,8 +17,6 @@ add_executable(sga
main.c
heap.c
heap.h
fibheap.c
fibheap.h
tree.c tree.h
decompose.c decompose.h
separator.c separator.h
......
......@@ -101,7 +101,7 @@ extern int *sumSizes;
void testDecompose(Graph g, int nbRuns, int algo) {
int *S = malloc(g->n * sizeof(int)); // list of vertices
int *posS = malloc(g->n * sizeof(int)); // booleans for separe
int *posS = malloc(g->n * sizeof(int)); // booleans for separation
int *nbCriticalNodes = malloc(g->n * sizeof(int)); // to calculate the numbers of critical nodes at each level
int bestHDec = g->n+1;
Node root;
......@@ -110,8 +110,6 @@ void testDecompose(Graph g, int nbRuns, int algo) {
int nbRunsAttempted = 0;
int trace = 0;
//if (g->n > 300000) nbRunsSeparation = 1; // commented 26 mai
if (perForceChoiceNotInC == NONE)
perForceChoiceNotInC = (g->n > 7600) ? 10 : 0;
......@@ -370,7 +368,7 @@ Node decompose(int *S, int n, int pos[], int depth, Graph g, int hmax, int conne
}
if (sizeForest(A)+ sizeForest(B)+ sizeForest(root) != nA+nB+nC) {
if (0) if (sizeForest(A)+ sizeForest(B)+ sizeForest(root) != nA+nB+nC) {
printf("nA=%d nB=%d nC=%d A:%d B:%d root:%d\n", nA, nB, nC, sizeForest(A), sizeForest(B), sizeForest(root));
exit(0);
}
......@@ -790,7 +788,7 @@ void allocNodes(Graph g) {
void allocSets(Graph g, int max) {
theSets = calloc((size_t) (g->n), sizeof(SET));
for (int i = 0; i < max; i ++)
theSets[i] = allocSet(g->n);
theSets[i] = allocSet(g->n + 100);
}
......
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <limits.h>
#include "fibheap.h"
ARBRE_FIBO *trees = NULL; /* table d'arbres indicee sur le degre. */
int size_trees = 32;
/****************** grands principes ******************
(1) Un noeud est marque lorsqu'il perd un fils. Quand il est decroche il
est demarque, ainsi que chaque fois qu'il devient fils d'un autre noeud.
S'il perd a nouveau un fils il est decroche et devient une racine non marquee;
(2) du coup si on note y1,...,yk les fils d'un noeud x dans leur ordre
d'arrivee, on a degre(yi)>=i-2 (ou 0 pour y1), et donc
degre(yi)=i-1 ou degre(yi)=i-2
(3) sk : taille min d'un arbre de degre k
On montre que sk >= 2+Sum_0^{k-2}si (le 2 vient du fait qu'on compte la
racine et le premier fils qui est de taille au moins 1 car de degre 0 ou 1 ;
pour le reste on sait que size(yi)>=s_{degre(yi)}>=s_{i-2} (voir (2))).
Comme Fk = 2+Sum_0^{k-2}Fi >= phi^k, on en deduit
sk >= phi^k
et donc pour tout x de degre k, size(x)>=phi^k
et donc pour tout x de taille N, degre(x) <= log_{phi} N
Pour un tas de taille N, le degre maximal est borne par log_{phi} N.
Donc la taille des arbres croit exponentiellement avec le degre de
la racine, ce qui induit la bonne complexite des operations de cout le
degre.
*/
void afficher_elt(TYPE_ELT e) {
printf("%d", e);
}
/****************** Utilitaires listes. ******************/
NODE_FIBO newHeapNode(int u, TYPE_ELT val, LISTED suiv, LISTED prec, LISTED fils, LISTED pere, int degre, int taille, NODE_FIBO x) {
if (x == NULL) {
x = malloc(sizeof(struct node_fibo_heap));
assert(x != NULL);
}
x->u = u;
x->val = val;
x->marque = 0;
x->suiv = suiv;
x->prec = prec;
x->fils = fils;
x->pere = pere;
x->degre = degre;
x->taille = taille;
return x;
}
LISTED addToList(ARBRE_FIBO t, LISTED l) {
/* Insertion de l'arbre t dans la liste l. */
if (l == NULL) {
t->suiv = t->prec = t;
return t;
}
t->suiv = l->suiv;
l->suiv = t;
t->prec = l;
t->suiv->prec = t;
return l;
}
void removeFromList(LISTED p)
/* Utilise dans extraire_min. */
/* On modifie le chainage de la liste. Suppose qu'il y a plus d'un noeud. */
{
LISTED prec = p->prec;
prec->suiv = p->suiv;
prec->suiv->prec = prec;
}
/****************** Utilitaires arbres. ******************/
ARBRE_FIBO mergeFiboTrees(ARBRE_FIBO s, ARBRE_FIBO t)
/* Comme pour les tas binomiaux on met en dessous celui qui a la plus grande
valeur a la racine et on met a jour les degres. */
{
if (s->val > t->val)
{
t->fils = addToList(s, t->fils);
t->degre = t->degre+1;
s->pere = t;
s->marque = 0;
return t;
}
else
{
s->fils = addToList(t, s->fils);
s->degre = s->degre+1;
t->pere = s;
t->marque = 0;
return s;
}
}
#define FULL_AFFICHAGE
void printFiboTree(ARBRE_FIBO p, int d) {
int i;
LISTED q;
for (i = 0; i < d; i++)
printf(" ");
afficher_elt(p->val);
#ifdef FULL_AFFICHAGE
printf(" [");
if (p->pere != NULL)
afficher_elt(p->pere->val);
printf("]");
printf(" ");
afficher_elt(p->prec->val);
printf("<>");
afficher_elt(p->suiv->val);
#endif
printf("\n");
if ((q = p->fils) != NULL)
{
LISTED r = q;
do
{
printFiboTree(r, d+1);
r = r->suiv;
}
while (r != q);
}
}
/****************** Tas de Fibonacci : utils ******************/
TAS_FIBO consolidateFiboHeap(TAS_FIBO t)
/* Remise en forme du tas : on parcourt les arbres, en les stockant dans
le tableau trees[] indic'e sur les degres. Chaque fois qu'on rencontre
deux arbres de memes degres on les fusionne et on recommence. */
{
ARBRE_FIBO p, s;
int d, dmax = 0, i;
if (t == NULL)
return NULL;
if (trees == NULL)
trees = malloc((size_trees+1) * sizeof(ARBRE_FIBO));
for (i = 0; i < size_trees+1; i++)
trees[i] = NULL;
/* Parcours de la liste des arbres en fusionnant. */
p = t;
do
{
s = p->suiv;
d = p->degre;
while (trees[d] != NULL)
{
/* on fusionne les deux arbres de meme degre. */
/* pas la peine de decrocher p, on reconstruira la liste des arbres*/
p = mergeFiboTrees(trees[d], p);
trees[d] = NULL;
d = p->degre;
}
trees[d] = p;
if (d > dmax)
dmax = d;
p = s;
}
while (p != t);
/* On parcourt la table trees[] pour reconstruire le tas. */
for (d = 0, t = NULL; d < dmax+1; d++)
if (trees[d] != NULL)
{
trees[d]->pere = NULL;
t = addToList(trees[d], t);
if (t->val > trees[d]->val)
t = trees[d];
}
return t;
}
void printFiboHeap(TAS_FIBO T) {
TAS_FIBO p = T;
if (T == NULL)
return;
do
{
printFiboTree(p, 0);
p = p->suiv;
}
while (p != T);
}
int sizeArbreFibo(ARBRE_FIBO a) {
ARBRE_FIBO q;
int size = 1;
if ((q = a->fils) != NULL)
{
LISTED r = q;
do
{
size += sizeArbreFibo(r);
r = r->suiv;
}
while (r != q);
}
return size;
}
int sizeTasFibo(TAS_FIBO H) {
TAS_FIBO p = H;
if (p == NULL)
return 0;
int size = 0;
do
{
size += sizeArbreFibo(p);
p = p->suiv;
}
while (p != H);
return size;
}
/****************** Tas de Fibonacci : operations de base ******************/
/* If p is NULL the new node is allocated in function newHeapNode(). */
TAS_FIBO insertFiboHeap(int u, TYPE_ELT val, TAS_FIBO t, NODE_FIBO p, ARBRE_FIBO *the)
/* insertion de val dans t. On insere un nouveau maillon dans la liste et
on met a jour le min. */
{
if (t == NULL)
{
p = newHeapNode(u, val, NULL, NULL, NULL, NULL, 0, 1, p);
p->suiv = p->prec = p;
if (the != NULL)
*the = p;
return p;
}
p = newHeapNode(u, val, t, t->prec, NULL, t->pere, 0, 1, p);
t->prec->suiv = p;
t->prec = p;
if (the != NULL)
*the = p;
if (p->val < t->val)
return p;
return t;
}
TAS_FIBO unionFiboHeap(TAS_FIBO s, TAS_FIBO t)
/* L'union consiste juste a concatener les listes en gerant le min. */
{
LISTED lt;
if (s == NULL)
return t;
if (t == NULL)
return s;
lt = t->prec;
lt->suiv = s->suiv;
s->suiv = t;
t->prec = s;
lt->suiv->prec = lt;
if (s->val < t->val)
return s;
return t;
}
int extractMinFiboHeap(TAS_FIBO *T, int free_node)
/* Extraction du minimum : on consolide le tas avec la liste des fils
du noeud extrait. */
{
LISTED t = *T;
LISTED p = t->suiv;
LISTED r = t->fils;
int min = t->u;
/* On s'occuppera des peres des fils de t dans consolider. */
if (p != t)
{
removeFromList(t);
r = unionFiboHeap(r, p);
}
if (free_node)
free(t);
*T = consolidateFiboHeap(r);
return min;
}
/* #define VERSION_COURTE */
void decreaseKeyFiboHeap(ARBRE_FIBO p, TYPE_ELT v, TAS_FIBO *T) {
TAS_FIBO t = *T;
ARBRE_FIBO pere = p->pere;
#ifdef VERSION_COURTE
ARBRE_FIBO pi = p;
#endif
p->val = v;
/* Cas ou ca ne change rien */
if (pere == NULL)
{
if (v < t->val)
*T = p;
return;
}
if (pere->val <= v)
return;
/* Cas ou il faut decrocher le sous arbre. */
#ifdef VERSION_COURTE
if (p->val < (*T)->val)
*T = p;
while ((pere != NULL) && ((p->marque == 1) || (p == pi)))
{
if (p->suiv == p)
pere->fils = NULL;
else
{
pere->fils = p->suiv; /* au hasard */
removeFromList(p);
}
pere->degre--;
p->pere = NULL;
if (p != pi)
p->marque = 0; /* Pour le premier coup c'est pas bon ? */
t = addToList(p, t);
p = pere;
pere = pere->pere;
}
if (p->marque == 1)
p->marque = 0; /* p est racine et marque. */
else
p->marque = 1;
#else
/* On decroche le noeud. */
pere->degre--;
if (p->suiv == p)
pere->fils = NULL;
else
{
pere->fils = p->suiv; /* au hasard */
removeFromList(p);
}
p->pere = NULL;
/* On insere dans la liste des arbres (il y a deja au moins le pere). */
t = addToList(p, t);
if (p->val < t->val)
*T = p;
if (pere->pere != NULL)
{
if (pere->marque == 0)
pere->marque = 1;
else
{
p = pere;
pere = pere->pere;
while ((pere != NULL) && (p->marque == 1))
{
if (p->suiv == p)
pere->fils = NULL;
else
{
pere->fils = p->suiv; /* au hasard */
removeFromList(p);
}
pere->degre--;
p->pere = NULL;
p->marque = 0;
t = addToList(p, t);
/* if (p->val < t->val) *T = p;
Inutile ici car p n'est pas racine de son arbre. */
p = pere;
pere = pere->pere;
}
if (p->marque == 1)
p->marque = 0; /* cas ou p est marque et racine dans le tas. */
else
p->marque = 1; /* cas ou on s'arrete sur un noeud non marque. */
}
}
#endif
}
void delete_tas(ARBRE_FIBO p, TAS_FIBO *T)
{
decreaseKeyFiboHeap(p, INT_MIN, T);
extractMinFiboHeap(T, 1);
}
#ifndef _H_tasfibo
#define _H_tasfibo
// #include "type_elt.h"
typedef int TYPE_ELT;
typedef struct node_fibo_heap * LISTED;
typedef struct node_fibo_heap * NODE_FIBO;
typedef struct node_fibo_heap * ARBRE_FIBO;
typedef struct node_fibo_heap * TAS_FIBO;
typedef struct {
TAS_FIBO heap;
int (*lt)(int, int);
}
* heapFibo;
struct node_fibo_heap
{
int u;
TYPE_ELT val;
int marque; /* indique si le noeud a perdu un fils depuis la derniere
fois ou il est devenu fils d'un autre noeud. */
LISTED suiv, prec, fils, pere;
int degre;
int taille;
int i; /* Indice dans le tableau the. */
};
void printFiboHeap(TAS_FIBO T);
int sizeTasFibo(TAS_FIBO H);
NODE_FIBO newHeapNode(int u, TYPE_ELT val, LISTED suiv, LISTED prec, LISTED fils, LISTED pere, int degre, int taille, NODE_FIBO x);
void decreaseKeyFiboHeap(LISTED p, TYPE_ELT v, TAS_FIBO *T);
void delete_tas(ARBRE_FIBO p, TAS_FIBO *T);
int extractMinFiboHeap(TAS_FIBO *T, int free_node);
TAS_FIBO insertFiboHeap(int u, TYPE_ELT val, TAS_FIBO t, NODE_FIBO p, ARBRE_FIBO *the);
TAS_FIBO unionFiboHeap(TAS_FIBO s, TAS_FIBO t);
#endif
......@@ -13,7 +13,6 @@
#include "lists.h"
#include "fibheap.h"
#include "heap.h"
#include "sets.h"
......@@ -39,8 +38,6 @@ struct graph {
int *nadj;
SET *neighbors;
NODE_FIBO * nodes; /* reserve of nodes for Fibonacci heaps. */
};
......
......@@ -58,13 +58,15 @@ int perForceChoiceNotInC = NONE; // Initialized before each separation if modeEv
int perChooseInCAtRandom = 1; // Choice in C at random
int nbRunsSeparation = 30; // 1 or 5
int maxTimeSeparation = 30; // test optilion 27/05: 80, 28/05: 60
int nbFlushes = 101; // default is 100,
int ratioMin = 5; // min=5 max=55
int ratioMax = 55; // too small ratioMax stops the flush (>50)
int modeEvalSeparator = EVAL_CARD; // EVAL_SQRT_CARD EVAL_TREE_HEIGHT_COMPLETE_GRAPH EVAL_MINIMIZE_C EVAL_CARD EVAL_MIN_A_B
double coeffHeightNbEdges = 2.0; // coefficient used to estimate the height for a given number of edges. Ponderates the evaluation against the cardinal of C.
int modeEvalAtRandom = 1;
int modeEvalAtRandom = 0;
......@@ -122,7 +124,7 @@ int main (int nargs, char ** args)
noSwapsInFirstRuns = 0;
printSolution = 1;
printResult = 0;
time_limit = 1811;
time_limit = 1803;
preliminaryGreedyDecomposition = 1;
goto START_SOLVE;
}
......@@ -208,6 +210,13 @@ int main (int nargs, char ** args)
nbRunsSeparation = atoi(args[i]);
}
else if (strcmp(args[i], "-max_time_sep") == 0) {
i ++;
if (i == nargs)
goto USAGE;
maxTimeSeparation = atoi(args[i]);
}
else if (strcmp(args[i], "-per_choice_AB") == 0) {
i ++;
if (i == nargs)
......@@ -268,12 +277,8 @@ int main (int nargs, char ** args)
algo = GREEDY_ALGORITHM;
}
else if (strcmp(args[i], "-separe") == 0) { // default
else if (strcmp(args[i], "-separe") == 0) {
algo = SEPARE_AND_EXPLORE;
if ((i+1 < nargs) && (isdigit(args[i+1][0]))) {
i ++;
sizeSwitchToGreedy = atoi(args[i]);
}
}
......@@ -307,10 +312,11 @@ START_SOLVE:
return 0;
USAGE:
printf("Usage :: ./treedepth [-file <file name>] [-runs <nb runs>] [-s <number>] [-trace] \\"
"[-save_solution <file name>] [-no_solution] [-improve] [-no_improve] [-no_pullup] [-no_swaps]\\"
"[-flushes <nb flushes>] [-per_choice_AB <per>] [-per_chrand_C <per>] [-sep_runs <nb runs>] \\"
"[-ratios <min> <max>] [-threshold <per>] [-eval <mode>] [-static_eval] [-dynamic_eval] \\"
"[-greedy] [-separe [<size to greedy>]] <file name>\n");
printf("Usage :: ./treedepth [-file <file name>] [-greedy] [-separe] [-runs <nb runs>] [-s <number>] [-trace] \\"
"[-save_solution <file name>] [-no_solution] [-no_improve] [-no_pullup] [-no_swaps]\\"
"[-sep_runs <nb runs>] [-max_time_sep <duration>] [-flushes <nb flushes>] \\"
"[-per_choice_AB <per>] [-per_chrand_C <per>] \\"
"[-ratios <min> <max>] [-threshold <per>] [-eval <mode>] \\"
"[-greedy] [-separe]\n");
return 0;
}
......@@ -9,8 +9,6 @@
#include <stdio.h>
#include <time.h>
//#define PACE_2020
#define TEST_PACE_2020
extern volatile sig_atomic_t stopSearch;
......@@ -31,6 +29,7 @@ extern int printResult;
extern int nbRunsSeparation;
extern int maxTimeSeparation;
extern int nbFlushes;
extern int perForceChoiceNotInC;
......
......@@ -31,8 +31,6 @@ int useMinPartitions = 2; // 0: maintain heap, 1-2: just put min elements at the
// 1: maintain mins 2: calculate mins only when necessary
int maxTimeSeparation = 120;
//
// Datas structures
......@@ -80,11 +78,6 @@ int *component;
// Warning: the preliminary call to initializeNbNeighbors() place first in the lists of neighbors
// those that are in the current set S[]. It is then unnecessary to verify each time that the vertex
// belongs to the current set.
//
// La separation suit une strategie d'effeuillage: on ne cherche pas a deplacer les sommets
// pour construire un bon ensemble, on cherche a enlever des morceaux un peu laches pour
// qu'il reste un noyeau dur. L'evaluation devrait dans cette optique favoriser la
// densite du noyeau restant (B pour flushBA) tout en minimisant la taille du separateur.
#ifdef STATS_SEPARATION
clock_t *timesSep = NULL;
......@@ -107,9 +100,6 @@ int searchSeparator(int *S, int n, SET V, Graph g, Separator theSeparator, int n
nbCallsSearchSeparator ++;
int mode = modeEvalSeparator;
if (modeEvalSeparator == NONE) mode = rand()%3;
theSeparator->C->n = g->n+1;
bestEval = -1.0;
bestIsUninitialized = 1;
......@@ -119,6 +109,8 @@ int searchSeparator(int *S, int n, SET V, Graph g, Separator theSeparator, int n
sizeMax = n * ratioMax / 100;
if ((g->n > 300000) && (depth < 6)) nbRunsSeparation = 1; // avoids WA ?
//saveNbNeighbors(S, n);
if (modeEvalAtRandom) {
......@@ -140,11 +132,15 @@ int searchSeparator(int *S, int n, SET V, Graph g, Separator theSeparator, int n
initSeparator(V, S, n, g, sep);
separe(S, n, V, g, sep, nFlushes, mode);
separe(S, n, V, g, sep, nFlushes, modeEvalSeparator);
if ((stopSearch) || ((clock()-start)/CLOCKS_PER_SEC > maxTimeSeparation/(depth+1))) break;
}
if (0 && depth < 3) printf("depth=%d tSep=%.1fs total=%.1fs\n", depth,
(float) (clock()-start)/CLOCKS_PER_SEC,
(float) (clock()-startTime)/CLOCKS_PER_SEC);
#ifdef STATS_SEPARATION
timesSep[depth] += clock()-start;
nbSearches[depth] ++;
......@@ -159,39 +155,12 @@ int searchSeparator(int *S, int n, SET V, Graph g, Separator theSeparator, int n
else
copySeparator(sep, theSeparator);
// This must not be done here the numbers of neighbors are not up to date
// Moreover the process is useless: when the best separator is built all vertices of C which have no neighbors
// in B are moved to A. If they had no neighbor in A next decomposition will discover unconnected components in A
//if (removeABDisconnectedVertices)
// selectABDisconnectedVertices(theSeparator, V, S, n, nbCallsSepare, g);
if (verifyTheSeparator && (! verifySeparator(S, n, theSeparator))) exit(0);
//if (verifyTheSeparator && (! verifySeparator(S, n, theSeparator))) exit(0);
return 1;
}
#ifdef NOTDEF
An idea to start with good vertices before flushing
int essaiSeparator = 0;
if (essaiSeparator) {
heapSetCompare(C, isSmallerNeighborsInBthenA);
makeHeap(B);
makeHeap(C);
int t = rand()%nbMaxD, vertex = NONE;
for (int i = 0; ; i ++)
if (nbNeighborsInS[S[i]] == maxDegree)
if (t -- == 0) { vertex = S[i]; break; }
assert(vertex != NONE);
heapRemove(vertex, B);
heapInsert(vertex, C);
nbEdgesInB -= nbNeighborsInB[vertex];
decreaseNbNeighborsInB(vertex, B, C, V, S, n, g);
removeNeighborsFromB(vertex, A, B, C, V, S, n, g);
}
#endif
int chooseFirstVertex(int *S, int n, Graph g) {
......@@ -248,9 +217,6 @@ int separe(int *S, int n, SET V, Graph g, Separator s, int nbFlushs, int mode) {
Heap B = s->B;
Heap C = s->C;
// NOTE: should not maintain the heap source
// Should insert directly in destination the vertices that have no more neighbor in the source
for (int i = 0; i < nbFlushs; i ++) {
if (useMinPartitions) {
......@@ -292,8 +258,7 @@ int separe(int *S, int n, SET V, Graph g, Separator s, int nbFlushs, int mode) {
copySeparator(bestSep, s);
if (0 && ! verifySeparator(S, n, s)) exit(0);
//if ( ! verifySeparator(S, n, s)) exit(0);
return 1;
}
......@@ -303,8 +268,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,...)
// 1 / f(C) / g(a-b) ou / g(ma-mb) with
int min = (nA > nB) ? nB : nA;
int max = (nA > nB) ? nA : nB;
int delta = max-min;
......@@ -316,24 +279,11 @@ double evalSep(int nA, int nB, int nC, int mA, int mB, int mode, int direction)
if (mode == EVAL_ESSAI) {
// minimize C size while the numbers of constraints in A and B are small and closed
return (1.0 / (1+nC) / (1+nC) / sqrt(1.0+maxE-minE));
return (sqrt((double) (nbEdgesInS - mA - mB)) / (1+nC) / (1+nC) / sqrt(1.0+maxE-minE));
double c = 2.0 - 1.0 / pow(2, 1.0+maxE-minE);
return (1.0 / (1+nC) / (1+nC) / c);
// evaluate tree height considering the density
//double densityA = (mA <= 1) ? 1.0 : (double) mA * 2 / A->n / (A->n-1);
//double densityB = (mB <= 1) ? 1.0 : (double) mB * 2 / B->n / (B->n-1);
double degreeA = (mA <= 1) ? 1.0 : (double) mA * 2 / nA;
double degreeB = (mB <= 1) ? 1.0 : (double) mB * 2 / nB;
double hA = sqrt((double) 2*mA) * (1.0 - pow(2, -1-degreeA));
double hB = sqrt((double) 2*mB) * (1.0 - pow(2, -1-degreeB));
return (1.0 / (nC + ((hA > hB) ? hA : hB))); // bof
}
if (mode == EVAL_TREE_HEIGHT_COMPLETE_GRAPH)
// 1/ approx tree height
// approx tree height
return (1.0 / (nC + sqrt((double) (coeffHeightNbEdges * maxE ))));
......@@ -343,18 +293,14 @@ double evalSep(int nA, int nB, int nC, int mA, int mB, int mode, int direction)
double rab = sqrt((double) (nA + nB));
double deltaSqrt = (ra > rb) ? (ra - rb) : (rb - ra);
if (mode == EVAL_0) return ((rab - deltaSqrt)*(rab - deltaSqrt) / (1+nC) / (1+nC));
if (nC > 0)
return ((rab - deltaSqrt) / nC / nC);
//return ((rab - deltaSqrt) / C->n / C->n );
if (nC > 0) return ((rab - deltaSqrt) / nC / nC);
return ((rab - deltaSqrt) / (1+nC));
//return ((rab-deltaSqrt)*(rab-deltaSqrt)/C->n);
}
if (mode == EVAL_CARD) return ((double) (min) / (nC+1)); // modified 1/05
//if (mode == EVAL_CARD) return ((C->n > 0) ? (double) (A->n+B->n-delta) / C->n : A->n+B->n+1); // heur_095.gr 3417 13667 h=13 4.07s 10 runs
if (mode == EVAL_LEVEL_DENSITY) {
// The idea: evaluate the cost to place vertices of C and the smallest among A and B
// 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
if (nA < nB) return ((double) (nA+nC) / (nC + sqrt(sqrt((double) 2.0*mB))));
else return ((double) (nB+nC) / (nC + sqrt(sqrt((double) 2.0*mA))) );
......@@ -374,8 +320,6 @@ double evalSep(int nA, int nB, int nC, int mA, int mB, int mode, int direction)
return 2.0 * mA / (nA - 1) / (nA - 1) / (nC + 1) / (nC + 1);
}
// few vertices
if (nA+nB+nC <= 7) return ((nC > 0) ? 1.0 / (1+delta) / (1+delta) / nC : 1.0 / (1+delta));
......@@ -402,8 +346,7 @@ int chooseEltInC(Heap C) {
int e = C->val[rand() % (C->n)];
return e;
}
//if (( ! chooseInCAtRandom) || (rand() % 100 >= perChooseInCAtRandom))
return C->val[0]; //heapExtractMin(C); the vertex that has the fewer neighbors in the from set
return C->val[0]; // the vertex that has the fewer neighbors in the from set
}
......@@ -422,7 +365,6 @@ int chooseEltInB(Heap B) {
if (choiceModeInAandB == CHOICE_AB_MIN_AB_MAX_C) {
// Search a vertex in B with minimal number of neighbors in B and max in C.
// The process works also when the vertices with the min number of neighbors are packed first in B
int best = B->val[0];
int nbBMin = nbNeighborsInB[B->val[0]];
int nbCMax = nbNeighborsInS[B->val[0]] - nbNeighborsInB[B->val[0]];
......@@ -467,12 +409,6 @@ int chooseEltInA(Heap A) {
}
void printDebugB(Heap B) {
printf("B: min=%d nbmin=%d :: ", B->min, B->nbmin);
for (int i = 0; i < B->n; i ++) printf("%d/%d ", B->val[i], nbNeighborsInB[B->val[i]]);
printf("\n");
}
int testSourceConnected = 0;
int thresholdConComponents = 13;
......@@ -520,7 +456,7 @@ void flushBtoA(Heap A, Heap B, Heap C, SET V, int S[], int n, int mode, int seed
if (A->n >= sizeMax) break;
if (B->n < sizeMin) break; // useless ?
if (B->n < sizeMin) break;
if (A->n >= sizeMin) {
int nB = B->n, nEB = nbEdgesInB;
......@@ -537,7 +473,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);
if ((bestIsUninitialized) || (e > bestEval)) {
// There can be vertices in C with no neighbor in B that must be poured in A
// There can be vertices in C with no neighbor in B
if (1) pourCintoA(A, nbNeighborsInB, nbNeighborsInA, &nbEdgesInA, C, g, 1);
bestIsUninitialized = 0;
bestEval = e;
......@@ -568,7 +504,7 @@ void flushAtoB(Heap A, Heap B, Heap C, SET V, int S[], int n, int mode, Graph g)
int e = NONE;
int bestBSize = NONE;
while (1) { // (B->n < A->n)
while (1) {
int sizeA = A->n;
......@@ -601,7 +537,7 @@ void flushAtoB(Heap A, Heap B, Heap C, SET V, int S[], int n, int mode, Graph g)
if (B->n >= sizeMax) break;
if (A->n < sizeMin) break; // 25/05: If there are few vertice in A and B
if (A->n < sizeMin) break; // 25/05
if (B->n >= sizeMin) {
int nA = A->n, nEA = nbEdgesInA;
......@@ -704,7 +640,6 @@ void removeNeighborsFromB(int e, Heap A, Heap B, Heap C, SET V, int *S, int n, G
if ((nbToThrow == 0) || (C->n == 0) || (B->n <= 1)) return;
//for (int *p = g->lists[e]; p-g->lists[e] < nbNeighborsInS[e]; p ++)
for (int *p = verticesToThrow; p < verticesToThrow+nbToThrow; p ++)
{
if ((C->n == 0) || (B->n <= 1)) return;
......@@ -919,7 +854,6 @@ int compareCVerticesFlushAtoB(int a, int b) {
//
void pourCintoA(Heap A, int nbNFrom[], int nbNTo[], int *nbEdges, Heap C, Graph g, int justAdd) {
// move isolated vertices from C to A
for (int i = 0; i < C->n; i++) {
int e = C->val[i];
if (nbNFrom[e] == 0) {
......
This diff is collapsed.
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment