utils.cpp 77 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296
  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. #include <fstream>
  29. namespace paradevs { namespace tests { namespace boost_graph {
  30. UnorientedGraph::vertex_iterator vertexIt, vertexEnd;
  31. UnorientedGraph::adjacency_iterator neighbourIt, neighbourEnd;
  32. OrientedGraph::vertex_iterator vertexIto, vertexEndo;
  33. OrientedGraph::adjacency_iterator neighbourIto, neighbourEndo;
  34. struct myclass
  35. {
  36. bool operator() (Entiers *i, Entiers *j)
  37. { return i->at(0) < j->at(0); }
  38. } myobject;
  39. struct myclass2
  40. {
  41. bool operator() (Entiers *i, Entiers *j, UnorientedGraph *g)
  42. { return Calcul_poids(i,g) < Calcul_poids(j,g); }
  43. } mon_tri;
  44. struct myclass3
  45. {
  46. bool operator() (Entiers *i, Entiers *j)
  47. { return i->size() > j->size(); }
  48. } myobject_taille;
  49. /**
  50. * Fonction de verification de la connexité d'un graphe
  51. * @param *g : adresse d'un graphe de type boost graphe undirected
  52. * @param Partition : vecteur contenant des vecteurs d'entiers [tableau contenant les parties de la partition]
  53. * @param part : vecteur d'entier (une partie de la partition)
  54. * @return un booleen
  55. */
  56. bool Est_connexe(UnorientedGraph *g, EntiersEntiers Partition, Entiers &part)
  57. {
  58. /*
  59. * Copie du graphe contenu par l'adresse *g
  60. */
  61. UnorientedGraph copie_g;
  62. copie_g = *g;
  63. /*
  64. * Modification du graphe copié afin de générer des sous graphes liés aux différentes parties
  65. */
  66. for (uint i=0; i<Partition.size()-1;i++)
  67. {
  68. for (uint j=1+i; j<Partition.size();j++)
  69. {
  70. for (uint k=0; k<Partition.at(i)->size();k++)
  71. {
  72. for (uint y=0; y<Partition.at(j)->size();y++)
  73. {
  74. remove_edge(Partition.at(i)->at(k),Partition.at(j)->at(y),copie_g); //suppression de certains arcs
  75. }
  76. }
  77. }
  78. }
  79. /*
  80. * Objectif : déterminer s'il existe un chemin reliant tous les noeuds d'une même partie
  81. * Méthode : partir d'un sommet de départ tiré aléatoirement dans la partie "part" et parcourir l'ensemble de ces voisins.
  82. * Si le voisin recontré n'est pas contenu dans le vecteur "sommets" il est ajouté. Le processus est répété pour chaque
  83. * nouveau sommet ajouté au vecteur.
  84. * Résultat : si le nombre de sommets contenu dans le vecteur "part" est égale au nombre de sommets du vecteur "sommets"
  85. * alors le graphe est connexe
  86. */
  87. int val;
  88. Entiers sommets;
  89. if(part.size()==1)
  90. val = 0;
  91. else
  92. val=rand_fini(0,part.size()-1); //tirage aléatoire d'un sommets
  93. int vertex = part.at(val);
  94. sommets.push_back(vertex); //ajout du sommets à la lsite des sommets parcouru
  95. /*
  96. * Recherche de voisins n'appartenant pas à la liste des sommets parcourus
  97. */
  98. for(uint i = 0;i<sommets.size();i++){
  99. tie(neighbourIt, neighbourEnd) = adjacent_vertices(sommets.at(i),copie_g);
  100. for (; neighbourIt != neighbourEnd; ++neighbourIt){
  101. if(In_tab(sommets,*neighbourIt)!=1)
  102. sommets.push_back(*neighbourIt);
  103. }
  104. }
  105. /*
  106. * Retour de la réponse vrai ou faux
  107. */
  108. if(part.size()!=sommets.size())
  109. return false;
  110. else
  111. return true;
  112. }
  113. /**
  114. * Fonction de projection
  115. * @param Partition : vecteur contenant des vecteurs d'entiers [tableau contenant les parties de la partition]
  116. * @param lit : itérateur sur une liste contenant une vecteur de vecteur d'entier
  117. * @return
  118. */
  119. /*
  120. * Objectif : obtenir la correspondance entre les sommets d'un graphe Gn et celui de Gn-1
  121. * Méthode : modification des sommets contenus dans "Partition" à l'aide de la liste de correspondance *lit
  122. */
  123. void projection(EntiersEntiers &Partition,ListEntiersEntiers::iterator lit)
  124. {
  125. /*
  126. * Création d'un nouveau vecteur contenant les adresses d'autres vecteur d'entiers.
  127. * Celui-ci est conçu pour recevoir les sommets contenus dans la liste de correspondance,
  128. * correspondant à la projection des sommets du graphe Gn à celui de Gn-1
  129. */
  130. EntiersEntiers new_partition;
  131. for(uint i = 0; i< Partition.size() ; i++)
  132. {
  133. Entiers *new_part = new Entiers();
  134. for(uint j = 0 ; j<Partition.at(i)->size() ; j++)
  135. {
  136. for(uint k = 0; k<((*lit)->at(Partition.at(i)->at(j)))->size();k++){
  137. new_part->push_back((*lit)->at(Partition.at(i)->at(j))->at(k));
  138. }
  139. }
  140. new_partition.push_back(new_part);
  141. }
  142. /*
  143. * Désalocation mémoire des pointeurs que contient "Partition"
  144. */
  145. for(EntiersEntiers::iterator it = Partition.begin(); it != Partition.end(); it++)
  146. {
  147. delete *it;
  148. *it = NULL;
  149. }
  150. Partition = new_partition; // copie de new_partition dans Partition
  151. for(uint i =0; i<Partition.size(); i++) {
  152. // permet de trier chaque sous vecteur de "Partition"
  153. std::sort(Partition[i]->begin(),Partition[i]->end());
  154. }
  155. new_partition.clear();
  156. }
  157. /**
  158. * Fonction qui calcul le poids d'une partie
  159. * @param * part : adresse d'un vecteur d'entier, ici une partie de la partition
  160. * @param *g : adresse d'un graphe de type boost graphe undirected
  161. * @return un type double contenant le poids associé à la partie
  162. */
  163. double Calcul_poids(Entiers *partie, UnorientedGraph *g)
  164. {
  165. double poids=0; // initialisation du poids à 0
  166. /*
  167. * Pour chaque sommet de la partie concerné on ajoute son poids au poids total
  168. */
  169. for(uint j = 0; j<partie->size();j++){
  170. poids+=(*g)[partie->at(j)]._weight;
  171. }
  172. return poids;
  173. }
  174. /**
  175. * Fonction d'affinage suivant un critère de poids
  176. * @param *g : adresse d'un graphe de type boost graphe undirected
  177. * @param Partition : vecteur contenant des vecteurs d'entiers [tableau contenant les parties de la partition]
  178. * @return modification de la partition
  179. */
  180. void Affinage_equilibrage_charge(UnorientedGraph *g, EntiersEntiers &Partition)
  181. {
  182. /*
  183. * Calcule de la somme des poids du graphe et le poids moyen à atteindre
  184. */
  185. double poids_moyen = 0.;
  186. for(uint i = 0; i < num_vertices(*g); i++) {
  187. poids_moyen += (*g)[i]._weight;
  188. }
  189. // détermination du poids moyen à atteindre pour chaque partie
  190. poids_moyen /= Partition.size();
  191. std::vector < double > poids_parties;
  192. /*
  193. * Calcul du poids de chaque partie de la partition
  194. */
  195. for (uint i = 0; i < Partition.size(); i++) {
  196. double tmp = Calcul_poids(Partition.at(i),g);
  197. poids_parties.push_back(tmp);
  198. }
  199. std::clog << "Poids initial des parties : " << std::endl;
  200. // for (uint i = 0; i < poids_parties.size(); i++){
  201. // std::cout << poids_parties.at(i) << " ";
  202. // }
  203. // std::cout << "\n" << std::endl;
  204. /*
  205. * Le critère d'amélioration consiste à faire tendre vers 0 la somme
  206. * des écarts entre le poids des parties et le poids moyen
  207. * le "critere" est la somme pour chaque partie de la différence
  208. * en valeurs absolues du poids
  209. * d'une partie moins le poids moyen divisé par le nombre de parties
  210. */
  211. double critere = 0.;
  212. for (uint i = 0; i < poids_parties.size(); i++){
  213. critere += abs(poids_parties.at(i) - poids_moyen);
  214. }
  215. critere /= Partition.size();
  216. // on conserve le poids maximum
  217. double p_max = *max_element(poids_parties.begin(), poids_parties.end());
  218. // std::cout << "Valeurs du criètre de départ : " << critere << std::endl;
  219. // création d'un second critère légérement plsu faible que le premier
  220. double best_critere = critere - 1e-7;
  221. uint nbr_passage = 1; // initialisation du nombre de passages à 1
  222. /*
  223. * Tant que le critère n'est pas amélioré etque le nombre de
  224. * passage est inférieur au nombre de parties on réalise
  225. * des modifications sur la partition
  226. */
  227. while (best_critere < critere or nbr_passage < Partition.size()) {
  228. critere = best_critere; //critere devient best_critere
  229. // recherche la partie associé au poids maximum
  230. int cpt = recherche_val_double(poids_parties,p_max);
  231. bool decision = false; //initialisatio d'un booleen a false
  232. int nbr_pass_interne = 0;
  233. /*
  234. * tirage aléatoire des sommets de la partie de poids maximum
  235. */
  236. Entiers random_orders(Partition.at(cpt)->size());
  237. for (uint i=0 ; i<Partition.at(cpt)->size() ; i++)
  238. random_orders.at(i)=Partition.at(cpt)->at(i);
  239. for (uint j=0 ; j<Partition.at(cpt)->size()-1 ; j++) {
  240. int rand_pos = (rand() % Partition.at(cpt)->size()-j)+j;
  241. int tmp = random_orders[j];
  242. random_orders[j] = random_orders[rand_pos];
  243. random_orders[rand_pos] = tmp;
  244. }
  245. /*
  246. * Si le nombre de sommets d'une partie excéde les 400, on tire au hasar 400 sommets sans remise
  247. * et on effectue les modifications (ceci permet d'eviter une explosion des temps de calcul)
  248. */
  249. int size;
  250. if(Partition.at(cpt)->size()>400)
  251. size = 400;
  252. else
  253. size = Partition.at(cpt)->size();
  254. /*
  255. * Seconde boucle Tant que sur les sommets d'une partie.
  256. * Tant que le critere booleen est vrai et que le nombre de passe interne est inférieur au seuil size faire
  257. */
  258. while(decision!=true && nbr_pass_interne < size){
  259. int vertex = random_orders.at(nbr_pass_interne); //tirage d'un sommets dans la parite de poids maximum
  260. Entiers community = Neigh_community(g,Partition,vertex,cpt); // recherche des communautés voisines à ce sommet (s'il est au bord)
  261. if(community.size()!=0) // s'il existe au moins une communauté voisine
  262. {
  263. std::vector<double> new_poids_parties; // initialisation d'un nouveau vecteur contenant des doubles
  264. std::vector<double> tmp_critere; // initialisation d'un nouveau vecteur contenant des doubles
  265. /*
  266. * Pour chacune des parties (communauté) voisine au sommet vertexs faire
  267. */
  268. for(uint k = 0; k < community.size();k++)
  269. {
  270. new_poids_parties = poids_parties; //copie du tableau de poids des parties dans new_poids_parties
  271. /*
  272. * Modification des poids des parties :
  273. * on ajoute le poids du sommets à la partie voisine
  274. * et on soustrait son poids à sa partie d'origine
  275. */
  276. new_poids_parties.at(community.at(k))+=(*g)[vertex]._weight;
  277. new_poids_parties.at(cpt)-=(*g)[vertex]._weight;
  278. /*
  279. * Calcul ldu nouveau critère associé à cette modification
  280. */
  281. double new_critere = 0.;
  282. for(uint i = 0; i<poids_parties.size();i++){
  283. new_critere += abs(new_poids_parties.at(i)-poids_moyen);
  284. }
  285. new_critere/=Partition.size();
  286. tmp_critere.push_back(new_critere); // enregistrement du résutlat dans le tableau tmp_critere
  287. }
  288. double val_min = *min_element(tmp_critere.begin(),tmp_critere.end()); // enregistrement de la valeur minimale du tableau tmp_critere
  289. int val = recherche_val_double(tmp_critere,val_min); // recherche de la communauté correspondant à cette valeur
  290. /*
  291. * Si la valeur associé est plus petite et que la partie selectionné n'est pas vérouillée faire
  292. */
  293. if(val_min<critere && poids_parties.at(val)!=-1)
  294. {
  295. /*
  296. * On change le sommet vertex de partie, il est déplacé vers la partie
  297. * qui permet la meilleure amélioration du critère
  298. */
  299. Partition.at(community.at(val))->push_back(vertex);
  300. suprim_val(*Partition.at(cpt),vertex);
  301. std::sort(Partition.at(community.at(val))->begin(), Partition.at(community.at(val))->end());
  302. /*
  303. * Vérification de la sauvegarde de la connexsité,
  304. * si se n'est pas le cas retour à l'état précédent
  305. */
  306. if(Est_connexe(g,Partition,*Partition.at(cpt))!=1)
  307. {
  308. suprim_val(*Partition.at(community.at(val)),vertex);
  309. Partition.at(cpt)->push_back(vertex);
  310. std::sort(Partition.at(cpt)->begin(), Partition.at(cpt)->end());
  311. // std::cout<<" C'EST MORT RETOUR EN ARRIERE ! "<<std::endl
  312. ;
  313. }
  314. else
  315. {
  316. poids_parties = new_poids_parties;
  317. decision = true;
  318. // std::cout<<" Modification reussi ! "<<std::endl;
  319. }
  320. }
  321. }
  322. nbr_pass_interne++;
  323. }
  324. /*
  325. * Si aucune modification n'a été réalisé pour cett partie de poids maximum
  326. */
  327. if(decision==false)
  328. {
  329. nbr_passage++; // augmentation du nombre de passage
  330. poids_parties.at(cpt)=-1; // vérrouillage de la partie
  331. std::clog<<"nouveau passag ! "<<std::endl;
  332. }
  333. else
  334. {
  335. best_critere = 0.;
  336. for(uint i = 0; i<poids_parties.size();i++){
  337. best_critere += abs(poids_parties.at(i)-poids_moyen);
  338. }
  339. best_critere/=Partition.size();
  340. nbr_passage = 0;
  341. }
  342. // std::clog<<"Poids des parties modifié : "<<std::endl;
  343. // for(uint i = 0; i<poids_parties.size(); i++){
  344. // std::cout<<poids_parties.at(i)<<" ";
  345. // }
  346. // std::cout<<"\n"<<std::endl;
  347. p_max = *max_element(poids_parties.begin(),poids_parties.end());
  348. // std::cout<<"Valeurs du criètre : "<<critere<<std::endl;
  349. // std::cout<<"Valeurs du best_criètre : "<<best_critere<<std::endl;
  350. // std::cout<<"Nombre de passage : "<<nbr_passage<<std::endl;
  351. // std::cout<<"\n"<<std::endl;
  352. }
  353. }
  354. Entiers Neigh_community(UnorientedGraph *g, EntiersEntiers &Partition, int vertex, int comm_in)
  355. {
  356. Entiers community;
  357. int comm;
  358. tie(neighbourIt, neighbourEnd) = adjacent_vertices(vertex,*g);
  359. for (; neighbourIt != neighbourEnd; ++neighbourIt){
  360. comm = In_community_dichotomie(Partition,*neighbourIt);
  361. if(In_tab(community,comm)!=1 && comm!=comm_in)
  362. community.push_back(comm);
  363. }
  364. return community;
  365. }
  366. void Affinage_recherche_locale(UnorientedGraph *g, EntiersEntiers &Partition, double &cut, std::string name)
  367. {
  368. Entiers random_orders(num_vertices(*g)); //gestion d'un tableau contenant tout les sommets et ranger de façon aléatoire
  369. for (uint i=0 ; i<num_vertices(*g) ; i++)
  370. random_orders.at(i)=i;
  371. for (uint j=0 ; j<num_vertices(*g)-1 ; j++) {
  372. int rand_pos = (rand() % num_vertices(*g)-j)+j;
  373. int tmp = random_orders[j];
  374. random_orders[j] = random_orders[rand_pos];
  375. random_orders[rand_pos] = tmp;
  376. }
  377. uint size = random_orders.size();
  378. if(num_vertices(*g)>500)
  379. size=500;
  380. std::vector<std::vector<double> > tabe_cut;
  381. //std::cout<<"Passage : "<<Partition.size()<<std::endl;
  382. for(uint k = 0; k < Partition.size();k++){
  383. std::vector<double> tmp;
  384. double vol = 0.;
  385. double cut = Modif_Cut_one_cluster(*Partition.at(k), *g, vol, name);
  386. tmp.push_back(cut);
  387. tmp.push_back(vol);
  388. tabe_cut.push_back(tmp);
  389. }
  390. for(uint i = 0; i < size; i++){
  391. if(random_orders.at(i)!=-1){
  392. int vertex = random_orders.at(i);
  393. //std::cout<<vertex<<std::endl;
  394. int comm = In_community_dichotomie(Partition, vertex);
  395. Entiers community = Neigh_community(g,Partition,vertex,comm);
  396. std::vector<double> tmp_cut;
  397. if(community.size()!=0 && Partition.at(comm)->size()!=1){
  398. tmp_cut = modif_cut_tmp(g,Partition,tabe_cut,vertex,comm,community,cut,name);
  399. /*for(uint z = 0; z<tmp_cut.size(); z++){
  400. std::cout<<tmp_cut.at(z)<<std::endl;
  401. }
  402. std::cout<<"\n"<<std::endl;*/
  403. double cut_min = *min_element(tmp_cut.begin(),tmp_cut.end());
  404. //std::cout<<"cout de coupe minimum de la liste : "<<cut_min<<std::endl;
  405. if(cut_min<cut){
  406. // std::clog<<"Changement ! "<<std::endl;
  407. int tmp = recherche_val_double(tmp_cut,cut_min);
  408. cut=cut_min;
  409. Partition.at(community.at(tmp))->push_back(vertex);
  410. suprim_val(*Partition.at(comm),vertex);
  411. std::sort(Partition.at(community.at(tmp))->begin(), Partition.at(community.at(tmp))->end());
  412. tabe_cut.clear();
  413. for(uint k = 0; k < Partition.size();k++){
  414. std::vector<double> tmp;
  415. double vol = 0.;
  416. double cut = Modif_Cut_one_cluster(*Partition.at(k), *g, vol, name);
  417. tmp.push_back(cut);
  418. tmp.push_back(vol);
  419. tabe_cut.push_back(tmp);
  420. }
  421. }
  422. }
  423. Modif_fonction_Gain_Cut(Partition,g,community,vertex,cut,name);
  424. /*if(Est_connexe(g,Partition,*Partition.at(comm))!=1)
  425. {
  426. suprim_val(*Partition.at(community.at(tmp)),vertex);
  427. Partition.at(comm)->push_back(vertex);
  428. std::sort(*Partition.at(comm));
  429. std::cout<<" C'EST MORT RETOUR EN ARRIERE ! "<<std::endl;
  430. }*/
  431. }
  432. }
  433. }
  434. double Modif_Cut_one_cluster(Entiers &cluster, UnorientedGraph &g, double &vol, std::string name)
  435. {
  436. edge_t e1;
  437. bool found;
  438. double cpt= 0.;
  439. if(name == "norm"){
  440. for(uint i=0;i<cluster.size();i++){
  441. tie(neighbourIt, neighbourEnd) = adjacent_vertices(cluster.at(i), g);
  442. for (; neighbourIt != neighbourEnd; ++neighbourIt){
  443. tie(e1,found)=edge(vertex(cluster[i],g),vertex(*neighbourIt,g),g);
  444. if(In_tab(cluster,*neighbourIt)!=1){
  445. cpt+=g[e1]._weight;
  446. }
  447. }
  448. }
  449. vol = Cluster_Degree(g,cluster);
  450. } else if(name == "ratio"){
  451. for(uint i=0;i<cluster.size();i++){
  452. tie(neighbourIt, neighbourEnd) = adjacent_vertices(cluster.at(i), g);
  453. for (; neighbourIt != neighbourEnd; ++neighbourIt){
  454. tie(e1,found)=edge(vertex(cluster[i],g),vertex(*neighbourIt,g),g);
  455. if(In_tab(cluster,*neighbourIt)!=1){
  456. cpt+=g[e1]._weight;
  457. }
  458. }
  459. }
  460. vol = Cluster_Weight(g,cluster);
  461. }
  462. return cpt;
  463. }
  464. 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){
  465. edge_t e1;
  466. bool found;
  467. //std::cout<<"le sommet tiré est : "<<vertexs<<std::endl;
  468. if(name == "cut")
  469. {
  470. std::vector<double> modif_cut(community.size());
  471. double cpt_comm_in;
  472. double cpt_comm_out;
  473. for(uint i =0; i<community.size(); i++){
  474. double tmp_cut = cut;
  475. cpt_comm_in=0;
  476. cpt_comm_out=0;
  477. tie(neighbourIt, neighbourEnd) = adjacent_vertices(vertexs,*g);
  478. for (; neighbourIt != neighbourEnd; ++neighbourIt){
  479. tie(e1,found)=edge(vertex(vertexs,*g),vertex(*neighbourIt,*g),*g);
  480. if(In_tab(*Partition.at(comm_in),*neighbourIt)==1)
  481. cpt_comm_in+=(*g)[e1]._weight;
  482. else if(In_tab(*Partition.at(community.at(i)),*neighbourIt)==1)
  483. cpt_comm_out+=(*g)[e1]._weight;
  484. }
  485. tmp_cut+=cpt_comm_in;
  486. tmp_cut-=cpt_comm_out;
  487. modif_cut.at(i)=tmp_cut;
  488. }
  489. return modif_cut;
  490. }
  491. else if(name == "norm"){
  492. std::vector<double> modif_cut(community.size());
  493. double cpt_comm_in;
  494. double cpt_comm_out;
  495. double tmp_cut;
  496. for(uint i =0; i<community.size(); i++){
  497. std::vector<std::vector<double> > tab_cut = tabe_cut;
  498. tmp_cut =0.;
  499. cpt_comm_in=0.;
  500. cpt_comm_out=0.;
  501. tie(neighbourIt, neighbourEnd) = adjacent_vertices(vertexs,*g);
  502. for (; neighbourIt != neighbourEnd; ++neighbourIt){
  503. tie(e1,found)=edge(vertex(vertexs,*g),vertex(*neighbourIt,*g),*g);
  504. if(In_tab(*Partition.at(comm_in),*neighbourIt)==1)
  505. cpt_comm_in+=(*g)[e1]._weight;
  506. else if(In_tab(*Partition.at(community.at(i)),*neighbourIt)==1)
  507. cpt_comm_out+=(*g)[e1]._weight;
  508. }
  509. cpt_comm_in/=2.;
  510. cpt_comm_out/=2.;
  511. tab_cut.at(comm_in).at(0)+=cpt_comm_in;
  512. tab_cut.at(comm_in).at(0)-=cpt_comm_out;
  513. tab_cut.at(comm_in).at(1)-= Degree(*g ,vertexs);
  514. tab_cut.at(community.at(i)).at(0)+=cpt_comm_in;
  515. tab_cut.at(community.at(i)).at(0)-=cpt_comm_out;
  516. tab_cut.at(community.at(i)).at(1)+= Degree(*g ,vertexs);
  517. for(uint j = 0; j < tab_cut.size();j++){
  518. tmp_cut+=((tab_cut.at(j).at(0))/(tab_cut.at(j).at(1)));
  519. }
  520. modif_cut.at(i)=tmp_cut;
  521. }
  522. }else if(name == "ratio"){
  523. std::vector<double> modif_cut(community.size());
  524. double cpt_comm_in;
  525. double cpt_comm_out;
  526. double tmp_cut;
  527. for(uint i =0; i<community.size(); i++){
  528. std::vector<std::vector<double> > tab_cut = tabe_cut;
  529. tmp_cut =0.;
  530. cpt_comm_in=0.;
  531. cpt_comm_out=0.;
  532. tie(neighbourIt, neighbourEnd) = adjacent_vertices(vertexs,*g);
  533. for (; neighbourIt != neighbourEnd; ++neighbourIt){
  534. tie(e1,found)=edge(vertex(vertexs,*g),vertex(*neighbourIt,*g),*g);
  535. if(In_tab(*Partition.at(comm_in),*neighbourIt)==1)
  536. cpt_comm_in+=(*g)[e1]._weight;
  537. else if(In_tab(*Partition.at(community.at(i)),*neighbourIt)==1)
  538. cpt_comm_out+=(*g)[e1]._weight;
  539. }
  540. /*cpt_comm_in/=2.;
  541. cpt_comm_out/=2.;*/
  542. tab_cut.at(comm_in).at(0)+=cpt_comm_in;
  543. tab_cut.at(comm_in).at(0)-=cpt_comm_out;
  544. tab_cut.at(comm_in).at(1)-= (*g)[vertexs]._weight;
  545. tab_cut.at(community.at(i)).at(0)+=cpt_comm_in;
  546. tab_cut.at(community.at(i)).at(0)-=cpt_comm_out;
  547. tab_cut.at(community.at(i)).at(1)+= (*g)[vertexs]._weight;
  548. for(uint j = 0; j < tab_cut.size();j++){
  549. tmp_cut+=((tab_cut.at(j).at(0))/(tab_cut.at(j).at(1)));
  550. }
  551. modif_cut.at(i)=tmp_cut;
  552. }
  553. return modif_cut;
  554. }
  555. }
  556. void Modif_fonction_Gain_Cut(EntiersEntiers &Partition,UnorientedGraph *g, Entiers &community, int val, double &cut,std::string name)
  557. {
  558. /*std::cout<<"Nombre de communauté voisine : "<<community.size()<<std::endl;
  559. std::cout<<"\n"<<std::endl;*/
  560. for(uint i = 0; i<community.size();i++){
  561. EntiersEntiers new_partition;
  562. for(uint k = 0; k < Partition.size();k++){
  563. Entiers * tmp = new Entiers();
  564. for(uint j = 0;j<Partition.at(k)->size();j++){
  565. tmp->push_back(Partition.at(k)->at(j));
  566. }
  567. new_partition.push_back(tmp);
  568. }
  569. /*std::cout<<"Avant Modification partition"<<std::endl;
  570. std::cout<<"************"<<std::endl;
  571. for(uint t = 0; t< new_partition.size() ; t++)
  572. {
  573. for(uint j = 0 ; j<new_partition.at(t)->size() ; j++)
  574. {
  575. std::cout<<new_partition.at(t)->at(j)<<std::endl;
  576. }
  577. std::cout<<"\n"<<std::endl;
  578. }
  579. std::cout<<"************"<<std::endl;*/
  580. new_partition.at(community.at(i))->push_back(val);
  581. suprim_val(*new_partition.at(In_community_dichotomie(Partition,val)),val);
  582. std::sort(new_partition.at(community.at(i))->begin(),
  583. new_partition.at(community.at(i))->end());
  584. /*std::cout<<"Modification partition"<<std::endl;
  585. std::cout<<"************"<<std::endl;
  586. for(uint t= 0; t< new_partition.size() ; t++)
  587. {
  588. for(uint j = 0 ; j<new_partition.at(t)->size() ; j++)
  589. {
  590. std::cout<<new_partition.at(t)->at(j)<<std::endl;
  591. }
  592. std::cout<<"\n"<<std::endl;
  593. }
  594. std::cout<<"************"<<std::endl;*/
  595. double coupe = Cut_cluster(new_partition,*g,name);
  596. //std::cout<<"cout de coupe : "<<coupe<<std::endl;
  597. if(coupe<cut)
  598. {
  599. for(EntiersEntiers::iterator it = Partition.begin(); it != Partition.end(); it++)
  600. {
  601. delete *it;
  602. *it = NULL;
  603. }
  604. Partition = new_partition;
  605. cut = coupe;
  606. }
  607. else
  608. {
  609. for(EntiersEntiers::iterator it = new_partition.begin(); it != new_partition.end(); it++)
  610. {
  611. delete *it;
  612. *it = NULL;
  613. }
  614. }
  615. }
  616. }
  617. bool contraction_HEM(UnorientedGraph *g, Base_Graph &baseg, ListEntiersEntiers &liste_corr, int val_reduc, int &val_cpt){
  618. UnorientedGraph *gtmp = new UnorientedGraph(*g);
  619. Entiers Random_list_vertices; // Initialisation du tableau de sommets rangés aléatoirements
  620. EntiersEntiers *tableau_de_correspondance = new EntiersEntiers();
  621. edge_t e1,e2; // Iterateurs sur les arcs
  622. bool found;
  623. uint nbr_vertex = num_vertices(*gtmp);
  624. Entiers sommets_a_detruire; // Initialisation d'un tableau pret à recevoir les "sommets à détruire"
  625. /*
  626. * Création d'un vecteur contenant l'ensemble des sommets du graphe. Ces sommets sont rangés
  627. * aléatoirement afin de simuler un tirage aléatoire
  628. */
  629. for (uint i=0 ; i<nbr_vertex ; i++)
  630. Random_list_vertices.push_back(i);
  631. for (uint j=0 ; j<nbr_vertex-1 ; j++) {
  632. int rand_pos = rand()%(nbr_vertex-j)+j;
  633. int tmp = Random_list_vertices[j];
  634. Random_list_vertices[j] = Random_list_vertices[rand_pos];
  635. Random_list_vertices[rand_pos] = tmp;
  636. }
  637. /*
  638. * Pour chaque sommet non verrouiller faire ....
  639. */
  640. for(uint i=0; i<nbr_vertex; i++){
  641. int vertexs = Random_list_vertices[i];
  642. //std::cout<<"Le sommet tiré est : "<<vertexs<<std::endl;
  643. if(vertexs!=-1){
  644. Entiers liste_voisin = Liste_adjacence(*gtmp,vertexs,Random_list_vertices); // Recherche des sommets adjacents au sommets tiré
  645. if(liste_voisin.size()!=0){
  646. /*
  647. * S'il en existe au mois un sommet adjacent au sommet tiré qui n'est pas verrouillé, on
  648. * choisi celui dont l'arc les reliants est le plus fort. Dans le cas où les arcs ont tous
  649. * le même poids, on selectionne le sommet d'index le plus petit
  650. */
  651. double poids_a = 0.;
  652. int best_vertexs = -1;
  653. for(uint j=0;j<liste_voisin.size();j++){
  654. tie(e1,found)=edge(vertex(vertexs,*gtmp),vertex(liste_voisin[j],*gtmp),*gtmp);
  655. if((*gtmp)[e1]._weight>poids_a){
  656. best_vertexs = liste_voisin[j];
  657. poids_a = (*gtmp)[e1]._weight;
  658. }
  659. }
  660. Entiers * couple = new Entiers(); // Initialisation du vecteur contenant le couple de sommet fusionné
  661. int vertex_delete = std::max(vertexs, best_vertexs); // Sommet d'index le plus grand (qui sera détruit)
  662. //std::cout<<"sommet détruit : "<<vertex_delete<<std::endl;
  663. int vertex_save = std::min(vertexs,best_vertexs); // Sommet d'identifiant le plus petit (qui sera conservé)
  664. //std::cout<<"sommet sauvé : "<<vertex_save<<std::endl;
  665. sommets_a_detruire.push_back(vertex_delete); // On ajoute le sommet détruit au tableau des sommets à détruire
  666. /*
  667. * On ajoute au tableau "couple" le couple de sommet à fusionner
  668. */
  669. couple->push_back(vertex_save);
  670. couple->push_back(vertex_delete);
  671. tableau_de_correspondance->push_back(couple); // Ajout du "couple" à la liste de correspondance
  672. remove_edge(vertex_save,vertex_delete,*gtmp); // Suppression de l'arc reliant le couple de sommets
  673. Entiers neigh_vertex_save; // Initialisation du vecteur contenant les sommets adjacents au "sommet sauvegardé"
  674. Entiers neigh_vertex_delete; // Initialisation du vecteur contenant les somemts adjacents au "sommet à détruire"
  675. tie(neighbourIt, neighbourEnd) = adjacent_vertices(vertex_save,*gtmp);
  676. /*
  677. * Remplissage de ces deux tableaux à l'aide de la fonction adjacent_vertices de boost graph
  678. * [La création de ces tableaux est nécéssaire du fait que certains arcs sont détruit au cours
  679. * du processus]
  680. */
  681. for (; neighbourIt != neighbourEnd; ++neighbourIt){
  682. neigh_vertex_save.push_back(*neighbourIt);
  683. }
  684. tie(neighbourIt, neighbourEnd) = adjacent_vertices(vertex_delete,*gtmp);
  685. for (; neighbourIt != neighbourEnd; ++neighbourIt){
  686. neigh_vertex_delete.push_back(*neighbourIt);
  687. }
  688. /*
  689. * Recherche de sommets communs entre le "sommet sauvegardé" et le "sommet à détruire"
  690. * S'il existe un tel sommet "v" alors on ajoute le poids de l'arcs (vertex_delet,v)
  691. * à celui de l'arcs (vertex_save,v) et on détruit l'arcs reliant "v" au "sommet à détruire"
  692. */
  693. for(uint j=0;j<neigh_vertex_delete.size();j++){
  694. if(In_tab(neigh_vertex_save,neigh_vertex_delete[j])==1){
  695. tie(e2,found)=edge(vertex(vertex_save,*gtmp),vertex(neigh_vertex_delete[j],*gtmp),*gtmp);
  696. tie(e1,found)=edge(vertex(vertex_delete,*gtmp),vertex(neigh_vertex_delete[j],*gtmp),*gtmp);
  697. (*gtmp)[e2]._weight+=(*gtmp)[e1]._weight;
  698. remove_edge(vertex_delete,neigh_vertex_delete[j],*gtmp);
  699. }
  700. else
  701. {
  702. tie(e1,found)=edge(vertex(vertex_delete,*gtmp),vertex(neigh_vertex_delete[j],*gtmp),*gtmp);
  703. add_edge(vertex_save,neigh_vertex_delete[j],EdgeProperties((*gtmp)[e1]._weight),*gtmp);
  704. remove_edge(vertex_delete,neigh_vertex_delete[j],*gtmp);
  705. }
  706. }
  707. (*gtmp)[vertex_save]._weight+=(*gtmp)[vertex_delete]._weight; // ajout du poids du sommet détruit au sommet conservé
  708. /*
  709. * Vérouillage du "sommet sauvegardé" et du "sommet à détruire"
  710. */
  711. Random_list_vertices[i]=-1;
  712. Random_list_vertices[recherche_val(Random_list_vertices,best_vertexs)]=-1;
  713. val_cpt--;
  714. // std::cout<<val_cpt<<std::endl;
  715. }
  716. else{
  717. /*
  718. * Et si le sommet tiré ne possède pas de sommet adjacent non verrouillé
  719. * alors on l'ajoute à la liste de correspondance des sommets et on
  720. * le verrouille
  721. */
  722. Entiers *couple = new Entiers();
  723. couple->push_back(Random_list_vertices.at(i));
  724. tableau_de_correspondance->push_back(couple);
  725. Random_list_vertices[i]=-1;
  726. }
  727. /*std::cout<<"Graphe contracté : "<<std::endl;
  728. tie(vertexIt, vertexEnd) = vertices(*gtmp);
  729. for (; vertexIt != vertexEnd; ++vertexIt) {
  730. std::cout << (*gtmp)[*vertexIt]._index
  731. << " est connecté avec ";
  732. tie(neighbourIt, neighbourEnd) = adjacent_vertices(*vertexIt,
  733. *gtmp);
  734. for (; neighbourIt != neighbourEnd; ++neighbourIt)
  735. std::cout << (*gtmp)[*neighbourIt]._index << " ";
  736. std::cout << " et son poids est de "
  737. << (*gtmp)[*vertexIt]._weight<<std::endl;
  738. }
  739. std::cout << std::endl;*/
  740. }
  741. if(val_cpt == val_reduc){
  742. for(uint j=i+1; j <nbr_vertex; j++){
  743. if(Random_list_vertices[j] !=-1){
  744. Entiers *couple = new Entiers();
  745. couple->push_back(Random_list_vertices.at(j));
  746. tableau_de_correspondance->push_back(couple);}
  747. }
  748. break;
  749. }
  750. }
  751. std::sort(sommets_a_detruire.begin(), sommets_a_detruire.end()); // Trie dans l'ordre croissant des "sommets à détruire"
  752. // std::cout<<"\n"<<std::endl;
  753. /*
  754. * Suppression des sommets de la liste "sommets à détruire". Cette suppression est
  755. * effectuée dans l'ordre décroissant afin à maintenir à jour la renumérotation
  756. * des sommets
  757. */
  758. for(int j=(sommets_a_detruire.size()-1);j>-1;j--){
  759. //std::cout<<"Noeuds a supprimer : "<<sommets_a_detruire.at(j)<<std::endl;
  760. remove_vertex(sommets_a_detruire[j],*gtmp);
  761. }
  762. // std::clog<<"Affichage avant tri "<<std::endl;
  763. // for(uint k = 0;k<tableau_de_correspondance->size();k++){
  764. // for(uint v = 0; v<tableau_de_correspondance->at(k)->size();v++){
  765. // std::cout<<tableau_de_correspondance->at(k)->at(v)<<" ";
  766. // }
  767. // std::cout<<"\n"<<std::endl;
  768. // }
  769. 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
  770. // std::clog<<"Tableau de correspondance "<<std::endl;
  771. // for(uint k = 0;k<tableau_de_correspondance->size();k++){
  772. // for(uint v = 0; v<tableau_de_correspondance->at(k)->size();v++){
  773. // std::cout<<tableau_de_correspondance->at(k)->at(v)<<" ";
  774. // }
  775. // std::cout<<"\n"<<std::endl;
  776. // }
  777. liste_corr.push_back(tableau_de_correspondance);
  778. // std::cout<<"\n"<<std::endl;
  779. baseg.push_back(gtmp); // Ajout du graphe modifié à la "base des graphe"
  780. if(val_cpt == val_reduc)
  781. return true;
  782. else
  783. return false;
  784. }
  785. bool contraction_Random_Maching(UnorientedGraph *g, Base_Graph &baseg, ListEntiersEntiers &liste_corr, int val_reduc, int &val_cpt){
  786. UnorientedGraph *gtmp = new UnorientedGraph();
  787. *gtmp=*g;
  788. Entiers Random_list_vertices; // Initialisation du tableau de sommets rangés aléatoirements
  789. EntiersEntiers *tableau_de_correspondance = new EntiersEntiers();
  790. edge_t e1,e2; // Iterateurs sur les arcs
  791. bool found;
  792. uint nbr_vertex = num_vertices(*gtmp);
  793. Entiers sommets_a_detruire; // Initialisation d'un tableau pret à recevoir les "sommets à détruire"
  794. /*
  795. * Création d'un vecteur contenant l'ensemble des sommets du graphe. Ces sommets sont rangés
  796. * aléatoirement afin de simuler un tirage aléatoire
  797. */
  798. for (uint i=0 ; i<nbr_vertex ; i++)
  799. Random_list_vertices.push_back(i);
  800. for (uint j=0 ; j<nbr_vertex-1 ; j++) {
  801. int rand_pos = rand()%(nbr_vertex-j)+j;
  802. int tmp = Random_list_vertices[j];
  803. Random_list_vertices[j] = Random_list_vertices[rand_pos];
  804. Random_list_vertices[rand_pos] = tmp;
  805. }
  806. /*
  807. * Pour chaque sommet non verrouiller faire ....
  808. */
  809. for(uint i=0; i<nbr_vertex; i++){
  810. int vertexs = Random_list_vertices[i];
  811. if(vertexs!=-1){
  812. Entiers liste_voisin = Liste_adjacence(*gtmp,vertexs,Random_list_vertices); // Recherche des sommets adjacents au sommets tiré
  813. if(liste_voisin.size()!=0){
  814. /*
  815. * S'il en existe au mois un sommet adjacent au sommet tiré qui n'est pas verrouillé, on
  816. * choisi celui dont l'arc les reliants est le plus fort. Dans le cas où les arcs ont tous
  817. * le même poids, on selectionne le sommet d'identifiant le plus petit
  818. */
  819. int tmp;
  820. if(liste_voisin.size()==1)
  821. tmp = 0;
  822. else
  823. tmp = rand_fini(0,liste_voisin.size()-1);
  824. int best_vertexs = liste_voisin.at(tmp);
  825. Entiers * couple = new Entiers(); // Initialisation du vecteur contenant le couple de sommet fusionné
  826. int vertex_delete = std::max(vertexs, best_vertexs); // Sommet d'indentifiant le plus grand (qui sera détruit)
  827. //std::cout<<"sommet détruit : "<<vertex_delete<<std::endl;
  828. int vertex_save = std::min(vertexs,best_vertexs); // Sommet d'identifiant le plus petit (qui sera conservé)
  829. //std::cout<<"sommet sauvé : "<<vertex_save<<std::endl;
  830. sommets_a_detruire.push_back(vertex_delete); // On ajoute le sommet détruit au tableau des sommets à détruire
  831. /*
  832. * On ajoute au tableau "couple" le couple de sommet à fusionner
  833. */
  834. couple->push_back(vertex_save);
  835. couple->push_back(vertex_delete);
  836. tableau_de_correspondance->push_back(couple); // Ajout du "couple" à la liste de correspondance
  837. remove_edge(vertex_save,vertex_delete,*gtmp); // Suppression de l'arc reliant le couple de sommets
  838. Entiers neigh_vertex_save; // Initialisation du vecteur contenant les somemts adjacents au "sommet sauvegardé"
  839. Entiers neigh_vertex_delete; // Initialisation du vecteur contenant les somemts adjacents au "sommet à détruire"
  840. tie(neighbourIt, neighbourEnd) = adjacent_vertices(vertex_save,*gtmp);
  841. /*
  842. * Remplissage de ces deux tableaux à l'aide de la fonction adjacent_vertices de boost graph
  843. * [La création de ces tableaux est nécéssaire du fait que certains arcs sont détruit au cours
  844. * du processus]
  845. */
  846. for (; neighbourIt != neighbourEnd; ++neighbourIt){
  847. neigh_vertex_save.push_back(*neighbourIt);
  848. }
  849. tie(neighbourIt, neighbourEnd) = adjacent_vertices(vertex_delete,*gtmp);
  850. for (; neighbourIt != neighbourEnd; ++neighbourIt){
  851. neigh_vertex_delete.push_back(*neighbourIt);
  852. }
  853. /*
  854. * Recherche de sommets communs entre le "sommet sauvegardé" et le "sommet à détruire"
  855. * S'il existe un tel sommet "v" alors on ajoute le poids de l'arcs (vertex_delet,v)
  856. * à celui de l'arcs (vertex_save,v) et on détruit l'arcs reliant "v" au "sommet à détruire"
  857. */
  858. for(uint j=0;j<neigh_vertex_delete.size();j++){
  859. if(In_tab(neigh_vertex_save,neigh_vertex_delete[j])==1){
  860. tie(e2,found)=edge(vertex(vertex_save,*gtmp),vertex(neigh_vertex_delete[j],*gtmp),*gtmp);
  861. tie(e1,found)=edge(vertex(vertex_delete,*gtmp),vertex(neigh_vertex_delete[j],*gtmp),*gtmp);
  862. (*gtmp)[e2]._weight+=(*gtmp)[e1]._weight;
  863. remove_edge(vertex_delete,neigh_vertex_delete[j],*gtmp);
  864. }
  865. else
  866. {
  867. tie(e1,found)=edge(vertex(vertex_delete,*gtmp),vertex(neigh_vertex_delete[j],*gtmp),*gtmp);
  868. add_edge(vertex_save,neigh_vertex_delete[j],EdgeProperties((*gtmp)[e1]._weight),*gtmp);
  869. remove_edge(vertex_delete,neigh_vertex_delete[j],*gtmp);
  870. }
  871. }
  872. (*gtmp)[vertex_save]._weight+=(*gtmp)[vertex_delete]._weight; // ajout du poids du sommet détruit au sommet conservé
  873. /*
  874. * Vérouillage du "sommet sauvegardé" et du "sommet à détruire"
  875. */
  876. Random_list_vertices[i]=-1;
  877. Random_list_vertices[recherche_val(Random_list_vertices,best_vertexs)]=-1;
  878. val_cpt--;
  879. // std::cout<<val_cpt<<std::endl;
  880. }
  881. else{
  882. /*
  883. * Et si le sommet tiré ne possède pas de sommet adjacent non verrouillé
  884. * alors on l'ajoute à la liste de correspondance des sommets et on
  885. * le verrouille
  886. */
  887. Entiers *couple = new Entiers();
  888. couple->push_back(Random_list_vertices.at(i));
  889. tableau_de_correspondance->push_back(couple);
  890. Random_list_vertices[i]=-1;
  891. }
  892. }
  893. if(val_cpt == val_reduc){
  894. for(uint j=i+1; j <nbr_vertex; j++){
  895. if(Random_list_vertices[j] !=-1){
  896. Entiers *couple = new Entiers();
  897. couple->push_back(Random_list_vertices.at(j));
  898. tableau_de_correspondance->push_back(couple);}
  899. }
  900. break;
  901. }
  902. }
  903. std::sort(sommets_a_detruire.begin(), sommets_a_detruire.end()); // Trie dans l'ordre croissant des "sommets à détruire"
  904. //std::cout<<"\n"<<std::endl;
  905. /*
  906. * Suppression des sommets de la liste "sommets à détruire". Cette suppression est
  907. * effectuée dans l'ordre décroissant afin à maintenir à jour la renumérotation
  908. * des sommets
  909. */
  910. for(int j=(sommets_a_detruire.size()-1);j>-1;j--){
  911. //std::cout<<"Noeuds a supprimer : "<<sommets_a_detruire.at(j)<<std::endl;
  912. remove_vertex(sommets_a_detruire[j],*gtmp);
  913. }
  914. /**std::clog<<"Affichage avant tri "<<std::endl;
  915. for(uint k = 0;k<tableau_de_correspondance->size();k++){
  916. for(uint v = 0; v<tableau_de_correspondance->at(k)->size();v++){
  917. std::cout<<tableau_de_correspondance->at(k)->at(v)<<" ";
  918. }
  919. std::cout<<"\n"<<std::endl;
  920. }*/
  921. 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
  922. // std::clog<<"Tableau de correspondance "<<std::endl;
  923. // for(uint k = 0;k<tableau_de_correspondance->size();k++){
  924. // for(uint v = 0; v<tableau_de_correspondance->at(k)->size();v++){
  925. // std::cout<<tableau_de_correspondance->at(k)->at(v)<<" ";
  926. // }
  927. // std::cout<<"\n"<<std::endl;
  928. // }
  929. liste_corr.push_back(tableau_de_correspondance);
  930. // std::cout<<"\n"<<std::endl;
  931. baseg.push_back(gtmp); // Ajout du graphe modifié à la "base des graphe"
  932. if(val_cpt == val_reduc)
  933. return true;
  934. else
  935. return false;
  936. }
  937. Entiers Liste_adjacence(UnorientedGraph &g, int vertexs,const Entiers &random_vertices){ // a revoir !!!!
  938. Entiers liste_voisin;
  939. tie(neighbourIt, neighbourEnd) = adjacent_vertices(vertexs, g);
  940. for (; neighbourIt != neighbourEnd; ++neighbourIt){
  941. if(In_tab(random_vertices,*neighbourIt)==1)
  942. liste_voisin.push_back(*neighbourIt);
  943. }
  944. return liste_voisin;
  945. }
  946. int rand_fini(int a, int b){
  947. return rand()%(b-a)+a;
  948. }
  949. /**
  950. * Fonction de recherche d'une valeur dans un tableau.
  951. * @param tab
  952. * @param val
  953. * @return
  954. */
  955. int recherche_val2(const std::vector<float> &tab,float val){
  956. int cpt=0;
  957. while(tab[cpt]!=val)
  958. cpt++;
  959. return cpt;
  960. }
  961. int recherche_val_double(const std::vector<double> &tab,double val){
  962. int cpt=0;
  963. while(tab[cpt]!=val)
  964. cpt++;
  965. return cpt;
  966. }
  967. int recherche_val(const Entiers &tab,int val){
  968. int cpt=0;
  969. while(tab[cpt]!=val)
  970. cpt++;
  971. return cpt;
  972. }
  973. /**
  974. * @param tab
  975. * @param i
  976. * @return
  977. */
  978. int dichotomie(const Entiers &tab, int i){
  979. /* déclaration des variables locales à la fonction */
  980. int id; //indice de début
  981. int ifin; //indice de fin
  982. int im; //indice de "milieu"
  983. /* initialisation de ces variables avant la boucle de recherche */
  984. id = 0; //intervalle de recherche compris entre 0...
  985. ifin = tab.size(); //...et nbVal
  986. /* boucle de recherche */
  987. while ((ifin - id) > 1){
  988. im = (id + ifin)/2; //on détermine l'indice de milieu
  989. 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
  990. 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
  991. }
  992. /* test conditionnant la valeur que la fonction va renvoyer */
  993. if (tab[id] == i) return id; //si on a trouvé la bonne valeur, on retourne l'indice
  994. else return -1; //sinon on retourne -1
  995. }
  996. /**
  997. * Fonction permettant de supprimer une case d'un tableau.
  998. * @param tab une référence sur un tableau d'entiers
  999. * @param i un indice dans tab
  1000. */
  1001. void suprim_val(Entiers &tab,int i) {
  1002. tab.erase(tab.begin() + dichotomie(tab,i));
  1003. }
  1004. /**
  1005. * Détermine si une valeur se trouve dans un tableau.
  1006. * @param tab une référence sur un tableau d'entiers
  1007. * @param val une valeur
  1008. * @return true si la valeur a été trouvée, false sinon
  1009. */
  1010. bool In_tab(const Entiers &tab, int val)
  1011. {
  1012. for (uint i=0; i < tab.size(); i++)
  1013. if(tab[i]==val)
  1014. return true;
  1015. return false;
  1016. }
  1017. bool In_tab_dichotomie(const Entiers &tab, int val)
  1018. {
  1019. if(dichotomie(tab,val)!=-1)
  1020. return true;
  1021. else
  1022. return false;
  1023. }
  1024. void Liste_Voisin(const Entiers &P,Entiers &tab,const UnorientedGraph &g)
  1025. {
  1026. tie(neighbourIt, neighbourEnd) = adjacent_vertices(P.at(P.size()-1), g);
  1027. for (; neighbourIt != neighbourEnd; ++neighbourIt)
  1028. {
  1029. if((In_tab(tab,*neighbourIt) == false ) && (In_tab(P,*neighbourIt) == false ))
  1030. tab.push_back(*neighbourIt);
  1031. }
  1032. }
  1033. int Cout_coupe(Entiers P,int val, UnorientedGraph &g)
  1034. {
  1035. int cpt=0;
  1036. P.push_back(val);
  1037. for(uint i=0;i<P.size();i++){
  1038. tie(neighbourIt, neighbourEnd) = adjacent_vertices(P[i], g);
  1039. for (; neighbourIt != neighbourEnd; ++neighbourIt){
  1040. if(In_tab(P,*neighbourIt)!=1){
  1041. cpt++;
  1042. }
  1043. }
  1044. }
  1045. return cpt;
  1046. }
  1047. double Cut_one_cluster(const Entiers &cluster, UnorientedGraph &g, std::string name)
  1048. {
  1049. if(name=="norm"){
  1050. edge_t e1;
  1051. bool found;
  1052. double cpt=0.;
  1053. for(uint i=0;i<cluster.size();i++){
  1054. tie(neighbourIt, neighbourEnd) = adjacent_vertices(cluster.at(i), g);
  1055. for (; neighbourIt != neighbourEnd; ++neighbourIt){
  1056. tie(e1,found)=edge(vertex(cluster[i],g),vertex(*neighbourIt,g),g);
  1057. if(In_tab(cluster,*neighbourIt)!=1){
  1058. cpt+=g[e1]._weight;
  1059. }
  1060. }
  1061. }
  1062. double deg = Cluster_Degree(g,cluster);
  1063. return cpt/deg;
  1064. }
  1065. else if(name == "cut"){
  1066. edge_t e1;
  1067. bool found;
  1068. double cpt=0.;
  1069. for(uint i=0;i<cluster.size();i++){
  1070. tie(neighbourIt, neighbourEnd) = adjacent_vertices(cluster.at(i), g);
  1071. for (; neighbourIt != neighbourEnd; ++neighbourIt){
  1072. tie(e1,found)=edge(vertex(cluster.at(i),g),vertex(*neighbourIt,g),g);
  1073. if(In_tab(cluster,*neighbourIt)!=1){
  1074. cpt+=g[e1]._weight;
  1075. }
  1076. }
  1077. }
  1078. return cpt/2.;
  1079. }
  1080. else if(name == "ratio"){
  1081. edge_t e1;
  1082. bool found;
  1083. double cpt=0.;
  1084. for(uint i=0;i<cluster.size();i++){
  1085. tie(neighbourIt, neighbourEnd) = adjacent_vertices(cluster.at(i), g);
  1086. for (; neighbourIt != neighbourEnd; ++neighbourIt){
  1087. tie(e1,found)=edge(vertex(cluster.at(i),g),vertex(*neighbourIt,g),g);
  1088. if(In_tab(cluster,*neighbourIt)!=1){
  1089. cpt+=g[e1]._weight;
  1090. }
  1091. }
  1092. }
  1093. double vol = Cluster_Weight(g,cluster);
  1094. return (cpt/2.)/vol;
  1095. }
  1096. /*Vérification de la formule : doute sur le /2.*/
  1097. }
  1098. double Cut_cluster(const EntiersEntiers &tab_cluster,UnorientedGraph &g,std::string name)
  1099. {
  1100. double cpt=0.;
  1101. for(uint i=0;i<tab_cluster.size();i++){
  1102. cpt+=Cut_one_cluster(*tab_cluster[i],g,name);
  1103. }
  1104. return cpt;
  1105. }
  1106. double Cout_coupe_pond(Entiers P, int val, UnorientedGraph &g)
  1107. {
  1108. edge_t e1;
  1109. bool found;
  1110. double cpt=0;
  1111. P.push_back(val);
  1112. for(uint i=0;i<P.size();i++){
  1113. tie(neighbourIt, neighbourEnd) = adjacent_vertices(P[i], g);
  1114. for (; neighbourIt != neighbourEnd; ++neighbourIt){
  1115. tie(e1,found)=edge(vertex(P[i],g),vertex(*neighbourIt,g),g);
  1116. if(In_tab(P,*neighbourIt)!=1){
  1117. cpt+=g[e1]._weight;
  1118. }
  1119. }
  1120. }
  1121. return cpt;
  1122. }
  1123. int In_community_dichotomie(const EntiersEntiers &part, int val)
  1124. {
  1125. for (uint i = 0; i < part.size() ; i++) {
  1126. if (In_tab_dichotomie(*part[i], val)) {
  1127. return i;
  1128. }
  1129. }
  1130. return -1;
  1131. }
  1132. double Degree(UnorientedGraph& g, int node)
  1133. {
  1134. edge_t e1;
  1135. bool found;
  1136. double val = 0.;
  1137. tie(neighbourIt, neighbourEnd) = adjacent_vertices(node, g);
  1138. for (; neighbourIt != neighbourEnd; ++neighbourIt) {
  1139. tie(e1, found) = edge(vertex(node, g), vertex(*neighbourIt, g), g);
  1140. val += g[e1]._weight;
  1141. }
  1142. return val;
  1143. }
  1144. double Cluster_Degree(UnorientedGraph &g , const Entiers &cluster)
  1145. {
  1146. double val = 0.;
  1147. for(uint i = 0; i < cluster.size(); i++){
  1148. val += Degree(g, cluster.at(i));
  1149. }
  1150. return val;
  1151. }
  1152. double Cluster_Weight(UnorientedGraph &g , const Entiers &cluster)
  1153. {
  1154. double val = 0.;
  1155. for(uint i = 0; i < cluster.size(); i++){
  1156. val += g[cluster.at(i)]._weight;;
  1157. }
  1158. return val;
  1159. }
  1160. void List_edge_partie(Entiers *Partie, OrientedGraph *go, Edges &edge_partie,
  1161. OutputEdges &outputedgespartie){
  1162. edge_to e1;
  1163. //bool found;
  1164. for(uint i = 0; i < Partie->size(); i++) {
  1165. tie(neighbourIto, neighbourEndo) = adjacent_vertices(Partie->at(i),
  1166. *go);
  1167. for (; neighbourIto != neighbourEndo; ++neighbourIto) {
  1168. if(In_tab_dichotomie(*Partie,*neighbourIto)) {
  1169. Edge new_edge;
  1170. new_edge.first = Partie->at(i);
  1171. new_edge.second = *neighbourIto;
  1172. edge_partie.push_back(new_edge);
  1173. } else {
  1174. Edge new_edge;
  1175. new_edge.first = Partie->at(i);
  1176. new_edge.second = *neighbourIto;
  1177. outputedgespartie.push_back(new_edge);
  1178. }
  1179. }
  1180. }
  1181. }
  1182. void Global_Neigh_community(UnorientedGraph *g,
  1183. const EntiersEntiers &Partition,
  1184. Entiers *community, int vertex, int comm_in)
  1185. {
  1186. int comm;
  1187. tie(neighbourIt, neighbourEnd) = adjacent_vertices(vertex, *g);
  1188. for (; neighbourIt != neighbourEnd; ++neighbourIt){
  1189. comm = In_community_dichotomie(Partition, *neighbourIt);
  1190. if (In_tab(*community,comm) != 1 and comm != comm_in)
  1191. community->push_back(comm);
  1192. }
  1193. }
  1194. OrientedGraphs Graph_Partition(const EntiersEntiers& Partition,
  1195. OrientedGraph *go,
  1196. UnorientedGraph *g,
  1197. OutputEdgeList &outputedgelist,
  1198. InputEdgeList &inputedgelist,
  1199. Connections &connections)
  1200. {
  1201. OrientedGraphs graph_partie;
  1202. EntiersEntiers neigh_community;
  1203. for (uint i = 0; i < Partition.size();i++){
  1204. Edges edge_partie;
  1205. List_edge_partie(Partition.at(i),go,edge_partie,outputedgelist.at(i));
  1206. OrientedGraph graph;
  1207. std::vector<vertex_to> tab_vertex_to;
  1208. Entiers *community = new Entiers();
  1209. for (uint j = 0; j < Partition.at(i)->size(); j++) {
  1210. Global_Neigh_community(g, Partition, community,
  1211. Partition.at(i)->at(j),i);
  1212. vertex_to v = add_vertex(graph);
  1213. tab_vertex_to.push_back(v);
  1214. graph[v] = VertexProperties((*go)[Partition.at(i)->at(j)]._index,
  1215. (*go)[Partition.at(i)->at(j)]._weight,
  1216. (*go)[Partition.at(i)->at(j)]._type);
  1217. }
  1218. neigh_community.push_back(community);
  1219. for(uint k = 0; k < edge_partie.size(); k++) {
  1220. add_edge(tab_vertex_to.at(recherche_val(*Partition.at(i),
  1221. edge_partie.at(k).first)),
  1222. tab_vertex_to.at(recherche_val(*Partition.at(i),
  1223. edge_partie.at(k).second)),
  1224. graph);
  1225. }
  1226. graph_partie.push_back(graph);
  1227. }
  1228. for (uint i = 0; i < neigh_community.size(); i++) {
  1229. InputEdges inputedges;
  1230. for (uint j = 0; j < neigh_community.at(i)->size(); j++) {
  1231. for (uint k = 0;
  1232. k < outputedgelist.at(neigh_community.at(i)->at(j)).size();
  1233. k++) {
  1234. if (In_tab_dichotomie(
  1235. *Partition.at(i),
  1236. outputedgelist.at(
  1237. neigh_community.at(i)->at(j)).at(k).second))
  1238. inputedges.push_back(
  1239. outputedgelist.at(
  1240. neigh_community.at(i)->at(j)).at(k));
  1241. }
  1242. }
  1243. inputedgelist.push_back(inputedges);
  1244. }
  1245. for (uint i = 0; i < outputedgelist.size(); i++){
  1246. Connection connec;
  1247. for(uint j = 0; j < outputedgelist.at(i).size(); j++){
  1248. Port port1;
  1249. port1.first = i + 1;
  1250. port1.second = outputedgelist.at(i).at(j).first;
  1251. Port port2;
  1252. port2.first = In_community_dichotomie(
  1253. Partition,outputedgelist.at(i).at(j).second) + 1;
  1254. port2.second = outputedgelist.at(i).at(j).second;
  1255. connec.first = port1;
  1256. connec.second = port2;
  1257. connections.push_back(connec);
  1258. }
  1259. }
  1260. for (EntiersEntiers::iterator it = neigh_community.begin();
  1261. it != neigh_community.end(); it++) {
  1262. delete *it;
  1263. *it = NULL;
  1264. }
  1265. return graph_partie;
  1266. }
  1267. double Best_Cut_cluster(EntiersEntiers &tab_cluster,Entiers *cluster1, Entiers *cluster2, int index_cluster1, UnorientedGraph &g,std::string name)
  1268. {
  1269. tab_cluster.push_back(cluster2);
  1270. double cpt=0.;
  1271. for(int i=0;i<tab_cluster.size();i++){
  1272. if(i!=index_cluster1){
  1273. cpt+=Cut_one_cluster(*tab_cluster[i],g,name);
  1274. }
  1275. }
  1276. cpt+=Cut_one_cluster(*cluster1,g,name);
  1277. tab_cluster.pop_back();
  1278. return cpt;
  1279. }
  1280. /*double In_modularity(UnorientedGraph &g , const Entiers &cluster){
  1281. property_map<UnorientedGraph,edge_weight_t>::type poids_arc=get(edge_weight_t(),g);
  1282. edge_t e1;
  1283. bool found;
  1284. int val=0;
  1285. for(uint i=0;i<cluster.size();i++){
  1286. tie(neighbourIt, neighbourEnd) = adjacent_vertices(cluster[i],g);
  1287. for (; neighbourIt != neighbourEnd; ++neighbourIt){
  1288. tie(e1,found)=edge(vertex(cluster[i],g),vertex(*neighbourIt,g),g);
  1289. if(In_tab(cluster,*neighbourIt)==1)
  1290. val+=get(poids_arc,e1);
  1291. }
  1292. }
  1293. return val/2.;
  1294. }*/
  1295. /**
  1296. *
  1297. * @param g
  1298. * @param cluster
  1299. * @return
  1300. */
  1301. /**
  1302. *
  1303. * @param g
  1304. * @param part
  1305. * @return
  1306. */
  1307. /*double Modularity(UnorientedGraph &g,const EntiersEntiers &part) {
  1308. double q = 0.;
  1309. int tmp=num_edges(g);
  1310. for(uint i=0;i<part.size();i++){
  1311. q+=In_modularity(g,*part[i])/tmp-(Cluster_Degree(g,*part[i])/(2*tmp))*(Cluster_Degree(g,*part[i])/(2*tmp));
  1312. }
  1313. return q;
  1314. }*/
  1315. /**
  1316. *
  1317. * @param part
  1318. * @param val
  1319. * @return
  1320. */
  1321. /**
  1322. * Fonction de calcul du gain de modularité de déplacement d'un sommet d'une communoté à une autre !!!!!
  1323. * ajoute le sommet à part[val] et on calcul la nouvelle modularité
  1324. * on prend la différence entre la modularité et la nouvouvelle !
  1325. * @param cur_mod
  1326. * @param val
  1327. * @param neight
  1328. * @param node_comm
  1329. * @param part
  1330. * @param g
  1331. */
  1332. /*double Modularity_gain(double cur_mod , int val , int neight , int node_comm , EntiersEntiers part , UnorientedGraph &g) {
  1333. double q;
  1334. part[neight]->push_back(val);
  1335. std::sort(*part[neight]);
  1336. q=Modularity(g,part);
  1337. return q-cur_mod;
  1338. }*/
  1339. /**
  1340. * Fonction de calcul du gain de modularité de déplacement d'un sommet d'une communoté à une autre !!!!!
  1341. * ajoute le sommet à part[val] et on calcul la nouvelle modularité
  1342. * on prend la différence entre la modularité et la nouvouvelle !
  1343. * @param cur_mod
  1344. * @param tmp_community
  1345. * @param neight
  1346. * @param node_comm
  1347. * @param part
  1348. * @param g
  1349. */
  1350. /*double Modularity_gain_phase_2(double cur_mod, Entiers tmp_community, int neight, int node_comm, EntiersEntiers part, UnorientedGraph &g) {
  1351. double q;
  1352. for (uint i=0;i<tmp_community.size();i++)
  1353. part[neight]->push_back(tmp_community[i]);
  1354. std::sort(*part[neight]);
  1355. q = Modularity(g,part);
  1356. return q - cur_mod;
  1357. }*/
  1358. /**
  1359. * Donne la liste des communautés voisines à celle contenant le sommet val.
  1360. * @param part
  1361. * @param val
  1362. * @param g
  1363. * @return
  1364. */
  1365. /*Entiers Neight_community(const EntiersEntiers &part, int val , UnorientedGraph &g){
  1366. Entiers Neight;
  1367. tie(neighbourIt, neighbourEnd) = adjacent_vertices(val, g);
  1368. for (; neighbourIt != neighbourEnd; ++neighbourIt){
  1369. int tmp=In_community(part,*neighbourIt);
  1370. if(In_tab(Neight,tmp)!=1 && In_tab(*part[In_community(part,val)],*neighbourIt)!=1)
  1371. Neight.push_back(tmp);
  1372. }
  1373. std::sort(Neight);
  1374. return Neight;
  1375. }*/
  1376. /**
  1377. *
  1378. * @param part
  1379. * @param community
  1380. * @param g
  1381. * @return
  1382. */
  1383. /*Entiers Part_Neight_community(const EntiersEntiers &part,int community, UnorientedGraph &g){
  1384. Entiers Neight;
  1385. for(uint i =0;i<part[community]->size();i++){
  1386. tie(neighbourIt, neighbourEnd) = adjacent_vertices(part[community]->at(i), g);
  1387. for (; neighbourIt != neighbourEnd; ++neighbourIt){
  1388. int tmp=In_community(part,*neighbourIt);
  1389. if(In_tab(Neight,tmp)!=1 && tmp!=community)
  1390. Neight.push_back(tmp);
  1391. }
  1392. }
  1393. std::sort(Neight);
  1394. return Neight;
  1395. }*/
  1396. void make_unoriented_graph(const OrientedGraph& og, UnorientedGraph& ug)
  1397. {
  1398. std::vector < vertex_t > ug_vertex_list;
  1399. std::vector < vertex_t > og_vertex_list;
  1400. for (uint i = 0; i < num_vertices(og); ++i) {
  1401. ug_vertex_list.push_back(add_vertex(ug));
  1402. }
  1403. OrientedGraph::vertex_iterator it_og, end_og;
  1404. UnorientedGraph::vertex_iterator it_ug, end_ug;
  1405. tie(it_og, end_og) = vertices(og);
  1406. tie(it_ug, end_ug) = vertices(ug);
  1407. for (; it_og != end_og; ++it_og, ++it_ug) {
  1408. ug[*it_ug] = og[*it_og];
  1409. og_vertex_list.push_back(*it_og);
  1410. }
  1411. OrientedGraph::edge_iterator ite_og, ende_og;
  1412. tie(ite_og, ende_og) = edges(og);
  1413. for (; ite_og != ende_og; ++ite_og) {
  1414. boost::add_edge(source(*ite_og, og), target(*ite_og, og),
  1415. og[*ite_og], ug);
  1416. }
  1417. // std::cout << "Oriented graph: " << std::endl;
  1418. // tie(it_og, end_og) = vertices(og);
  1419. // for (; it_og != end_og; ++it_og) {
  1420. // OrientedGraph::adjacency_iterator neighbour_it, neighbour_end;
  1421. // std::cout << og[*it_og]._index << " is connected with ";
  1422. // tie(neighbour_it, neighbour_end) = adjacent_vertices(*it_og, og);
  1423. // for (; neighbour_it != neighbour_end; ++neighbour_it)
  1424. // std::cout << og[*neighbour_it]._index << " ";
  1425. // std::cout << " and weight = " << og[*it_og]._weight << std::endl;
  1426. // }
  1427. // std::cout << std::endl;
  1428. // std::cout << "Unoriented graph: " << std::endl;
  1429. // tie(it_ug, end_ug) = vertices(ug);
  1430. // for (; it_ug != end_ug; ++it_ug) {
  1431. // UnorientedGraph::adjacency_iterator neighbour_it, neighbour_end;
  1432. // std::cout << ug[*it_ug]._index << " is connected with ";
  1433. // tie(neighbour_it, neighbour_end) = adjacent_vertices(*it_ug, ug);
  1434. // for (; neighbour_it != neighbour_end; ++neighbour_it)
  1435. // std::cout << ug[*neighbour_it]._index << " ";
  1436. // std::cout << " and weight = " << ug[*it_ug]._weight << std::endl;
  1437. // }
  1438. // std::cout << std::endl;
  1439. }
  1440. void adjacence_ggp(int vertex, Entiers &sommets_adj, UnorientedGraph *g)
  1441. {
  1442. tie(neighbourIt, neighbourEnd) = adjacent_vertices(vertex, *g);
  1443. for (; neighbourIt != neighbourEnd; ++neighbourIt)
  1444. {
  1445. sommets_adj.push_back(*neighbourIt);
  1446. }
  1447. }
  1448. double modif_Cout_coupe(const Entiers &P, int val, double cut, UnorientedGraph *g)
  1449. {
  1450. //std::cout<<"Cout de coupe initiale : "<<cut<<std::endl;
  1451. //std::cout<<"degré du sommet tiré : "<<Degree(*g,val)<<std::endl;
  1452. double cpt = 0.;
  1453. double new_cut;
  1454. bool found;
  1455. edge_t e1;
  1456. tie(neighbourIt, neighbourEnd) = adjacent_vertices(val, *g);
  1457. for (; neighbourIt != neighbourEnd; neighbourIt++){
  1458. if(In_tab(P,*neighbourIt)==1){
  1459. tie(e1,found)=edge(vertex(val,*g),vertex(*neighbourIt,*g),*g);
  1460. cpt += (*g)[e1]._weight;
  1461. }
  1462. }
  1463. new_cut = cut + (Degree(*g,val) - 2*cpt);
  1464. return new_cut;
  1465. }
  1466. int decimal(int valeur){
  1467. int res;
  1468. switch(valeur){
  1469. case 0 ... 9 : res = 0;
  1470. break;
  1471. case 10 ... 99 : res = 1;
  1472. break;
  1473. case 100 ... 999 : res = 2;
  1474. break;
  1475. case 1000 ... 9999 : res = 3;
  1476. break;
  1477. case 10000 ... 99999 : res = 4;
  1478. break;
  1479. case 100000 ... 999999 : res = 5;
  1480. break;
  1481. case 1000000 ... 9999999 : res = 6;
  1482. break;
  1483. case 10000000 ... 99999999 : res = 7;
  1484. break;
  1485. case 100000000 ... 999999999 : res = 8;
  1486. break;
  1487. default :
  1488. std::cout<<"L'interval n'est pas de taille suffisante"<<std::endl;
  1489. break;
  1490. }
  1491. return res;
  1492. }
  1493. void Graph_constructor_txt(const char* text, OrientedGraph * Og){
  1494. //Traitement initial
  1495. std::ifstream fichier (text, std::ios::in);
  1496. int lines = std::count(std::istreambuf_iterator<char>( fichier ),
  1497. std::istreambuf_iterator<char>(),'\n' );
  1498. //std::cout<<"Nombre de ligne : "<<lines<<std::endl;
  1499. fichier.seekg(0, std::ios::beg);
  1500. std::string caractere;
  1501. getline(fichier, caractere);
  1502. int caractere_size = caractere.size()+1;
  1503. fichier.seekg(0, std::ios::beg);
  1504. int nbr_vertices;
  1505. fichier >> nbr_vertices;
  1506. //std::cout << "Nombre de sommets : "<< nbr_vertices<< std::endl;
  1507. //Création des sommets
  1508. std::vector<vertex_to> vect_vertex;
  1509. for(int i =0; i<nbr_vertices; i++){
  1510. vertex_to v0 = boost::add_vertex(*Og);
  1511. vect_vertex.push_back(v0);
  1512. }
  1513. //Création des arcs
  1514. int deplacement_sup = 0;
  1515. for(int i = 0; i <(lines-nbr_vertices-1); i++){
  1516. fichier.seekg((8)*i+caractere_size+deplacement_sup, std::ios::beg);
  1517. int vertex_in, vertex_out;
  1518. double weight;
  1519. fichier >> vertex_in >> vertex_out >> weight ;
  1520. add_edge(vect_vertex.at(vertex_in), vect_vertex.at(vertex_out), EdgeProperties(weight), *Og);
  1521. //std::cout << vertex_in << " " << vertex_out << " " << weight << std::endl;
  1522. int tmp = decimal(vertex_in) + decimal(vertex_out) + decimal(floor(weight));
  1523. deplacement_sup += tmp;
  1524. }
  1525. //Pondération des sommets
  1526. int cpt =0;
  1527. for(int i = lines-nbr_vertices-1; i <lines-1; i++){
  1528. fichier.seekg((8)*(lines-nbr_vertices-1)+caractere_size+deplacement_sup, std::ios::beg);
  1529. double poids;
  1530. std::string txt;
  1531. fichier >> poids >> txt ;
  1532. DynamicsType type;
  1533. if(txt == "NORMAL_PIXEL"){
  1534. type = NORMAL_PIXEL;
  1535. }else{
  1536. type = TOP_PIXEL;
  1537. }
  1538. (*Og)[vect_vertex.at(cpt)] = VertexProperties(cpt, poids, type);
  1539. //std::cout << poids << std::endl;
  1540. int tmp = decimal(floor(poids)) + 17;
  1541. deplacement_sup += tmp;
  1542. cpt++;
  1543. }
  1544. fichier.close();
  1545. }
  1546. void Text_generator_graph(const char *texte, OrientedGraph *go){
  1547. bool found;
  1548. edge_to e1;
  1549. std::ofstream fichier (texte, std::ios::out);
  1550. fichier<<num_vertices(*go)<<std::endl;
  1551. tie(vertexIto, vertexEndo) = vertices(*go);
  1552. for (; vertexIto != vertexEndo; ++vertexIto) {
  1553. tie(neighbourIto, neighbourEndo) = adjacent_vertices(*vertexIto,
  1554. *go);
  1555. for (; neighbourIto != neighbourEndo; ++neighbourIto){
  1556. tie(e1,found)=edge(vertex(*vertexIto,*go),vertex(*neighbourIto,*go),*go);
  1557. if(((*go)[e1]._weight - floor((*go)[e1]._weight)) == 0 ){
  1558. fichier<<(*go)[*vertexIto]._index<<" "<<(*go)[*neighbourIto]._index<<" "<<(*go)[e1]._weight<<".0"<<std::endl;
  1559. }else{
  1560. fichier<<(*go)[*vertexIto]._index<<" "<<(*go)[*neighbourIto]._index<<" "<<(*go)[e1]._weight<<std::endl;
  1561. }
  1562. }
  1563. }
  1564. tie(vertexIto, vertexEndo) = vertices(*go);
  1565. for (; vertexIto != vertexEndo; ++vertexIto) {
  1566. if(((*go)[*vertexIto]._weight - floor((*go)[*vertexIto]._weight)) == 0 && (*go)[*vertexIto]._type == TOP_PIXEL){
  1567. fichier<<(*go)[*vertexIto]._weight<<".0"<<" "<<"TOP_PIXEL"<<" "<<std::endl;
  1568. }else if(((*go)[*vertexIto]._weight - floor((*go)[*vertexIto]._weight)) == 0 && (*go)[*vertexIto]._type == NORMAL_PIXEL){
  1569. fichier<<(*go)[*vertexIto]._weight<<".0"<<" "<<"NORMAL_PIXEL"<<std::endl;
  1570. }else if(((*go)[*vertexIto]._weight - floor((*go)[*vertexIto]._weight)) != 0 && (*go)[*vertexIto]._type == TOP_PIXEL){
  1571. fichier<<(*go)[*vertexIto]._weight<<" "<<"TOP_PIXEL"<<std::endl;
  1572. }else{
  1573. fichier<<(*go)[*vertexIto]._weight<<" "<<"NORMAL_PIXEL"<<std::endl;
  1574. }
  1575. }
  1576. fichier.close();
  1577. }
  1578. double Diff_cut_ratio(UnorientedGraph *g, const EntiersEntiers &Partition, int partie, int node, std::string name){
  1579. double Dif;
  1580. double Int = 0.;
  1581. double Ext = 0.;
  1582. edge_t e1;
  1583. bool found;
  1584. tie(neighbourIt, neighbourEnd) = adjacent_vertices(node, *g);
  1585. for (; neighbourIt != neighbourEnd; ++neighbourIt){
  1586. tie(e1, found) = edge(vertex(node, *g), vertex(*neighbourIt, *g), *g);
  1587. if(In_tab_dichotomie(*Partition.at(partie),*neighbourIt) == 1){
  1588. Int+= (*g)[e1]._weight;
  1589. }else{
  1590. Ext+= (*g)[e1]._weight;
  1591. }
  1592. }
  1593. if(name == "ratio"){
  1594. Int/=Cluster_Weight(*g,*Partition.at(partie));
  1595. Ext/=Cluster_Weight(*g,*Partition.at(partie));
  1596. }
  1597. Dif = Ext - Int;
  1598. return Dif;
  1599. }
  1600. double Diff_cut_ratio_bissection(UnorientedGraph *g, Entiers *part, int node, std::string name){
  1601. double Ext = 0.;
  1602. edge_t e1;
  1603. bool found;
  1604. tie(neighbourIt, neighbourEnd) = adjacent_vertices(node, *g);
  1605. for (; neighbourIt != neighbourEnd; ++neighbourIt){
  1606. tie(e1, found) = edge(vertex(node, *g), vertex(*neighbourIt, *g), *g);
  1607. if(In_tab_dichotomie(*part,*neighbourIt) != 1){
  1608. Ext+= (*g)[e1]._weight;
  1609. }
  1610. }
  1611. return Ext;
  1612. }
  1613. std::vector<std::vector<int>> Vector_diff_cut_ratio(UnorientedGraph *g, const EntiersEntiers &Partition, std::string name){
  1614. std::vector<std::vector<int>> Diff_vector;
  1615. for(uint i = 0; i < Partition.size(); i++){
  1616. std::vector<std::pair<double,int>> D_vector;
  1617. for(uint j = 0; j < Partition.at(i)->size(); j++){
  1618. double gain_d = Diff_cut_ratio(g, Partition, i, Partition.at(i)->at(j), name);
  1619. //std::cout<<gain_d<<std::endl;
  1620. if(gain_d > 0){
  1621. std::pair<double, int> D;
  1622. D.first = gain_d;
  1623. D.second = Partition.at(i)->at(j);
  1624. D_vector.push_back(D);
  1625. }
  1626. }
  1627. sort(D_vector.begin(),D_vector.end());
  1628. std::reverse(D_vector.begin(),D_vector.end());
  1629. std::vector<int> index_vector;
  1630. for(uint id = 0; id < D_vector.size(); id++){
  1631. index_vector.push_back(D_vector.at(id).second);
  1632. }
  1633. Diff_vector.push_back(index_vector);
  1634. }
  1635. /*std::cout<<"Tableau des différences "<<std::endl;
  1636. for(uint i = 0; i<Diff_vector.size(); i++){
  1637. std::cout<<"*"<<i<<"* ";
  1638. for(uint j = 0; j<Diff_vector.at(i).size(); j++){
  1639. std::cout<<Diff_vector.at(i).at(j)<<" ";
  1640. }
  1641. std::cout<<std::endl;
  1642. }*/
  1643. return Diff_vector;
  1644. }
  1645. std::vector<int> Vector_diff_cut_ratio_2(UnorientedGraph *g, const EntiersEntiers &Partition, std::string name){
  1646. std::vector<int> Diff_vector;
  1647. std::vector<std::pair<double,int>> D_vector;
  1648. for(uint i = 0; i < Partition.size(); i++){
  1649. for(uint j = 0; j < Partition.at(i)->size(); j++){
  1650. double gain_d = Diff_cut_ratio(g, Partition, i, Partition.at(i)->at(j), name);
  1651. //std::cout<<gain_d<<std::endl;
  1652. if(gain_d > 0){
  1653. std::pair<double, int> D;
  1654. D.first = gain_d;
  1655. D.second = Partition.at(i)->at(j);
  1656. D_vector.push_back(D);
  1657. }
  1658. }
  1659. }
  1660. sort(D_vector.begin(),D_vector.end());
  1661. for(uint id = 0; id < D_vector.size(); id++){
  1662. Diff_vector.push_back(D_vector.at(id).second);
  1663. }
  1664. /*std::cout<<"Tableau des différences "<<std::endl;
  1665. for(uint i = 0; i<Diff_vector.size(); i++){
  1666. std::cout<<"*"<<i<<"* ";
  1667. for(uint j = 0; j<Diff_vector.at(i).size(); j++){
  1668. std::cout<<Diff_vector.at(i).at(j)<<" ";
  1669. }
  1670. std::cout<<std::endl;
  1671. }*/
  1672. /*for(uint j = 0; j<Diff_vector.size(); j++){
  1673. std::cout<<Diff_vector.at(j)<<" ";
  1674. }
  1675. std::cout<<std::endl;*/
  1676. return Diff_vector;
  1677. }
  1678. void Modif_vector_diff_cut_ratio_2(UnorientedGraph *g, const EntiersEntiers &Partition, std::vector<int> &Diff_vector, int node, std::string name){
  1679. std::vector<std::pair<double,int>> D_vector;
  1680. tie(neighbourIt, neighbourEnd) = adjacent_vertices(node, *g);
  1681. for (; neighbourIt != neighbourEnd; ++neighbourIt){
  1682. //std::cout<<"node : "<<node<<std::endl;
  1683. //std::cout<<"voisin : "<<*neighbourIt<<std::endl;
  1684. int neigh_ind = In_community_dichotomie(Partition, *neighbourIt);
  1685. //std::cout<<"dans : "<<neigh_ind<<std::endl;
  1686. double gain_d = Diff_cut_ratio(g, Partition, neigh_ind, *neighbourIt, name);
  1687. //std::cout<<"gain_d : "<<gain_d<<std::endl;
  1688. if(gain_d > 0){
  1689. std::pair<double, int> D;
  1690. D.first = gain_d;
  1691. D.second = *neighbourIt;
  1692. D_vector.push_back(D);
  1693. }
  1694. //suprim_val(Diff_vector,*neighbourIt);
  1695. }
  1696. if(D_vector.size() == 0){
  1697. Diff_vector.erase(Diff_vector.begin());
  1698. return;
  1699. }
  1700. //std::cout<<"**"<<std::endl;
  1701. sort(D_vector.begin(),D_vector.end());
  1702. for(uint id = 0; id < D_vector.size(); id++){
  1703. if(In_tab(Diff_vector,D_vector.at(id).second) != 1)
  1704. Diff_vector.push_back(D_vector.at(id).second);
  1705. }
  1706. //std::cout<<"***"<<std::endl;
  1707. Diff_vector.erase(Diff_vector.begin());
  1708. //std::cout<<"**!**"<<std::endl;
  1709. sort(Diff_vector.begin(),Diff_vector.end());
  1710. for(uint j = 0; j<Diff_vector.size(); j++){
  1711. std::cout<<Diff_vector.at(j)<<" ";
  1712. }
  1713. //std::cout<<std::endl;
  1714. }
  1715. void Modif_vector_diff_cut_ratio(UnorientedGraph *g, const EntiersEntiers &Partition, std::vector<std::vector<int>> &Diff_vector, int recalcul1, int recalcul2, std::string name){
  1716. std::vector<std::pair<double,int>> D_vector;
  1717. for(uint j = 0; j < Partition.at(recalcul1)->size(); j++){
  1718. double gain_d = Diff_cut_ratio(g, Partition, recalcul1, Partition.at(recalcul1)->at(j), name);
  1719. //std::cout<<gain_d<<std::endl;
  1720. if(gain_d > 0){
  1721. std::pair<double, int> D;
  1722. D.first = gain_d;
  1723. D.second = Partition.at(recalcul1)->at(j);
  1724. D_vector.push_back(D);
  1725. }
  1726. }
  1727. sort(D_vector.begin(),D_vector.end());
  1728. std::reverse(D_vector.begin(),D_vector.end());
  1729. std::vector<int> index_vector;
  1730. for(uint id = 0; id < D_vector.size(); id++){
  1731. index_vector.push_back(D_vector.at(id).second);
  1732. }
  1733. Diff_vector.at(recalcul1) = index_vector;
  1734. std::vector<std::pair<double,int>> D_vector2;
  1735. for(uint j = 0; j < Partition.at(recalcul2)->size(); j++){
  1736. double gain_d = Diff_cut_ratio(g, Partition, recalcul2, Partition.at(recalcul2)->at(j), name);
  1737. //std::cout<<gain_d<<std::endl;
  1738. if(gain_d > 0){
  1739. std::pair<double, int> D;
  1740. D.first = gain_d;
  1741. D.second = Partition.at(recalcul2)->at(j);
  1742. D_vector2.push_back(D);
  1743. }
  1744. }
  1745. sort(D_vector2.begin(),D_vector2.end());
  1746. std::reverse(D_vector2.begin(),D_vector2.end());
  1747. std::vector<int> index_vector2;
  1748. for(uint id = 0; id < D_vector2.size(); id++){
  1749. index_vector2.push_back(D_vector2.at(id).second);
  1750. }
  1751. Diff_vector.at(recalcul2) = index_vector2;
  1752. /*std::cout<<"Tableau des différences modifié "<<std::endl;
  1753. for(uint i = 0; i<Diff_vector.size(); i++){
  1754. std::cout<<"*"<<i<<"* ";
  1755. for(uint j = 0; j<Diff_vector.at(i).size(); j++){
  1756. std::cout<<Diff_vector.at(i).at(j)<<" ";
  1757. }
  1758. std::cout<<std::endl;
  1759. }*/
  1760. }
  1761. void Affinache_gain_diff(UnorientedGraph *g, EntiersEntiers &Partition, double &cut, std::string name, double poids_moy){
  1762. double old_cut = -1.;
  1763. while(old_cut != cut){
  1764. //std::cout<<"Boucle d'ammélioration "<<std::endl;
  1765. old_cut = cut;
  1766. sort(Partition.begin(), Partition.end(), myobject_taille);
  1767. std::vector<std::vector<int>> diff_vector;
  1768. diff_vector = Vector_diff_cut_ratio(g, Partition, name);
  1769. for(uint indice = 0; indice < diff_vector.size(); indice ++){
  1770. if(diff_vector.at(indice).size() != 0 && Partition.at(indice)->size() >1){
  1771. //for(uint i = 0; i < diff_vector.at(indice).size(); i++){
  1772. int i =0;
  1773. while(diff_vector.at(indice).size() != 0 && Partition.at(indice)->size() >1 && i < diff_vector.at(indice).size() &&
  1774. Cluster_Weight(*g,*Partition.at(indice)) > (poids_moy-poids_moy/Partition.size())){
  1775. //std::cout<<"Sommet de départ : "<< diff_vector.at(indice).at(i) <<" dans "<<indice<<std::endl;
  1776. Entiers neigh_part;
  1777. neigh_part = Neigh_community(g, Partition, diff_vector.at(indice).at(i), indice);
  1778. int best_neigh_part = neigh_part.at(0);
  1779. double gain = -10000000.;
  1780. for(uint ind_neigh = 0; ind_neigh < neigh_part.size(); ind_neigh++){
  1781. double tmp_gain;
  1782. if(name == "ratio"){
  1783. tmp_gain = Gain_ratio(g,Partition,indice,neigh_part.at(ind_neigh),diff_vector.at(indice).at(i),cut);
  1784. }else{
  1785. double Int = 0.;
  1786. double Ext = 0.;
  1787. edge_t e1;
  1788. bool found;
  1789. tie(neighbourIt, neighbourEnd) = adjacent_vertices(diff_vector.at(indice).at(i), *g);
  1790. for (; neighbourIt != neighbourEnd; ++neighbourIt){
  1791. tie(e1, found) = edge(vertex(diff_vector.at(indice).at(i), *g), vertex(*neighbourIt, *g), *g);
  1792. if(In_tab_dichotomie(*Partition.at(neigh_part.at(ind_neigh)),*neighbourIt) == 1){
  1793. Ext+= (*g)[e1]._weight;
  1794. }else if(In_tab_dichotomie(*Partition.at(indice),*neighbourIt) == 1){
  1795. Int+= (*g)[e1]._weight;
  1796. }
  1797. }
  1798. tmp_gain = Ext - Int;
  1799. }
  1800. if(tmp_gain > gain & tmp_gain > 0){
  1801. gain = tmp_gain;
  1802. best_neigh_part = neigh_part.at(ind_neigh);
  1803. }
  1804. }
  1805. //std::cout<<" Ensemble de déstination "<<best_neigh_part<<" gain de : "<<gain<<std::endl;
  1806. if(gain > 0){
  1807. //std::cout<<"Modification"<<std::endl;
  1808. cut -= gain; /*Grosse modification a apporté de ce coté la*/
  1809. //std::cout<<"Ratio de coupe : "<<cut<<std::endl;
  1810. suprim_val(*Partition.at(indice),diff_vector.at(indice).at(i));
  1811. Partition.at(best_neigh_part)->push_back(diff_vector.at(indice).at(i));
  1812. sort(Partition.at(best_neigh_part)->begin(),Partition.at(best_neigh_part)->end());
  1813. //double cut2 = Cut_cluster(Partition,*g,"ratio");
  1814. //std::cout<<"Vrai ratio de coupe : "<<cut2<<std::endl;
  1815. Modif_vector_diff_cut_ratio(g,Partition,diff_vector,best_neigh_part,indice,name);
  1816. i = 0;
  1817. }else{
  1818. i++;
  1819. }
  1820. }
  1821. }
  1822. }
  1823. //std::cout<<cut<<std::endl;
  1824. }
  1825. }
  1826. void Affinache_gain_diff_2(UnorientedGraph *g, EntiersEntiers &Partition, double &cut, std::string name, double poids_moy){
  1827. double old_cut = -1.;
  1828. //while(old_cut != cut){
  1829. //std::cout<<"Boucle d'ammélioration "<<std::endl;
  1830. //old_cut = cut;
  1831. sort(Partition.begin(), Partition.end(), myobject_taille);
  1832. std::vector<int> diff_vector;
  1833. diff_vector = Vector_diff_cut_ratio_2(g, Partition, name);
  1834. //for(uint indice = 0; indice < diff_vector.size(); indice ++){
  1835. int indice = 0;
  1836. while(/*indice < diff_vector.size() &&*/ diff_vector.size() != 0){
  1837. int com = In_community_dichotomie(Partition,diff_vector.at(indice));
  1838. std::cout<<" Ensemble de départ "<<com<<" sommet : "<<diff_vector.at(indice)<<std::endl;
  1839. if(Partition.at(com)->size() >1 && Cluster_Weight(*g,*Partition.at(com)) > (poids_moy-poids_moy/Partition.size())){
  1840. Entiers neigh_part;
  1841. neigh_part = Neigh_community(g, Partition, diff_vector.at(indice), com);
  1842. int best_neigh_part = neigh_part.at(0);
  1843. double gain = -10000000.;
  1844. for(uint ind_neigh = 0; ind_neigh < neigh_part.size(); ind_neigh++){
  1845. double tmp_gain;
  1846. if(name == "ratio"){
  1847. tmp_gain = Gain_ratio(g,Partition,com,neigh_part.at(ind_neigh),diff_vector.at(indice),cut);
  1848. }else{
  1849. double Int = 0.;
  1850. double Ext = 0.;
  1851. edge_t e1;
  1852. bool found;
  1853. tie(neighbourIt, neighbourEnd) = adjacent_vertices(diff_vector.at(indice), *g);
  1854. for (; neighbourIt != neighbourEnd; ++neighbourIt){
  1855. tie(e1, found) = edge(vertex(diff_vector.at(indice), *g), vertex(*neighbourIt, *g), *g);
  1856. if(In_tab_dichotomie(*Partition.at(neigh_part.at(ind_neigh)),*neighbourIt) == 1){
  1857. Ext+= (*g)[e1]._weight;
  1858. }else if(In_tab_dichotomie(*Partition.at(com),*neighbourIt) == 1){
  1859. Int+= (*g)[e1]._weight;
  1860. }
  1861. }
  1862. tmp_gain = Ext - Int;
  1863. }
  1864. if(tmp_gain > gain & tmp_gain > 0){
  1865. gain = tmp_gain;
  1866. best_neigh_part = neigh_part.at(ind_neigh);
  1867. }
  1868. }
  1869. std::cout<<" Ensemble de déstination "<<best_neigh_part<<" gain de : "<<gain<<std::endl;
  1870. if(gain > 0){
  1871. std::cout<<"Modification"<<std::endl;
  1872. cut -= gain; /*Grosse modification a apporté de ce coté la*/
  1873. std::cout<<"Ratio de coupe : "<<cut<<std::endl;
  1874. suprim_val(*Partition.at(com),diff_vector.at(indice));
  1875. Partition.at(best_neigh_part)->push_back(diff_vector.at(indice));
  1876. sort(Partition.at(best_neigh_part)->begin(),Partition.at(best_neigh_part)->end());
  1877. double cut2 = Cut_cluster(Partition,*g,"ratio");
  1878. std::cout<<"Vrai ratio de coupe : "<<cut2<<std::endl;
  1879. //Modif_vector_diff_cut_ratio_2(g,Partition,diff_vector,diff_vector.at(indice),name);
  1880. //indice = 0;
  1881. diff_vector.erase(diff_vector.begin());
  1882. }else{
  1883. diff_vector.erase(diff_vector.begin());
  1884. }
  1885. }
  1886. }
  1887. //std::cout<<cut<<std::endl;
  1888. // }
  1889. }
  1890. double Gain_ratio(UnorientedGraph *g,const EntiersEntiers &Partition, int in, int out, int node, double ratio){
  1891. double new_ratio = ratio;
  1892. double poids_in = Cluster_Weight(*g,*Partition.at(in));
  1893. double poids_out = Cluster_Weight(*g,*Partition.at(out));
  1894. double tmp_poids_in = poids_in - (*g)[node]._weight;
  1895. double tmp_poids_out = poids_out + (*g)[node]._weight;
  1896. //std::cout<<"tmp_poids_in "<< tmp_poids_in <<std::endl;
  1897. //std::cout<<"tmp_poids_out "<< tmp_poids_out <<std::endl;
  1898. double cut_in = 0.;
  1899. double cut_out = 0.;
  1900. double tmp_cut_in = 0.;
  1901. double tmp_cut_out = 0.;
  1902. edge_t e1;
  1903. bool found;
  1904. for(uint i = 0; i < Partition.at(in)->size(); i++){
  1905. tie(neighbourIt, neighbourEnd) = adjacent_vertices(Partition.at(in)->at(i), *g);
  1906. for (; neighbourIt != neighbourEnd; ++neighbourIt){
  1907. tie(e1,found)=edge(vertex(Partition.at(in)->at(i),*g),vertex(*neighbourIt,*g),*g);
  1908. if(In_tab_dichotomie(*Partition.at(in),*neighbourIt) != 1){
  1909. if(Partition.at(in)->at(i) != node){
  1910. tmp_cut_in += (*g)[e1]._weight;
  1911. }
  1912. cut_in += (*g)[e1]._weight;
  1913. }else if(*neighbourIt == node){
  1914. tmp_cut_in += (*g)[e1]._weight;
  1915. }
  1916. }
  1917. }
  1918. for(uint i = 0; i < Partition.at(out)->size(); i++){
  1919. tie(neighbourIt, neighbourEnd) = adjacent_vertices(Partition.at(out)->at(i), *g);
  1920. for (; neighbourIt != neighbourEnd; ++neighbourIt){
  1921. tie(e1,found)=edge(vertex(Partition.at(out)->at(i),*g),vertex(*neighbourIt,*g),*g);
  1922. if(In_tab_dichotomie(*Partition.at(out),*neighbourIt) != 1){
  1923. if(*neighbourIt != node){
  1924. tmp_cut_out += (*g)[e1]._weight;
  1925. }
  1926. cut_out += (*g)[e1]._weight;
  1927. }
  1928. }
  1929. }
  1930. tie(neighbourIt, neighbourEnd) = adjacent_vertices(node, *g);
  1931. for (; neighbourIt != neighbourEnd; ++neighbourIt){
  1932. tie(e1,found)=edge(vertex(node,*g),vertex(*neighbourIt,*g),*g);
  1933. if(In_tab_dichotomie(*Partition.at(out),*neighbourIt) != 1){
  1934. tmp_cut_out += (*g)[e1]._weight;
  1935. }
  1936. }
  1937. //std::cout<<"tmp_cut_in "<< tmp_cut_in/2. <<std::endl;
  1938. //std::cout<<"tmp_cut_out "<< tmp_cut_out/2. <<std::endl;
  1939. new_ratio -= cut_in/2./poids_in;
  1940. new_ratio -= cut_out/2./poids_out;
  1941. new_ratio += tmp_cut_in/2./tmp_poids_in;
  1942. new_ratio += tmp_cut_out/2./tmp_poids_out;
  1943. //std::cout<<"Nouveau ratio : " <<new_ratio<<std::endl;
  1944. return ratio - new_ratio;
  1945. }
  1946. double Modif_ratio_cut(UnorientedGraph *g,Entiers *Ss, Entiers *Sd, int node, double ratio){/*Revoir cette fonction, modification psa forcement nécéssaire, plus simple !!!*/
  1947. double new_ratio;
  1948. double poids_in = Cluster_Weight(*g,*Ss);
  1949. double poids_out = Cluster_Weight(*g,*Sd);
  1950. double tmp_poids_in = poids_in - (*g)[node]._weight;
  1951. double tmp_poids_out = poids_out + (*g)[node]._weight;
  1952. //std::cout<<"tmp_poids_in "<< tmp_poids_in <<std::endl;
  1953. //std::cout<<"tmp_poids_out "<< tmp_poids_out <<std::endl;
  1954. double new_cut = 0.;
  1955. //double new_cut_out = 0.;
  1956. //double tmp_cut_in = 0.;
  1957. //double tmp_cut_out = 0.;
  1958. edge_t e1;
  1959. bool found;
  1960. for(uint i = 0; i < Ss->size(); i++){
  1961. if(Ss->at(i) != node){
  1962. tie(neighbourIt, neighbourEnd) = adjacent_vertices(Ss->at(i), *g);
  1963. for (; neighbourIt != neighbourEnd; ++neighbourIt){
  1964. tie(e1,found)=edge(vertex(Ss->at(i),*g),vertex(*neighbourIt,*g),*g);
  1965. if(In_tab_dichotomie(*Ss,*neighbourIt) != 1){
  1966. new_cut += (*g)[e1]._weight;
  1967. }else if(*neighbourIt == node){
  1968. new_cut += (*g)[e1]._weight;
  1969. }
  1970. }
  1971. }
  1972. }
  1973. /*for(uint i = 0; i < Sd->size(); i++){
  1974. tie(neighbourIt, neighbourEnd) = adjacent_vertices(Sd->at(i), *g);
  1975. for (; neighbourIt != neighbourEnd; ++neighbourIt){
  1976. tie(e1,found)=edge(vertex(Sd->at(i),*g),vertex(*neighbourIt,*g),*g);
  1977. if(In_tab(*Sd,*neighbourIt) != 1){
  1978. if(*neighbourIt != node){
  1979. tmp_cut_out += (*g)[e1]._weight;
  1980. }
  1981. cut_out += (*g)[e1]._weight;
  1982. }
  1983. }
  1984. }
  1985. tie(neighbourIt, neighbourEnd) = adjacent_vertices(node, *g);
  1986. for (; neighbourIt != neighbourEnd; ++neighbourIt){
  1987. tie(e1,found)=edge(vertex(node,*g),vertex(*neighbourIt,*g),*g);
  1988. if(In_tab(*Sd,*neighbourIt) != 1){
  1989. tmp_cut_out += (*g)[e1]._weight;
  1990. }
  1991. }*/
  1992. //std::cout<<"tmp_cut_in "<< tmp_cut_in/2. <<std::endl;
  1993. //std::cout<<"tmp_cut_out "<< tmp_cut_out/2. <<std::endl;
  1994. new_ratio = new_cut/2./tmp_poids_in + new_cut/2./tmp_poids_out;
  1995. /*new_ratio -= cut_out/2./poids_out;
  1996. new_ratio += tmp_cut_in/2./tmp_poids_in;
  1997. new_ratio += tmp_cut_out/2./tmp_poids_out;*/
  1998. //std::cout<<"Nouveau ratio : " <<new_ratio<<std::endl;
  1999. return new_ratio;
  2000. }
  2001. } } } // namespace paradevs tests boost_graph