utils.cpp 51 KB

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