/** * @file tests/boost_graph/partitioning/utils.cpp * @author The PARADEVS Development Team * See the AUTHORS or Authors.txt file */ /* * PARADEVS - the multimodeling and simulation environment * This file is a part of the PARADEVS environment * * Copyright (C) 2013-2015 ULCO http://www.univ-litoral.fr * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include #include #include namespace paradevs { namespace tests { namespace boost_graph { UnorientedGraph::vertex_iterator vertexIt, vertexEnd; UnorientedGraph::adjacency_iterator neighbourIt, neighbourEnd; OrientedGraph::vertex_iterator vertexIto, vertexEndo; OrientedGraph::adjacency_iterator neighbourIto, neighbourEndo; struct myclass { bool operator() (Entiers *i, Entiers *j) { return i->at(0) < j->at(0); } } myobject; struct myclass2 { bool operator() (Entiers *i, Entiers *j, UnorientedGraph *g) { return Calcul_poids(i,g) < Calcul_poids(j,g); } } mon_tri; struct myclass3 { bool operator() (Entiers *i, Entiers *j) { return i->size() > j->size(); } } myobject_taille; struct myclass4 { bool operator() (int i, int j, UnorientedGraph *g) { return (*g)[i]._weight > (*g)[j]._weight; } } mon_poids; /** * Fonction de verification de la connexité d'un graphe * @param *g : adresse d'un graphe de type boost graphe undirected * @param Partition : vecteur contenant des vecteurs d'entiers [tableau contenant les parties de la partition] * @param part : vecteur d'entier (une partie de la partition) * @return un booleen */ bool Est_connexe(UnorientedGraph *g, EntiersEntiers Partition, Entiers &part) { /* * Copie du graphe contenu par l'adresse *g */ UnorientedGraph copie_g; copie_g = *g; /* * Modification du graphe copié afin de générer des sous graphes liés aux différentes parties */ for (uint i=0; isize();k++) { for (uint y=0; ysize();y++) { remove_edge(Partition.at(i)->at(k),Partition.at(j)->at(y),copie_g); //suppression de certains arcs } } } } /* * Objectif : déterminer s'il existe un chemin reliant tous les noeuds d'une même partie * Méthode : partir d'un sommet de départ tiré aléatoirement dans la partie "part" et parcourir l'ensemble de ces voisins. * Si le voisin recontré n'est pas contenu dans le vecteur "sommets" il est ajouté. Le processus est répété pour chaque * nouveau sommet ajouté au vecteur. * Résultat : si le nombre de sommets contenu dans le vecteur "part" est égale au nombre de sommets du vecteur "sommets" * alors le graphe est connexe */ uint val; Entiers sommets; if(part.size()==1) val = 0; else val=rand_fini(0,part.size()-1); //tirage aléatoire d'un sommets uint vertex = part.at(val); sommets.push_back(vertex); //ajout du sommets à la lsite des sommets parcouru /* * Recherche de voisins n'appartenant pas à la liste des sommets parcourus */ for(uint i = 0;isize() ; j++) { for(uint k = 0; k<((*lit)->at(Partition.at(i)->at(j)))->size();k++){ new_part->push_back((*lit)->at(Partition.at(i)->at(j))->at(k)); } } new_partition.push_back(new_part); } /* * Désalocation mémoire des pointeurs que contient "Partition" */ for(EntiersEntiers::iterator it = Partition.begin(); it != Partition.end(); it++) { delete *it; *it = NULL; } Partition = new_partition; // copie de new_partition dans Partition for(uint i =0; ibegin(),Partition[i]->end()); } new_partition.clear(); } /** * Fonction qui calcul le poids d'une partie * @param * part : adresse d'un vecteur d'entier, ici une partie de la partition * @param *g : adresse d'un graphe de type boost graphe undirected * @return un type double contenant le poids associé à la partie */ double Calcul_poids(Entiers *partie, UnorientedGraph *g) { double poids=0; // initialisation du poids à 0 /* * Pour chaque sommet de la partie concerné on ajoute son poids au poids total */ for(uint j = 0; jsize();j++){ poids+=(*g)[partie->at(j)]._weight; } return poids; } /** * Fonction d'affinage suivant un critère de poids * @param *g : adresse d'un graphe de type boost graphe undirected * @param Partition : vecteur contenant des vecteurs d'entiers [tableau contenant les parties de la partition] * @return modification de la partition */ void Affinage_equilibrage_charge(UnorientedGraph *g, EntiersEntiers &Partition) { /* * Calcule de la somme des poids du graphe et le poids moyen à atteindre */ double poids_moyen = 0.; for(uint i = 0; i < num_vertices(*g); i++) { poids_moyen += (*g)[i]._weight; } // détermination du poids moyen à atteindre pour chaque partie poids_moyen /= Partition.size(); std::vector < double > poids_parties; /* * Calcul du poids de chaque partie de la partition */ for (uint i = 0; i < Partition.size(); i++) { double tmp = Calcul_poids(Partition.at(i),g); poids_parties.push_back(tmp); } std::clog << "Poids initial des parties : " << std::endl; // for (uint i = 0; i < poids_parties.size(); i++){ // std::cout << poids_parties.at(i) << " "; // } // std::cout << "\n" << std::endl; /* * Le critère d'amélioration consiste à faire tendre vers 0 la somme * des écarts entre le poids des parties et le poids moyen * le "critere" est la somme pour chaque partie de la différence * en valeurs absolues du poids * d'une partie moins le poids moyen divisé par le nombre de parties */ double critere = 0.; for (uint i = 0; i < poids_parties.size(); i++){ critere += abs(poids_parties.at(i) - poids_moyen); } critere /= Partition.size(); // on conserve le poids maximum double p_max = *max_element(poids_parties.begin(), poids_parties.end()); // std::cout << "Valeurs du criètre de départ : " << critere << std::endl; // création d'un second critère légérement plsu faible que le premier double best_critere = critere - 1e-7; uint nbr_passage = 1; // initialisation du nombre de passages à 1 /* * Tant que le critère n'est pas amélioré etque le nombre de * passage est inférieur au nombre de parties on réalise * des modifications sur la partition */ while (best_critere < critere or nbr_passage < Partition.size()) { critere = best_critere; //critere devient best_critere // recherche la partie associé au poids maximum int cpt = recherche_val_double(poids_parties,p_max); bool decision = false; //initialisatio d'un booleen a false int nbr_pass_interne = 0; /* * tirage aléatoire des sommets de la partie de poids maximum */ Entiers random_orders(Partition.at(cpt)->size()); for (uint i=0 ; isize() ; i++) random_orders.at(i)=Partition.at(cpt)->at(i); for (uint j=0 ; jsize()-1 ; j++) { int rand_pos = (rand() % Partition.at(cpt)->size()-j)+j; int tmp = random_orders[j]; random_orders[j] = random_orders[rand_pos]; random_orders[rand_pos] = tmp; } /* * Si le nombre de sommets d'une partie excéde les 400, on tire au hasar 400 sommets sans remise * et on effectue les modifications (ceci permet d'eviter une explosion des temps de calcul) */ int size; if(Partition.at(cpt)->size()>400) size = 400; else size = Partition.at(cpt)->size(); /* * Seconde boucle Tant que sur les sommets d'une partie. * Tant que le critere booleen est vrai et que le nombre de passe interne est inférieur au seuil size faire */ while(decision!=true && nbr_pass_interne < size){ int vertex = random_orders.at(nbr_pass_interne); //tirage d'un sommets dans la parite de poids maximum Entiers community = Neigh_community(g,Partition,vertex,cpt); // recherche des communautés voisines à ce sommet (s'il est au bord) if(community.size()!=0) // s'il existe au moins une communauté voisine { std::vector new_poids_parties; // initialisation d'un nouveau vecteur contenant des doubles std::vector tmp_critere; // initialisation d'un nouveau vecteur contenant des doubles /* * Pour chacune des parties (communauté) voisine au sommet vertexs faire */ for(uint k = 0; k < community.size();k++) { new_poids_parties = poids_parties; //copie du tableau de poids des parties dans new_poids_parties /* * Modification des poids des parties : * on ajoute le poids du sommets à la partie voisine * et on soustrait son poids à sa partie d'origine */ new_poids_parties.at(community.at(k))+=(*g)[vertex]._weight; new_poids_parties.at(cpt)-=(*g)[vertex]._weight; /* * Calcul ldu nouveau critère associé à cette modification */ double new_critere = 0.; for(uint i = 0; ipush_back(vertex); suprim_val(*Partition.at(cpt),vertex); std::sort(Partition.at(community.at(val))->begin(), Partition.at(community.at(val))->end()); /* * Vérification de la sauvegarde de la connexsité, * si se n'est pas le cas retour à l'état précédent */ if(Est_connexe(g,Partition,*Partition.at(cpt))!=1) { suprim_val(*Partition.at(community.at(val)),vertex); Partition.at(cpt)->push_back(vertex); std::sort(Partition.at(cpt)->begin(), Partition.at(cpt)->end()); // std::cout<<" C'EST MORT RETOUR EN ARRIERE ! "<500) size=500; std::vector > tabe_cut; //std::cout<<"Passage : "< tmp; double vol = 0.; double cut = Modif_Cut_one_cluster(*Partition.at(k), *g, vol, name); tmp.push_back(cut); tmp.push_back(vol); tabe_cut.push_back(tmp); } for(uint i = 0; i < size; i++){ if(random_orders.at(i)!=-1){ int vertex = random_orders.at(i); //std::cout< tmp_cut; if(community.size()!=0 && Partition.at(comm)->size()!=1){ tmp_cut = modif_cut_tmp(g,Partition,tabe_cut,vertex,comm,community,cut,name); /*for(uint z = 0; zpush_back(vertex); suprim_val(*Partition.at(comm),vertex); std::sort(Partition.at(community.at(tmp))->begin(), Partition.at(community.at(tmp))->end()); tabe_cut.clear(); for(uint k = 0; k < Partition.size();k++){ std::vector tmp; double vol = 0.; double cut = Modif_Cut_one_cluster(*Partition.at(k), *g, vol, name); tmp.push_back(cut); tmp.push_back(vol); tabe_cut.push_back(tmp); } } } Modif_fonction_Gain_Cut(Partition,g,community,vertex,cut,name); /*if(Est_connexe(g,Partition,*Partition.at(comm))!=1) { suprim_val(*Partition.at(community.at(tmp)),vertex); Partition.at(comm)->push_back(vertex); std::sort(*Partition.at(comm)); std::cout<<" C'EST MORT RETOUR EN ARRIERE ! "< modif_cut_tmp(UnorientedGraph *g, EntiersEntiers &Partition, std::vector > tabe_cut, int vertexs, int comm_in, Entiers community, double cut,std::string name){ edge_t e1; bool found; //std::cout<<"le sommet tiré est : "< modif_cut(community.size()); double cpt_comm_in; double cpt_comm_out; for(uint i =0; i modif_cut(community.size()); double cpt_comm_in; double cpt_comm_out; double tmp_cut; for(uint i =0; i > tab_cut = tabe_cut; tmp_cut =0.; cpt_comm_in=0.; cpt_comm_out=0.; tie(neighbourIt, neighbourEnd) = adjacent_vertices(vertexs,*g); for (; neighbourIt != neighbourEnd; ++neighbourIt){ tie(e1,found)=edge(vertex(vertexs,*g),vertex(*neighbourIt,*g),*g); if(In_tab(*Partition.at(comm_in),*neighbourIt)==1) cpt_comm_in+=(*g)[e1]._weight; else if(In_tab(*Partition.at(community.at(i)),*neighbourIt)==1) cpt_comm_out+=(*g)[e1]._weight; } cpt_comm_in/=2.; cpt_comm_out/=2.; tab_cut.at(comm_in).at(0)+=cpt_comm_in; tab_cut.at(comm_in).at(0)-=cpt_comm_out; tab_cut.at(comm_in).at(1)-= Degree(*g ,vertexs); tab_cut.at(community.at(i)).at(0)+=cpt_comm_in; tab_cut.at(community.at(i)).at(0)-=cpt_comm_out; tab_cut.at(community.at(i)).at(1)+= Degree(*g ,vertexs); for(uint j = 0; j < tab_cut.size();j++){ tmp_cut+=((tab_cut.at(j).at(0))/(tab_cut.at(j).at(1))); } modif_cut.at(i)=tmp_cut; } }else if(name == "ratio"){ std::vector modif_cut(community.size()); double cpt_comm_in; double cpt_comm_out; double tmp_cut; for(uint i =0; i > tab_cut = tabe_cut; tmp_cut =0.; cpt_comm_in=0.; cpt_comm_out=0.; tie(neighbourIt, neighbourEnd) = adjacent_vertices(vertexs,*g); for (; neighbourIt != neighbourEnd; ++neighbourIt){ tie(e1,found)=edge(vertex(vertexs,*g),vertex(*neighbourIt,*g),*g); if(In_tab(*Partition.at(comm_in),*neighbourIt)==1) cpt_comm_in+=(*g)[e1]._weight; else if(In_tab(*Partition.at(community.at(i)),*neighbourIt)==1) cpt_comm_out+=(*g)[e1]._weight; } /*cpt_comm_in/=2.; cpt_comm_out/=2.;*/ tab_cut.at(comm_in).at(0)+=cpt_comm_in; tab_cut.at(comm_in).at(0)-=cpt_comm_out; tab_cut.at(comm_in).at(1)-= (*g)[vertexs]._weight; tab_cut.at(community.at(i)).at(0)+=cpt_comm_in; tab_cut.at(community.at(i)).at(0)-=cpt_comm_out; tab_cut.at(community.at(i)).at(1)+= (*g)[vertexs]._weight; for(uint j = 0; j < tab_cut.size();j++){ tmp_cut+=((tab_cut.at(j).at(0))/(tab_cut.at(j).at(1))); } modif_cut.at(i)=tmp_cut; } return modif_cut; } } void Modif_fonction_Gain_Cut(EntiersEntiers &Partition,UnorientedGraph *g, Entiers &community, int val, double &cut,std::string name) { /*std::cout<<"Nombre de communauté voisine : "<size();j++){ tmp->push_back(Partition.at(k)->at(j)); } new_partition.push_back(tmp); } /*std::cout<<"Avant Modification partition"<size() ; j++) { std::cout<at(j)<push_back(val); suprim_val(*new_partition.at(In_community_dichotomie(Partition,val)),val); std::sort(new_partition.at(community.at(i))->begin(), new_partition.at(community.at(i))->end()); /*std::cout<<"Modification partition"<size() ; j++) { std::cout<at(j)<poids_a){ best_vertexs = liste_voisin[j]; poids_a = (*gtmp)[e1]._weight; } } Entiers * couple = new Entiers(); // Initialisation du vecteur contenant le couple de sommet fusionné int vertex_delete = std::max(vertexs, best_vertexs); // Sommet d'index le plus grand (qui sera détruit) //std::cout<<"sommet détruit : "<<(*gtmp)[vertex_delete]._index<push_back(vertex_save); couple->push_back(vertex_delete); tableau_de_correspondance->push_back(couple); // Ajout du "couple" à la liste de correspondance remove_edge(vertex_save,vertex_delete,*gtmp); // Suppression de l'arc reliant le couple de sommets Entiers neigh_vertex_save; // Initialisation du vecteur contenant les sommets adjacents au "sommet sauvegardé" Entiers neigh_vertex_delete; // Initialisation du vecteur contenant les somemts adjacents au "sommet à détruire" tie(neighbourIt, neighbourEnd) = adjacent_vertices(vertex_save,*gtmp); /* * Remplissage de ces deux tableaux à l'aide de la fonction adjacent_vertices de boost graph * [La création de ces tableaux est nécéssaire du fait que certains arcs sont détruit au cours * du processus] */ for (; neighbourIt != neighbourEnd; ++neighbourIt){ neigh_vertex_save.push_back(*neighbourIt); } tie(neighbourIt, neighbourEnd) = adjacent_vertices(vertex_delete,*gtmp); for (; neighbourIt != neighbourEnd; ++neighbourIt){ neigh_vertex_delete.push_back(*neighbourIt); } /* * Recherche de sommets communs entre le "sommet sauvegardé" et le "sommet à détruire" * S'il existe un tel sommet "v" alors on ajoute le poids de l'arcs (vertex_delet,v) * à celui de l'arcs (vertex_save,v) et on détruit l'arcs reliant "v" au "sommet à détruire" */ for(uint j=0;jpush_back(Random_list_vertices.at(i)); tableau_de_correspondance->push_back(couple); Random_list_vertices[i]=-1; } /*std::cout<<"Poids noeud graphe contracté : "< "; std::cout << (*gtmp)[*vertexIt]._weight<<" ; "; } std::cout << std::endl;*/ } if(val_cpt == val_reduc){ for(uint j=i+1; j push_back(Random_list_vertices.at(j)); tableau_de_correspondance->push_back(couple);} } break; } } std::sort(sommets_a_detruire.begin(), sommets_a_detruire.end()); // Trie dans l'ordre croissant des "sommets à détruire" // std::cout<<"\n"<-1;j--){ //std::cout<<"Noeuds a supprimer : "<size();k++){ // for(uint v = 0; vat(k)->size();v++){ // std::cout<at(k)->at(v)<<" "; // } // std::cout<<"\n"<begin(),tableau_de_correspondance->end(),myobject); // Trie dans l'ordre croissant des couples de sommets de la liste de correspondance // std::clog<<"Tableau de correspondance "<size();k++){ // for(uint v = 0; vat(k)->size();v++){ // std::cout<at(k)->at(v)<<" "; // } // std::cout<<"\n"<poids_a){ best_vertexs = liste_voisin[j]; poids_a = (*gtmp)[e1]._weight; } } Entiers *couple = new Entiers(); // Initialisation du vecteur contenant le couple de sommet fusionné int vertex_delete = std::max(vertexs, best_vertexs); // Sommet d'index le plus grand (qui sera détruit) //std::cout<<"sommet détruit : "<<(*gtmp)[vertex_delete]._index<push_back(vertex_save); couple->push_back(vertex_delete); tableau_de_correspondance->push_back(couple); // Ajout du "couple" à la liste de correspondance remove_edge(vertex_save,vertex_delete,*gtmp); // Suppression de l'arc reliant le couple de sommets Entiers neigh_vertex_save; // Initialisation du vecteur contenant les sommets adjacents au "sommet sauvegardé" Entiers neigh_vertex_delete; // Initialisation du vecteur contenant les somemts adjacents au "sommet à détruire" tie(neighbourIt, neighbourEnd) = adjacent_vertices(vertex_save,*gtmp); /* * Remplissage de ces deux tableaux à l'aide de la fonction adjacent_vertices de boost graph * [La création de ces tableaux est nécéssaire du fait que certains arcs sont détruit au cours * du processus] */ for (; neighbourIt != neighbourEnd; ++neighbourIt){ neigh_vertex_save.push_back(*neighbourIt); } tie(neighbourIt, neighbourEnd) = adjacent_vertices(vertex_delete,*gtmp); for (; neighbourIt != neighbourEnd; ++neighbourIt){ neigh_vertex_delete.push_back(*neighbourIt); } sort(neigh_vertex_save.begin(),neigh_vertex_save.end()); sort(neigh_vertex_delete.begin(),neigh_vertex_delete.end()); /* * Recherche de sommets communs entre le "sommet sauvegardé" et le "sommet à détruire" * S'il existe un tel sommet "v" alors on ajoute le poids de l'arcs (vertex_delet,v) * à celui de l'arcs (vertex_save,v) et on détruit l'arcs reliant "v" au "sommet à détruire" */ for(uint j=0;jpush_back(vertexs); tableau_de_correspondance->push_back(couple); Index_Vertex.at(Random_list_vertices.at(i))=-1; } /*std::cout<<"Poids noeud graphe contracté : "< "; std::cout << (*gtmp)[*vertexIt]._weight<<" ; "; } std::cout << std::endl;*/ } if(val_cpt == val_reduc){ for(uint j=i+1; j < nbr_vertex; j++){ if(Index_Vertex.at(Random_list_vertices.at(j)) != -1){ Entiers *couple = new Entiers(); couple->push_back(Index_Vertex.at(Random_list_vertices.at(j))); tableau_de_correspondance->push_back(couple);} } break; } } std::sort(sommets_a_detruire.begin(), sommets_a_detruire.end()); // Trie dans l'ordre croissant des "sommets à détruire" // std::cout<<"\n"<-1;j--){ //std::cout<<"Noeuds a supprimer : "<size();k++){ // for(uint v = 0; vat(k)->size();v++){ // std::cout<at(k)->at(v)<<" "; // } // std::cout<<"\n"<begin(),tableau_de_correspondance->end(),myobject); // Trie dans l'ordre croissant des couples de sommets de la liste de correspondance // std::clog<<"Tableau de correspondance "<size();k++){ // for(uint v = 0; vat(k)->size();v++){ // std::cout<at(k)->at(v)<<" "; // } // std::cout<<"\n"<poids_a){ best_vertexs = liste_voisin[j]; poids_a = (*gtmp)[e1]._weight; } } Entiers *couple = new Entiers(); // Initialisation du vecteur contenant le couple de sommet fusionné /* Sélection du sommet possedant un degrès maximum */ std::pair couple1, couple2, best_min, best_max; couple1.first = Degree(*gtmp,vertexs); couple1.second = vertexs; couple2.first = Degree(*gtmp,best_vertexs); couple2.second = best_vertexs; best_min = std::min(couple1,couple2); best_max = std::max(couple1,couple2); int vertex_delete = best_min.second; // Sommet d'index le plus grand (qui sera détruit) //std::cout<<"sommet détruit : "<<(*gtmp)[vertex_delete]._index<push_back(vertex_save); couple->push_back(vertex_delete); tableau_de_correspondance->push_back(couple); // Ajout du "couple" à la liste de correspondance remove_edge(vertex_save,vertex_delete,*gtmp); // Suppression de l'arc reliant le couple de sommets Entiers neigh_vertex_save; // Initialisation du vecteur contenant les sommets adjacents au "sommet sauvegardé" Entiers neigh_vertex_delete; // Initialisation du vecteur contenant les somemts adjacents au "sommet à détruire" /* * Remplissage de ces deux tableaux à l'aide de la fonction adjacent_vertices de boost graph * [La création de ces tableaux est nécéssaire du fait que certains arcs sont détruit au cours * du processus] */ tie(neighbourIt, neighbourEnd) = adjacent_vertices(vertex_save,*gtmp); for (; neighbourIt != neighbourEnd; ++neighbourIt){ neigh_vertex_save.push_back(*neighbourIt); } tie(neighbourIt, neighbourEnd) = adjacent_vertices(vertex_delete,*gtmp); for (; neighbourIt != neighbourEnd; ++neighbourIt){ neigh_vertex_delete.push_back(*neighbourIt); } sort(neigh_vertex_save.begin(),neigh_vertex_save.end()); sort(neigh_vertex_delete.begin(),neigh_vertex_delete.end()); /* * Recherche de sommets communs entre le "sommet sauvegardé" et le "sommet à détruire" * S'il existe un tel sommet "v" alors on ajoute le poids de l'arcs (vertex_delet,v) * à celui de l'arcs (vertex_save,v) et on détruit l'arcs reliant "v" au "sommet à détruire" */ for(uint j=0;jpush_back(vertexs); tableau_de_correspondance->push_back(couple); Index_Vertex.at(Random_list_vertices.at(i))=-1; } } if(val_cpt == val_reduc){ for(uint j=i+1; j < nbr_vertex; j++){ if(Index_Vertex.at(Random_list_vertices.at(j)) != -1){ Entiers *couple = new Entiers(); couple->push_back(Index_Vertex.at(Random_list_vertices.at(j))); tableau_de_correspondance->push_back(couple);} } break; } } std::sort(sommets_a_detruire.begin(), sommets_a_detruire.end()); // Trie dans l'ordre croissant des "sommets à détruire" /* * Suppression des sommets de la liste "sommets à détruire". Cette suppression est * effectuée dans l'ordre décroissant afin à maintenir à jour la renumérotation * des sommets */ for(int j=(sommets_a_detruire.size()-1);j>-1;j--){ remove_vertex(sommets_a_detruire[j],*gtmp); } std::sort(tableau_de_correspondance->begin(),tableau_de_correspondance->end(),myobject); // Trie dans l'ordre croissant des couples de sommets de la liste de correspondance liste_corr.push_back(tableau_de_correspondance); baseg.push_back(gtmp); // Ajout du graphe modifié à la "base des graphe" if(val_cpt == val_reduc) return true; else return false; } bool contraction_HEM_degree(UnorientedGraph *g, Base_Graph &baseg, ListEntiersEntiers &liste_corr, int val_reduc, int &val_cpt){ UnorientedGraph *gtmp = new UnorientedGraph(); boost::copy_graph(*g, *gtmp); Entiers Index_Vertex; // Initialisation du tableau de sommets rangés aléatoirements std::vector vertex_degree; EntiersEntiers *tableau_de_correspondance = new EntiersEntiers(); edge_t e1,e2; // Iterateurs sur les arcs bool found; uint nbr_vertex = num_vertices(*gtmp); Entiers sommets_a_detruire; // Initialisation d'un tableau pret à recevoir les "sommets à détruire" int cpt = nbr_vertex; /* * Création d'un vecteur contenant l'ensemble des sommets du graphe. Ces sommets sont rangés * aléatoirement afin de simuler un tirage aléatoire */ /*for (uint i=0 ; i Neight_weight, Best_neight; int best_vertexs; for(uint j=0;j 1){ int ind; double deg =1000000000; double tmp_deg; for(uint j=0;j "<<(*gtmp)[best_vertexs]._index; Entiers *couple = new Entiers(); // Initialisation du vecteur contenant le couple de sommet fusionné /* Sélection du sommet possedant un degrès maximum */ std::pair couple1, couple2, best_min, best_max; couple1.first = Degree(*gtmp,vertexs); couple1.second = vertexs; couple2.first = Degree(*gtmp,best_vertexs); couple2.second = best_vertexs; best_min = std::min(couple1,couple2); best_max = std::max(couple1,couple2); int vertex_delete = best_min.second; // Sommet d'index le plus grand (qui sera détruit) //std::cout<<"sommet détruit : "<<(*gtmp)[vertex_delete]._index<push_back(vertex_save); couple->push_back(vertex_delete); tableau_de_correspondance->push_back(couple); // Ajout du "couple" à la liste de correspondance remove_edge(vertex_save,vertex_delete,*gtmp); // Suppression de l'arc reliant le couple de sommets Entiers neigh_vertex_save; // Initialisation du vecteur contenant les sommets adjacents au "sommet sauvegardé" Entiers neigh_vertex_delete; // Initialisation du vecteur contenant les somemts adjacents au "sommet à détruire" /* * Remplissage de ces deux tableaux à l'aide de la fonction adjacent_vertices de boost graph * [La création de ces tableaux est nécéssaire du fait que certains arcs sont détruit au cours * du processus] */ tie(neighbourIt, neighbourEnd) = adjacent_vertices(vertex_save,*gtmp); for (; neighbourIt != neighbourEnd; ++neighbourIt){ neigh_vertex_save.push_back(*neighbourIt); } tie(neighbourIt, neighbourEnd) = adjacent_vertices(vertex_delete,*gtmp); for (; neighbourIt != neighbourEnd; ++neighbourIt){ neigh_vertex_delete.push_back(*neighbourIt); } sort(neigh_vertex_save.begin(),neigh_vertex_save.end()); sort(neigh_vertex_delete.begin(),neigh_vertex_delete.end()); /* * Recherche de sommets communs entre le "sommet sauvegardé" et le "sommet à détruire" * S'il existe un tel sommet "v" alors on ajoute le poids de l'arcs (vertex_delet,v) * à celui de l'arcs (vertex_save,v) et on détruit l'arcs reliant "v" au "sommet à détruire" */ for(uint j=0;jpush_back(vertexs); tableau_de_correspondance->push_back(couple); Index_Vertex.at(compteur)=-1; vertex_degree.at(compteur)=-1; cpt --; //std::cout<<" * "<push_back(Index_Vertex.at(j)); tableau_de_correspondance->push_back(couple);} } break; } } //std::cout<<"cpt : "<-1;j--){ remove_vertex(sommets_a_detruire[j],*gtmp); } std::sort(tableau_de_correspondance->begin(),tableau_de_correspondance->end(),myobject); // Trie dans l'ordre croissant des couples de sommets de la liste de correspondance liste_corr.push_back(tableau_de_correspondance); baseg.push_back(gtmp); // Ajout du graphe modifié à la "base des graphe" if(val_cpt == val_reduc) return true; else return false; } bool contraction_HEM_mds_ameliore_KK(UnorientedGraph *g, Base_Graph &baseg, ListEntiersEntiers &liste_corr, int val_reduc, int &val_cpt){ UnorientedGraph *gtmp = new UnorientedGraph(); boost::copy_graph(*g, *gtmp); Entiers Random_list_vertices, Index_Vertex; // Initialisation du tableau de sommets rangés aléatoirements EntiersEntiers *tableau_de_correspondance = new EntiersEntiers(); edge_t e1,e2; // Iterateurs sur les arcs bool found; uint nbr_vertex = num_vertices(*gtmp); Entiers sommets_a_detruire; // Initialisation d'un tableau pret à recevoir les "sommets à détruire" /* * Création d'un vecteur contenant l'ensemble des sommets du graphe. Ces sommets sont rangés * aléatoirement afin de simuler un tirage aléatoire */ for (uint i=0 ; i adjacent_weight; //std::cout<<"adjacent_weight"<1){ //std::cout<<"Top **"< couple1, couple2, best_min, best_max; couple1.first = Degree(*gtmp,vertexs); couple1.second = vertexs; couple2.first = Degree(*gtmp,best_vertexs); couple2.second = best_vertexs; best_min = std::min(couple1,couple2); best_max = std::max(couple1,couple2); int vertex_delete = best_min.second; // Sommet d'index le plus grand (qui sera détruit) //std::cout<<"sommet détruit : "<<(*gtmp)[vertex_delete]._index<push_back(vertex_save); couple->push_back(vertex_delete); tableau_de_correspondance->push_back(couple); // Ajout du "couple" à la liste de correspondance remove_edge(vertex_save,vertex_delete,*gtmp); // Suppression de l'arc reliant le couple de sommets Entiers neigh_vertex_save; // Initialisation du vecteur contenant les sommets adjacents au "sommet sauvegardé" Entiers neigh_vertex_delete; // Initialisation du vecteur contenant les somemts adjacents au "sommet à détruire" /* * Remplissage de ces deux tableaux à l'aide de la fonction adjacent_vertices de boost graph * [La création de ces tableaux est nécéssaire du fait que certains arcs sont détruit au cours * du processus] */ tie(neighbourIt, neighbourEnd) = adjacent_vertices(vertex_save,*gtmp); for (; neighbourIt != neighbourEnd; ++neighbourIt){ neigh_vertex_save.push_back(*neighbourIt); } tie(neighbourIt, neighbourEnd) = adjacent_vertices(vertex_delete,*gtmp); for (; neighbourIt != neighbourEnd; ++neighbourIt){ neigh_vertex_delete.push_back(*neighbourIt); } sort(neigh_vertex_save.begin(),neigh_vertex_save.end()); sort(neigh_vertex_delete.begin(),neigh_vertex_delete.end()); /* * Recherche de sommets communs entre le "sommet sauvegardé" et le "sommet à détruire" * S'il existe un tel sommet "v" alors on ajoute le poids de l'arcs (vertex_delet,v) * à celui de l'arcs (vertex_save,v) et on détruit l'arcs reliant "v" au "sommet à détruire" */ for(uint j=0;jpush_back(vertexs); tableau_de_correspondance->push_back(couple); Index_Vertex.at(Random_list_vertices.at(i))=-1; } }else{ //std::cout<<"Le sommet est bloqué "<push_back(vertexs); tableau_de_correspondance->push_back(couple);} } break; } } std::sort(sommets_a_detruire.begin(), sommets_a_detruire.end()); // Trie dans l'ordre croissant des "sommets à détruire" /* * Suppression des sommets de la liste "sommets à détruire". Cette suppression est * effectuée dans l'ordre décroissant afin à maintenir à jour la renumérotation * des sommets */ for(int j=(sommets_a_detruire.size()-1);j>-1;j--){ remove_vertex(sommets_a_detruire[j],*gtmp); } std::sort(tableau_de_correspondance->begin(),tableau_de_correspondance->end(),myobject); // Trie dans l'ordre croissant des couples de sommets de la liste de correspondance liste_corr.push_back(tableau_de_correspondance); baseg.push_back(gtmp); // Ajout du graphe modifié à la "base des graphe" if(val_cpt == val_reduc) return true; else return false; } bool Est_voisin(UnorientedGraph *g, int vertex, int vertex_select){ bool reponse = false; tie(neighbourIt, neighbourEnd) = adjacent_vertices(vertex, *g); for (; neighbourIt != neighbourEnd; ++neighbourIt){ if(*neighbourIt == vertex_select) reponse = true; } return reponse; } bool contraction_Random_Maching(UnorientedGraph *g, Base_Graph &baseg, ListEntiersEntiers &liste_corr, int val_reduc, int &val_cpt){ UnorientedGraph *gtmp = new UnorientedGraph(); *gtmp=*g; Entiers Random_list_vertices; // Initialisation du tableau de sommets rangés aléatoirements EntiersEntiers *tableau_de_correspondance = new EntiersEntiers(); edge_t e1,e2; // Iterateurs sur les arcs bool found; uint nbr_vertex = num_vertices(*gtmp); Entiers sommets_a_detruire; // Initialisation d'un tableau pret à recevoir les "sommets à détruire" /* * Création d'un vecteur contenant l'ensemble des sommets du graphe. Ces sommets sont rangés * aléatoirement afin de simuler un tirage aléatoire */ for (uint i=0 ; ipush_back(vertex_save); couple->push_back(vertex_delete); tableau_de_correspondance->push_back(couple); // Ajout du "couple" à la liste de correspondance remove_edge(vertex_save,vertex_delete,*gtmp); // Suppression de l'arc reliant le couple de sommets Entiers neigh_vertex_save; // Initialisation du vecteur contenant les somemts adjacents au "sommet sauvegardé" Entiers neigh_vertex_delete; // Initialisation du vecteur contenant les somemts adjacents au "sommet à détruire" tie(neighbourIt, neighbourEnd) = adjacent_vertices(vertex_save,*gtmp); /* * Remplissage de ces deux tableaux à l'aide de la fonction adjacent_vertices de boost graph * [La création de ces tableaux est nécéssaire du fait que certains arcs sont détruit au cours * du processus] */ for (; neighbourIt != neighbourEnd; ++neighbourIt){ neigh_vertex_save.push_back(*neighbourIt); } tie(neighbourIt, neighbourEnd) = adjacent_vertices(vertex_delete,*gtmp); for (; neighbourIt != neighbourEnd; ++neighbourIt){ neigh_vertex_delete.push_back(*neighbourIt); } /* * Recherche de sommets communs entre le "sommet sauvegardé" et le "sommet à détruire" * S'il existe un tel sommet "v" alors on ajoute le poids de l'arcs (vertex_delet,v) * à celui de l'arcs (vertex_save,v) et on détruit l'arcs reliant "v" au "sommet à détruire" */ for(uint j=0;jpush_back(Random_list_vertices.at(i)); tableau_de_correspondance->push_back(couple); Random_list_vertices[i]=-1; } } if(val_cpt == val_reduc){ for(uint j=i+1; j push_back(Random_list_vertices.at(j)); tableau_de_correspondance->push_back(couple);} } break; } } std::sort(sommets_a_detruire.begin(), sommets_a_detruire.end()); // Trie dans l'ordre croissant des "sommets à détruire" //std::cout<<"\n"<-1;j--){ //std::cout<<"Noeuds a supprimer : "<size();k++){ for(uint v = 0; vat(k)->size();v++){ std::cout<at(k)->at(v)<<" "; } std::cout<<"\n"<begin(),tableau_de_correspondance->end(),myobject); // Trie dans l'ordre croissant des couples de sommets de la liste de correspondance // std::clog<<"Tableau de correspondance "<size();k++){ // for(uint v = 0; vat(k)->size();v++){ // std::cout<at(k)->at(v)<<" "; // } // std::cout<<"\n"< &tab,float val){ int cpt=0; while(tab[cpt]!=val) cpt++; return cpt; } int recherche_val_double(const std::vector &tab,double val){ int cpt=0; while(tab[cpt]!=val) cpt++; return cpt; } int recherche_val(const Entiers &tab,int val){ int cpt=0; while(tab[cpt]!=val) cpt++; return cpt; } /** * @param tab * @param i * @return */ int dichotomie(const Entiers &tab, int i){ /* déclaration des variables locales à la fonction */ int id; //indice de début int ifin; //indice de fin int im; //indice de "milieu" /* initialisation de ces variables avant la boucle de recherche */ id = 0; //intervalle de recherche compris entre 0... ifin = tab.size(); //...et nbVal /* boucle de recherche */ while ((ifin - id) > 1){ im = (id + ifin)/2; //on détermine l'indice de milieu if(tab[im] > i) ifin = im; //si la valeur qui est à la case "im" est supérieure à la valeur recherchée, l'indice de fin "ifin" << devient >> l'indice de milieu, ainsi l'intervalle de recherche est restreint lors du prochain tour de boucle else id = im; //sinon l'indice de début << devient >> l'indice de milieu et l'intervalle est de la même façon restreint } /* test conditionnant la valeur que la fonction va renvoyer */ if (tab[id] == i) return id; //si on a trouvé la bonne valeur, on retourne l'indice else return -1; //sinon on retourne -1 } /** * Fonction permettant de supprimer une case d'un tableau. * @param tab une référence sur un tableau d'entiers * @param i un indice dans tab */ void suprim_val(Entiers &tab,int i) { tab.erase(tab.begin() + dichotomie(tab,i)); } /** * Détermine si une valeur se trouve dans un tableau. * @param tab une référence sur un tableau d'entiers * @param val une valeur * @return true si la valeur a été trouvée, false sinon */ bool In_tab(const Entiers &tab, int val) { for (uint i=0; i < tab.size(); i++) if(tab[i]==val) return true; return false; } bool In_tab_dichotomie(const Entiers &tab, int val) { if(dichotomie(tab,val)!=-1) return true; else return false; } void Liste_Voisin(const Entiers &P,Entiers &tab,const UnorientedGraph &g) { tie(neighbourIt, neighbourEnd) = adjacent_vertices(P.at(P.size()-1), g); for (; neighbourIt != neighbourEnd; ++neighbourIt) { if((In_tab(tab,*neighbourIt) == false ) && (In_tab(P,*neighbourIt) == false )) tab.push_back(*neighbourIt); } } int Cout_coupe(Entiers P,int val, UnorientedGraph &g) { int cpt=0; P.push_back(val); for(uint i=0;isize(); i++) { tie(neighbourIto, neighbourEndo) = adjacent_vertices(Partie->at(i), *go); for (; neighbourIto != neighbourEndo; ++neighbourIto) { if(In_tab_dichotomie(*Partie,*neighbourIto)) { Edge new_edge; new_edge.first = Partie->at(i); new_edge.second = *neighbourIto; edge_partie.push_back(new_edge); } else { Edge new_edge; new_edge.first = Partie->at(i); new_edge.second = *neighbourIto; outputedgespartie.push_back(new_edge); } } } } void Global_Neigh_community(UnorientedGraph *g, const EntiersEntiers &Partition, Entiers *community, int vertex, int comm_in) { int comm; tie(neighbourIt, neighbourEnd) = adjacent_vertices(vertex, *g); for (; neighbourIt != neighbourEnd; ++neighbourIt){ comm = In_community_dichotomie(Partition, *neighbourIt); if (In_tab(*community,comm) != 1 and comm != comm_in) community->push_back(comm); } } OrientedGraphs Graph_Partition(const EntiersEntiers& Partition, OrientedGraph *go, UnorientedGraph *g, OutputEdgeList &outputedgelist, InputEdgeList &inputedgelist, Connections &connections) { OrientedGraphs graph_partie; EntiersEntiers neigh_community; for (uint i = 0; i < Partition.size();i++){ Edges edge_partie; List_edge_partie(Partition.at(i),go,edge_partie,outputedgelist.at(i)); OrientedGraph graph; std::vector tab_vertex_to; Entiers *community = new Entiers(); for (uint j = 0; j < Partition.at(i)->size(); j++) { Global_Neigh_community(g, Partition, community, Partition.at(i)->at(j),i); vertex_to v = add_vertex(graph); tab_vertex_to.push_back(v); graph[v] = VertexProperties((*go)[Partition.at(i)->at(j)]._index, (*go)[Partition.at(i)->at(j)]._weight, (*go)[Partition.at(i)->at(j)]._type); } neigh_community.push_back(community); for(uint k = 0; k < edge_partie.size(); k++) { add_edge(tab_vertex_to.at(recherche_val(*Partition.at(i), edge_partie.at(k).first)), tab_vertex_to.at(recherche_val(*Partition.at(i), edge_partie.at(k).second)), graph); } graph_partie.push_back(graph); } for (uint i = 0; i < neigh_community.size(); i++) { InputEdges inputedges; for (uint j = 0; j < neigh_community.at(i)->size(); j++) { for (uint k = 0; k < outputedgelist.at(neigh_community.at(i)->at(j)).size(); k++) { if (In_tab_dichotomie( *Partition.at(i), outputedgelist.at( neigh_community.at(i)->at(j)).at(k).second)) inputedges.push_back( outputedgelist.at( neigh_community.at(i)->at(j)).at(k)); } } inputedgelist.push_back(inputedges); } for (uint i = 0; i < outputedgelist.size(); i++){ Connection connec; for(uint j = 0; j < outputedgelist.at(i).size(); j++){ Port port1; port1.first = i + 1; port1.second = outputedgelist.at(i).at(j).first; Port port2; port2.first = In_community_dichotomie( Partition,outputedgelist.at(i).at(j).second) + 1; port2.second = outputedgelist.at(i).at(j).second; connec.first = port1; connec.second = port2; connections.push_back(connec); } } for (EntiersEntiers::iterator it = neigh_community.begin(); it != neigh_community.end(); it++) { delete *it; *it = NULL; } return graph_partie; } double Best_Cut_cluster(EntiersEntiers &tab_cluster,Entiers *cluster1, Entiers *cluster2, int index_cluster1, UnorientedGraph &g,std::string name) { tab_cluster.push_back(cluster2); double cpt=0.; for(int i=0;i::type poids_arc=get(edge_weight_t(),g); edge_t e1; bool found; int val=0; for(uint i=0;ipush_back(val); std::sort(*part[neight]); q=Modularity(g,part); return q-cur_mod; }*/ /** * Fonction de calcul du gain de modularité de déplacement d'un sommet d'une communoté à une autre !!!!! * ajoute le sommet à part[val] et on calcul la nouvelle modularité * on prend la différence entre la modularité et la nouvouvelle ! * @param cur_mod * @param tmp_community * @param neight * @param node_comm * @param part * @param g */ /*double Modularity_gain_phase_2(double cur_mod, Entiers tmp_community, int neight, int node_comm, EntiersEntiers part, UnorientedGraph &g) { double q; for (uint i=0;ipush_back(tmp_community[i]); std::sort(*part[neight]); q = Modularity(g,part); return q - cur_mod; }*/ /** * Donne la liste des communautés voisines à celle contenant le sommet val. * @param part * @param val * @param g * @return */ /*Entiers Neight_community(const EntiersEntiers &part, int val , UnorientedGraph &g){ Entiers Neight; tie(neighbourIt, neighbourEnd) = adjacent_vertices(val, g); for (; neighbourIt != neighbourEnd; ++neighbourIt){ int tmp=In_community(part,*neighbourIt); if(In_tab(Neight,tmp)!=1 && In_tab(*part[In_community(part,val)],*neighbourIt)!=1) Neight.push_back(tmp); } std::sort(Neight); return Neight; }*/ /** * * @param part * @param community * @param g * @return */ /*Entiers Part_Neight_community(const EntiersEntiers &part,int community, UnorientedGraph &g){ Entiers Neight; for(uint i =0;isize();i++){ tie(neighbourIt, neighbourEnd) = adjacent_vertices(part[community]->at(i), g); for (; neighbourIt != neighbourEnd; ++neighbourIt){ int tmp=In_community(part,*neighbourIt); if(In_tab(Neight,tmp)!=1 && tmp!=community) Neight.push_back(tmp); } } std::sort(Neight); return Neight; }*/ void make_unoriented_graph(const OrientedGraph& og, UnorientedGraph& ug) { std::vector < vertex_t > ug_vertex_list; std::vector < vertex_t > og_vertex_list; for (uint i = 0; i < num_vertices(og); ++i) { ug_vertex_list.push_back(add_vertex(ug)); } OrientedGraph::vertex_iterator it_og, end_og; UnorientedGraph::vertex_iterator it_ug, end_ug; tie(it_og, end_og) = vertices(og); tie(it_ug, end_ug) = vertices(ug); for (; it_og != end_og; ++it_og, ++it_ug) { ug[*it_ug] = og[*it_og]; og_vertex_list.push_back(*it_og); } OrientedGraph::edge_iterator ite_og, ende_og; tie(ite_og, ende_og) = edges(og); for (; ite_og != ende_og; ++ite_og) { boost::add_edge(source(*ite_og, og), target(*ite_og, og), og[*ite_og], ug); } // std::cout << "Oriented graph: " << std::endl; // tie(it_og, end_og) = vertices(og); // for (; it_og != end_og; ++it_og) { // OrientedGraph::adjacency_iterator neighbour_it, neighbour_end; // std::cout << og[*it_og]._index << " is connected with "; // tie(neighbour_it, neighbour_end) = adjacent_vertices(*it_og, og); // for (; neighbour_it != neighbour_end; ++neighbour_it) // std::cout << og[*neighbour_it]._index << " "; // std::cout << " and weight = " << og[*it_og]._weight << std::endl; // } // std::cout << std::endl; // std::cout << "Unoriented graph: " << std::endl; // tie(it_ug, end_ug) = vertices(ug); // for (; it_ug != end_ug; ++it_ug) { // UnorientedGraph::adjacency_iterator neighbour_it, neighbour_end; // std::cout << ug[*it_ug]._index << " is connected with "; // tie(neighbour_it, neighbour_end) = adjacent_vertices(*it_ug, ug); // for (; neighbour_it != neighbour_end; ++neighbour_it) // std::cout << ug[*neighbour_it]._index << " "; // std::cout << " and weight = " << ug[*it_ug]._weight << std::endl; // } // std::cout << std::endl; } void adjacence_ggp(int vertex, Entiers &sommets_adj, UnorientedGraph *g) { tie(neighbourIt, neighbourEnd) = adjacent_vertices(vertex, *g); for (; neighbourIt != neighbourEnd; ++neighbourIt) { sommets_adj.push_back(*neighbourIt); } } double modif_Cout_coupe(const Entiers &P, int val, double cut, UnorientedGraph *g) { //std::cout<<"Cout de coupe initiale : "<( fichier ), std::istreambuf_iterator(),'\n' ); //std::cout<<"Nombre de ligne : "<> nbr_vertices; //std::cout << "Nombre de sommets : "<< nbr_vertices<< std::endl; //Création des sommets std::vector vect_vertex; for(int i =0; i> vertex_in >> vertex_out >> weight ; add_edge(vect_vertex.at(vertex_in), vect_vertex.at(vertex_out), EdgeProperties(weight), *Og); //std::cout << vertex_in << " " << vertex_out << " " << weight << std::endl; int tmp = decimal(vertex_in) + decimal(vertex_out) + decimal(floor(weight)); deplacement_sup += tmp; } //Pondération des sommets int cpt =0; for(int i = lines-nbr_vertices-1; i > poids >> txt ; DynamicsType type; if(txt == "NORMAL_PIXEL"){ type = NORMAL_PIXEL; }else{ type = TOP_PIXEL; } (*Og)[vect_vertex.at(cpt)] = VertexProperties(cpt, poids, type); //std::cout << poids << std::endl; int tmp = decimal(floor(poids)) + 17; deplacement_sup += tmp; cpt++; } fichier.close(); } void Text_generator_graph(const char *texte, OrientedGraph *go){ bool found; edge_to e1; std::ofstream fichier (texte, std::ios::out); fichier<> Vector_diff_cut_ratio(UnorientedGraph *g, const EntiersEntiers &Partition, std::string name){ std::vector> Diff_vector; for(uint i = 0; i < Partition.size(); i++){ std::vector> D_vector; for(uint j = 0; j < Partition.at(i)->size(); j++){ double gain_d = Diff_cut_ratio(g, Partition, i, Partition.at(i)->at(j), name); //std::cout< 0){ std::pair D; D.first = gain_d; D.second = Partition.at(i)->at(j); D_vector.push_back(D); } } sort(D_vector.begin(),D_vector.end()); std::reverse(D_vector.begin(),D_vector.end()); std::vector index_vector; for(uint id = 0; id < D_vector.size(); id++){ index_vector.push_back(D_vector.at(id).second); } Diff_vector.push_back(index_vector); } /*std::cout<<"Tableau des différences "< Vector_diff_cut_ratio_2(UnorientedGraph *g, const EntiersEntiers &Partition, std::string name){ std::vector Diff_vector; std::vector> D_vector; for(uint i = 0; i < Partition.size(); i++){ for(uint j = 0; j < Partition.at(i)->size(); j++){ double gain_d = Diff_cut_ratio(g, Partition, i, Partition.at(i)->at(j), name); //std::cout< 0){ std::pair D; D.first = gain_d; D.second = Partition.at(i)->at(j); D_vector.push_back(D); } } } sort(D_vector.begin(),D_vector.end()); for(uint id = 0; id < D_vector.size(); id++){ Diff_vector.push_back(D_vector.at(id).second); } /*std::cout<<"Tableau des différences "< &Diff_vector, int node, std::string name){ std::vector> D_vector; tie(neighbourIt, neighbourEnd) = adjacent_vertices(node, *g); for (; neighbourIt != neighbourEnd; ++neighbourIt){ //std::cout<<"node : "< 0){ std::pair D; D.first = gain_d; D.second = *neighbourIt; D_vector.push_back(D); } //suprim_val(Diff_vector,*neighbourIt); } if(D_vector.size() == 0){ Diff_vector.erase(Diff_vector.begin()); return; } //std::cout<<"**"<> &Diff_vector, int recalcul1, int recalcul2, std::string name){ std::vector> D_vector; for(uint j = 0; j < Partition.at(recalcul1)->size(); j++){ double gain_d = Diff_cut_ratio(g, Partition, recalcul1, Partition.at(recalcul1)->at(j), name); //std::cout< 0){ std::pair D; D.first = gain_d; D.second = Partition.at(recalcul1)->at(j); D_vector.push_back(D); } } sort(D_vector.begin(),D_vector.end()); std::reverse(D_vector.begin(),D_vector.end()); std::vector index_vector; for(uint id = 0; id < D_vector.size(); id++){ index_vector.push_back(D_vector.at(id).second); } Diff_vector.at(recalcul1) = index_vector; std::vector> D_vector2; for(uint j = 0; j < Partition.at(recalcul2)->size(); j++){ double gain_d = Diff_cut_ratio(g, Partition, recalcul2, Partition.at(recalcul2)->at(j), name); //std::cout< 0){ std::pair D; D.first = gain_d; D.second = Partition.at(recalcul2)->at(j); D_vector2.push_back(D); } } sort(D_vector2.begin(),D_vector2.end()); std::reverse(D_vector2.begin(),D_vector2.end()); std::vector index_vector2; for(uint id = 0; id < D_vector2.size(); id++){ index_vector2.push_back(D_vector2.at(id).second); } Diff_vector.at(recalcul2) = index_vector2; /*std::cout<<"Tableau des différences modifié "<size()<> diff_vector; diff_vector = Vector_diff_cut_ratio(g, Partition, name); /*for(uint i = 0; isize() >1){ //for(uint i = 0; i < diff_vector.at(indice).size(); i++){ int i =0; while(diff_vector.at(indice).size() != 0 && Partition.at(indice)->size() >1 && i < diff_vector.at(indice).size() && Cluster_Weight(*g,*Partition.at(indice)) > (poids_moy-poids_moy/Partition.size())){ //std::cout<<"Sommet de départ : "<< (*g)[diff_vector.at(indice).at(i)]._index <<" dans "< gain & tmp_gain > 0){ gain = tmp_gain; best_neigh_part = neigh_part.at(ind_neigh); } } //std::cout<<" Ensemble de déstination "< 0){ //std::cout<<"Modification"<push_back(diff_vector.at(indice).at(i)); sort(Partition.at(best_neigh_part)->begin(),Partition.at(best_neigh_part)->end()); //double cut2 = Cut_cluster(Partition,*g,"ratio"); //std::cout<<"Vrai ratio de coupe : "< diff_vector; diff_vector = Vector_diff_cut_ratio_2(g, Partition, name); //for(uint indice = 0; indice < diff_vector.size(); indice ++){ int indice = 0; while(/*indice < diff_vector.size() &&*/ diff_vector.size() != 0){ int com = In_community_dichotomie(Partition,diff_vector.at(indice)); std::cout<<" Ensemble de départ "<size() >1 && Cluster_Weight(*g,*Partition.at(com)) > (poids_moy-poids_moy/Partition.size())){ Entiers neigh_part; neigh_part = Neigh_community(g, Partition, diff_vector.at(indice), com); int best_neigh_part = neigh_part.at(0); double gain = -10000000.; for(uint ind_neigh = 0; ind_neigh < neigh_part.size(); ind_neigh++){ double tmp_gain; if(name == "ratio"){ tmp_gain = Gain_ratio(g,Partition,com,neigh_part.at(ind_neigh),diff_vector.at(indice),cut); }else{ double Int = 0.; double Ext = 0.; edge_t e1; bool found; tie(neighbourIt, neighbourEnd) = adjacent_vertices(diff_vector.at(indice), *g); for (; neighbourIt != neighbourEnd; ++neighbourIt){ tie(e1, found) = edge(vertex(diff_vector.at(indice), *g), vertex(*neighbourIt, *g), *g); if(In_tab_dichotomie(*Partition.at(neigh_part.at(ind_neigh)),*neighbourIt) == 1){ Ext+= (*g)[e1]._weight; }else if(In_tab_dichotomie(*Partition.at(com),*neighbourIt) == 1){ Int+= (*g)[e1]._weight; } } tmp_gain = Ext - Int; } if(tmp_gain > gain & tmp_gain > 0){ gain = tmp_gain; best_neigh_part = neigh_part.at(ind_neigh); } } std::cout<<" Ensemble de déstination "< 0){ std::cout<<"Modification"<push_back(diff_vector.at(indice)); sort(Partition.at(best_neigh_part)->begin(),Partition.at(best_neigh_part)->end()); double cut2 = Cut_cluster(Partition,*g,"ratio"); std::cout<<"Vrai ratio de coupe : "<size(); i++){ tie(neighbourIt, neighbourEnd) = adjacent_vertices(Partition.at(in)->at(i), *g); for (; neighbourIt != neighbourEnd; ++neighbourIt){ tie(e1,found)=edge(vertex(Partition.at(in)->at(i),*g),vertex(*neighbourIt,*g),*g); if(In_tab_dichotomie(*Partition.at(in),*neighbourIt) != 1){ if(Partition.at(in)->at(i) != node){ tmp_cut_in += (*g)[e1]._weight; } cut_in += (*g)[e1]._weight; }else if(*neighbourIt == node){ tmp_cut_in += (*g)[e1]._weight; } } } for(uint i = 0; i < Partition.at(out)->size(); i++){ tie(neighbourIt, neighbourEnd) = adjacent_vertices(Partition.at(out)->at(i), *g); for (; neighbourIt != neighbourEnd; ++neighbourIt){ tie(e1,found)=edge(vertex(Partition.at(out)->at(i),*g),vertex(*neighbourIt,*g),*g); if(In_tab_dichotomie(*Partition.at(out),*neighbourIt) != 1){ if(*neighbourIt != node){ tmp_cut_out += (*g)[e1]._weight; } cut_out += (*g)[e1]._weight; } } } tie(neighbourIt, neighbourEnd) = adjacent_vertices(node, *g); for (; neighbourIt != neighbourEnd; ++neighbourIt){ tie(e1,found)=edge(vertex(node,*g),vertex(*neighbourIt,*g),*g); if(In_tab_dichotomie(*Partition.at(out),*neighbourIt) != 1){ tmp_cut_out += (*g)[e1]._weight; } } //std::cout<<"tmp_cut_in "<< tmp_cut_in/2. <size(); i++){ if(Ss->at(i) != node){ tie(neighbourIt, neighbourEnd) = adjacent_vertices(Ss->at(i), *g); for (; neighbourIt != neighbourEnd; ++neighbourIt){ tie(e1,found)=edge(vertex(Ss->at(i),*g),vertex(*neighbourIt,*g),*g); if(In_tab_dichotomie(*Ss,*neighbourIt) != 1){ new_cut += (*g)[e1]._weight; }else if(*neighbourIt == node){ new_cut += (*g)[e1]._weight; } } } } /*for(uint i = 0; i < Sd->size(); i++){ tie(neighbourIt, neighbourEnd) = adjacent_vertices(Sd->at(i), *g); for (; neighbourIt != neighbourEnd; ++neighbourIt){ tie(e1,found)=edge(vertex(Sd->at(i),*g),vertex(*neighbourIt,*g),*g); if(In_tab(*Sd,*neighbourIt) != 1){ if(*neighbourIt != node){ tmp_cut_out += (*g)[e1]._weight; } cut_out += (*g)[e1]._weight; } } } tie(neighbourIt, neighbourEnd) = adjacent_vertices(node, *g); for (; neighbourIt != neighbourEnd; ++neighbourIt){ tie(e1,found)=edge(vertex(node,*g),vertex(*neighbourIt,*g),*g); if(In_tab(*Sd,*neighbourIt) != 1){ tmp_cut_out += (*g)[e1]._weight; } }*/ //std::cout<<"tmp_cut_in "<< tmp_cut_in/2. <( fichier ), std::istreambuf_iterator(),'\n' ); std::cout<<"Nombre de ligne : "<> nmax_vertex; std::cout<<"nmax_vertex : "<> edge; if(edge != -1) part->push_back(edge); } Partition.push_back(part); length = fichier.tellg(); fichier.seekg(length+1, std::ios::beg); cpt++; } }else{ std::cerr << "Impossible d'ouvrir le fichier dans Spectral_Partition !" << std::endl; } return(Partition); } void Adjacent_Matrix_Txt(UnorientedGraph *g, const char* text){ std::ofstream GRAPH4 (text, std::ios::out); if(GRAPH4){ tie(vertexIt, vertexEnd) = vertices(*g); edge_t e1; bool found; for (; vertexIt != vertexEnd; ++vertexIt) { int cpt = 0; tie(neighbourIt, neighbourEnd) = adjacent_vertices(*vertexIt, *g); for(int i = cpt; i " <<(*go)[*neighbourIto]._index<<" [label=" <<(*go)[e1]._weight <<", fontsize=10, fontcolor= blue];"<(*g)[*vertexIt]._index){ tie(e1,found)=edge(vertex(*vertexIt,*g),vertex(*neighbourIt,*g),*g); GRAPH2<<(*g)[*vertexIt]._index<<" -- "<<(*g)[*neighbourIt]._index<<" [label="<<(*g)[e1]._weight<<", fontsize=10, fontcolor= blue];"<(*g)[*vertexIt]._index){ tie(e1,found)=edge(vertex(*vertexIt,*g),vertex(*neighbourIt,*g),*g); GRAPH2<<(*g)[*vertexIt]._index<<" -- "<<(*g)[*neighbourIt]._index<<" [label="<<(*g)[e1]._weight<<", fontsize=10, fontcolor= blue];"< color; color.push_back(", color=blue2, fontcolor=blue2];"); color.push_back(", color=red, fontcolor=red];"); color.push_back(", color=green, fontcolor=green];"); color.push_back(", color=turquoise, fontcolor=turquoise];"); color.push_back(", color=saddlebrown, fontcolor=saddlebrown];"); color.push_back(", color=indigo, fontcolor=indigo];"); color.push_back(", color=yellow, fontcolor=yellow2];"); color.push_back(", color=orange, fontcolor=orange];"); color.push_back(", color=olivedrab, fontcolor=olivedrab];"); color.push_back(", color=gold, fontcolor=gold];"); color.push_back(", color=slateblue2, fontcolor=slateblue2];"); color.push_back(", color=dimgrey, fontcolor=dimgrey];"); color.push_back(", color=cyan, fontcolor=cyan];"); color.push_back(", color=purple1, fontcolor=purpule1];"); color.push_back(", color=crimson, fontcolor=crimson];"); color.push_back(", color=black, fontcolor=black];"); for(uint k=0; ksize(); t++) { GRAPH2<<(*g)[Partition.at(k)->at(t)]._index<<" [label="<<(*g)[Partition.at(k)->at(t)]._weight< color; color.push_back("[color=blue2, fontcolor=blue2];"); color.push_back("[color=red, fontcolor=red];"); color.push_back("[color=green, fontcolor=green];"); color.push_back("[color=turquoise, fontcolor=turquoise];"); color.push_back("[color=saddlebrown, fontcolor=saddlebrown];"); color.push_back("[color=indigo, fontcolor=indigo];"); color.push_back("[color=yellow, fontcolor=yellow2];"); color.push_back("[color=orange, fontcolor=orange];"); color.push_back("[color=olivedrab, fontcolor=olivedrab];"); color.push_back("[color=gold, fontcolor=gold];"); color.push_back("[color=slateblue2, fontcolor=slateblue2];"); color.push_back("[color=dimgrey, fontcolor=dimgrey];"); color.push_back("[color=cyan, fontcolor=cyan];"); color.push_back("[color=purple1, fontcolor=purpule1];"); color.push_back("[color=crimson, fontcolor=crimson];"); color.push_back("[color=black, fontcolor=black];"); std::ofstream fichier2 (text, std::ios::out); fichier2<<"digraph G {"< "<<(*go)[*neighbourIto]._index<<" [label="<<(*go)[e1]._weight<<", fontsize=10, fontcolor= blue];"<size(); j++) { fichier2<at(j)< "; tie(neighbourIto, neighbourEndo) = adjacent_vertices(*vertexIto, *go); for (; neighbourIto != neighbourEndo; ++neighbourIto){ std::cout<<(*go)[*neighbourIto]._index<<" "; } std::cout< "; tie(neighbourIt, neighbourEnd) = adjacent_vertices(*vertexIt, *g); for (; neighbourIt != neighbourEnd; ++neighbourIt){ std::cout<<(*g)[*neighbourIt]._index<<" "; } std::cout<(*g)[*vertexIt]._index){ tie(e1,found)=edge(vertex(*vertexIt,*g),vertex(*neighbourIt,*g),*g); Sum_weight_edges += (*g)[e1]._weight; } } } return Sum_weight_edges; } void Merge_Boost_Graph(OrientedGraph *go1, OrientedGraph *go2, std::vector> &connection, std::vector &connection_weight){ edge_to e1; bool found; int nbr_go1 = num_vertices(*go1); int nbr_go2 = num_vertices(*go2); /*** Fusion ***/ if(nbr_go1 >= nbr_go2){ tie(vertexIto, vertexEndo) = vertices(*go2); for (; vertexIto != vertexEndo; ++vertexIto){ vertex_to v0 = boost::add_vertex(*go1); (*go1)[v0] = VertexProperties((*go2)[*vertexIto]._index, (*go2)[*vertexIto]._weight, NORMAL_PIXEL); } tie(vertexIto, vertexEndo) = vertices(*go2); for (; vertexIto != vertexEndo; ++vertexIto){ tie(neighbourIto, neighbourEndo) = adjacent_vertices(*vertexIto,*go2); for (; neighbourIto != neighbourEndo; ++neighbourIto){ tie(e1,found)=edge(vertex(*vertexIto,*go2),vertex(*neighbourIto,*go2),*go2); add_edge(*vertexIto + nbr_go1, *neighbourIto + nbr_go1, (*go2)[e1]._weight, *go1); } } /*** Connection ***/ /* Fonctionne si l'ordre de nomation respecte l'ordre boost sinon possibilité d'identification par nom*/ for(uint i = 0; i < connection.size(); i++){ add_edge(connection.at(i).first, connection.at(i).second, connection_weight.at(i) , *go1); } }else{ tie(vertexIto, vertexEndo) = vertices(*go1); for (; vertexIto != vertexEndo; ++vertexIto){ vertex_to v0 = boost::add_vertex(*go2); (*go2)[v0] = VertexProperties((*go1)[*vertexIto]._index, (*go1)[*vertexIto]._weight, NORMAL_PIXEL); } tie(vertexIto, vertexEndo) = vertices(*go1); for (; vertexIto != vertexEndo; ++vertexIto){ tie(neighbourIto, neighbourEndo) = adjacent_vertices(*vertexIto,*go1); for (; neighbourIto != neighbourEndo; ++neighbourIto){ tie(e1,found)=edge(vertex(*vertexIto,*go1),vertex(*neighbourIto,*go1),*go1); add_edge(*vertexIto + nbr_go2, *neighbourIto + nbr_go2, (*go1)[e1]._weight, *go2); } } /*** Connection ***/ /* Fonctionne si l'ordre de nomation respecte l'ordre boost sinon possibilité d'identification par nom*/ for(uint i = 0; i < connection.size(); i++){ add_edge(connection.at(i).first, connection.at(i).second, connection_weight.at(i) , *go2); } } } } } } // namespace paradevs tests boost_graph