/***************************************************************************************** * * Author : Olivier Elemento, elemento@lirmm.fr * * LICENSE : Permission is granted to copy, modify, distribute this source for any purpose. * INPUT : distance file in PHYLIP format * SORTIES : a single tree in Newick format ****************************************************************************************/ #include #include #include #include #include #include #include #define max(x,y) (x>y?x:y) #define min(x,y) (x 0) { trace = 1; fp_trace = fopen(tracefile, "w"); } filename = (char*)calloc(30, sizeof(char)); outfile = (char*)calloc(30, sizeof(char)); if ((argv[1] == 0) || !(fp = fopen(argv[1], "r"))) { printf("Input file : "); scanf("%s", filename); printf("Output file : "); scanf("%s", outfile); } else { strcat(filename, argv[1]); fclose (fp); } data = loadDistances(filename, &nb_species); if (verbose) showDistances(data, 2 * nb_species - 1); /** alloue un nouveau seqs **/ seqs = allocSeqs(nb_species); initSeqs(seqs, nb_species); /** nouvel arbre de nb_species feuilles **/ tr = allocTree(nb_species); /** alloue une premiere matrice de couts dont la taille est égale au nombre final de noeuds **/ crdata = allocMatrix(2 * nb_species - 1); /** rempli avec des -1 **/ for (i=0; isize != 2) { if (verbose) { showDistances(crdata, nb_species * 2 - 1); //getchar(); } /** initialise le nombre de paires calculées **/ nbpairscalc = 0; /** initialise le nombre de doubles sommes **/ nbdblesums = 0; nbpairs = 0; /** raccourci **/ s = seqs->sequences; /** longueur maxi de la fenetre **/ d_maxlength = seqs->size / 2; /** cout mini **/ maxcost = - SHRT_MAX; /** pour chaque longueur de duplication **/ for (l=1; l<=d_maxlength; l++) { if (verbose) printf("L=%d\n", l); p = 0; while (p+l < seqs->size) { //for (p=0; p+2*l<=seqs->size; p++) { crdata[ min(s[p], s[p+l]) ][ max(s[p], s[p+l]) ] = getPairCost(crdata, data, p, l, lastopti, lastoptl, seqs, u, v, w, uv); if (verbose) printf("Cout de la paire (%d, %d) = %3.1f\n", s[p], s[p+l], crdata[ min(s[p], s[p+l]) ][ max(s[p], s[p+l]) ]); cost = crdata[ min(s[p], s[p+l]) ][ max(s[p], s[p+l]) ]; if (cost > maxcost) { /** NOW : determiner le cout de la duplication englobant la paire p,p+l, sachant que celui-ci peut-etre inferieur ou cout max **/ /** BACKWARD : calcule le cout de la duplication la plus a gauche si c'est possible **/ if (verbose) printf("BACKWARD : calcule le cout de la duplication la plus a gauche si c'est possible et si elles n'ont pas ete calculées ...\n"); for (i=max(0,p-l+1); isize-l); i++) { crdata[ min(s[i], s[i+l]) ][ max(s[i], s[i+l]) ] = getPairCost(crdata, data, i, l, lastopti, lastoptl, seqs, u, v, w, uv); } /** CALCUL : fenetres en commencant par celle située à i = max(0,p-l+1) et finissant a p **/ if (verbose) printf("calcule toutes les fenetres de i=%d à i=%d\n", max(0,p-l+1), p); for (i=max(0,p-l+1); i<=min(p, seqs->size-2*l); i++) { getMinMoyCost(i, l, seqs, crdata, &min, &moy); if (verbose) printf("Fenetre i=%d, l=%d, cout = %d\n", i, l, (int)min); if (min > maxcost) { opti = i; optl = l; maxcost = min; maxmoy = moy; } else if ((min == maxcost) && (moy > maxmoy)) { opti = i; optl = l; maxmoy = moy; } } } else { /** met les couts a -1 entre p+1 et p+l-1 **/ for (i=p+1; isize-l); i++) { crdata[ min(s[i], s[i+l]) ][ max(s[i], s[i+l]) ] = -1.0; } if (verbose) printf("Ca ameliore pas ... saute de l\n"); } p += l; } } if (verbose) printf("Meilleure duplication trouvée : opti = %d (%d), optl = %d pour un cout = %d\n", opti, s[opti], optl, (int)maxcost); lastopti = opti; lastoptl = optl; if (verbose) { printf("Matrice de couts modifée = \n"); showCostMatrix(crdata, seqs); getchar(); } /** verif a tejer **/ if (nbpairs != (nbpairscalc + nbdblesums)) { printf("OOUPS ...\n"); exit(0); } if (trace) fprintf(fp_trace, "%4d %4d\n", nbpairscalc, nbdblesums); //printCostMatrix(fp_trace, crdata, seqs); /** cree une fenetre de nodes internes w **/ w = (short*)malloc(optl*sizeof(short)); /** cree les nodes internes (u = ensemble des nouveaux noeuds) **/ for (i=0; isequences+opti, optl * sizeof(short)); v = (short*)malloc(optl*sizeof(short)); memcpy(v, seqs->sequences+opti+optl, optl * sizeof(short)); uv = (short*)malloc(2*optl*sizeof(short)); memcpy(uv, u, optl * sizeof(short)); memcpy(uv+optl, v, optl * sizeof(short)); for (i=0; isize = %d\n", seqs->size); } } if (verbose) printf("seqs->sequences[0] = %d, seqs->sequences[1] = %d ...\n", seqs->sequences[0], seqs->sequences[1]); tr->children[0][0] = seqs->sequences[0]; tr->children[0][1] = seqs->sequences[1]; tr->nodes[seqs->sequences[0]] = 0; tr->nodes[seqs->sequences[1]] = 0; if (verbose) { getchar(); printf("tree = \n"); showAllNodes(tr); } if (strlen(outfile) == 0) printTree(tr); else fprintTree(tr, outfile); if (outorder) printOrderFile(nb_species, orderfile); ftime(&t2); if (trace) fprintf(fp_trace, "temps = %d\n", (int)((t2.time - t1.time)*1000 + (t2.millitm - t1.millitm))); if (trace) fclose(fp_trace); return 0; } void printOrderFile(int n, char* s_orderFile) { int i; FILE* fp = fopen(s_orderFile, "w"); fprintf(fp, "%d\n", n); for (i=0; inumintnodes, t->numleaves); for (i=0; imaxnodes; i++) { printf("%d\t%d\t%d,%d\n", i, t->nodes[i], t->children[i][0], t->children[i][1]); } } void printTree(tree* t) { char* str = (char*)calloc(4096, sizeof(char)); saveTree(t, 0, str); printf("%s;\n", str); free(str); str = 0; } /* * fprintTree : sauve un arbre dans un fichier * */ void fprintTree(tree* t, char* outfile) { FILE* fp; char* str = (char*)calloc(4096, sizeof(char)); saveTree(t, 0, str); fp = fopen(outfile, "w"); fprintf(fp, "%s;\n", str); fclose(fp); free(str); str = 0; } /** avec les longueurs de branches **/ void saveTree(tree* t, int numnode, char* str) { //char tmp[10]; if (t->children[numnode][0] == -1) { //sprintf(tmp, "rep%d", numnode - t->maxintnodes + 1); //strcat(str, tmp); strcat(str, names[numnode - t->maxintnodes]); } else { strcat(str, "("); saveTree(t, t->children[numnode][0], str); strcat(str, ","); saveTree(t, t->children[numnode][1], str); strcat(str, ")"); } } /** alloue une matrice n*n **/ float** allocMatrix(int nb_species) { float** dists; int lig, col; dists = (float**)malloc(nb_species*sizeof(float*)); for(lig=0; lig < nb_species; lig++) { dists[lig] = (float*)malloc(nb_species*sizeof(float)); for (col=0; colsequences = (short*)malloc(numleaves*sizeof(short)); seqs->size = numleaves; return seqs; } /** initialise un seqs **/ void initSeqs(SEQS* seqs, short numleaves) { short i; for (i=0; isequences[i] = i + numleaves - 1; if (verbose) printSeqs(seqs); } short updateTree(tree* t, SEQS* seqs, short posi, short posj) { int u; // nouvelle node = t->numintnodes u = t->numintnodes; if (verbose) { printf("new node (u) = %d\n", u); getchar(); } t->children[u][0] = seqs->sequences[posi]; t->children[u][1] = seqs->sequences[posj]; t->nodes[seqs->sequences[posi]] = u; t->nodes[seqs->sequences[posj]] = u; t->numintnodes++; return u; } /** * merge un locus * i position de la bande a supprimer **/ void mergeSequences(SEQS* seqs, short* u, short i, short l) { short* liste; liste = (short*)malloc((seqs->size - l) * sizeof(short)); /** copie de 0 a i vers 0 **/ memcpy(liste, seqs->sequences, i*sizeof(short)); /** copie de i a i+l vers i **/ memcpy(liste + i, u, l * sizeof(short)); /** copie de i+l vers i **/ memcpy(liste + i + l, seqs->sequences + i + 2*l, (seqs->size - i - 2*l) *sizeof(short)); seqs->sequences = liste; seqs->size -= l; } /** * merge un seqs * i, j paire a merger * u nouvelle node **/ void mergeSeqs(SEQS* seqs, short u, short posi, short posj) { int a,b; short* liste; if (verbose) printf("u=%d, posi=%d, posj=%d \n", u, posi, posj); /** nouvelle liste de seqs contenant seqs->size - 1 indiv **/ liste = (short*)malloc((seqs->size - 1) * sizeof(short)); /** recopier dans la nouvelle liste **/ b = 0; for (a=0; asize; a++) { if (a == posi) { liste[b] = u; b++; } else if (a == posj) { // ne fait rien } else { liste[b] = seqs->sequences[a]; b++; } } seqs->sequences = liste; seqs->size--; if (verbose) printSeqs(seqs); } void printSeqs(SEQS* loc) { int i; for (i=0; isize; i++) { printf("%d ", loc->sequences[i]); } printf("\n"); } /* * calcule le cout d'une duplication (ajouté cr) * @param i debut de la duplication sur le locus * @param l taille de la duplication (fenetre / 2) * @param locus * @param data distances */ float getCost(int i, int l, SEQS* seqs, float** dists) { int j; float cost = 0.0; short* s = seqs->sequences; if (verbose) printf("cost = "); for (j=i; jsequences; if (verbose) printf("cost = "); for (j=i; jsequences; for (j=i; jsequences[r], locus->sequences[q]); /** q est nécéssairement avant r (voir les for) **/ /** d(r, q) = d(r, q) + d(r+l, q) - d(r, r+l) **/ if (!correction) dists[ min(u[s], seqs->sequences[q]) ][ max(u[s], seqs->sequences[q]) ] = (dists[ min(seqs->sequences[q], seqs->sequences[r]) ][ max(seqs->sequences[q], seqs->sequences[r]) ] + dists[ min(seqs->sequences[q], seqs->sequences[r+l]) ][ max(seqs->sequences[q], seqs->sequences[r+l]) ] ) / 2.0; else dists[ min(u[s], seqs->sequences[q]) ][ max(u[s], seqs->sequences[q]) ] = (dists[ min(seqs->sequences[q], seqs->sequences[r]) ][ max(seqs->sequences[q ], seqs->sequences[r]) ] + dists[ min(seqs->sequences[q], seqs->sequences[r+l]) ][ max(seqs->sequences[q ], seqs->sequences[r+l]) ] - dists[ min(seqs->sequences[r], seqs->sequences[r+l]) ][ max(seqs->sequences[r] , seqs->sequences[r+l]) ]) / 2.0; if (verbose) printf("dist[%d][%d] = %5.4f\n", min(u[s] , seqs->sequences[q]), max(u[s], seqs->sequences[q]), dists[ min(u[s], seqs->sequences[q]) ][ max(u[s] , seqs->sequences[q]) ]); /** - dists[ seqs->sequences[r] ][ seqs->sequences[r+l] ]) / 2; **/ } /** sequencess après la partie dupliquée **/ for (q=i+2*l; qsize; q++) { //printf("modifie la distance entre %d et %d\n", seqs->sequences[r], seqs->sequences[q]); /** q est nécéssairement après r (voir les for) **/ /** d(r, q) = d(r, q) + d(r+l, q) - d(r, r+l) **/ /** dists[ min(u[s] , seqs->sequences[q]) ][ max(u[s] , seqs->sequences[q]) ] = (dists[ min(seqs->sequences[r], seqs->sequences[q]) ][ max(seqs->sequences[r], seqs->sequences[q]) ] + dists[ min(seqs->sequences[r+l], seqs->sequences[q]) ][ max(seqs->sequences[r+l], seqs->sequences[q]) ] - dists[ min(seqs->sequences[r], seqs->sequences[r+l]) ][ max(seqs->sequences[r] , seqs->sequences[r+l]) ]) / 2.0; **/ if (!correction) dists[ min(u[s] , seqs->sequences[q]) ][ max(u[s] , seqs->sequences[q]) ] = (dists[ min(seqs->sequences[r], seqs->sequences[q]) ][ max(seqs->sequences[r], seqs->sequences[q]) ] + dists[ min(seqs->sequences[r+l], seqs->sequences[q]) ][ max(seqs->sequences[r+l], seqs->sequences[q]) ]) / 2.0; else dists[ min(u[s] , seqs->sequences[q]) ][ max(u[s] , seqs->sequences[q]) ] = (dists[ min(seqs->sequences[r], seqs->sequences[q]) ][ max(seqs->sequences[r], seqs->sequences[q]) ] + dists[ min(seqs->sequences[r+l], seqs->sequences[q]) ][ max(seqs->sequences[r+l], seqs->sequences[q]) ] - dists[ min(seqs->sequences[r], seqs->sequences[r+l]) ][ max(seqs->sequences[r] , seqs->sequences[r+l]) ]) / 2.0; if (verbose) printf("dist[%d][%d] = %5.4f\n", min(u[s] , seqs->sequences[q]), max(u[s], seqs->sequences[q]), dists[ min(u[s], seqs->sequences[q]) ][ max(u[s] , seqs->sequences[q]) ]); /** dists[ min(u[s] , seqs->sequences[q]) ][ max(u[s] , seqs->sequences[q]) ] = (dists[ min(seqs->sequences[r], seqs->sequences[q]) ][ max(seqs->sequences[r], seqs->sequences[q]) ] + dists[ min(seqs->sequences[r+l], seqs->sequences[q]) ][ max(seqs->sequences[r+l], seqs->sequences[q]) ]) / 2.0; **/ /** - dists[ seqs->sequences[r] ][ seqs->sequences[r+l] ]) / 2; **/ } } /** distances entre séquences intérieures à la duplication **/ for (r=i, s=0; rsequences[r], seqs->sequences[q]); if (verbose) { printf("dist[%d][%d] = ( dist[%d][%d](%5.4f) + dist[%d][%d](%5.4f) ) / 4.0 + ( dist[%d][%d](%5.4f) + dist[%d][%d](%5.4f) ) / 4.0\n", min( u[s] , u[t] ), max(u[s] , u[t] ), min(seqs->sequences[r ], seqs->sequences[q ]), max(seqs->sequences[r ], seqs->sequences[q ]), dists[ min(seqs->sequences[r ], seqs->sequences[q ]) ][ max(seqs->sequences[r ], seqs->sequences[q ]) ], min(seqs->sequences[r+l], seqs->sequences[q ]), max(seqs->sequences[r+l], seqs->sequences[q ]), dists[ min(seqs->sequences[r+l], seqs->sequences[q ]) ][ max(seqs->sequences[r+l], seqs->sequences[q ]) ], min(seqs->sequences[r ], seqs->sequences[q+l ]), max(seqs->sequences[r ], seqs->sequences[q+l ]), dists[ min(seqs->sequences[r ], seqs->sequences[q+l ]) ][ max(seqs->sequences[r ], seqs->sequences[q+l ]) ], min(seqs->sequences[r+l ], seqs->sequences[q+l]), max(seqs->sequences[r+l ], seqs->sequences[q+l]), dists[ min(seqs->sequences[r+l ], seqs->sequences[q+l]) ][ max(seqs->sequences[r+l ], seqs->sequences[q+l]) ] ); } if (!correction) dists[ min( u[s] , u[t] ) ][ max(u[s] , u[t] ) ] = (dists[ min(seqs->sequences[r ], seqs->sequences[q ]) ][ max(seqs->sequences[r ], seqs->sequences[q ]) ] + dists[ min(seqs->sequences[r+l], seqs->sequences[q ]) ][ max(seqs->sequences[r+l], seqs->sequences[q ]) ] ) / 4.0 + (dists[ min(seqs->sequences[r ], seqs->sequences[q+l ]) ][ max(seqs->sequences[r ], seqs->sequences[q+l ]) ] + dists[ min(seqs->sequences[r+l ], seqs->sequences[q+l]) ][ max(seqs->sequences[r+l ], seqs->sequences[q+l]) ] ) / 4.0; else dists[ min( u[s] , u[t] ) ][ max(u[s] , u[t] ) ] = (dists[ min(seqs->sequences[r ], seqs->sequences[q ]) ][ max(seqs->sequences[r ], seqs->sequences[q ]) ] + dists[ min(seqs->sequences[r+l], seqs->sequences[q ]) ][ max(seqs->sequences[r+l], seqs->sequences[q ]) ] - dists[ min(seqs->sequences[r] , seqs->sequences[r+l]) ][ max(seqs->sequences[r ], seqs->sequences[r+l]) ]) / 4.0 + (dists[ min(seqs->sequences[r ], seqs->sequences[q+l ]) ][ max(seqs->sequences[r ], seqs->sequences[q+l ]) ] + dists[ min(seqs->sequences[r+l ], seqs->sequences[q+l]) ][ max(seqs->sequences[r+l ], seqs->sequences[q+l]) ] - dists[ min(seqs->sequences[q ], seqs->sequences[q+l]) ][ min(seqs->sequences[q ], seqs->sequences[q+l]) ]) / 4.0; /** - dists[ min(seqs->sequences[r] , seqs->sequences[r+l]) ][ max(seqs->sequences[r ], seqs->sequences[r+l]) ] **/ /** - dists[ min(seqs->sequences[q ], seqs->sequences[q+l]) ][ min(seqs->sequences[q ], seqs->sequences[q+l]) ] **/ } } } /** charge une matrice de distances **/ float** loadDistances(char* file, int* nb_spec) { float** dists; int lig, col; int matsize; FILE* fp = fopen(file, "r"); if (fp == 0) { printf("impossible d'ouvrir %s\n", file); exit(0); } fscanf(fp, " %d", nb_spec); //printf("Matrice de %d distances...\n", *nb_spec); matsize = 2 * (*nb_spec) - 1; names = (char**)malloc(*nb_spec*sizeof(char*)); for (lig=0; lig<*nb_spec; lig++) names[lig] = (char*)calloc(10, sizeof(char)); dists = (float**)malloc(matsize*sizeof(float*)); for(lig=0; lig < matsize; lig++) { dists[lig] = (float*)malloc(matsize*sizeof(float)); } for(lig=0; lig < *nb_spec; lig++) { fscanf(fp,"%s",names[lig]); //dists[lig] = (float*)malloc(matsize*sizeof(float)); for(col= 0; col < *nb_spec; col++) { fscanf(fp,"%f", &(dists[lig + *nb_spec - 1][col + *nb_spec - 1])); /* read the distance */ } } return dists; } /** * affiche la matrice de couts * */ void printCostMatrix(FILE* fp, float** dists, SEQS* seqs) { int i, j; short* s = seqs->sequences; for (i=0; isize; i++) { for (j=0; jsize; j++) { if (j>i) fprintf(fp, "%3d ", (int)dists[ min(s[i],s[j]) ][ max(s[i],s[j]) ]); else fprintf(fp, "%3d ", (int)0.000); } fprintf(fp, "\n"); } fprintf(fp, "\n"); } /** * affiche la matrice de couts * */ void showCostMatrix(float** dists, SEQS* seqs) { int i, j; short* s = seqs->sequences; for (i=0; isize; i++) { for (j=0; jsize; j++) { printf("%3d ", (int)dists[ min(s[i],s[j]) ][ max(s[i],s[j]) ]); } printf("\n"); } } void printDistances(FILE* fp, float** dists, int nb_spec) { int lig, col; for(lig=0; lig < nb_spec; lig++) { for(col= 0; col < nb_spec; col++) { fprintf(fp, "%3.4f ", dists[lig][col]); } fprintf(fp, "\n"); } fprintf(fp, "\n"); } /** affiche une matrice de distances **/ void showDistances(float** dists, int nb_spec) { int lig, col; for(lig=0; lig < nb_spec; lig++) { for(col= 0; col < nb_spec; col++) { printf("%3.4f ", dists[lig][col]); } printf("\n"); } } /** alloue un nouvel arbre * * @param T int nombre de feuilles */ tree* allocTree(int T) { int i; int maxnodes = 2*T-1; tree* t = (tree*)malloc(sizeof(tree)); t->nodes = (int*) malloc(maxnodes * sizeof(int)); t->children = (int**)malloc(maxnodes * sizeof(int*)); t->maxnodes = maxnodes; for (i=0; ichildren[i] = (int*)malloc(2*sizeof(int)); for (i=0; imaxnodes; i++) t->nodes[i] = -1; for (i=0; imaxnodes; i++) { t->children[i][0] = -1; t->children[i][1] = -1; } t->maxleaves = T; t->maxintnodes = T-1; t->numleaves = T; t->numintnodes = 1; //t->nodes[t->maxintnodes] = 0; //t->nodes[t->maxintnodes+1] = 0; //t->children[0][0] = t->maxintnodes; //t->children[0][1] = t->maxintnodes + 1; return t; } /* * retourne le cout d'une paire p, p+l * */ float getPairCost( float** mycrdata, float** mydata, int p, int l, int lastopti, int lastoptl, SEQS* seqs, short* u, short* v, short* w, short* uv) { int i, j, t; float s1, s2, s3; float cost; short* s; nbpairs++; s = seqs->sequences; cost = mycrdata[ min(s[p], s[p+l]) ][ max(s[p], s[p+l]) ]; /** si la paire p,p+l est dans le cas A, cad ne chevauche pas l'ancienne duplication et qu'elle n'est pas à -1 **/ if ((cost > -0.5) && (!((p+l >= lastopti) && (p+l < lastopti+lastoptl)) || ((p >= lastopti) && (p < lastopti+lastoptl)))) { if (verbose) printf("Cout initial de la paire (%d, %d) = %3.1f\n", s[p], s[p+l], cost); nbdblesums++; /** calcul du cout de la paire p, p+l **/ for (i=0; i<2*lastoptl-1; i++) { for (j=i+1; j<2*lastoptl; j++) { if (verbose) printf("étudie le quadruplet (%d, %d) (%d, %d)", s[p], s[p+l], uv[i], uv[j]); s1 = mydata[ min(s[p], s[p+l]) ][ max(s[p], s[p+l]) ] + mydata[ min(uv[i], uv[j]) ][ max(uv[i], uv[j]) ]; s2 = mydata[ min(s[p], uv[j] ) ][ max(s[p], uv[j] ) ] + mydata[ min(uv[i], s[p+l]) ][ max(uv[i], s[p+l]) ]; s3 = mydata[ min(s[p], uv[i] ) ][ max(s[p], uv[i] ) ] + mydata[ min(uv[j], s[p+l]) ][ max(uv[j], s[p+l]) ]; //nbdblesums++; if ((s1 < s2) && (s1 < s3)) { cost -= 1.0; if (verbose) { printf(" -1\n"); } } else { if (verbose) { printf(" \n"); } } } } for (i=0; isize; t++) { if ((t == p) || (t == p+l) || (u[i] == s[t])) continue; /** cout des paire (p,p+l)(u_i, t) **/ if ((t < lastopti) || (t >= lastopti+lastoptl)) { if (verbose) printf("etudie le quadruplet (%d, %d) (%d, %d) (u)", min(s[p], s[p+l]), max(s[p], s[p+l]), min(u[i], s[t]), max(u[i], s[t])); s1 = mydata[ min(s[p], s[p+l]) ][ max(s[p], s[p+l]) ] + mydata[ min(u[i], s[t]) ][ max(u[i], s[t]) ]; s2 = mydata[ min(s[p], s[t] ) ][ max(s[p], s[t] ) ] + mydata[ min(u[i], s[p+l]) ][ max(u[i], s[p+l]) ]; s3 = mydata[ min(s[p], u[i] ) ][ max(s[p], u[i] ) ] + mydata[ min(s[t], s[p+l]) ][ max(s[t], s[p+l]) ]; //nbdblesums++; if ((s1 < s2) && (s1 < s3)) { cost -= 1.0; if (verbose) { printf(" -1\n"); } } else { if (verbose) { printf(" \n"); } } } if ((t < lastopti) || (t >= lastopti+lastoptl)) { if (verbose) printf("etudie le quadruplet (%d, %d) (%d, %d) (v)", min(s[p], s[p+l]), max(s[p], s[p+l]), min(v[i], s[t]), max(v[i], s[t])); /** cout des paire (p,p+l)(v_i, t) **/ s1 = mydata[ min(s[p], s[p+l]) ][ max(s[p], s[p+l]) ] + mydata[ min(v[i], s[t]) ][ max(v[i], s[t]) ]; s2 = mydata[ min(s[p], s[t] ) ][ max(s[p], s[t] ) ] + mydata[ min(v[i], s[p+l]) ][ max(v[i], s[p+l]) ]; s3 = mydata[ min(s[p], v[i] ) ][ max(s[p], v[i] ) ] + mydata[ min(s[t], s[p+l]) ][ max(s[t], s[p+l]) ]; //nbdblesums++; if ((s1 < s2) && (s1 < s3)) { cost -= 1.0; if (verbose) { printf(" -1\n"); } } else { if (verbose) { printf(" \n"); } } } if ((t < lastopti) || (t >= lastopti+lastoptl)) { if (verbose) printf("etudie le quadruplet (%d, %d) (%d, %d) (w)", min(s[p], s[p+l]), max(s[p], s[p+l]), min(w[i], s[t]), max(w[i], s[t])); /** cout des paire (p,p+l)(w_i, t), valable quelque soit t **/ s1 = mydata[ min(s[p], s[p+l]) ][ max(s[p], s[p+l]) ] + mydata[ min(w[i], s[t]) ][ max(w[i], s[t]) ]; s2 = mydata[ min(s[p], s[t] ) ][ max(s[p], s[t] ) ] + mydata[ min(w[i], s[p+l]) ][ max(w[i], s[p+l]) ]; s3 = mydata[ min(s[p], w[i] ) ][ max(s[p], w[i] ) ] + mydata[ min(s[t], s[p+l]) ][ max(s[t], s[p+l]) ]; //nbdblesums++; if ((s1 < s2) && (s1 < s3)) { cost += 1.0; if (verbose) { printf(" +1\n"); } } else { if (verbose) { printf(" \n"); } } } } for (j=i+1; jsize; i++) { if ((i == p) || (i == p+l)) continue; for (t=i+1; tsize; t++) { if ((t == p) || (t == p+l)) continue; if (verbose) printf("etudie le quadruplet (%d, %d) (%d, %d) ", min(s[p], s[p+l]), max(s[p], s[p+l]), min(s[i], s[t]), max(s[i], s[t])); /** cout des paire (p,p+l)(w_i, t), valable quelque soit t **/ s1 = mydata[ min(s[p], s[p+l]) ][ max(s[p], s[p+l]) ] + mydata[ min(s[i], s[t]) ][ max(s[i], s[t]) ]; s2 = mydata[ min(s[p], s[t] ) ][ max(s[p], s[t] ) ] + mydata[ min(s[i], s[p+l]) ][ max(s[i], s[p+l]) ]; s3 = mydata[ min(s[p], s[i] ) ][ max(s[p], s[i] ) ] + mydata[ min(s[t], s[p+l]) ][ max(s[t], s[p+l]) ]; //nbdblesums++; if ((s1 < s2) && (s1 < s3)) { cost += 1.0; if (verbose) printf("+1\n"); } else if (verbose) printf("\n"); } } } return cost; } char* get_parameter(int argc, char** argv, char* param) { int i = 0; while ((i < argc) && (strcmp(param, argv[i]))) i++; if (i