utils.cpp 54 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588
  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. }
  308. else
  309. {
  310. poids_parties = new_poids_parties;
  311. decision = true;
  312. // std::cout<<" Modification reussi ! "<<std::endl;
  313. }
  314. }
  315. }
  316. nbr_pass_interne++;
  317. }
  318. /*
  319. * Si aucune modification n'a été réalisé pour cett partie de poids maximum
  320. */
  321. if(decision==false)
  322. {
  323. nbr_passage++; // augmentation du nombre de passage
  324. poids_parties.at(cpt)=-1; // vérrouillage de la partie
  325. std::clog<<"nouveau passag ! "<<std::endl;
  326. }
  327. else
  328. {
  329. best_critere = 0.;
  330. for(uint i = 0; i<poids_parties.size();i++){
  331. best_critere += abs(poids_parties.at(i)-poids_moyen);
  332. }
  333. best_critere/=Partition.size();
  334. nbr_passage = 0;
  335. }
  336. // std::clog<<"Poids des parties modifié : "<<std::endl;
  337. // for(uint i = 0; i<poids_parties.size(); i++){
  338. // std::cout<<poids_parties.at(i)<<" ";
  339. // }
  340. // std::cout<<"\n"<<std::endl;
  341. p_max = *max_element(poids_parties.begin(),poids_parties.end());
  342. // std::cout<<"Valeurs du criètre : "<<critere<<std::endl;
  343. // std::cout<<"Valeurs du best_criètre : "<<best_critere<<std::endl;
  344. // std::cout<<"Nombre de passage : "<<nbr_passage<<std::endl;
  345. // std::cout<<"\n"<<std::endl;
  346. }
  347. }
  348. Entiers Neigh_community(UnorientedGraph *g, EntiersEntiers &Partition, int vertex, int comm_in)
  349. {
  350. Entiers community;
  351. int comm;
  352. tie(neighbourIt, neighbourEnd) = adjacent_vertices(vertex,*g);
  353. for (; neighbourIt != neighbourEnd; ++neighbourIt){
  354. comm = In_community_dichotomie(Partition,*neighbourIt);
  355. if(In_tab(community,comm)!=1 && comm!=comm_in)
  356. community.push_back(comm);
  357. }
  358. return community;
  359. }
  360. void Affinage_recherche_locale(UnorientedGraph *g, EntiersEntiers &Partition, double &cut, std::string name)
  361. {
  362. Entiers random_orders(num_vertices(*g)); //gestion d'un tableau contenant tout les sommets et ranger de façon aléatoire
  363. for (uint i=0 ; i<num_vertices(*g) ; i++)
  364. random_orders.at(i)=i;
  365. for (uint j=0 ; j<num_vertices(*g)-1 ; j++) {
  366. int rand_pos = (rand() % num_vertices(*g)-j)+j;
  367. int tmp = random_orders[j];
  368. random_orders[j] = random_orders[rand_pos];
  369. random_orders[rand_pos] = tmp;
  370. }
  371. uint size = random_orders.size();
  372. if(num_vertices(*g)>500)
  373. size=500;
  374. std::vector<std::vector<double> > tabe_cut;
  375. //std::cout<<"Passage : "<<Partition.size()<<std::endl;
  376. for(uint k = 0; k < Partition.size();k++){
  377. std::vector<double> tmp;
  378. double vol = 0.;
  379. double cut = Modif_Cut_one_cluster(*Partition.at(k), *g, vol);
  380. tmp.push_back(cut);
  381. tmp.push_back(vol);
  382. tabe_cut.push_back(tmp);
  383. }
  384. for(uint i = 0; i < size; i++){
  385. if(random_orders.at(i)!=-1){
  386. int vertex = random_orders.at(i);
  387. //std::cout<<vertex<<std::endl;
  388. int comm = In_community_dichotomie(Partition, vertex);
  389. Entiers community = Neigh_community(g,Partition,vertex,comm);
  390. std::vector<double> tmp_cut;
  391. if(community.size()!=0 && Partition.at(comm)->size()!=1){
  392. tmp_cut = modif_cut_tmp(g,Partition,tabe_cut,vertex,comm,community,cut,name);
  393. /*for(uint z = 0; z<tmp_cut.size(); z++){
  394. std::cout<<tmp_cut.at(z)<<std::endl;
  395. }
  396. std::cout<<"\n"<<std::endl;*/
  397. double cut_min = *min_element(tmp_cut.begin(),tmp_cut.end());
  398. //std::cout<<"cout de coupe minimum de la liste : "<<cut_min<<std::endl;
  399. if(cut_min<cut){
  400. // std::clog<<"Changement ! "<<std::endl;
  401. int tmp = recherche_val_double(tmp_cut,cut_min);
  402. cut=cut_min;
  403. Partition.at(community.at(tmp))->push_back(vertex);
  404. suprim_val(*Partition.at(comm),vertex);
  405. std::sort(Partition.at(community.at(tmp))->begin(), Partition.at(community.at(tmp))->end());
  406. tabe_cut.clear();
  407. for(uint k = 0; k < Partition.size();k++){
  408. std::vector<double> tmp;
  409. double vol = 0.;
  410. double cut = Modif_Cut_one_cluster(*Partition.at(k), *g, vol);
  411. tmp.push_back(cut);
  412. tmp.push_back(vol);
  413. tabe_cut.push_back(tmp);
  414. }
  415. }
  416. }
  417. //Modif_fonction_Gain_Cut(Partition,g,community,vertex,cut,name);
  418. /*if(Est_connexe(g,Partition,*Partition.at(comm))!=1)
  419. {
  420. suprim_val(*Partition.at(community.at(tmp)),vertex);
  421. Partition.at(comm)->push_back(vertex);
  422. std::sort(*Partition.at(comm));
  423. std::cout<<" C'EST MORT RETOUR EN ARRIERE ! "<<std::endl;
  424. }*/
  425. }
  426. }
  427. }
  428. double Modif_Cut_one_cluster(Entiers &cluster, UnorientedGraph &g, double &vol)
  429. {
  430. edge_t e1;
  431. bool found;
  432. double cpt=0.;
  433. for(uint i=0;i<cluster.size();i++){
  434. tie(neighbourIt, neighbourEnd) = adjacent_vertices(cluster.at(i), g);
  435. for (; neighbourIt != neighbourEnd; ++neighbourIt){
  436. tie(e1,found)=edge(vertex(cluster[i],g),vertex(*neighbourIt,g),g);
  437. if(In_tab(cluster,*neighbourIt)!=1){
  438. cpt+=g[e1]._weight;
  439. }
  440. }
  441. }
  442. vol = Cluster_Degree(g,cluster);
  443. return cpt/2.;
  444. }
  445. 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){
  446. edge_t e1;
  447. bool found;
  448. //std::cout<<"le sommet tiré est : "<<vertexs<<std::endl;
  449. if(name!="norm")
  450. {
  451. std::vector<double> modif_cut(community.size());
  452. double cpt_comm_in;
  453. double cpt_comm_out;
  454. for(uint i =0; i<community.size(); i++){
  455. double tmp_cut = cut;
  456. cpt_comm_in=0;
  457. cpt_comm_out=0;
  458. tie(neighbourIt, neighbourEnd) = adjacent_vertices(vertexs,*g);
  459. for (; neighbourIt != neighbourEnd; ++neighbourIt){
  460. tie(e1,found)=edge(vertex(vertexs,*g),vertex(*neighbourIt,*g),*g);
  461. if(In_tab(*Partition.at(comm_in),*neighbourIt)==1)
  462. cpt_comm_in+=(*g)[e1]._weight;
  463. else if(In_tab(*Partition.at(community.at(i)),*neighbourIt)==1)
  464. cpt_comm_out+=(*g)[e1]._weight;
  465. }
  466. tmp_cut+=cpt_comm_in;
  467. tmp_cut-=cpt_comm_out;
  468. modif_cut.at(i)=tmp_cut;
  469. }
  470. return modif_cut;
  471. }
  472. else{
  473. std::vector<double> modif_cut(community.size());
  474. double cpt_comm_in;
  475. double cpt_comm_out;
  476. double tmp_cut;
  477. for(uint i =0; i<community.size(); i++){
  478. std::vector<std::vector<double> > tab_cut = tabe_cut;
  479. tmp_cut =0.;
  480. cpt_comm_in=0.;
  481. cpt_comm_out=0.;
  482. tie(neighbourIt, neighbourEnd) = adjacent_vertices(vertexs,*g);
  483. for (; neighbourIt != neighbourEnd; ++neighbourIt){
  484. tie(e1,found)=edge(vertex(vertexs,*g),vertex(*neighbourIt,*g),*g);
  485. if(In_tab(*Partition.at(comm_in),*neighbourIt)==1)
  486. cpt_comm_in+=(*g)[e1]._weight;
  487. else if(In_tab(*Partition.at(community.at(i)),*neighbourIt)==1)
  488. cpt_comm_out+=(*g)[e1]._weight;
  489. }
  490. cpt_comm_in/=2.;
  491. cpt_comm_out/=2.;
  492. tab_cut.at(comm_in).at(0)+=cpt_comm_in;
  493. tab_cut.at(comm_in).at(0)-=cpt_comm_out;
  494. tab_cut.at(comm_in).at(1)-= Degree(*g ,vertexs);
  495. tab_cut.at(community.at(i)).at(0)+=cpt_comm_in;
  496. tab_cut.at(community.at(i)).at(0)-=cpt_comm_out;
  497. tab_cut.at(community.at(i)).at(1)+= Degree(*g ,vertexs);
  498. for(uint j = 0; j < tab_cut.size();j++){
  499. tmp_cut+=((tab_cut.at(j).at(0))/(tab_cut.at(j).at(1)));
  500. }
  501. modif_cut.at(i)=tmp_cut;
  502. }
  503. return modif_cut;
  504. }
  505. }
  506. void Modif_fonction_Gain_Cut(EntiersEntiers &Partition,UnorientedGraph *g, Entiers &community, int val, double &cut,std::string name)
  507. {
  508. /*std::cout<<"Nombre de communauté voisine : "<<community.size()<<std::endl;
  509. std::cout<<"\n"<<std::endl;*/
  510. for(uint i = 0; i<community.size();i++){
  511. EntiersEntiers new_partition;
  512. for(uint k = 0; k < Partition.size();k++){
  513. Entiers * tmp = new Entiers();
  514. for(uint j = 0;j<Partition.at(k)->size();j++){
  515. tmp->push_back(Partition.at(k)->at(j));
  516. }
  517. new_partition.push_back(tmp);
  518. }
  519. /*std::cout<<"Avant Modification partition"<<std::endl;
  520. std::cout<<"************"<<std::endl;
  521. for(uint t = 0; t< new_partition.size() ; t++)
  522. {
  523. for(uint j = 0 ; j<new_partition.at(t)->size() ; j++)
  524. {
  525. std::cout<<new_partition.at(t)->at(j)<<std::endl;
  526. }
  527. std::cout<<"\n"<<std::endl;
  528. }
  529. std::cout<<"************"<<std::endl;*/
  530. new_partition.at(community.at(i))->push_back(val);
  531. suprim_val(*new_partition.at(In_community_dichotomie(Partition,val)),val);
  532. std::sort(new_partition.at(community.at(i))->begin(),
  533. new_partition.at(community.at(i))->end());
  534. /*std::cout<<"Modification partition"<<std::endl;
  535. std::cout<<"************"<<std::endl;
  536. for(uint t= 0; t< new_partition.size() ; t++)
  537. {
  538. for(uint j = 0 ; j<new_partition.at(t)->size() ; j++)
  539. {
  540. std::cout<<new_partition.at(t)->at(j)<<std::endl;
  541. }
  542. std::cout<<"\n"<<std::endl;
  543. }
  544. std::cout<<"************"<<std::endl;*/
  545. double coupe = Cut_cluster(new_partition,*g,name);
  546. //std::cout<<"cout de coupe : "<<coupe<<std::endl;
  547. if(coupe<cut)
  548. {
  549. for(EntiersEntiers::iterator it = Partition.begin(); it != Partition.end(); it++)
  550. {
  551. delete *it;
  552. *it = NULL;
  553. }
  554. Partition = new_partition;
  555. cut = coupe;
  556. }
  557. else
  558. {
  559. for(EntiersEntiers::iterator it = new_partition.begin(); it != new_partition.end(); it++)
  560. {
  561. delete *it;
  562. *it = NULL;
  563. }
  564. }
  565. }
  566. }
  567. bool contraction_HEM(UnorientedGraph *g, Base_Graph &baseg, ListEntiersEntiers &liste_corr, int val_reduc, int &val_cpt){
  568. UnorientedGraph *gtmp = new UnorientedGraph();
  569. *gtmp=*g;
  570. Entiers Random_list_vertices; // Initialisation du tableau de sommets rangés aléatoirements
  571. EntiersEntiers *tableau_de_correspondance = new EntiersEntiers();
  572. edge_t e1,e2; // Iterateurs sur les arcs
  573. bool found;
  574. uint nbr_vertex = num_vertices(*gtmp);
  575. Entiers sommets_a_detruire; // Initialisation d'un tableau pret à recevoir les "sommets à détruire"
  576. /*
  577. * Création d'un vecteur contenant l'ensemble des sommets du graphe. Ces sommets sont rangés
  578. * aléatoirement afin de simuler un tirage aléatoire
  579. */
  580. for (uint i=0 ; i<nbr_vertex ; i++)
  581. Random_list_vertices.push_back(i);
  582. for (uint j=0 ; j<nbr_vertex-1 ; j++) {
  583. int rand_pos = rand()%(nbr_vertex-j)+j;
  584. int tmp = Random_list_vertices[j];
  585. Random_list_vertices[j] = Random_list_vertices[rand_pos];
  586. Random_list_vertices[rand_pos] = tmp;
  587. }
  588. /*
  589. * Pour chaque sommet non verrouiller faire ....
  590. */
  591. for(uint i=0; i<nbr_vertex; i++){
  592. int vertexs = Random_list_vertices[i];
  593. //std::cout<<"Le sommet tiré est : "<<vertexs<<std::endl;
  594. if(vertexs!=-1){
  595. Entiers liste_voisin = Liste_adjacence(*gtmp,vertexs,Random_list_vertices); // Recherche des sommets adjacents au sommets tiré
  596. if(liste_voisin.size()!=0){
  597. /*
  598. * S'il en existe au mois un sommet adjacent au sommet tiré qui n'est pas verrouillé, on
  599. * choisi celui dont l'arc les reliants est le plus fort. Dans le cas où les arcs ont tous
  600. * le même poids, on selectionne le sommet d'identifiant le plus petit
  601. */
  602. double poids_a = 0.;
  603. int best_vertexs = -1;
  604. for(uint j=0;j<liste_voisin.size();j++){
  605. tie(e1,found)=edge(vertex(vertexs,*gtmp),vertex(liste_voisin[j],*gtmp),*gtmp);
  606. if((*gtmp)[e1]._weight>poids_a){
  607. best_vertexs = liste_voisin[j];
  608. poids_a = (*gtmp)[e1]._weight;
  609. }
  610. }
  611. Entiers * couple = new Entiers(); // Initialisation du vecteur contenant le couple de sommet fusionné
  612. int vertex_delete = std::max(vertexs, best_vertexs); // Sommet d'indentifiant le plus grand (qui sera détruit)
  613. //std::cout<<"sommet détruit : "<<vertex_delete<<std::endl;
  614. int vertex_save = std::min(vertexs,best_vertexs); // Sommet d'identifiant le plus petit (qui sera conservé)
  615. //std::cout<<"sommet sauvé : "<<vertex_save<<std::endl;
  616. sommets_a_detruire.push_back(vertex_delete); // On ajoute le sommet détruit au tableau des sommets à détruire
  617. /*
  618. * On ajoute au tableau "couple" le couple de sommet à fusionner
  619. */
  620. couple->push_back(vertex_save);
  621. couple->push_back(vertex_delete);
  622. tableau_de_correspondance->push_back(couple); // Ajout du "couple" à la liste de correspondance
  623. remove_edge(vertex_save,vertex_delete,*gtmp); // Suppression de l'arc reliant le couple de sommets
  624. Entiers neigh_vertex_save; // Initialisation du vecteur contenant les sommets adjacents au "sommet sauvegardé"
  625. Entiers neigh_vertex_delete; // Initialisation du vecteur contenant les somemts adjacents au "sommet à détruire"
  626. tie(neighbourIt, neighbourEnd) = adjacent_vertices(vertex_save,*gtmp);
  627. /*
  628. * Remplissage de ces deux tableaux à l'aide de la fonction adjacent_vertices de boost graph
  629. * [La création de ces tableaux est nécéssaire du fait que certains arcs sont détruit au cours
  630. * du processus]
  631. */
  632. for (; neighbourIt != neighbourEnd; ++neighbourIt){
  633. neigh_vertex_save.push_back(*neighbourIt);
  634. }
  635. tie(neighbourIt, neighbourEnd) = adjacent_vertices(vertex_delete,*gtmp);
  636. for (; neighbourIt != neighbourEnd; ++neighbourIt){
  637. neigh_vertex_delete.push_back(*neighbourIt);
  638. }
  639. /*
  640. * Recherche de sommets communs entre le "sommet sauvegardé" et le "sommet à détruire"
  641. * S'il existe un tel sommet "v" alors on ajoute le poids de l'arcs (vertex_delet,v)
  642. * à celui de l'arcs (vertex_save,v) et on détruit l'arcs reliant "v" au "sommet à détruire"
  643. */
  644. for(uint j=0;j<neigh_vertex_delete.size();j++){
  645. if(In_tab(neigh_vertex_save,neigh_vertex_delete[j])==1){
  646. tie(e2,found)=edge(vertex(vertex_save,*gtmp),vertex(neigh_vertex_delete[j],*gtmp),*gtmp);
  647. tie(e1,found)=edge(vertex(vertex_delete,*gtmp),vertex(neigh_vertex_delete[j],*gtmp),*gtmp);
  648. (*gtmp)[e2]._weight+=(*gtmp)[e1]._weight;
  649. remove_edge(vertex_delete,neigh_vertex_delete[j],*gtmp);
  650. }
  651. else
  652. {
  653. tie(e1,found)=edge(vertex(vertex_delete,*gtmp),vertex(neigh_vertex_delete[j],*gtmp),*gtmp);
  654. add_edge(vertex_save,neigh_vertex_delete[j],EdgeProperties((*gtmp)[e1]._weight),*gtmp);
  655. remove_edge(vertex_delete,neigh_vertex_delete[j],*gtmp);
  656. }
  657. }
  658. (*gtmp)[vertex_save]._weight+=(*gtmp)[vertex_delete]._weight; // ajout du poids du sommet détruit au sommet conservé
  659. /*
  660. * Vérouillage du "sommet sauvegardé" et du "sommet à détruire"
  661. */
  662. Random_list_vertices[i]=-1;
  663. Random_list_vertices[recherche_val(Random_list_vertices,best_vertexs)]=-1;
  664. val_cpt--;
  665. // std::cout<<val_cpt<<std::endl;
  666. }
  667. else{
  668. /*
  669. * Et si le sommet tiré ne possède pas de sommet adjacent non verrouillé
  670. * alors on l'ajoute à la liste de correspondance des sommets et on
  671. * le verrouille
  672. */
  673. Entiers *couple = new Entiers();
  674. couple->push_back(Random_list_vertices.at(i));
  675. tableau_de_correspondance->push_back(couple);
  676. Random_list_vertices[i]=-1;
  677. }
  678. /*std::cout<<"Graphe contracté : "<<std::endl;
  679. tie(vertexIt, vertexEnd) = vertices(*gtmp);
  680. for (; vertexIt != vertexEnd; ++vertexIt) {
  681. std::cout << (*gtmp)[*vertexIt]._index
  682. << " est connecté avec ";
  683. tie(neighbourIt, neighbourEnd) = adjacent_vertices(*vertexIt,
  684. *gtmp);
  685. for (; neighbourIt != neighbourEnd; ++neighbourIt)
  686. std::cout << (*gtmp)[*neighbourIt]._index << " ";
  687. std::cout << " et son poids est de "
  688. << (*gtmp)[*vertexIt]._weight<<std::endl;
  689. }
  690. std::cout << std::endl;*/
  691. }
  692. if(val_cpt == val_reduc){
  693. for(uint j=i+1; j <nbr_vertex; j++){
  694. if(Random_list_vertices[j] !=-1){
  695. Entiers *couple = new Entiers();
  696. couple->push_back(Random_list_vertices.at(j));
  697. tableau_de_correspondance->push_back(couple);}
  698. }
  699. break;
  700. }
  701. }
  702. std::sort(sommets_a_detruire.begin(), sommets_a_detruire.end()); // Trie dans l'ordre croissant des "sommets à détruire"
  703. // std::cout<<"\n"<<std::endl;
  704. /*
  705. * Suppression des sommets de la liste "sommets à détruire". Cette suppression est
  706. * effectuée dans l'ordre décroissant afin à maintenir à jour la renumérotation
  707. * des sommets
  708. */
  709. for(int j=(sommets_a_detruire.size()-1);j>-1;j--){
  710. //std::cout<<"Noeuds a supprimer : "<<sommets_a_detruire.at(j)<<std::endl;
  711. remove_vertex(sommets_a_detruire[j],*gtmp);
  712. }
  713. // std::clog<<"Affichage avant tri "<<std::endl;
  714. // for(uint k = 0;k<tableau_de_correspondance->size();k++){
  715. // for(uint v = 0; v<tableau_de_correspondance->at(k)->size();v++){
  716. // std::cout<<tableau_de_correspondance->at(k)->at(v)<<" ";
  717. // }
  718. // std::cout<<"\n"<<std::endl;
  719. // }
  720. 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
  721. // std::clog<<"Tableau de correspondance "<<std::endl;
  722. // for(uint k = 0;k<tableau_de_correspondance->size();k++){
  723. // for(uint v = 0; v<tableau_de_correspondance->at(k)->size();v++){
  724. // std::cout<<tableau_de_correspondance->at(k)->at(v)<<" ";
  725. // }
  726. // std::cout<<"\n"<<std::endl;
  727. // }
  728. liste_corr.push_back(tableau_de_correspondance);
  729. // std::cout<<"\n"<<std::endl;
  730. baseg.push_back(gtmp); // Ajout du graphe modifié à la "base des graphe"
  731. if(val_cpt == val_reduc)
  732. return true;
  733. else
  734. return false;
  735. }
  736. bool contraction_Random_Maching(UnorientedGraph *g, Base_Graph &baseg, ListEntiersEntiers &liste_corr, int val_reduc, int &val_cpt){
  737. UnorientedGraph *gtmp = new UnorientedGraph();
  738. *gtmp=*g;
  739. Entiers Random_list_vertices; // Initialisation du tableau de sommets rangés aléatoirements
  740. EntiersEntiers *tableau_de_correspondance = new EntiersEntiers();
  741. edge_t e1,e2; // Iterateurs sur les arcs
  742. bool found;
  743. uint nbr_vertex = num_vertices(*gtmp);
  744. Entiers sommets_a_detruire; // Initialisation d'un tableau pret à recevoir les "sommets à détruire"
  745. /*
  746. * Création d'un vecteur contenant l'ensemble des sommets du graphe. Ces sommets sont rangés
  747. * aléatoirement afin de simuler un tirage aléatoire
  748. */
  749. for (uint i=0 ; i<nbr_vertex ; i++)
  750. Random_list_vertices.push_back(i);
  751. for (uint j=0 ; j<nbr_vertex-1 ; j++) {
  752. int rand_pos = rand()%(nbr_vertex-j)+j;
  753. int tmp = Random_list_vertices[j];
  754. Random_list_vertices[j] = Random_list_vertices[rand_pos];
  755. Random_list_vertices[rand_pos] = tmp;
  756. }
  757. /*
  758. * Pour chaque sommet non verrouiller faire ....
  759. */
  760. for(uint i=0; i<nbr_vertex; i++){
  761. int vertexs = Random_list_vertices[i];
  762. if(vertexs!=-1){
  763. Entiers liste_voisin = Liste_adjacence(*gtmp,vertexs,Random_list_vertices); // Recherche des sommets adjacents au sommets tiré
  764. if(liste_voisin.size()!=0){
  765. /*
  766. * S'il en existe au mois un sommet adjacent au sommet tiré qui n'est pas verrouillé, on
  767. * choisi celui dont l'arc les reliants est le plus fort. Dans le cas où les arcs ont tous
  768. * le même poids, on selectionne le sommet d'identifiant le plus petit
  769. */
  770. int tmp;
  771. if(liste_voisin.size()==1)
  772. tmp = 0;
  773. else
  774. tmp = rand_fini(0,liste_voisin.size()-1);
  775. int best_vertexs = liste_voisin.at(tmp);
  776. Entiers * couple = new Entiers(); // Initialisation du vecteur contenant le couple de sommet fusionné
  777. int vertex_delete = std::max(vertexs, best_vertexs); // Sommet d'indentifiant le plus grand (qui sera détruit)
  778. //std::cout<<"sommet détruit : "<<vertex_delete<<std::endl;
  779. int vertex_save = std::min(vertexs,best_vertexs); // Sommet d'identifiant le plus petit (qui sera conservé)
  780. //std::cout<<"sommet sauvé : "<<vertex_save<<std::endl;
  781. sommets_a_detruire.push_back(vertex_delete); // On ajoute le sommet détruit au tableau des sommets à détruire
  782. /*
  783. * On ajoute au tableau "couple" le couple de sommet à fusionner
  784. */
  785. couple->push_back(vertex_save);
  786. couple->push_back(vertex_delete);
  787. tableau_de_correspondance->push_back(couple); // Ajout du "couple" à la liste de correspondance
  788. remove_edge(vertex_save,vertex_delete,*gtmp); // Suppression de l'arc reliant le couple de sommets
  789. Entiers neigh_vertex_save; // Initialisation du vecteur contenant les somemts adjacents au "sommet sauvegardé"
  790. Entiers neigh_vertex_delete; // Initialisation du vecteur contenant les somemts adjacents au "sommet à détruire"
  791. tie(neighbourIt, neighbourEnd) = adjacent_vertices(vertex_save,*gtmp);
  792. /*
  793. * Remplissage de ces deux tableaux à l'aide de la fonction adjacent_vertices de boost graph
  794. * [La création de ces tableaux est nécéssaire du fait que certains arcs sont détruit au cours
  795. * du processus]
  796. */
  797. for (; neighbourIt != neighbourEnd; ++neighbourIt){
  798. neigh_vertex_save.push_back(*neighbourIt);
  799. }
  800. tie(neighbourIt, neighbourEnd) = adjacent_vertices(vertex_delete,*gtmp);
  801. for (; neighbourIt != neighbourEnd; ++neighbourIt){
  802. neigh_vertex_delete.push_back(*neighbourIt);
  803. }
  804. /*
  805. * Recherche de sommets communs entre le "sommet sauvegardé" et le "sommet à détruire"
  806. * S'il existe un tel sommet "v" alors on ajoute le poids de l'arcs (vertex_delet,v)
  807. * à celui de l'arcs (vertex_save,v) et on détruit l'arcs reliant "v" au "sommet à détruire"
  808. */
  809. for(uint j=0;j<neigh_vertex_delete.size();j++){
  810. if(In_tab(neigh_vertex_save,neigh_vertex_delete[j])==1){
  811. tie(e2,found)=edge(vertex(vertex_save,*gtmp),vertex(neigh_vertex_delete[j],*gtmp),*gtmp);
  812. tie(e1,found)=edge(vertex(vertex_delete,*gtmp),vertex(neigh_vertex_delete[j],*gtmp),*gtmp);
  813. (*gtmp)[e2]._weight+=(*gtmp)[e1]._weight;
  814. remove_edge(vertex_delete,neigh_vertex_delete[j],*gtmp);
  815. }
  816. else
  817. {
  818. tie(e1,found)=edge(vertex(vertex_delete,*gtmp),vertex(neigh_vertex_delete[j],*gtmp),*gtmp);
  819. add_edge(vertex_save,neigh_vertex_delete[j],EdgeProperties((*gtmp)[e1]._weight),*gtmp);
  820. remove_edge(vertex_delete,neigh_vertex_delete[j],*gtmp);
  821. }
  822. }
  823. (*gtmp)[vertex_save]._weight+=(*gtmp)[vertex_delete]._weight; // ajout du poids du sommet détruit au sommet conservé
  824. /*
  825. * Vérouillage du "sommet sauvegardé" et du "sommet à détruire"
  826. */
  827. Random_list_vertices[i]=-1;
  828. Random_list_vertices[recherche_val(Random_list_vertices,best_vertexs)]=-1;
  829. val_cpt--;
  830. // std::cout<<val_cpt<<std::endl;
  831. }
  832. else{
  833. /*
  834. * Et si le sommet tiré ne possède pas de sommet adjacent non verrouillé
  835. * alors on l'ajoute à la liste de correspondance des sommets et on
  836. * le verrouille
  837. */
  838. Entiers *couple = new Entiers();
  839. couple->push_back(Random_list_vertices.at(i));
  840. tableau_de_correspondance->push_back(couple);
  841. Random_list_vertices[i]=-1;
  842. }
  843. }
  844. if(val_cpt == val_reduc){
  845. for(uint j=i+1; j <nbr_vertex; j++){
  846. if(Random_list_vertices[j] !=-1){
  847. Entiers *couple = new Entiers();
  848. couple->push_back(Random_list_vertices.at(j));
  849. tableau_de_correspondance->push_back(couple);}
  850. }
  851. break;
  852. }
  853. }
  854. std::sort(sommets_a_detruire.begin(), sommets_a_detruire.end()); // Trie dans l'ordre croissant des "sommets à détruire"
  855. //std::cout<<"\n"<<std::endl;
  856. /*
  857. * Suppression des sommets de la liste "sommets à détruire". Cette suppression est
  858. * effectuée dans l'ordre décroissant afin à maintenir à jour la renumérotation
  859. * des sommets
  860. */
  861. for(int j=(sommets_a_detruire.size()-1);j>-1;j--){
  862. //std::cout<<"Noeuds a supprimer : "<<sommets_a_detruire.at(j)<<std::endl;
  863. remove_vertex(sommets_a_detruire[j],*gtmp);
  864. }
  865. /**std::clog<<"Affichage avant tri "<<std::endl;
  866. for(uint k = 0;k<tableau_de_correspondance->size();k++){
  867. for(uint v = 0; v<tableau_de_correspondance->at(k)->size();v++){
  868. std::cout<<tableau_de_correspondance->at(k)->at(v)<<" ";
  869. }
  870. std::cout<<"\n"<<std::endl;
  871. }*/
  872. 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
  873. // std::clog<<"Tableau de correspondance "<<std::endl;
  874. // for(uint k = 0;k<tableau_de_correspondance->size();k++){
  875. // for(uint v = 0; v<tableau_de_correspondance->at(k)->size();v++){
  876. // std::cout<<tableau_de_correspondance->at(k)->at(v)<<" ";
  877. // }
  878. // std::cout<<"\n"<<std::endl;
  879. // }
  880. liste_corr.push_back(tableau_de_correspondance);
  881. // std::cout<<"\n"<<std::endl;
  882. baseg.push_back(gtmp); // Ajout du graphe modifié à la "base des graphe"
  883. if(val_cpt == val_reduc)
  884. return true;
  885. else
  886. return false;
  887. }
  888. Entiers Liste_adjacence(UnorientedGraph &g, int vertexs,const Entiers &random_vertices){ // a revoir !!!!
  889. Entiers liste_voisin;
  890. tie(neighbourIt, neighbourEnd) = adjacent_vertices(vertexs, g);
  891. for (; neighbourIt != neighbourEnd; ++neighbourIt){
  892. if(In_tab(random_vertices,*neighbourIt)==1)
  893. liste_voisin.push_back(*neighbourIt);
  894. }
  895. return liste_voisin;
  896. }
  897. int rand_fini(int a, int b){
  898. return rand()%(b-a)+a;
  899. }
  900. /**
  901. * Fonction de recherche d'une valeur dans un tableau.
  902. * @param tab
  903. * @param val
  904. * @return
  905. */
  906. int recherche_val2(const std::vector<float> &tab,float val){
  907. int cpt=0;
  908. while(tab[cpt]!=val)
  909. cpt++;
  910. return cpt;
  911. }
  912. int recherche_val_double(const std::vector<double> &tab,double val){
  913. int cpt=0;
  914. while(tab[cpt]!=val)
  915. cpt++;
  916. return cpt;
  917. }
  918. int recherche_val(const Entiers &tab,int val){
  919. int cpt=0;
  920. while(tab[cpt]!=val)
  921. cpt++;
  922. return cpt;
  923. }
  924. /**
  925. * @param tab
  926. * @param i
  927. * @return
  928. */
  929. int dichotomie(const Entiers &tab, int i){
  930. /* déclaration des variables locales à la fonction */
  931. int id; //indice de début
  932. int ifin; //indice de fin
  933. int im; //indice de "milieu"
  934. /* initialisation de ces variables avant la boucle de recherche */
  935. id = 0; //intervalle de recherche compris entre 0...
  936. ifin = tab.size(); //...et nbVal
  937. /* boucle de recherche */
  938. while ((ifin - id) > 1){
  939. im = (id + ifin)/2; //on détermine l'indice de milieu
  940. 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
  941. 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
  942. }
  943. /* test conditionnant la valeur que la fonction va renvoyer */
  944. if (tab[id] == i) return id; //si on a trouvé la bonne valeur, on retourne l'indice
  945. else return -1; //sinon on retourne -1
  946. }
  947. /**
  948. * Fonction permettant de supprimer une case d'un tableau.
  949. * @param tab une référence sur un tableau d'entiers
  950. * @param i un indice dans tab
  951. */
  952. void suprim_val(Entiers &tab,int i) {
  953. tab.erase(tab.begin() + dichotomie(tab,i));
  954. }
  955. /**
  956. * Détermine si une valeur se trouve dans un tableau.
  957. * @param tab une référence sur un tableau d'entiers
  958. * @param val une valeur
  959. * @return true si la valeur a été trouvée, false sinon
  960. */
  961. bool In_tab(const Entiers &tab, int val)
  962. {
  963. for (uint i=0; i < tab.size(); i++)
  964. if(tab[i]==val)
  965. return true;
  966. return false;
  967. }
  968. bool In_tab_dichotomie(const Entiers &tab, int val)
  969. {
  970. if(dichotomie(tab,val)!=-1)
  971. return true;
  972. else
  973. return false;
  974. }
  975. void Liste_Voisin(const Entiers &P,Entiers &tab,const UnorientedGraph &g)
  976. {
  977. tie(neighbourIt, neighbourEnd) = adjacent_vertices(P.at(P.size()-1), g);
  978. for (; neighbourIt != neighbourEnd; ++neighbourIt)
  979. {
  980. if((In_tab(tab,*neighbourIt) == false ) && (In_tab(P,*neighbourIt) == false ))
  981. tab.push_back(*neighbourIt);
  982. }
  983. }
  984. int Cout_coupe(Entiers P,int val, UnorientedGraph &g)
  985. {
  986. int cpt=0;
  987. P.push_back(val);
  988. for(uint i=0;i<P.size();i++){
  989. tie(neighbourIt, neighbourEnd) = adjacent_vertices(P[i], g);
  990. for (; neighbourIt != neighbourEnd; ++neighbourIt){
  991. if(In_tab(P,*neighbourIt)!=1){
  992. cpt++;
  993. }
  994. }
  995. }
  996. return cpt;
  997. }
  998. double Cut_one_cluster(const Entiers &cluster, UnorientedGraph &g, std::string name)
  999. {
  1000. if(name=="norm"){
  1001. edge_t e1;
  1002. bool found;
  1003. double cpt=0.;
  1004. for(uint i=0;i<cluster.size();i++){
  1005. tie(neighbourIt, neighbourEnd) = adjacent_vertices(cluster[i], g);
  1006. for (; neighbourIt != neighbourEnd; ++neighbourIt){
  1007. tie(e1,found)=edge(vertex(cluster[i],g),vertex(*neighbourIt,g),g);
  1008. if(In_tab(cluster,*neighbourIt)!=1){
  1009. cpt+=g[e1]._weight;
  1010. }
  1011. }
  1012. }
  1013. double vol = Cluster_Degree(g,cluster);
  1014. return (cpt/2.)/vol;
  1015. }
  1016. else{
  1017. edge_t e1;
  1018. bool found;
  1019. double cpt=0.;
  1020. for(uint i=0;i<cluster.size();i++){
  1021. tie(neighbourIt, neighbourEnd) = adjacent_vertices(cluster.at(i), g);
  1022. for (; neighbourIt != neighbourEnd; ++neighbourIt){
  1023. tie(e1,found)=edge(vertex(cluster.at(i),g),vertex(*neighbourIt,g),g);
  1024. if(In_tab(cluster,*neighbourIt)!=1){
  1025. cpt+=g[e1]._weight;
  1026. }
  1027. }
  1028. }
  1029. return cpt/2.;
  1030. }
  1031. }
  1032. double Cut_cluster(const EntiersEntiers &tab_cluster,UnorientedGraph &g,std::string name)
  1033. {
  1034. double cpt=0.;
  1035. for(uint i=0;i<tab_cluster.size();i++){
  1036. cpt+=Cut_one_cluster(*tab_cluster[i],g,name);
  1037. }
  1038. return cpt;
  1039. }
  1040. double Cout_coupe_pond(Entiers P, int val, UnorientedGraph &g)
  1041. {
  1042. edge_t e1;
  1043. bool found;
  1044. double cpt=0;
  1045. P.push_back(val);
  1046. for(uint i=0;i<P.size();i++){
  1047. tie(neighbourIt, neighbourEnd) = adjacent_vertices(P[i], g);
  1048. for (; neighbourIt != neighbourEnd; ++neighbourIt){
  1049. tie(e1,found)=edge(vertex(P[i],g),vertex(*neighbourIt,g),g);
  1050. if(In_tab(P,*neighbourIt)!=1){
  1051. cpt+=g[e1]._weight;
  1052. }
  1053. }
  1054. }
  1055. return cpt;
  1056. }
  1057. int In_community_dichotomie(const EntiersEntiers &part, int val)
  1058. {
  1059. for (uint i = 0; i < part.size() ; i++) {
  1060. if (In_tab_dichotomie(*part[i], val)) {
  1061. return i;
  1062. }
  1063. }
  1064. return -1;
  1065. }
  1066. double Degree(UnorientedGraph& g, int node)
  1067. {
  1068. edge_t e1;
  1069. bool found;
  1070. double val = 0.;
  1071. tie(neighbourIt, neighbourEnd) = adjacent_vertices(node, g);
  1072. for (; neighbourIt != neighbourEnd; ++neighbourIt) {
  1073. tie(e1, found) = edge(vertex(node, g), vertex(*neighbourIt, g), g);
  1074. val += g[e1]._weight;
  1075. }
  1076. return val;
  1077. }
  1078. double Cluster_Degree(UnorientedGraph &g , const Entiers &cluster)
  1079. {
  1080. double val = 0.;
  1081. for(uint i = 0; i < cluster.size(); i++){
  1082. val += Degree(g, cluster.at(i));
  1083. }
  1084. return val;
  1085. }
  1086. void List_edge_partie(Entiers *Partie, OrientedGraph *go, Edges &edge_partie,
  1087. OutputEdges &outputedgespartie){
  1088. edge_to e1;
  1089. //bool found;
  1090. for(uint i = 0; i < Partie->size(); i++) {
  1091. tie(neighbourIto, neighbourEndo) = adjacent_vertices(Partie->at(i),
  1092. *go);
  1093. for (; neighbourIto != neighbourEndo; ++neighbourIto) {
  1094. if(In_tab_dichotomie(*Partie,*neighbourIto)) {
  1095. Edge new_edge;
  1096. new_edge.first = Partie->at(i);
  1097. new_edge.second = *neighbourIto;
  1098. edge_partie.push_back(new_edge);
  1099. } else {
  1100. Edge new_edge;
  1101. new_edge.first = Partie->at(i);
  1102. new_edge.second = *neighbourIto;
  1103. outputedgespartie.push_back(new_edge);
  1104. }
  1105. }
  1106. }
  1107. }
  1108. void Global_Neigh_community(UnorientedGraph *g,
  1109. const EntiersEntiers &Partition,
  1110. Entiers *community, int vertex, int comm_in)
  1111. {
  1112. int comm;
  1113. tie(neighbourIt, neighbourEnd) = adjacent_vertices(vertex, *g);
  1114. for (; neighbourIt != neighbourEnd; ++neighbourIt){
  1115. comm = In_community_dichotomie(Partition, *neighbourIt);
  1116. if (In_tab(*community,comm) != 1 and comm != comm_in)
  1117. community->push_back(comm);
  1118. }
  1119. }
  1120. OrientedGraphs Graph_Partition(const EntiersEntiers& Partition,
  1121. OrientedGraph *go,
  1122. UnorientedGraph *g,
  1123. OutputEdgeList &outputedgelist,
  1124. InputEdgeList &inputedgelist,
  1125. Connections &connections)
  1126. {
  1127. OrientedGraphs graph_partie;
  1128. EntiersEntiers neigh_community;
  1129. for (uint i = 0; i < Partition.size();i++){
  1130. Edges edge_partie;
  1131. List_edge_partie(Partition.at(i),go,edge_partie,outputedgelist.at(i));
  1132. OrientedGraph graph;
  1133. std::vector<vertex_to> tab_vertex_to;
  1134. Entiers *community = new Entiers();
  1135. for (uint j = 0; j < Partition.at(i)->size(); j++) {
  1136. Global_Neigh_community(g, Partition, community,
  1137. Partition.at(i)->at(j),i);
  1138. vertex_to v = add_vertex(graph);
  1139. tab_vertex_to.push_back(v);
  1140. graph[v] = VertexProperties((*go)[Partition.at(i)->at(j)]._index,
  1141. (*go)[Partition.at(i)->at(j)]._weight,
  1142. (*go)[Partition.at(i)->at(j)]._type);
  1143. }
  1144. neigh_community.push_back(community);
  1145. for(uint k = 0; k < edge_partie.size(); k++) {
  1146. add_edge(tab_vertex_to.at(recherche_val(*Partition.at(i),
  1147. edge_partie.at(k).first)),
  1148. tab_vertex_to.at(recherche_val(*Partition.at(i),
  1149. edge_partie.at(k).second)),
  1150. graph);
  1151. }
  1152. graph_partie.push_back(graph);
  1153. }
  1154. for (uint i = 0; i < neigh_community.size(); i++) {
  1155. InputEdges inputedges;
  1156. for (uint j = 0; j < neigh_community.at(i)->size(); j++) {
  1157. for (uint k = 0;
  1158. k < outputedgelist.at(neigh_community.at(i)->at(j)).size();
  1159. k++) {
  1160. if (In_tab_dichotomie(
  1161. *Partition.at(i),
  1162. outputedgelist.at(
  1163. neigh_community.at(i)->at(j)).at(k).second))
  1164. inputedges.push_back(
  1165. outputedgelist.at(
  1166. neigh_community.at(i)->at(j)).at(k));
  1167. }
  1168. }
  1169. inputedgelist.push_back(inputedges);
  1170. }
  1171. for (uint i = 0; i < outputedgelist.size(); i++){
  1172. Connection connec;
  1173. for(uint j = 0; j < outputedgelist.at(i).size(); j++){
  1174. Port port1;
  1175. port1.first = i + 1;
  1176. port1.second = outputedgelist.at(i).at(j).first;
  1177. Port port2;
  1178. port2.first = In_community_dichotomie(
  1179. Partition,outputedgelist.at(i).at(j).second) + 1;
  1180. port2.second = outputedgelist.at(i).at(j).second;
  1181. connec.first = port1;
  1182. connec.second = port2;
  1183. connections.push_back(connec);
  1184. }
  1185. }
  1186. for (EntiersEntiers::iterator it = neigh_community.begin();
  1187. it != neigh_community.end(); it++) {
  1188. delete *it;
  1189. *it = NULL;
  1190. }
  1191. return graph_partie;
  1192. }
  1193. /*double In_modularity(UnorientedGraph &g , const Entiers &cluster){
  1194. property_map<UnorientedGraph,edge_weight_t>::type poids_arc=get(edge_weight_t(),g);
  1195. edge_t e1;
  1196. bool found;
  1197. int val=0;
  1198. for(uint i=0;i<cluster.size();i++){
  1199. tie(neighbourIt, neighbourEnd) = adjacent_vertices(cluster[i],g);
  1200. for (; neighbourIt != neighbourEnd; ++neighbourIt){
  1201. tie(e1,found)=edge(vertex(cluster[i],g),vertex(*neighbourIt,g),g);
  1202. if(In_tab(cluster,*neighbourIt)==1)
  1203. val+=get(poids_arc,e1);
  1204. }
  1205. }
  1206. return val/2.;
  1207. }*/
  1208. /**
  1209. *
  1210. * @param g
  1211. * @param cluster
  1212. * @return
  1213. */
  1214. /**
  1215. *
  1216. * @param g
  1217. * @param part
  1218. * @return
  1219. */
  1220. /*double Modularity(UnorientedGraph &g,const EntiersEntiers &part) {
  1221. double q = 0.;
  1222. int tmp=num_edges(g);
  1223. for(uint i=0;i<part.size();i++){
  1224. q+=In_modularity(g,*part[i])/tmp-(Cluster_Degree(g,*part[i])/(2*tmp))*(Cluster_Degree(g,*part[i])/(2*tmp));
  1225. }
  1226. return q;
  1227. }*/
  1228. /**
  1229. *
  1230. * @param part
  1231. * @param val
  1232. * @return
  1233. */
  1234. /**
  1235. * Fonction de calcul du gain de modularité de déplacement d'un sommet d'une communoté à une autre !!!!!
  1236. * ajoute le sommet à part[val] et on calcul la nouvelle modularité
  1237. * on prend la différence entre la modularité et la nouvouvelle !
  1238. * @param cur_mod
  1239. * @param val
  1240. * @param neight
  1241. * @param node_comm
  1242. * @param part
  1243. * @param g
  1244. */
  1245. /*double Modularity_gain(double cur_mod , int val , int neight , int node_comm , EntiersEntiers part , UnorientedGraph &g) {
  1246. double q;
  1247. part[neight]->push_back(val);
  1248. std::sort(*part[neight]);
  1249. q=Modularity(g,part);
  1250. return q-cur_mod;
  1251. }*/
  1252. /**
  1253. * Fonction de calcul du gain de modularité de déplacement d'un sommet d'une communoté à une autre !!!!!
  1254. * ajoute le sommet à part[val] et on calcul la nouvelle modularité
  1255. * on prend la différence entre la modularité et la nouvouvelle !
  1256. * @param cur_mod
  1257. * @param tmp_community
  1258. * @param neight
  1259. * @param node_comm
  1260. * @param part
  1261. * @param g
  1262. */
  1263. /*double Modularity_gain_phase_2(double cur_mod, Entiers tmp_community, int neight, int node_comm, EntiersEntiers part, UnorientedGraph &g) {
  1264. double q;
  1265. for (uint i=0;i<tmp_community.size();i++)
  1266. part[neight]->push_back(tmp_community[i]);
  1267. std::sort(*part[neight]);
  1268. q = Modularity(g,part);
  1269. return q - cur_mod;
  1270. }*/
  1271. /**
  1272. * Donne la liste des communautés voisines à celle contenant le sommet val.
  1273. * @param part
  1274. * @param val
  1275. * @param g
  1276. * @return
  1277. */
  1278. /*Entiers Neight_community(const EntiersEntiers &part, int val , UnorientedGraph &g){
  1279. Entiers Neight;
  1280. tie(neighbourIt, neighbourEnd) = adjacent_vertices(val, g);
  1281. for (; neighbourIt != neighbourEnd; ++neighbourIt){
  1282. int tmp=In_community(part,*neighbourIt);
  1283. if(In_tab(Neight,tmp)!=1 && In_tab(*part[In_community(part,val)],*neighbourIt)!=1)
  1284. Neight.push_back(tmp);
  1285. }
  1286. std::sort(Neight);
  1287. return Neight;
  1288. }*/
  1289. /**
  1290. *
  1291. * @param part
  1292. * @param community
  1293. * @param g
  1294. * @return
  1295. */
  1296. /*Entiers Part_Neight_community(const EntiersEntiers &part,int community, UnorientedGraph &g){
  1297. Entiers Neight;
  1298. for(uint i =0;i<part[community]->size();i++){
  1299. tie(neighbourIt, neighbourEnd) = adjacent_vertices(part[community]->at(i), g);
  1300. for (; neighbourIt != neighbourEnd; ++neighbourIt){
  1301. int tmp=In_community(part,*neighbourIt);
  1302. if(In_tab(Neight,tmp)!=1 && tmp!=community)
  1303. Neight.push_back(tmp);
  1304. }
  1305. }
  1306. std::sort(Neight);
  1307. return Neight;
  1308. }*/
  1309. void make_unoriented_graph(const OrientedGraph& og, UnorientedGraph& ug)
  1310. {
  1311. std::vector < vertex_t > ug_vertex_list;
  1312. std::vector < vertex_t > og_vertex_list;
  1313. for (uint i = 0; i < num_vertices(og); ++i) {
  1314. ug_vertex_list.push_back(add_vertex(ug));
  1315. }
  1316. OrientedGraph::vertex_iterator it_og, end_og;
  1317. UnorientedGraph::vertex_iterator it_ug, end_ug;
  1318. tie(it_og, end_og) = vertices(og);
  1319. tie(it_ug, end_ug) = vertices(ug);
  1320. for (; it_og != end_og; ++it_og, ++it_ug) {
  1321. ug[*it_ug] = og[*it_og];
  1322. og_vertex_list.push_back(*it_og);
  1323. }
  1324. OrientedGraph::edge_iterator ite_og, ende_og;
  1325. tie(ite_og, ende_og) = edges(og);
  1326. for (; ite_og != ende_og; ++ite_og) {
  1327. boost::add_edge(source(*ite_og, og), target(*ite_og, og),
  1328. og[*ite_og], ug);
  1329. }
  1330. // std::cout << "Oriented graph: " << std::endl;
  1331. // tie(it_og, end_og) = vertices(og);
  1332. // for (; it_og != end_og; ++it_og) {
  1333. // OrientedGraph::adjacency_iterator neighbour_it, neighbour_end;
  1334. // std::cout << og[*it_og]._index << " is connected with ";
  1335. // tie(neighbour_it, neighbour_end) = adjacent_vertices(*it_og, og);
  1336. // for (; neighbour_it != neighbour_end; ++neighbour_it)
  1337. // std::cout << og[*neighbour_it]._index << " ";
  1338. // std::cout << " and weight = " << og[*it_og]._weight << std::endl;
  1339. // }
  1340. // std::cout << std::endl;
  1341. // std::cout << "Unoriented graph: " << std::endl;
  1342. // tie(it_ug, end_ug) = vertices(ug);
  1343. // for (; it_ug != end_ug; ++it_ug) {
  1344. // UnorientedGraph::adjacency_iterator neighbour_it, neighbour_end;
  1345. // std::cout << ug[*it_ug]._index << " is connected with ";
  1346. // tie(neighbour_it, neighbour_end) = adjacent_vertices(*it_ug, ug);
  1347. // for (; neighbour_it != neighbour_end; ++neighbour_it)
  1348. // std::cout << ug[*neighbour_it]._index << " ";
  1349. // std::cout << " and weight = " << ug[*it_ug]._weight << std::endl;
  1350. // }
  1351. // std::cout << std::endl;
  1352. }
  1353. void adjacence_ggp(int vertex, Entiers &sommets_adj, UnorientedGraph *g)
  1354. {
  1355. tie(neighbourIt, neighbourEnd) = adjacent_vertices(vertex, *g);
  1356. for (; neighbourIt != neighbourEnd; ++neighbourIt)
  1357. {
  1358. sommets_adj.push_back(*neighbourIt);
  1359. }
  1360. }
  1361. float modif_Cout_coupe(const Entiers &P, int val, float cut, UnorientedGraph *g)
  1362. {
  1363. //std::cout<<"Cout de coupe initiale : "<<cut<<std::endl;
  1364. //std::cout<<"degré du sommet tiré : "<<Degree(*g,val)<<std::endl;
  1365. double cpt=0;
  1366. float new_cut;
  1367. tie(neighbourIt, neighbourEnd) = adjacent_vertices(val, *g);
  1368. for (; neighbourIt != neighbourEnd; neighbourIt++){
  1369. if(In_tab(P,*neighbourIt)==1){
  1370. cpt++;
  1371. }
  1372. }
  1373. new_cut = cut + (Degree(*g,val) - (2 * cpt));
  1374. return new_cut;
  1375. }
  1376. } } } // namespace paradevs tests boost_graph