utils.cpp 43 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302
  1. /**
  2. * @file tests/boost_graph/partitioning/utils.cpp
  3. * @author The PARADEVS Development Team
  4. * See the AUTHORS or Authors.txt file
  5. */
  6. /*
  7. * PARADEVS - the multimodeling and simulation environment
  8. * This file is a part of the PARADEVS environment
  9. *
  10. * Copyright (C) 2013 ULCO http://www.univ-litoral.fr
  11. *
  12. * This program is free software: you can redistribute it and/or modify
  13. * it under the terms of the GNU General Public License as published by
  14. * the Free Software Foundation, either version 3 of the License, or
  15. * (at your option) any later version.
  16. *
  17. * This program is distributed in the hope that it will be useful,
  18. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  19. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  20. * GNU General Public License for more details.
  21. *
  22. * You should have received a copy of the GNU General Public License
  23. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  24. */
  25. #include <tests/boost_graph/partitioning/utils.hpp>
  26. #include <algorithm>
  27. #include <iostream>
  28. namespace paradevs { namespace tests { namespace boost_graph {
  29. UnorientedGraph::vertex_iterator vertexIt, vertexEnd;
  30. UnorientedGraph::adjacency_iterator neighbourIt, neighbourEnd;
  31. OrientedGraph::vertex_iterator vertexIto, vertexEndo;
  32. OrientedGraph::adjacency_iterator neighbourIto, neighbourEndo;
  33. struct myclass
  34. {
  35. bool operator() (Entiers *i, Entiers *j)
  36. { return i->at(0) < j->at(0); }
  37. } myobject;
  38. struct myclass2
  39. {
  40. bool operator() (Entiers *i, Entiers *j, UnorientedGraph *g)
  41. { return Calcul_poids(i,g) < Calcul_poids(j,g); }
  42. } mon_tri;
  43. /**
  44. * Fonction de verification de la connexité d'un graphe
  45. * @param *g : adresse d'un graphe de type boost graphe undirected
  46. * @param Partition : vecteur contenant des vecteurs d'entiers [tableau contenant les parties de la partition]
  47. * @param part : vecteur d'entier (une partie de la partition)
  48. * @return un booleen
  49. */
  50. bool Est_connexe(UnorientedGraph *g, EntiersEntiers Partition, Entiers &part)
  51. {
  52. /*
  53. * Copie du graphe contenu par l'adresse *g
  54. */
  55. UnorientedGraph copie_g;
  56. copie_g = *g;
  57. /*
  58. * Modification du graphe copié afin de générer des sous graphes liés aux différentes parties
  59. */
  60. for (uint i=0; i<Partition.size()-1;i++)
  61. {
  62. for (uint j=1+i; j<Partition.size();j++)
  63. {
  64. for (uint k=0; k<Partition.at(i)->size();k++)
  65. {
  66. for (uint y=0; y<Partition.at(j)->size();y++)
  67. {
  68. remove_edge(Partition.at(i)->at(k),Partition.at(j)->at(y),copie_g); //suppression de certains arcs
  69. }
  70. }
  71. }
  72. }
  73. /*
  74. * Objectif : déterminer s'il existe un chemin reliant tous les noeuds d'une même partie
  75. * Méthode : partir d'un sommet de départ tiré aléatoirement dans la partie "part" et parcourir l'ensemble de ces voisins.
  76. * Si le voisin recontré n'est pas contenu dans le vecteur "sommets" il est ajouté. Le processus est répété pour chaque
  77. * nouveau sommet ajouté au vecteur.
  78. * Résultat : si le nombre de sommets contenu dans le vecteur "part" est égale au nombre de sommets du vecteur "sommets"
  79. * alors le graphe est connexe
  80. */
  81. int val;
  82. Entiers sommets;
  83. if(part.size()==1)
  84. val = 0;
  85. else
  86. val=rand_fini(0,part.size()-1); //tirage aléatoire d'un sommets
  87. int vertex = part.at(val);
  88. sommets.push_back(vertex); //ajout du sommets à la lsite des sommets parcouru
  89. /*
  90. * Recherche de voisins n'appartenant pas à la liste des sommets parcourus
  91. */
  92. for(uint i = 0;i<sommets.size();i++){
  93. tie(neighbourIt, neighbourEnd) = adjacent_vertices(sommets.at(i),copie_g);
  94. for (; neighbourIt != neighbourEnd; ++neighbourIt){
  95. if(In_tab(sommets,*neighbourIt)!=1)
  96. sommets.push_back(*neighbourIt);
  97. }
  98. }
  99. /*
  100. * Retour de la réponse vrai ou faux
  101. */
  102. if(part.size()!=sommets.size())
  103. return false;
  104. else
  105. return true;
  106. }
  107. /**
  108. * Fonction de projection
  109. * @param Partition : vecteur contenant des vecteurs d'entiers [tableau contenant les parties de la partition]
  110. * @param lit : itérateur sur une liste contenant une vecteur de vecteur d'entier
  111. * @return
  112. */
  113. /*
  114. * Objectif : obtenir la correspondance entre les sommets d'un graphe Gn et celui de Gn-1
  115. * Méthode : modification des sommets contenus dans "Partition" à l'aide de la liste de correspondance *lit
  116. */
  117. void projection(EntiersEntiers &Partition,ListEntiersEntiers::iterator lit)
  118. {
  119. /*
  120. * Création d'un nouveau vecteur contenant les adresses d'autres vecteur d'entiers.
  121. * Celui-ci est conçu pour recevoir les sommets contenus dans la liste de correspondance,
  122. * correspondant à la projection des sommets du graphe Gn à celui de Gn-1
  123. */
  124. EntiersEntiers new_partition;
  125. for(uint i = 0; i< Partition.size() ; i++)
  126. {
  127. Entiers *new_part = new Entiers();
  128. for(uint j = 0 ; j<Partition.at(i)->size() ; j++)
  129. {
  130. for(uint k = 0; k<((*lit)->at(Partition.at(i)->at(j)))->size();k++){
  131. new_part->push_back((*lit)->at(Partition.at(i)->at(j))->at(k));
  132. }
  133. }
  134. new_partition.push_back(new_part);
  135. }
  136. /*
  137. * Désalocation mémoire des pointeurs que contient "Partition"
  138. */
  139. for(EntiersEntiers::iterator it = Partition.begin(); it != Partition.end(); it++)
  140. {
  141. delete *it;
  142. *it = NULL;
  143. }
  144. Partition = new_partition; // copie de new_partition dans Partition
  145. for(uint i =0; i<Partition.size(); i++) {
  146. // permet de trier chaque sous vecteur de "Partition"
  147. std::sort(Partition[i]->begin(),Partition[i]->end());
  148. }
  149. new_partition.clear();
  150. }
  151. /**
  152. * Fonction qui calcul le poids d'une partie
  153. * @param * part : adresse d'un vecteur d'entier, ici une partie de la partition
  154. * @param *g : adresse d'un graphe de type boost graphe undirected
  155. * @return un type double contenant le poids associé à la partie
  156. */
  157. double Calcul_poids(Entiers *partie, UnorientedGraph *g)
  158. {
  159. double poids=0; // initialisation du poids à 0
  160. /*
  161. * Pour chaque sommet de la partie concerné on ajoute son poids au poids total
  162. */
  163. for(uint j = 0; j<partie->size();j++){
  164. poids+=(*g)[partie->at(j)]._weight;
  165. }
  166. return poids;
  167. }
  168. /**
  169. * Fonction d'affinage suivant un critère de poids
  170. * @param *g : adresse d'un graphe de type boost graphe undirected
  171. * @param Partition : vecteur contenant des vecteurs d'entiers [tableau contenant les parties de la partition]
  172. * @return modification de la partition
  173. */
  174. void Affinage_equilibrage_charge(UnorientedGraph *g, EntiersEntiers &Partition)
  175. {
  176. /*
  177. * Calcule de la somme des poids du graphe et le poids moyen à atteindre
  178. */
  179. double poids_moyen = 0.;
  180. for(uint i = 0; i < num_vertices(*g); i++) {
  181. poids_moyen += (*g)[i]._weight;
  182. }
  183. // détermination du poids moyen à atteindre pour chaque partie
  184. poids_moyen /= Partition.size();
  185. std::vector < double > poids_parties;
  186. /*
  187. * Calcul du poids de chaque partie de la partition
  188. */
  189. for (uint i = 0; i < Partition.size(); i++) {
  190. double tmp = Calcul_poids(Partition.at(i),g);
  191. poids_parties.push_back(tmp);
  192. }
  193. std::clog << "Poids initial des parties : " << std::endl;
  194. for (uint i = 0; i < poids_parties.size(); i++){
  195. std::cout << poids_parties.at(i) << " ";
  196. }
  197. std::cout << "\n" << std::endl;
  198. /*
  199. * Le critère d'amélioration consiste à faire tendre vers 0 la somme
  200. * des écarts entre le poids des parties et le poids moyen
  201. * le "critere" est la somme pour chaque partie de la différence
  202. * en valeurs absolues du poids
  203. * d'une partie moins le poids moyen divisé par le nombre de parties
  204. */
  205. double critere = 0.;
  206. for (uint i = 0; i < poids_parties.size(); i++){
  207. critere += abs(poids_parties.at(i) - poids_moyen);
  208. }
  209. critere /= Partition.size();
  210. // on conserve le poids maximum
  211. double p_max = *max_element(poids_parties.begin(), poids_parties.end());
  212. std::cout << "Valeurs du criètre de départ : " << critere << std::endl;
  213. // création d'un second critère légérement plsu faible que le premier
  214. double best_critere = critere - 1e-7;
  215. uint nbr_passage = 1; // initialisation du nombre de passages à 1
  216. /*
  217. * Tant que le critère n'est pas amélioré etque le nombre de
  218. * passage est inférieur au nombre de parties on réalise
  219. * des modifications sur la partition
  220. */
  221. while (best_critere < critere or nbr_passage < Partition.size()) {
  222. critere = best_critere; //critere devient best_critere
  223. // recherche la partie associé au poids maximum
  224. int cpt = recherche_val_double(poids_parties,p_max);
  225. bool decision = false; //initialisatio d'un booleen a false
  226. int nbr_pass_interne = 0;
  227. /*
  228. * tirage aléatoire des sommets de la partie de poids maximum
  229. */
  230. Entiers random_orders(Partition.at(cpt)->size());
  231. for (uint i=0 ; i<Partition.at(cpt)->size() ; i++)
  232. random_orders.at(i)=Partition.at(cpt)->at(i);
  233. for (uint j=0 ; j<Partition.at(cpt)->size()-1 ; j++) {
  234. int rand_pos = (rand() % Partition.at(cpt)->size()-j)+j;
  235. int tmp = random_orders[j];
  236. random_orders[j] = random_orders[rand_pos];
  237. random_orders[rand_pos] = tmp;
  238. }
  239. /*
  240. * Si le nombre de sommets d'une partie excéde les 400, on tire au hasar 400 sommets sans remise
  241. * et on effectue les modifications (ceci permet d'eviter une explosion des temps de calcul)
  242. */
  243. int size;
  244. if(Partition.at(cpt)->size()>400)
  245. size = 400;
  246. else
  247. size = Partition.at(cpt)->size();
  248. /*
  249. * Seconde boucle Tant que sur les sommets d'une partie.
  250. * Tant que le critere booleen est vrai et que le nombre de passe interne est inférieur au seuil size faire
  251. */
  252. while(decision!=true && nbr_pass_interne < size){
  253. int vertex = random_orders.at(nbr_pass_interne); //tirage d'un sommets dans la parite de poids maximum
  254. Entiers community = Neigh_community(g,Partition,vertex,cpt); // recherche des communautés voisines à ce sommet (s'il est au bord)
  255. if(community.size()!=0) // s'il existe au moins une communauté voisine
  256. {
  257. std::vector<double> new_poids_parties; // initialisation d'un nouveau vecteur contenant des doubles
  258. std::vector<double> tmp_critere; // initialisation d'un nouveau vecteur contenant des doubles
  259. /*
  260. * Pour chacune des parties (communauté) voisine au sommet vertexs faire
  261. */
  262. for(uint k = 0; k < community.size();k++)
  263. {
  264. new_poids_parties = poids_parties; //copie du tableau de poids des parties dans new_poids_parties
  265. /*
  266. * Modification des poids des parties :
  267. * on ajoute le poids du sommets à la partie voisine
  268. * et on soustrait son poids à sa partie d'origine
  269. */
  270. new_poids_parties.at(community.at(k))+=(*g)[vertex]._weight;
  271. new_poids_parties.at(cpt)-=(*g)[vertex]._weight;
  272. /*
  273. * Calcul ldu nouveau critère associé à cette modification
  274. */
  275. double new_critere = 0.;
  276. for(uint i = 0; i<poids_parties.size();i++){
  277. new_critere += abs(new_poids_parties.at(i)-poids_moyen);
  278. }
  279. new_critere/=Partition.size();
  280. tmp_critere.push_back(new_critere); // enregistrement du résutlat dans le tableau tmp_critere
  281. }
  282. double val_min = *min_element(tmp_critere.begin(),tmp_critere.end()); // enregistrement de la valeur minimale du tableau tmp_critere
  283. int val = recherche_val_double(tmp_critere,val_min); // recherche de la communauté correspondant à cette valeur
  284. /*
  285. * Si la valeur associé est plus petite et que la partie selectionné n'est pas vérouillée faire
  286. */
  287. if(val_min<critere && poids_parties.at(val)!=-1)
  288. {
  289. /*
  290. * On change le sommet vertex de partie, il est déplacé vers la partie
  291. * qui permet la meilleure amélioration du critère
  292. */
  293. Partition.at(community.at(val))->push_back(vertex);
  294. suprim_val(*Partition.at(cpt),vertex);
  295. std::sort(Partition.at(community.at(val))->begin(), Partition.at(community.at(val))->end());
  296. /*
  297. * Vérification de la sauvegarde de la connexsité,
  298. * si se n'est pas le cas retour à l'état précédent
  299. */
  300. if(Est_connexe(g,Partition,*Partition.at(cpt))!=1)
  301. {
  302. suprim_val(*Partition.at(community.at(val)),vertex);
  303. Partition.at(cpt)->push_back(vertex);
  304. std::sort(Partition.at(cpt)->begin(), Partition.at(cpt)->end());
  305. std::cout<<" C'EST MORT RETOUR EN ARRIERE ! "<<std::endl;
  306. }
  307. else
  308. {
  309. poids_parties = new_poids_parties;
  310. decision = true;
  311. std::cout<<" Modification reussi ! "<<std::endl;
  312. }
  313. }
  314. }
  315. nbr_pass_interne++;
  316. }
  317. /*
  318. * Si aucune modification n'a été réalisé pour cett partie de poids maximum
  319. */
  320. if(decision==false)
  321. {
  322. nbr_passage++; // augmentation du nombre de passage
  323. poids_parties.at(cpt)=-1; // vérrouillage de la partie
  324. std::clog<<"nouveau passag ! "<<std::endl;
  325. }
  326. else
  327. {
  328. best_critere = 0.;
  329. for(uint i = 0; i<poids_parties.size();i++){
  330. best_critere += abs(poids_parties.at(i)-poids_moyen);
  331. }
  332. best_critere/=Partition.size();
  333. nbr_passage = 0;
  334. }
  335. std::clog<<"Poids des parties modifié : "<<std::endl;
  336. for(uint i = 0; i<poids_parties.size(); i++){
  337. std::cout<<poids_parties.at(i)<<" ";
  338. }
  339. std::cout<<"\n"<<std::endl;
  340. p_max = *max_element(poids_parties.begin(),poids_parties.end());
  341. std::cout<<"Valeurs du criètre : "<<critere<<std::endl;
  342. std::cout<<"Valeurs du best_criètre : "<<best_critere<<std::endl;
  343. std::cout<<"Nombre de passage : "<<nbr_passage<<std::endl;
  344. std::cout<<"\n"<<std::endl;
  345. }
  346. }
  347. Entiers Neigh_community(UnorientedGraph *g, EntiersEntiers &Partition, int vertex, int comm_in)
  348. {
  349. Entiers community;
  350. int comm;
  351. tie(neighbourIt, neighbourEnd) = adjacent_vertices(vertex,*g);
  352. for (; neighbourIt != neighbourEnd; ++neighbourIt){
  353. comm = In_community_dichotomie(Partition,*neighbourIt);
  354. if(In_tab(community,comm)!=1 && comm!=comm_in)
  355. community.push_back(comm);
  356. }
  357. return community;
  358. }
  359. void Affinage_recherche_locale(UnorientedGraph *g, EntiersEntiers &Partition, double &cut, std::string name)
  360. {
  361. Entiers random_orders(num_vertices(*g)); //gestion d'un tableau contenant tout les sommets et ranger de façon aléatoire
  362. for (uint i=0 ; i<random_orders.size() ; i++)
  363. random_orders.at(i)=i;
  364. for (uint j=0 ; j<num_vertices(*g)-1 ; j++) {
  365. int rand_pos = (rand() % num_vertices(*g)-j)+j;
  366. int tmp = random_orders[j];
  367. random_orders[j] = random_orders[rand_pos];
  368. random_orders[rand_pos] = tmp;
  369. }
  370. uint size = random_orders.size();
  371. if(random_orders.size()>500)
  372. size=500;
  373. std::vector<std::vector<double> > tabe_cut;
  374. for(uint k = 0; k < Partition.size();k++){
  375. std::vector<double> tmp;
  376. double vol = 0.;
  377. double cut = Modif_Cut_one_cluster(*Partition.at(k), *g, vol);
  378. tmp.push_back(cut);
  379. tmp.push_back(vol);
  380. tabe_cut.push_back(tmp);
  381. }
  382. for(uint i = 0; i < size; i++){
  383. if(random_orders.at(i)!=-1){
  384. int vertex = random_orders.at(i);
  385. int comm = In_community_dichotomie(Partition, vertex);
  386. Entiers community = Neigh_community(g,Partition,vertex,comm);
  387. std::vector<double> tmp_cut;
  388. if(community.size()!=0 && Partition.at(comm)->size()!=1){
  389. tmp_cut = modif_cut_tmp(g,Partition,tabe_cut,vertex,comm,community,cut,name);
  390. for(uint z = 0; z<tmp_cut.size(); z++){
  391. std::cout<<tmp_cut.at(z)<<std::endl;
  392. }
  393. std::cout<<"\n"<<std::endl;
  394. double cut_min = *min_element(tmp_cut.begin(),tmp_cut.end());
  395. std::cout<<"cout de coupe minimum de la liste : "<<cut_min<<std::endl;
  396. if(cut_min<cut){
  397. std::clog<<"Changement ! "<<std::endl;
  398. int tmp = recherche_val_double(tmp_cut,cut_min);
  399. cut=cut_min;
  400. Partition.at(community.at(tmp))->push_back(vertex);
  401. suprim_val(*Partition.at(comm),vertex);
  402. std::sort(Partition.at(community.at(tmp))->begin(), Partition.at(community.at(tmp))->end());
  403. tabe_cut.clear();
  404. for(uint k = 0; k < Partition.size();k++){
  405. std::vector<double> tmp;
  406. double vol = 0.;
  407. double cut = Modif_Cut_one_cluster(*Partition.at(k), *g, vol);
  408. tmp.push_back(cut);
  409. tmp.push_back(vol);
  410. tabe_cut.push_back(tmp);
  411. }
  412. }
  413. }
  414. //Modif_fonction_Gain_Cut(Partition,g,community,vertex,cut,name);
  415. /*if(Est_connexe(g,Partition,*Partition.at(comm))!=1)
  416. {
  417. suprim_val(*Partition.at(community.at(tmp)),vertex);
  418. Partition.at(comm)->push_back(vertex);
  419. std::sort(*Partition.at(comm));
  420. std::cout<<" C'EST MORT RETOUR EN ARRIERE ! "<<std::endl;
  421. }*/
  422. }
  423. }
  424. }
  425. double Modif_Cut_one_cluster(Entiers &cluster, UnorientedGraph &g, double &vol)
  426. {
  427. edge_t e1;
  428. bool found;
  429. double cpt=0.;
  430. for(uint i=0;i<cluster.size();i++){
  431. tie(neighbourIt, neighbourEnd) = adjacent_vertices(cluster.at(i), g);
  432. for (; neighbourIt != neighbourEnd; ++neighbourIt){
  433. tie(e1,found)=edge(vertex(cluster[i],g),vertex(*neighbourIt,g),g);
  434. if(In_tab(cluster,*neighbourIt)!=1){
  435. cpt+=g[e1]._weight;
  436. }
  437. }
  438. }
  439. vol = Cluster_Degree(g,cluster);
  440. return cpt/2.;
  441. }
  442. std::vector<double> modif_cut_tmp(UnorientedGraph *g, EntiersEntiers &Partition, std::vector<std::vector<double> > tabe_cut, int vertexs, int comm_in, Entiers community, double cut,std::string name){
  443. edge_t e1;
  444. bool found;
  445. std::cout<<"le sommet tiré est : "<<vertexs<<std::endl;
  446. if(name!="norm")
  447. {
  448. std::vector<double> modif_cut(community.size());
  449. double cpt_comm_in;
  450. double cpt_comm_out;
  451. for(uint i =0; i<community.size(); i++){
  452. double tmp_cut = cut;
  453. cpt_comm_in=0;
  454. cpt_comm_out=0;
  455. tie(neighbourIt, neighbourEnd) = adjacent_vertices(vertexs,*g);
  456. for (; neighbourIt != neighbourEnd; ++neighbourIt){
  457. tie(e1,found)=edge(vertex(vertexs,*g),vertex(*neighbourIt,*g),*g);
  458. if(In_tab(*Partition.at(comm_in),*neighbourIt)==1)
  459. cpt_comm_in+=(*g)[e1]._weight;
  460. else if(In_tab(*Partition.at(community.at(i)),*neighbourIt)==1)
  461. cpt_comm_out+=(*g)[e1]._weight;
  462. }
  463. tmp_cut+=cpt_comm_in;
  464. tmp_cut-=cpt_comm_out;
  465. modif_cut.at(i)=tmp_cut;
  466. }
  467. return modif_cut;
  468. }
  469. else{
  470. std::vector<double> modif_cut(community.size());
  471. double cpt_comm_in;
  472. double cpt_comm_out;
  473. double tmp_cut;
  474. for(uint i =0; i<community.size(); i++){
  475. std::vector<std::vector<double> > tab_cut = tabe_cut;
  476. tmp_cut =0.;
  477. cpt_comm_in=0.;
  478. cpt_comm_out=0.;
  479. tie(neighbourIt, neighbourEnd) = adjacent_vertices(vertexs,*g);
  480. for (; neighbourIt != neighbourEnd; ++neighbourIt){
  481. tie(e1,found)=edge(vertex(vertexs,*g),vertex(*neighbourIt,*g),*g);
  482. if(In_tab(*Partition.at(comm_in),*neighbourIt)==1)
  483. cpt_comm_in+=(*g)[e1]._weight;
  484. else if(In_tab(*Partition.at(community.at(i)),*neighbourIt)==1)
  485. cpt_comm_out+=(*g)[e1]._weight;
  486. }
  487. cpt_comm_in/=2.;
  488. cpt_comm_out/=2.;
  489. tab_cut.at(comm_in).at(0)+=cpt_comm_in;
  490. tab_cut.at(comm_in).at(0)-=cpt_comm_out;
  491. tab_cut.at(comm_in).at(1)-= Degree(*g ,vertexs);
  492. tab_cut.at(community.at(i)).at(0)+=cpt_comm_in;
  493. tab_cut.at(community.at(i)).at(0)-=cpt_comm_out;
  494. tab_cut.at(community.at(i)).at(1)+= Degree(*g ,vertexs);
  495. for(uint j = 0; j < tab_cut.size();j++){
  496. tmp_cut+=((tab_cut.at(j).at(0))/(tab_cut.at(j).at(1)));
  497. }
  498. modif_cut.at(i)=tmp_cut;
  499. }
  500. return modif_cut;
  501. }
  502. }
  503. void Modif_fonction_Gain_Cut(EntiersEntiers &Partition,UnorientedGraph *g, Entiers &community, int val, double &cut,std::string name)
  504. {
  505. /*std::cout<<"Nombre de communauté voisine : "<<community.size()<<std::endl;
  506. std::cout<<"\n"<<std::endl;*/
  507. for(uint i = 0; i<community.size();i++){
  508. EntiersEntiers new_partition;
  509. for(uint k = 0; k < Partition.size();k++){
  510. Entiers * tmp = new Entiers();
  511. for(uint j = 0;j<Partition.at(k)->size();j++){
  512. tmp->push_back(Partition.at(k)->at(j));
  513. }
  514. new_partition.push_back(tmp);
  515. }
  516. /*std::cout<<"Avant Modification partition"<<std::endl;
  517. std::cout<<"************"<<std::endl;
  518. for(uint t = 0; t< new_partition.size() ; t++)
  519. {
  520. for(uint j = 0 ; j<new_partition.at(t)->size() ; j++)
  521. {
  522. std::cout<<new_partition.at(t)->at(j)<<std::endl;
  523. }
  524. std::cout<<"\n"<<std::endl;
  525. }
  526. std::cout<<"************"<<std::endl;*/
  527. new_partition.at(community.at(i))->push_back(val);
  528. suprim_val(*new_partition.at(In_community_dichotomie(Partition,val)),val);
  529. std::sort(new_partition.at(community.at(i))->begin(),
  530. new_partition.at(community.at(i))->end());
  531. /*std::cout<<"Modification partition"<<std::endl;
  532. std::cout<<"************"<<std::endl;
  533. for(uint t= 0; t< new_partition.size() ; t++)
  534. {
  535. for(uint j = 0 ; j<new_partition.at(t)->size() ; j++)
  536. {
  537. std::cout<<new_partition.at(t)->at(j)<<std::endl;
  538. }
  539. std::cout<<"\n"<<std::endl;
  540. }
  541. std::cout<<"************"<<std::endl;*/
  542. double coupe = Cut_cluster(new_partition,*g,name);
  543. //std::cout<<"cout de coupe : "<<coupe<<std::endl;
  544. if(coupe<cut)
  545. {
  546. for(EntiersEntiers::iterator it = Partition.begin(); it != Partition.end(); it++)
  547. {
  548. delete *it;
  549. *it = NULL;
  550. }
  551. Partition = new_partition;
  552. cut = coupe;
  553. }
  554. else
  555. {
  556. for(EntiersEntiers::iterator it = new_partition.begin(); it != new_partition.end(); it++)
  557. {
  558. delete *it;
  559. *it = NULL;
  560. }
  561. }
  562. }
  563. }
  564. void contraction_HEM(UnorientedGraph *g, Base_Graph &baseg, ListEntiersEntiers &liste_corr){
  565. UnorientedGraph *gtmp = new UnorientedGraph();
  566. *gtmp=*g;
  567. Entiers Random_list_vertices; // Initialisation du tableau de sommets rangés aléatoirements
  568. EntiersEntiers *tableau_de_correspondance = new EntiersEntiers();
  569. edge_t e1,e2; // Iterateurs sur les arcs
  570. bool found;
  571. uint nbr_vertex = num_vertices(*gtmp);
  572. Entiers sommets_a_detruire; // Initialisation d'un tableau pret à recevoir les "sommets à détruire"
  573. /*
  574. * Création d'un vecteur contenant l'ensemble des sommets du graphe. Ces sommets sont rangés
  575. * aléatoirement afin de simuler un tirage aléatoire
  576. */
  577. for (uint i=0 ; i<nbr_vertex ; i++)
  578. Random_list_vertices.push_back(i);
  579. for (uint j=0 ; j<nbr_vertex-1 ; j++) {
  580. int rand_pos = rand()%(nbr_vertex-j)+j;
  581. int tmp = Random_list_vertices[j];
  582. Random_list_vertices[j] = Random_list_vertices[rand_pos];
  583. Random_list_vertices[rand_pos] = tmp;
  584. }
  585. /*
  586. * Pour chaque sommet non verrouiller faire ....
  587. */
  588. for(uint i=0; i<nbr_vertex; i++){
  589. int vertexs = Random_list_vertices[i];
  590. if(vertexs!=-1){
  591. Entiers liste_voisin = Liste_adjacence(*gtmp,vertexs,Random_list_vertices); // Recherche des sommets adjacents au sommets tiré
  592. if(liste_voisin.size()!=0){
  593. /*
  594. * S'il en existe au mois un sommet adjacent au sommet tiré qui n'est pas verrouillé, on
  595. * choisi celui dont l'arc les reliants est le plus fort. Dans le cas où les arcs ont tous
  596. * le même poids, on selectionne le sommet d'identifiant le plus petit
  597. */
  598. double poids_a = 0.;
  599. int best_vertexs = -1;
  600. for(uint j=0;j<liste_voisin.size();j++){
  601. tie(e1,found)=edge(vertex(vertexs,*gtmp),vertex(liste_voisin[j],*gtmp),*gtmp);
  602. if((*gtmp)[e1]._weight>poids_a){
  603. best_vertexs = liste_voisin[j];
  604. poids_a = (*gtmp)[e1]._weight;
  605. }
  606. }
  607. Entiers * couple = new Entiers(); // Initialisation du vecteur contenant le couple de sommet fusionné
  608. int vertex_delete = std::max(vertexs, best_vertexs); // Sommet d'indentifiant le plus grand (qui sera détruit)
  609. //std::cout<<"sommet détruit : "<<vertex_delete<<std::endl;
  610. int vertex_save = std::min(vertexs,best_vertexs); // Sommet d'identifiant le plus petit (qui sera conservé)
  611. //std::cout<<"sommet sauvé : "<<vertex_save<<std::endl;
  612. sommets_a_detruire.push_back(vertex_delete); // On ajoute le sommet détruit au tableau des sommets à détruire
  613. /*
  614. * On ajoute au tableau "couple" le couple de sommet à fusionner
  615. */
  616. couple->push_back(vertex_save);
  617. couple->push_back(vertex_delete);
  618. tableau_de_correspondance->push_back(couple); // Ajout du "couple" à la liste de correspondance
  619. remove_edge(vertex_save,vertex_delete,*gtmp); // Suppression de l'arc reliant le couple de sommets
  620. Entiers neigh_vertex_save; // Initialisation du vecteur contenant les somemts adjacents au "sommet sauvegardé"
  621. Entiers neigh_vertex_delete; // Initialisation du vecteur contenant les somemts adjacents au "sommet à détruire"
  622. tie(neighbourIt, neighbourEnd) = adjacent_vertices(vertex_save,*gtmp);
  623. /*
  624. * Remplissage de ces deux tableaux à l'aide de la fonction adjacent_vertices de boost graph
  625. * [La création de ces tableaux est nécéssaire du fait que certains arcs sont détruit au cours
  626. * du processus]
  627. */
  628. for (; neighbourIt != neighbourEnd; ++neighbourIt){
  629. neigh_vertex_save.push_back(*neighbourIt);
  630. }
  631. tie(neighbourIt, neighbourEnd) = adjacent_vertices(vertex_delete,*gtmp);
  632. for (; neighbourIt != neighbourEnd; ++neighbourIt){
  633. neigh_vertex_delete.push_back(*neighbourIt);
  634. }
  635. /*
  636. * Recherche de sommets communs entre le "sommet sauvegardé" et le "sommet à détruire"
  637. * S'il existe un tel sommet "v" alors on ajoute le poids de l'arcs (vertex_delet,v)
  638. * à celui de l'arcs (vertex_save,v) et on détruit l'arcs reliant "v" au "sommet à détruire"
  639. */
  640. for(uint j=0;j<neigh_vertex_delete.size();j++){
  641. if(In_tab(neigh_vertex_save,neigh_vertex_delete[j])==1){
  642. tie(e2,found)=edge(vertex(vertex_save,*gtmp),vertex(neigh_vertex_delete[j],*gtmp),*gtmp);
  643. tie(e1,found)=edge(vertex(vertex_delete,*gtmp),vertex(neigh_vertex_delete[j],*gtmp),*gtmp);
  644. (*gtmp)[e2]._weight+=(*gtmp)[e1]._weight;
  645. remove_edge(vertex_delete,neigh_vertex_delete[j],*gtmp);
  646. }
  647. else
  648. {
  649. tie(e1,found)=edge(vertex(vertex_delete,*gtmp),vertex(neigh_vertex_delete[j],*gtmp),*gtmp);
  650. add_edge(vertex_save,neigh_vertex_delete[j],EdgeProperties((*gtmp)[e1]._weight),*gtmp);
  651. remove_edge(vertex_delete,neigh_vertex_delete[j],*gtmp);
  652. }
  653. }
  654. (*gtmp)[vertex_save]._weight+=(*gtmp)[vertex_delete]._weight; // ajout du poids du sommet détruit au sommet conservé
  655. /*
  656. * Vérouillage du "sommet sauvegardé" et du "sommet à détruire"
  657. */
  658. Random_list_vertices[i]=-1;
  659. Random_list_vertices[recherche_val(Random_list_vertices,best_vertexs)]=-1;
  660. }
  661. else{
  662. /*
  663. * Et si le sommet tiré ne possède pas de sommet adjacent non verrouillé
  664. * alors on l'ajoute à la liste de correspondance des sommets et on
  665. * le verrouille
  666. */
  667. Entiers *couple = new Entiers();
  668. couple->push_back(Random_list_vertices.at(i));
  669. tableau_de_correspondance->push_back(couple);
  670. Random_list_vertices[i]=-1;
  671. }
  672. }
  673. }
  674. std::sort(sommets_a_detruire.begin(), sommets_a_detruire.end()); // Trie dans l'ordre croissant des "sommets à détruire"
  675. //std::cout<<"\n"<<std::endl;
  676. /*
  677. * Suppression des sommets de la liste "sommets à détruire". Cette suppression est
  678. * effectuée dans l'ordre décroissant afin à maintenir à jour la renumérotation
  679. * des sommets
  680. */
  681. for(int j=(sommets_a_detruire.size()-1);j>-1;j--){
  682. //std::cout<<"Noeuds a supprimer : "<<sommets_a_detruire.at(j)<<std::endl;
  683. remove_vertex(sommets_a_detruire[j],*gtmp);
  684. }
  685. /**std::clog<<"Affichage avant tri "<<std::endl;
  686. for(uint k = 0;k<tableau_de_correspondance->size();k++){
  687. for(uint v = 0; v<tableau_de_correspondance->at(k)->size();v++){
  688. std::cout<<tableau_de_correspondance->at(k)->at(v)<<" ";
  689. }
  690. std::cout<<"\n"<<std::endl;
  691. }*/
  692. 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
  693. std::clog<<"Tableau de correspondance "<<std::endl;
  694. for(uint k = 0;k<tableau_de_correspondance->size();k++){
  695. for(uint v = 0; v<tableau_de_correspondance->at(k)->size();v++){
  696. std::cout<<tableau_de_correspondance->at(k)->at(v)<<" ";
  697. }
  698. std::cout<<"\n"<<std::endl;
  699. }
  700. liste_corr.push_back(tableau_de_correspondance);
  701. std::cout<<"\n"<<std::endl;
  702. baseg.push_back(gtmp); // Ajout du graphe modifié à la "base des graphe"
  703. }
  704. Entiers Liste_adjacence(UnorientedGraph &g, int vertexs,const Entiers &random_vertices){ // a revoir !!!!
  705. Entiers liste_voisin;
  706. tie(neighbourIt, neighbourEnd) = adjacent_vertices(vertexs, g);
  707. for (; neighbourIt != neighbourEnd; ++neighbourIt){
  708. if(In_tab(random_vertices,*neighbourIt)==1)
  709. liste_voisin.push_back(*neighbourIt);
  710. }
  711. return liste_voisin;
  712. }
  713. int rand_fini(int a, int b){
  714. return rand()%(b-a)+a;
  715. }
  716. /**
  717. * Fonction de recherche d'une valeur dans un tableau.
  718. * @param tab
  719. * @param val
  720. * @return
  721. */
  722. int recherche_val2(const std::vector<float> &tab,float val){
  723. int cpt=0;
  724. while(tab[cpt]!=val)
  725. cpt++;
  726. return cpt;
  727. }
  728. int recherche_val_double(const std::vector<double> &tab,double val){
  729. int cpt=0;
  730. while(tab[cpt]!=val)
  731. cpt++;
  732. return cpt;
  733. }
  734. int recherche_val(const Entiers &tab,int val){
  735. int cpt=0;
  736. while(tab[cpt]!=val)
  737. cpt++;
  738. return cpt;
  739. }
  740. /**
  741. * @param tab
  742. * @param i
  743. * @return
  744. */
  745. int dichotomie(const Entiers &tab, int i){
  746. /* déclaration des variables locales à la fonction */
  747. int id; //indice de début
  748. int ifin; //indice de fin
  749. int im; //indice de "milieu"
  750. /* initialisation de ces variables avant la boucle de recherche */
  751. id = 0; //intervalle de recherche compris entre 0...
  752. ifin = tab.size(); //...et nbVal
  753. /* boucle de recherche */
  754. while ((ifin - id) > 1){
  755. im = (id + ifin)/2; //on détermine l'indice de milieu
  756. 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
  757. 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
  758. }
  759. /* test conditionnant la valeur que la fonction va renvoyer */
  760. if (tab[id] == i) return id; //si on a trouvé la bonne valeur, on retourne l'indice
  761. else return -1; //sinon on retourne -1
  762. }
  763. /**
  764. * Fonction permettant de supprimer une case d'un tableau.
  765. * @param tab une référence sur un tableau d'entiers
  766. * @param i un indice dans tab
  767. */
  768. void suprim_val(Entiers &tab,int i) {
  769. tab.erase(tab.begin() + dichotomie(tab,i));
  770. }
  771. /**
  772. * Détermine si une valeur se trouve dans un tableau.
  773. * @param tab une référence sur un tableau d'entiers
  774. * @param val une valeur
  775. * @return true si la valeur a été trouvée, false sinon
  776. */
  777. bool In_tab(const Entiers &tab, int val)
  778. {
  779. for (uint i=0; i < tab.size(); i++)
  780. if(tab[i]==val)
  781. return true;
  782. return false;
  783. }
  784. bool In_tab_dichotomie(const Entiers &tab, int val)
  785. {
  786. if(dichotomie(tab,val)!=-1)
  787. return true;
  788. else
  789. return false;
  790. }
  791. void Liste_Voisin(Entiers &P,Entiers &tab,const UnorientedGraph &g)
  792. {
  793. tie(neighbourIt, neighbourEnd) = adjacent_vertices(P[P.size()-1], g);
  794. for (; neighbourIt != neighbourEnd; ++neighbourIt)
  795. {
  796. if((In_tab(tab,*neighbourIt) == false ) && (In_tab(P,*neighbourIt) == false ))
  797. tab.push_back(*neighbourIt);
  798. }
  799. }
  800. int Cout_coupe(Entiers P,int val, UnorientedGraph &g)
  801. {
  802. int cpt=0;
  803. P.push_back(val);
  804. for(uint i=0;i<P.size();i++){
  805. tie(neighbourIt, neighbourEnd) = adjacent_vertices(P[i], g);
  806. for (; neighbourIt != neighbourEnd; ++neighbourIt){
  807. if(In_tab(P,*neighbourIt)!=1){
  808. cpt++;
  809. }
  810. }
  811. }
  812. return cpt;
  813. }
  814. double Cut_one_cluster(const Entiers &cluster, UnorientedGraph &g, std::string name)
  815. {
  816. if(name=="norm"){
  817. edge_t e1;
  818. bool found;
  819. double cpt=0.;
  820. for(uint i=0;i<cluster.size();i++){
  821. tie(neighbourIt, neighbourEnd) = adjacent_vertices(cluster[i], g);
  822. for (; neighbourIt != neighbourEnd; ++neighbourIt){
  823. tie(e1,found)=edge(vertex(cluster[i],g),vertex(*neighbourIt,g),g);
  824. if(In_tab(cluster,*neighbourIt)!=1){
  825. cpt+=g[e1]._weight;
  826. }
  827. }
  828. }
  829. double vol = Cluster_Degree(g,cluster);
  830. return (cpt/2.)/vol;
  831. }
  832. else{
  833. edge_t e1;
  834. bool found;
  835. double cpt=0.;
  836. for(uint i=0;i<cluster.size();i++){
  837. tie(neighbourIt, neighbourEnd) = adjacent_vertices(cluster.at(i), g);
  838. for (; neighbourIt != neighbourEnd; ++neighbourIt){
  839. tie(e1,found)=edge(vertex(cluster.at(i),g),vertex(*neighbourIt,g),g);
  840. if(In_tab(cluster,*neighbourIt)!=1){
  841. cpt+=g[e1]._weight;
  842. }
  843. }
  844. }
  845. return cpt/2.;
  846. }
  847. }
  848. double Cut_cluster(const EntiersEntiers &tab_cluster,UnorientedGraph &g,std::string name)
  849. {
  850. double cpt=0.;
  851. for(uint i=0;i<tab_cluster.size();i++){
  852. cpt+=Cut_one_cluster(*tab_cluster[i],g,name);
  853. }
  854. return cpt;
  855. }
  856. double Cout_coupe_pond(Entiers P, int val, UnorientedGraph &g)
  857. {
  858. edge_t e1;
  859. bool found;
  860. double cpt=0;
  861. P.push_back(val);
  862. for(uint i=0;i<P.size();i++){
  863. tie(neighbourIt, neighbourEnd) = adjacent_vertices(P[i], g);
  864. for (; neighbourIt != neighbourEnd; ++neighbourIt){
  865. tie(e1,found)=edge(vertex(P[i],g),vertex(*neighbourIt,g),g);
  866. if(In_tab(P,*neighbourIt)!=1){
  867. cpt+=g[e1]._weight;
  868. }
  869. }
  870. }
  871. return cpt;
  872. }
  873. int In_community_dichotomie(const EntiersEntiers &part, int val)
  874. {
  875. for (uint i = 0; i < part.size() ; i++) {
  876. if (In_tab_dichotomie(*part[i], val)) {
  877. return i;
  878. }
  879. }
  880. return -1;
  881. }
  882. double Degree(UnorientedGraph& g, int node)
  883. {
  884. edge_t e1;
  885. bool found;
  886. double val = 0.;
  887. tie(neighbourIt, neighbourEnd) = adjacent_vertices(node, g);
  888. for (; neighbourIt != neighbourEnd; ++neighbourIt) {
  889. tie(e1, found) = edge(vertex(node, g), vertex(*neighbourIt, g), g);
  890. val += g[e1]._weight;
  891. }
  892. return val;
  893. }
  894. double Cluster_Degree(UnorientedGraph &g , const Entiers &cluster)
  895. {
  896. double val = 0.;
  897. for(uint i = 0; i < cluster.size(); i++){
  898. val += Degree(g, cluster.at(i));
  899. }
  900. return val;
  901. }
  902. void List_edge_partie(Entiers *Partie, OrientedGraph *go, Edges &edge_partie,
  903. OutputEdges &outputedgespartie){
  904. edge_to e1;
  905. //bool found;
  906. for(uint i = 0; i < Partie->size(); i++) {
  907. tie(neighbourIto, neighbourEndo) = adjacent_vertices(Partie->at(i),
  908. *go);
  909. for (; neighbourIto != neighbourEndo; ++neighbourIto) {
  910. if(In_tab_dichotomie(*Partie,*neighbourIto)) {
  911. Edge new_edge;
  912. new_edge.first = Partie->at(i);
  913. new_edge.second = *neighbourIto;
  914. edge_partie.push_back(new_edge);
  915. } else {
  916. Edge new_edge;
  917. new_edge.first = Partie->at(i);
  918. new_edge.second = *neighbourIto;
  919. outputedgespartie.push_back(new_edge);
  920. }
  921. }
  922. }
  923. }
  924. void Global_Neigh_community(UnorientedGraph *g,
  925. const EntiersEntiers &Partition,
  926. Entiers *community, int vertex, int comm_in)
  927. {
  928. int comm;
  929. tie(neighbourIt, neighbourEnd) = adjacent_vertices(vertex, *g);
  930. for (; neighbourIt != neighbourEnd; ++neighbourIt){
  931. comm = In_community_dichotomie(Partition, *neighbourIt);
  932. if (In_tab(*community,comm) != 1 and comm != comm_in)
  933. community->push_back(comm);
  934. }
  935. }
  936. OrientedGraphs Graph_Partition(const EntiersEntiers& Partition,
  937. OrientedGraph *go,
  938. UnorientedGraph *g,
  939. OutputEdgeList &outputedgelist,
  940. InputEdgeList &inputedgelist,
  941. Connections &connections)
  942. {
  943. OrientedGraphs graph_partie;
  944. EntiersEntiers neigh_community;
  945. for (uint i = 0; i < Partition.size();i++){
  946. Edges edge_partie;
  947. List_edge_partie(Partition.at(i),go,edge_partie,outputedgelist.at(i));
  948. OrientedGraph graph;
  949. std::vector<vertex_to> tab_vertex_to;
  950. Entiers *community = new Entiers();
  951. for (uint j = 0; j < Partition.at(i)->size(); j++) {
  952. Global_Neigh_community(g, Partition, community,
  953. Partition.at(i)->at(j),i);
  954. vertex_to v = add_vertex(graph);
  955. tab_vertex_to.push_back(v);
  956. graph[v] = VertexProperties((*go)[Partition.at(i)->at(j)]._index,
  957. (*go)[Partition.at(i)->at(j)]._weight,
  958. (*go)[Partition.at(i)->at(j)]._type);
  959. }
  960. neigh_community.push_back(community);
  961. for(uint k = 0; k < edge_partie.size(); k++) {
  962. add_edge(tab_vertex_to.at(recherche_val(*Partition.at(i),
  963. edge_partie.at(k).first)),
  964. tab_vertex_to.at(recherche_val(*Partition.at(i),
  965. edge_partie.at(k).second)),
  966. graph);
  967. }
  968. graph_partie.push_back(graph);
  969. }
  970. for (uint i = 0; i < neigh_community.size(); i++) {
  971. InputEdges inputedges;
  972. for (uint j = 0; j < neigh_community.at(i)->size(); j++) {
  973. for (uint k = 0;
  974. k < outputedgelist.at(neigh_community.at(i)->at(j)).size();
  975. k++) {
  976. if (In_tab_dichotomie(
  977. *Partition.at(i),
  978. outputedgelist.at(
  979. neigh_community.at(i)->at(j)).at(k).second))
  980. inputedges.push_back(
  981. outputedgelist.at(
  982. neigh_community.at(i)->at(j)).at(k));
  983. }
  984. }
  985. inputedgelist.push_back(inputedges);
  986. }
  987. for (uint i = 0; i < outputedgelist.size(); i++){
  988. Connection connec;
  989. for(uint j = 0; j < outputedgelist.at(i).size(); j++){
  990. Port port1;
  991. port1.first = i + 1;
  992. port1.second = outputedgelist.at(i).at(j).first;
  993. Port port2;
  994. port2.first = In_community_dichotomie(
  995. Partition,outputedgelist.at(i).at(j).second) + 1;
  996. port2.second = outputedgelist.at(i).at(j).second;
  997. connec.first = port1;
  998. connec.second = port2;
  999. connections.push_back(connec);
  1000. }
  1001. }
  1002. for (EntiersEntiers::iterator it = neigh_community.begin();
  1003. it != neigh_community.end(); it++) {
  1004. delete *it;
  1005. *it = NULL;
  1006. }
  1007. return graph_partie;
  1008. }
  1009. /*double In_modularity(UnorientedGraph &g , const Entiers &cluster){
  1010. property_map<UnorientedGraph,edge_weight_t>::type poids_arc=get(edge_weight_t(),g);
  1011. edge_t e1;
  1012. bool found;
  1013. int val=0;
  1014. for(uint i=0;i<cluster.size();i++){
  1015. tie(neighbourIt, neighbourEnd) = adjacent_vertices(cluster[i],g);
  1016. for (; neighbourIt != neighbourEnd; ++neighbourIt){
  1017. tie(e1,found)=edge(vertex(cluster[i],g),vertex(*neighbourIt,g),g);
  1018. if(In_tab(cluster,*neighbourIt)==1)
  1019. val+=get(poids_arc,e1);
  1020. }
  1021. }
  1022. return val/2.;
  1023. }*/
  1024. /**
  1025. *
  1026. * @param g
  1027. * @param cluster
  1028. * @return
  1029. */
  1030. /**
  1031. *
  1032. * @param g
  1033. * @param part
  1034. * @return
  1035. */
  1036. /*double Modularity(UnorientedGraph &g,const EntiersEntiers &part) {
  1037. double q = 0.;
  1038. int tmp=num_edges(g);
  1039. for(uint i=0;i<part.size();i++){
  1040. q+=In_modularity(g,*part[i])/tmp-(Cluster_Degree(g,*part[i])/(2*tmp))*(Cluster_Degree(g,*part[i])/(2*tmp));
  1041. }
  1042. return q;
  1043. }*/
  1044. /**
  1045. *
  1046. * @param part
  1047. * @param val
  1048. * @return
  1049. */
  1050. /**
  1051. * Fonction de calcul du gain de modularité de déplacement d'un sommet d'une communoté à une autre !!!!!
  1052. * ajoute le sommet à part[val] et on calcul la nouvelle modularité
  1053. * on prend la différence entre la modularité et la nouvouvelle !
  1054. * @param cur_mod
  1055. * @param val
  1056. * @param neight
  1057. * @param node_comm
  1058. * @param part
  1059. * @param g
  1060. */
  1061. /*double Modularity_gain(double cur_mod , int val , int neight , int node_comm , EntiersEntiers part , UnorientedGraph &g) {
  1062. double q;
  1063. part[neight]->push_back(val);
  1064. std::sort(*part[neight]);
  1065. q=Modularity(g,part);
  1066. return q-cur_mod;
  1067. }*/
  1068. /**
  1069. * Fonction de calcul du gain de modularité de déplacement d'un sommet d'une communoté à une autre !!!!!
  1070. * ajoute le sommet à part[val] et on calcul la nouvelle modularité
  1071. * on prend la différence entre la modularité et la nouvouvelle !
  1072. * @param cur_mod
  1073. * @param tmp_community
  1074. * @param neight
  1075. * @param node_comm
  1076. * @param part
  1077. * @param g
  1078. */
  1079. /*double Modularity_gain_phase_2(double cur_mod, Entiers tmp_community, int neight, int node_comm, EntiersEntiers part, UnorientedGraph &g) {
  1080. double q;
  1081. for (uint i=0;i<tmp_community.size();i++)
  1082. part[neight]->push_back(tmp_community[i]);
  1083. std::sort(*part[neight]);
  1084. q = Modularity(g,part);
  1085. return q - cur_mod;
  1086. }*/
  1087. /**
  1088. * Donne la liste des communautés voisines à celle contenant le sommet val.
  1089. * @param part
  1090. * @param val
  1091. * @param g
  1092. * @return
  1093. */
  1094. /*Entiers Neight_community(const EntiersEntiers &part, int val , UnorientedGraph &g){
  1095. Entiers Neight;
  1096. tie(neighbourIt, neighbourEnd) = adjacent_vertices(val, g);
  1097. for (; neighbourIt != neighbourEnd; ++neighbourIt){
  1098. int tmp=In_community(part,*neighbourIt);
  1099. if(In_tab(Neight,tmp)!=1 && In_tab(*part[In_community(part,val)],*neighbourIt)!=1)
  1100. Neight.push_back(tmp);
  1101. }
  1102. std::sort(Neight);
  1103. return Neight;
  1104. }*/
  1105. /**
  1106. *
  1107. * @param part
  1108. * @param community
  1109. * @param g
  1110. * @return
  1111. */
  1112. /*Entiers Part_Neight_community(const EntiersEntiers &part,int community, UnorientedGraph &g){
  1113. Entiers Neight;
  1114. for(uint i =0;i<part[community]->size();i++){
  1115. tie(neighbourIt, neighbourEnd) = adjacent_vertices(part[community]->at(i), g);
  1116. for (; neighbourIt != neighbourEnd; ++neighbourIt){
  1117. int tmp=In_community(part,*neighbourIt);
  1118. if(In_tab(Neight,tmp)!=1 && tmp!=community)
  1119. Neight.push_back(tmp);
  1120. }
  1121. }
  1122. std::sort(Neight);
  1123. return Neight;
  1124. }*/
  1125. } } } // namespace paradevs tests boost_graph