gggp.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476
  1. /**
  2. * @file tests/boost_graph/partitioning/gggp.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/gggp.hpp>
  26. #include <algorithm>
  27. #include <iostream>
  28. namespace paradevs { namespace tests { namespace boost_graph {
  29. extern UnorientedGraph::vertex_iterator vertexIt, vertexEnd;
  30. extern UnorientedGraph::adjacency_iterator neighbourIt, neighbourEnd;
  31. extern OrientedGraph::vertex_iterator vertexIto, vertexEndo;
  32. extern OrientedGraph::adjacency_iterator neighbourIto, neighbourEndo;
  33. void gggp(UnorientedGraph *g, Entiers *sommetsSource,
  34. Entiers *sommetsDestination, EntiersEntiers &Partition)
  35. {
  36. int val;
  37. Entiers sommets_adj;
  38. if (sommetsSource->size() - 1 == 0) {
  39. Entiers tailles;
  40. val = 0;
  41. for (uint i = 0;i < Partition.size(); i++) {
  42. tailles.push_back(Partition.at(i)->size());
  43. }
  44. uint tmp = *max_element(tailles.begin(), tailles.end());
  45. for (uint i = 0; i < Partition.size(); i++) {
  46. if (Partition.at(i)->size() == tmp) {
  47. gggp(g, Partition.at(i), sommetsDestination, Partition);
  48. }
  49. break;
  50. }
  51. } else {
  52. // Tirage aléatoire de l'indice du premier sommet entre 0 et
  53. // taille du tableau -1
  54. val = rand_fini(0, sommetsSource->size() - 1);
  55. }
  56. float poids_max=sommetsSource->size()/2.;
  57. float poids=1;
  58. Entiers sommets_cut;
  59. //clog<<"Etape 1 : "<<std::endl;
  60. sommetsDestination->push_back(sommetsSource->at(val));
  61. sommetsSource->erase(sommetsSource->begin() + val);
  62. if (sommetsSource->size() < 2) {
  63. return;
  64. }
  65. while (poids < poids_max) {
  66. // for(uint i =0; i< sommetsDestination.size();i++){
  67. // std::cout<<sommetsDestination.at(i)<<std::endl;
  68. // }
  69. Liste_Voisin(*sommetsDestination, sommets_adj, *g);
  70. if (sommets_adj.size() == 0) {
  71. std::cout<<"Je suis sorti !!!! "<<std::endl;
  72. break;
  73. } else {
  74. /*clog<<"Liste voisin est : "<<std::endl;
  75. for(int i=0;i<sommets_adj.size();i++)
  76. {
  77. std::cout<<sommets_adj[i]<<std::endl;
  78. }*/
  79. std::sort(sommets_adj.begin(), sommets_adj.end());
  80. for (uint i = 0; i < sommets_adj.size(); i++) {
  81. sommets_cut.push_back(Cout_coupe(*sommetsDestination,
  82. sommets_adj[i], *g));
  83. }
  84. int tmp = recherche_val(sommets_cut,
  85. *min_element(sommets_cut.begin(),
  86. sommets_cut.end()));
  87. sommetsDestination->push_back(sommets_adj[tmp]);
  88. suprim_val(*sommetsSource, sommets_adj[tmp]);
  89. suprim_val(sommets_adj, sommets_adj[tmp]);
  90. sommets_cut.clear();
  91. poids++;
  92. }
  93. }
  94. for (uint i = 0; i < sommetsSource->size(); i++) {
  95. for (uint j = 0; j < sommetsDestination->size(); j++) {
  96. remove_edge(sommetsSource->at(i), sommetsDestination->at(j), *g);
  97. }
  98. }
  99. sort(sommetsDestination->begin(), sommetsDestination->end());
  100. }
  101. void gggp_pond(UnorientedGraph *g, Entiers *sommetsSource,
  102. Entiers *sommetsDestination, EntiersEntiers &Partition)
  103. {
  104. int val;
  105. Entiers sommets_adj;
  106. if((sommetsSource->size()-1)==0){
  107. val=0;
  108. std::cout<<"Entré dans le debug ! "<<std::endl;
  109. Entiers tailles;
  110. for(uint i=0;i<Partition.size();i++){
  111. tailles.push_back(Partition.at(i)->size());
  112. }
  113. uint tmp=*max_element(tailles.begin(),tailles.end());
  114. for(uint i=0; i<Partition.size();i++){
  115. if(Partition.at(i)->size()==tmp)
  116. gggp_pond(g,Partition[i],sommetsDestination,Partition);
  117. break;
  118. }
  119. }
  120. else
  121. val=rand_fini(0,sommetsSource->size()-1);//Tirage aléatoire de l'indice du premier sommet entre 0 et taille du tableau -1
  122. double poids_max=0;
  123. for(uint i=0;i<sommetsSource->size();i++){
  124. poids_max+=(*g)[sommetsSource->at(i)]._weight;
  125. }
  126. poids_max/=2.;
  127. double poids=(*g)[sommetsSource->at(val)]._weight;
  128. std::vector<float> sommets_cut;
  129. sommetsDestination->push_back(sommetsSource->at(val));
  130. sommetsSource->erase(sommetsSource->begin() + val);
  131. if(sommetsSource->size()<2)
  132. return;
  133. while(poids<poids_max)
  134. {
  135. Liste_Voisin(*sommetsDestination,sommets_adj,*g);
  136. if((sommets_adj.size()==0))
  137. {
  138. std::cout<<"Je suis sorti !!!! "<<std::endl;
  139. return;
  140. }
  141. else{
  142. sort(sommets_adj.begin(), sommets_adj.end());
  143. for(uint i=0;i<sommets_adj.size();i++)
  144. {
  145. sommets_cut.push_back(Cout_coupe_pond(*sommetsDestination,sommets_adj[i],*g));
  146. }
  147. sommetsDestination->push_back(sommets_adj[recherche_val2(sommets_cut,*min_element(sommets_cut.begin(),sommets_cut.end()))]);
  148. poids+=(*g)[sommets_adj[recherche_val2(sommets_cut,*min_element(sommets_cut.begin(),sommets_cut.end()))]]._weight;
  149. suprim_val(*sommetsSource, sommets_adj[recherche_val2(sommets_cut,*min_element(sommets_cut.begin(),sommets_cut.end()))]);
  150. suprim_val(sommets_adj, sommets_adj[recherche_val2(sommets_cut,*min_element(sommets_cut.begin(),sommets_cut.end()))]);
  151. sommets_cut.clear();
  152. }
  153. }
  154. edge_t e1;
  155. // bool found;
  156. for (uint i=0; i<sommetsSource->size();i++)
  157. {
  158. for (uint j=0; j<sommetsDestination->size();j++)
  159. {
  160. remove_edge(sommetsSource->at(i),sommetsDestination->at(j),*g);
  161. }
  162. }
  163. sort(sommetsDestination->begin(), sommetsDestination->end());
  164. }
  165. void Iter_2l(EntiersEntiers &part, int nbr_parties, UnorientedGraph *g,
  166. const std::string &nom)
  167. {
  168. if (nom!="gggp_pond"){
  169. //std::cout<<"je jsuis dans gggp"<<std::endl;
  170. for(int i = 0; i<floor(log(nbr_parties)/log(2)); i++)
  171. {
  172. //std::cout<<"Et un tours de plus !!!! "<<std::endl;
  173. for(int j = 0; j< pow(2,i);j++)
  174. {
  175. Entiers *Q = new Entiers();
  176. gggp(g,part[j],Q,part);
  177. part.push_back(Q);
  178. }
  179. }
  180. } else {
  181. //std::cout<<"je jsuis dans gggp_pond"<<std::endl;
  182. for(int i = 0; i<floor(log(nbr_parties)/log(2)); i++)
  183. {
  184. std::cout<<"Et un tours de plus !!!! "<<std::endl;
  185. for(int j = 0; j< pow(2,i);j++)
  186. {
  187. Entiers *Q = new Entiers();
  188. gggp_pond(g,part.at(j),Q,part);
  189. std::clog<<"sortie du gggp_pond"<<std::endl;
  190. part.push_back(Q);
  191. }
  192. }
  193. }
  194. }
  195. void bissectionRec(UnorientedGraph *g, EntiersEntiers &Partition,
  196. int nbr_parties, const std::string &nom)
  197. {
  198. if((nbr_parties&(nbr_parties-1))==0)
  199. {
  200. //std::cout<<"C'est de la forme 2l : "<<nbr_parties<<std::endl;
  201. Iter_2l(Partition,nbr_parties,g,nom);
  202. } else {
  203. int puissance_2=0;
  204. Entiers tailles;
  205. while(pow(2,puissance_2)<nbr_parties)
  206. puissance_2++;
  207. Iter_2l(Partition,pow(2,puissance_2-1),g,nom);
  208. for(unsigned int i = 0; i< Partition.size() -1 ; i++)
  209. {
  210. for(EntiersEntiers::iterator it1 = Partition.begin() + i ; it1!=Partition.end(); it1++)
  211. {
  212. if((*it1)->size() > Partition.at(i)->size())
  213. Partition.at(i)->swap(**it1);
  214. }
  215. }
  216. /*std::cout<<"****"<<std::endl;
  217. for(int k=0; k<Partition.size(); k++)
  218. {
  219. for(int j=0; j<Partition[k]->size(); j++)
  220. {
  221. std::cout<<Partition[k]->at(j)<<std::endl;
  222. }
  223. std::cout<<"\n"<<std::endl;
  224. }
  225. std::cout<<"****"<<std::endl;
  226. std::cout<<"Et on termine les dernières bissections !!!! "<<std::endl;*/
  227. for(int j = 0; j<nbr_parties-pow(2,puissance_2-1);j++)
  228. {
  229. Entiers *Q = new Entiers();
  230. if(nom!="gggp_pond")
  231. gggp(g,Partition.at(j),Q,Partition);
  232. else
  233. gggp_pond(g,Partition.at(j),Q,Partition);
  234. Partition.push_back(Q);
  235. //Q.clear();
  236. }
  237. }
  238. }
  239. /**
  240. * Fonction réalisant un partitionnement pseudo aléatoire suivant un voisinage.
  241. * @param *g : adresse d'un graphe de type boost graphe undirected
  242. * @param Partition : vecteur contenant des vecteurs d'entiers [tableau contenant les parties de la partition]
  243. * @param nbr_partie : entier correspondant au nombre de parties voulues pour la partition
  244. * @return
  245. */
  246. void Pseudo_random_partitioning(UnorientedGraph *g, EntiersEntiers &Partition,
  247. uint nbr_parties)
  248. {
  249. /*
  250. * Principe : distribution des sommets de la première partie en plusieurs autres parties
  251. * Le partitionnement étant pseudo aléatoire il n'y a pas de contrainte stricte sur le nombre
  252. * de sommets par partie
  253. */
  254. uint size = Partition.at(0)->size();
  255. uint cpt_sommets=1;
  256. int val;
  257. uint cpt;
  258. if(nbr_parties==size){
  259. for(uint i = 0; i < nbr_parties;i++){
  260. if(Partition.at(0)->size()!=1)
  261. {
  262. val=rand_fini(0,Partition.at(0)->size()-1);//tirage aléatoire d'un sommets
  263. }
  264. else
  265. val=0;
  266. int vertex = Partition.at(0)->at(val);
  267. Entiers *part = new Entiers();
  268. part->push_back(vertex);// ajout du sommet tiré
  269. suprim_val(*Partition.at(0),vertex);//suppression du sommet dans la premiere partie
  270. }
  271. }
  272. /*
  273. * Boucle sur le nombre de partie à réaliser
  274. */
  275. for(uint i = 0; i < nbr_parties-1;i++){
  276. if(Partition.at(0)->size()!=1)
  277. {
  278. val=rand_fini(0,Partition.at(0)->size()-1);//tirage aléatoire d'un sommets
  279. }
  280. else
  281. val=0;
  282. int vertex = Partition.at(0)->at(val);
  283. /*
  284. * Initialisation d'un pointeur sur un vecteur d'entier, dans notre cas
  285. * la n+1 ième partie de la partition
  286. */
  287. Entiers *part = new Entiers();
  288. part->push_back(vertex);// ajout du sommet tiré
  289. suprim_val(*Partition.at(0),vertex);//suppression du sommet dans la premiere partie
  290. cpt=1;
  291. /*
  292. * Pour chaque element de la nouvelle partie faire
  293. */
  294. for(uint j = 0; j<part->size();j++){
  295. /*
  296. * Détermination des voisins de chacun des sommets de cette nouvelle
  297. * partie et ajoue de ce voisin si celui-ci est présent dans la première partie (Partition[0])
  298. */
  299. tie(neighbourIt, neighbourEnd) = adjacent_vertices(part->at(j),*g);
  300. for (; neighbourIt != neighbourEnd; ++neighbourIt){
  301. if(In_tab(*Partition.at(0),*neighbourIt)==1){
  302. std::cout<<"le voisin déplacé est : "<<*neighbourIt<<std::endl;
  303. part->push_back(*neighbourIt);
  304. cpt_sommets++;
  305. suprim_val(*Partition.at(0),*neighbourIt);
  306. cpt++;
  307. }
  308. /*
  309. * Si le nombre moyen de sommets est atteind dans la partie on sort de la boucle des voisins
  310. * Même chose si l'on a rencontré le nombre total de sommets
  311. */
  312. if(cpt==(size/nbr_parties)+1)
  313. break;
  314. if(cpt_sommets==size)
  315. break;
  316. }
  317. /*
  318. * Même chose
  319. */
  320. if(cpt==(size/nbr_parties)+1)
  321. break;
  322. if(cpt_sommets==size)
  323. break;
  324. }
  325. Partition.push_back(part);// ajoue de la nouvelle partie à la partition
  326. if(cpt_sommets==size)
  327. break;
  328. }
  329. }
  330. OrientedGraphs Multiniveau(uint niveau_contraction,
  331. UnorientedGraph *g,
  332. OrientedGraph *go,
  333. int nbr_parties,
  334. std::string type_methode,
  335. std::string choix_affinage,
  336. std::string type_cut,
  337. Edges& /* edge_partie */,
  338. OutputEdgeList& outputedgeslist,
  339. InputEdgeList& inputedgelist,
  340. Connections& connections)
  341. {
  342. EntiersEntiers Partition;
  343. Entiers *part = new Entiers();
  344. Base_Graph baseg;
  345. baseg.push_back(g);
  346. ListEntiersEntiers liste_corr;
  347. uint cpt =0;
  348. while(num_vertices(*baseg.at(cpt))>niveau_contraction)
  349. {
  350. contraction_HEM(baseg.at(cpt),baseg,liste_corr);
  351. cpt++;
  352. }
  353. for(uint i = 0;i < num_vertices(*baseg.at(baseg.size() - 1)); i++)
  354. {
  355. part->push_back(i);
  356. }
  357. Partition.push_back(part);
  358. bissectionRec(baseg.at(baseg.size()-1),Partition,nbr_parties,type_methode);
  359. std::clog<<"Partition : "<<std::endl;
  360. for(uint i = 0; i< Partition.size() ; i++)
  361. {
  362. for(uint j = 0 ; j<Partition.at(i)->size() ; j++)
  363. {
  364. std::cout<<(*baseg.at(baseg.size()-1))[Partition.at(i)->at(j)]._index<<std::endl;
  365. }
  366. std::cout<<"\n"<<std::endl;
  367. }
  368. ListEntiersEntiers::iterator lit(liste_corr.end());
  369. lit--;
  370. for(uint y =0; y<liste_corr.size();y++){
  371. projection(Partition,lit);
  372. double cut = Cut_cluster(Partition,*baseg.at(baseg.size()-2-y),type_cut);
  373. std::cout<<"Cout de coupe avant affinage : "<<cut<<std::endl;
  374. if(choix_affinage=="charge")
  375. Affinage_equilibrage_charge(baseg.at(baseg.size()-2-y),Partition);
  376. else
  377. Affinage_recherche_locale(baseg.at(baseg.size()-2-y),Partition,cut,type_cut);
  378. std::cout<<"Cout de coupe après affinage : "<<cut<<std::endl;
  379. lit--;
  380. }
  381. OrientedGraphs Graphes = Graph_Partition(Partition, go, g, outputedgeslist,
  382. inputedgelist, connections);
  383. for(int k=0; k<Partition.size(); k++)
  384. {
  385. for(int j=0; j<Partition[k]->size(); j++)
  386. {
  387. std::cout<<Partition[k]->at(j)<<std::endl;
  388. }
  389. std::cout<<"\n"<<std::endl;
  390. }
  391. std::cout<<"****"<<std::endl;
  392. for(EntiersEntiers::iterator it = Partition.begin(); it != Partition.end(); it++)
  393. {
  394. delete *it;
  395. *it = NULL;
  396. }
  397. for(ListEntiersEntiers::iterator it = liste_corr.begin(); it != liste_corr.end(); it++)
  398. {
  399. for(EntiersEntiers::iterator it1 = (*it)->begin(); it1 != (*it)->end(); it1++)
  400. {
  401. delete *it1;
  402. *it1 = NULL;
  403. }
  404. delete *it;
  405. *it = NULL;
  406. }
  407. for(Base_Graph::iterator it = baseg.begin(); it != baseg.end(); it++)
  408. {
  409. delete *it;
  410. *it = NULL;
  411. }
  412. return Graphes;
  413. }
  414. } } } // namespace paradevs tests boost_graph