utils.cpp 119 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390
  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-2015 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. struct myclass4
  50. {
  51. bool operator() (int i, int j, UnorientedGraph *g)
  52. { return (*g)[i]._weight > (*g)[j]._weight; }
  53. } mon_poids;
  54. /**
  55. * Fonction de verification de la connexité d'un graphe
  56. * @param *g : adresse d'un graphe de type boost graphe undirected
  57. * @param Partition : vecteur contenant des vecteurs d'entiers [tableau contenant les parties de la partition]
  58. * @param part : vecteur d'entier (une partie de la partition)
  59. * @return un booleen
  60. */
  61. bool Est_connexe(UnorientedGraph *g, EntiersEntiers Partition, Entiers &part)
  62. {
  63. /*
  64. * Copie du graphe contenu par l'adresse *g
  65. */
  66. UnorientedGraph copie_g;
  67. copie_g = *g;
  68. /*
  69. * Modification du graphe copié afin de générer des sous graphes liés aux différentes parties
  70. */
  71. for (uint i=0; i<Partition.size()-1;i++)
  72. {
  73. for (uint j=1+i; j<Partition.size();j++)
  74. {
  75. for (uint k=0; k<Partition.at(i)->size();k++)
  76. {
  77. for (uint y=0; y<Partition.at(j)->size();y++)
  78. {
  79. remove_edge(Partition.at(i)->at(k),Partition.at(j)->at(y),copie_g); //suppression de certains arcs
  80. }
  81. }
  82. }
  83. }
  84. /*
  85. * Objectif : déterminer s'il existe un chemin reliant tous les noeuds d'une même partie
  86. * Méthode : partir d'un sommet de départ tiré aléatoirement dans la partie "part" et parcourir l'ensemble de ces voisins.
  87. * Si le voisin recontré n'est pas contenu dans le vecteur "sommets" il est ajouté. Le processus est répété pour chaque
  88. * nouveau sommet ajouté au vecteur.
  89. * Résultat : si le nombre de sommets contenu dans le vecteur "part" est égale au nombre de sommets du vecteur "sommets"
  90. * alors le graphe est connexe
  91. */
  92. uint val;
  93. Entiers sommets;
  94. if(part.size()==1)
  95. val = 0;
  96. else
  97. val=rand_fini(0,part.size()-1); //tirage aléatoire d'un sommets
  98. uint vertex = part.at(val);
  99. sommets.push_back(vertex); //ajout du sommets à la lsite des sommets parcouru
  100. /*
  101. * Recherche de voisins n'appartenant pas à la liste des sommets parcourus
  102. */
  103. for(uint i = 0;i<sommets.size();i++){
  104. tie(neighbourIt, neighbourEnd) = adjacent_vertices(sommets.at(i),copie_g);
  105. for (; neighbourIt != neighbourEnd; ++neighbourIt){
  106. if(In_tab(sommets,*neighbourIt)!=1)
  107. sommets.push_back(*neighbourIt);
  108. }
  109. }
  110. /*
  111. * Retour de la réponse vrai ou faux
  112. */
  113. if(part.size()!=sommets.size())
  114. return false;
  115. else
  116. return true;
  117. }
  118. /**
  119. * Fonction de projection
  120. * @param Partition : vecteur contenant des vecteurs d'entiers [tableau contenant les parties de la partition]
  121. * @param lit : itérateur sur une liste contenant une vecteur de vecteur d'entier
  122. * @return
  123. */
  124. /*
  125. * Objectif : obtenir la correspondance entre les sommets d'un graphe Gn et celui de Gn-1
  126. * Méthode : modification des sommets contenus dans "Partition" à l'aide de la liste de correspondance *lit
  127. */
  128. void projection(EntiersEntiers &Partition,ListEntiersEntiers::iterator lit)
  129. {
  130. /*
  131. * Création d'un nouveau vecteur contenant les adresses d'autres vecteur d'entiers.
  132. * Celui-ci est conçu pour recevoir les sommets contenus dans la liste de correspondance,
  133. * correspondant à la projection des sommets du graphe Gn à celui de Gn-1
  134. */
  135. EntiersEntiers new_partition;
  136. for(uint i = 0; i< Partition.size() ; i++)
  137. {
  138. Entiers *new_part = new Entiers();
  139. for(uint j = 0 ; j<Partition.at(i)->size() ; j++)
  140. {
  141. for(uint k = 0; k<((*lit)->at(Partition.at(i)->at(j)))->size();k++){
  142. new_part->push_back((*lit)->at(Partition.at(i)->at(j))->at(k));
  143. }
  144. }
  145. new_partition.push_back(new_part);
  146. }
  147. /*
  148. * Désalocation mémoire des pointeurs que contient "Partition"
  149. */
  150. for(EntiersEntiers::iterator it = Partition.begin(); it != Partition.end(); it++)
  151. {
  152. delete *it;
  153. *it = NULL;
  154. }
  155. Partition = new_partition; // copie de new_partition dans Partition
  156. for(uint i =0; i<Partition.size(); i++) {
  157. // permet de trier chaque sous vecteur de "Partition"
  158. std::sort(Partition[i]->begin(),Partition[i]->end());
  159. }
  160. new_partition.clear();
  161. }
  162. /**
  163. * Fonction qui calcul le poids d'une partie
  164. * @param * part : adresse d'un vecteur d'entier, ici une partie de la partition
  165. * @param *g : adresse d'un graphe de type boost graphe undirected
  166. * @return un type double contenant le poids associé à la partie
  167. */
  168. double Calcul_poids(Entiers *partie, UnorientedGraph *g)
  169. {
  170. double poids=0; // initialisation du poids à 0
  171. /*
  172. * Pour chaque sommet de la partie concerné on ajoute son poids au poids total
  173. */
  174. for(uint j = 0; j<partie->size();j++){
  175. poids+=(*g)[partie->at(j)]._weight;
  176. }
  177. return poids;
  178. }
  179. /**
  180. * Fonction d'affinage suivant un critère de poids
  181. * @param *g : adresse d'un graphe de type boost graphe undirected
  182. * @param Partition : vecteur contenant des vecteurs d'entiers [tableau contenant les parties de la partition]
  183. * @return modification de la partition
  184. */
  185. void Affinage_equilibrage_charge(UnorientedGraph *g, EntiersEntiers &Partition)
  186. {
  187. /*
  188. * Calcule de la somme des poids du graphe et le poids moyen à atteindre
  189. */
  190. double poids_moyen = 0.;
  191. for(uint i = 0; i < num_vertices(*g); i++) {
  192. poids_moyen += (*g)[i]._weight;
  193. }
  194. // détermination du poids moyen à atteindre pour chaque partie
  195. poids_moyen /= Partition.size();
  196. std::vector < double > poids_parties;
  197. /*
  198. * Calcul du poids de chaque partie de la partition
  199. */
  200. for (uint i = 0; i < Partition.size(); i++) {
  201. double tmp = Calcul_poids(Partition.at(i),g);
  202. poids_parties.push_back(tmp);
  203. }
  204. std::clog << "Poids initial des parties : " << std::endl;
  205. // for (uint i = 0; i < poids_parties.size(); i++){
  206. // std::cout << poids_parties.at(i) << " ";
  207. // }
  208. // std::cout << "\n" << std::endl;
  209. /*
  210. * Le critère d'amélioration consiste à faire tendre vers 0 la somme
  211. * des écarts entre le poids des parties et le poids moyen
  212. * le "critere" est la somme pour chaque partie de la différence
  213. * en valeurs absolues du poids
  214. * d'une partie moins le poids moyen divisé par le nombre de parties
  215. */
  216. double critere = 0.;
  217. for (uint i = 0; i < poids_parties.size(); i++){
  218. critere += abs(poids_parties.at(i) - poids_moyen);
  219. }
  220. critere /= Partition.size();
  221. // on conserve le poids maximum
  222. double p_max = *max_element(poids_parties.begin(), poids_parties.end());
  223. // std::cout << "Valeurs du criètre de départ : " << critere << std::endl;
  224. // création d'un second critère légérement plsu faible que le premier
  225. double best_critere = critere - 1e-7;
  226. uint nbr_passage = 1; // initialisation du nombre de passages à 1
  227. /*
  228. * Tant que le critère n'est pas amélioré etque le nombre de
  229. * passage est inférieur au nombre de parties on réalise
  230. * des modifications sur la partition
  231. */
  232. while (best_critere < critere or nbr_passage < Partition.size()) {
  233. critere = best_critere; //critere devient best_critere
  234. // recherche la partie associé au poids maximum
  235. int cpt = recherche_val_double(poids_parties,p_max);
  236. bool decision = false; //initialisatio d'un booleen a false
  237. int nbr_pass_interne = 0;
  238. /*
  239. * tirage aléatoire des sommets de la partie de poids maximum
  240. */
  241. Entiers random_orders = Random_Sort_Vector(Partition.at(cpt)->size());
  242. /*
  243. * Si le nombre de sommets d'une partie excéde les 400, on tire au hasar 400 sommets sans remise
  244. * et on effectue les modifications (ceci permet d'eviter une explosion des temps de calcul)
  245. */
  246. int size;
  247. if(Partition.at(cpt)->size()>400)
  248. size = 400;
  249. else
  250. size = Partition.at(cpt)->size();
  251. /*
  252. * Seconde boucle Tant que sur les sommets d'une partie.
  253. * Tant que le critere booleen est vrai et que le nombre de passe interne est inférieur au seuil size faire
  254. */
  255. while(decision!=true && nbr_pass_interne < size){
  256. int vertex = random_orders.at(nbr_pass_interne); //tirage d'un sommets dans la parite de poids maximum
  257. Entiers community = Neigh_community(g,Partition,vertex,cpt); // recherche des communautés voisines à ce sommet (s'il est au bord)
  258. if(community.size()!=0) // s'il existe au moins une communauté voisine
  259. {
  260. std::vector<double> new_poids_parties; // initialisation d'un nouveau vecteur contenant des doubles
  261. std::vector<double> tmp_critere; // initialisation d'un nouveau vecteur contenant des doubles
  262. /*
  263. * Pour chacune des parties (communauté) voisine au sommet vertexs faire
  264. */
  265. for(uint k = 0; k < community.size();k++)
  266. {
  267. new_poids_parties = poids_parties; //copie du tableau de poids des parties dans new_poids_parties
  268. /*
  269. * Modification des poids des parties :
  270. * on ajoute le poids du sommets à la partie voisine
  271. * et on soustrait son poids à sa partie d'origine
  272. */
  273. new_poids_parties.at(community.at(k))+=(*g)[vertex]._weight;
  274. new_poids_parties.at(cpt)-=(*g)[vertex]._weight;
  275. /*
  276. * Calcul ldu nouveau critère associé à cette modification
  277. */
  278. double new_critere = 0.;
  279. for(uint i = 0; i<poids_parties.size();i++){
  280. new_critere += abs(new_poids_parties.at(i)-poids_moyen);
  281. }
  282. new_critere/=Partition.size();
  283. tmp_critere.push_back(new_critere); // enregistrement du résutlat dans le tableau tmp_critere
  284. }
  285. double val_min = *min_element(tmp_critere.begin(),tmp_critere.end()); // enregistrement de la valeur minimale du tableau tmp_critere
  286. int val = recherche_val_double(tmp_critere,val_min); // recherche de la communauté correspondant à cette valeur
  287. /*
  288. * Si la valeur associé est plus petite et que la partie selectionné n'est pas vérouillée faire
  289. */
  290. if(val_min<critere && poids_parties.at(val)!=-1)
  291. {
  292. /*
  293. * On change le sommet vertex de partie, il est déplacé vers la partie
  294. * qui permet la meilleure amélioration du critère
  295. */
  296. Partition.at(community.at(val))->push_back(vertex);
  297. suprim_val(*Partition.at(cpt),vertex);
  298. std::sort(Partition.at(community.at(val))->begin(), Partition.at(community.at(val))->end());
  299. /*
  300. * Vérification de la sauvegarde de la connexsité,
  301. * si se n'est pas le cas retour à l'état précédent
  302. */
  303. if(Est_connexe(g,Partition,*Partition.at(cpt))!=1)
  304. {
  305. suprim_val(*Partition.at(community.at(val)),vertex);
  306. Partition.at(cpt)->push_back(vertex);
  307. std::sort(Partition.at(cpt)->begin(), Partition.at(cpt)->end());
  308. // std::cout<<" C'EST MORT RETOUR EN ARRIERE ! "<<std::endl
  309. ;
  310. }
  311. else
  312. {
  313. poids_parties = new_poids_parties;
  314. decision = true;
  315. // std::cout<<" Modification reussi ! "<<std::endl;
  316. }
  317. }
  318. }
  319. nbr_pass_interne++;
  320. }
  321. /*
  322. * Si aucune modification n'a été réalisé pour cett partie de poids maximum
  323. */
  324. if(decision==false)
  325. {
  326. nbr_passage++; // augmentation du nombre de passage
  327. poids_parties.at(cpt)=-1; // vérrouillage de la partie
  328. std::clog<<"nouveau passag ! "<<std::endl;
  329. }
  330. else
  331. {
  332. best_critere = 0.;
  333. for(uint i = 0; i<poids_parties.size();i++){
  334. best_critere += abs(poids_parties.at(i)-poids_moyen);
  335. }
  336. best_critere/=Partition.size();
  337. nbr_passage = 0;
  338. }
  339. // std::clog<<"Poids des parties modifié : "<<std::endl;
  340. // for(uint i = 0; i<poids_parties.size(); i++){
  341. // std::cout<<poids_parties.at(i)<<" ";
  342. // }
  343. // std::cout<<"\n"<<std::endl;
  344. p_max = *max_element(poids_parties.begin(),poids_parties.end());
  345. // std::cout<<"Valeurs du criètre : "<<critere<<std::endl;
  346. // std::cout<<"Valeurs du best_criètre : "<<best_critere<<std::endl;
  347. // std::cout<<"Nombre de passage : "<<nbr_passage<<std::endl;
  348. // std::cout<<"\n"<<std::endl;
  349. }
  350. }
  351. Entiers Neigh_community(UnorientedGraph *g, EntiersEntiers &Partition, int vertex, int comm_in)
  352. {
  353. Entiers community;
  354. int comm;
  355. tie(neighbourIt, neighbourEnd) = adjacent_vertices(vertex,*g);
  356. for (; neighbourIt != neighbourEnd; ++neighbourIt){
  357. comm = In_community_dichotomie(Partition,*neighbourIt);
  358. if(In_tab(community,comm)!=1 && comm!=comm_in)
  359. community.push_back(comm);
  360. }
  361. return community;
  362. }
  363. void Affinage_recherche_locale(UnorientedGraph *g, EntiersEntiers &Partition, double &cut, std::string name)
  364. {
  365. Entiers random_orders = Random_Sort_Vector(num_vertices(*g)); //gestion d'un tableau contenant tout les sommets et ranger de façon aléatoire
  366. uint size = random_orders.size();
  367. if(num_vertices(*g)>500)
  368. size=500;
  369. std::vector<std::vector<double> > tabe_cut;
  370. //std::cout<<"Passage : "<<Partition.size()<<std::endl;
  371. for(uint k = 0; k < Partition.size();k++){
  372. std::vector<double> tmp;
  373. double vol = 0.;
  374. double cut = Modif_Cut_one_cluster(*Partition.at(k), *g, vol, name);
  375. tmp.push_back(cut);
  376. tmp.push_back(vol);
  377. tabe_cut.push_back(tmp);
  378. }
  379. for(uint i = 0; i < size; i++){
  380. if(random_orders.at(i)!=-1){
  381. int vertex = random_orders.at(i);
  382. //std::cout<<vertex<<std::endl;
  383. int comm = In_community_dichotomie(Partition, vertex);
  384. Entiers community = Neigh_community(g,Partition,vertex,comm);
  385. std::vector<double> tmp_cut;
  386. if(community.size()!=0 && Partition.at(comm)->size()!=1){
  387. tmp_cut = modif_cut_tmp(g,Partition,tabe_cut,vertex,comm,community,cut,name);
  388. /*for(uint z = 0; z<tmp_cut.size(); z++){
  389. std::cout<<tmp_cut.at(z)<<std::endl;
  390. }
  391. std::cout<<"\n"<<std::endl;*/
  392. double cut_min = *min_element(tmp_cut.begin(),tmp_cut.end());
  393. //std::cout<<"cout de coupe minimum de la liste : "<<cut_min<<std::endl;
  394. if(cut_min<cut){
  395. // std::clog<<"Changement ! "<<std::endl;
  396. int tmp = recherche_val_double(tmp_cut,cut_min);
  397. cut=cut_min;
  398. Partition.at(community.at(tmp))->push_back(vertex);
  399. suprim_val(*Partition.at(comm),vertex);
  400. std::sort(Partition.at(community.at(tmp))->begin(), Partition.at(community.at(tmp))->end());
  401. tabe_cut.clear();
  402. for(uint k = 0; k < Partition.size();k++){
  403. std::vector<double> tmp;
  404. double vol = 0.;
  405. double cut = Modif_Cut_one_cluster(*Partition.at(k), *g, vol, name);
  406. tmp.push_back(cut);
  407. tmp.push_back(vol);
  408. tabe_cut.push_back(tmp);
  409. }
  410. }
  411. }
  412. Modif_fonction_Gain_Cut(Partition,g,community,vertex,cut,name);
  413. /*if(Est_connexe(g,Partition,*Partition.at(comm))!=1)
  414. {
  415. suprim_val(*Partition.at(community.at(tmp)),vertex);
  416. Partition.at(comm)->push_back(vertex);
  417. std::sort(*Partition.at(comm));
  418. std::cout<<" C'EST MORT RETOUR EN ARRIERE ! "<<std::endl;
  419. }*/
  420. }
  421. }
  422. }
  423. double Modif_Cut_one_cluster(Entiers &cluster, UnorientedGraph &g, double &vol, std::string name)
  424. {
  425. edge_t e1;
  426. bool found;
  427. double cpt= 0.;
  428. if(name == "norm"){
  429. for(uint i=0;i<cluster.size();i++){
  430. tie(neighbourIt, neighbourEnd) = adjacent_vertices(cluster.at(i), g);
  431. for (; neighbourIt != neighbourEnd; ++neighbourIt){
  432. tie(e1,found)=edge(vertex(cluster[i],g),vertex(*neighbourIt,g),g);
  433. if(In_tab(cluster,*neighbourIt)!=1){
  434. cpt+=g[e1]._weight;
  435. }
  436. }
  437. }
  438. vol = Cluster_Degree(g,cluster);
  439. } else if(name == "ratio"){
  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_Weight(g,cluster);
  450. }
  451. return cpt;
  452. }
  453. 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){
  454. edge_t e1;
  455. bool found;
  456. //std::cout<<"le sommet tiré est : "<<vertexs<<std::endl;
  457. if(name == "cut")
  458. {
  459. std::vector<double> modif_cut(community.size());
  460. double cpt_comm_in;
  461. double cpt_comm_out;
  462. for(uint i =0; i<community.size(); i++){
  463. double tmp_cut = cut;
  464. cpt_comm_in=0;
  465. cpt_comm_out=0;
  466. tie(neighbourIt, neighbourEnd) = adjacent_vertices(vertexs,*g);
  467. for (; neighbourIt != neighbourEnd; ++neighbourIt){
  468. tie(e1,found)=edge(vertex(vertexs,*g),vertex(*neighbourIt,*g),*g);
  469. if(In_tab(*Partition.at(comm_in),*neighbourIt)==1)
  470. cpt_comm_in+=(*g)[e1]._weight;
  471. else if(In_tab(*Partition.at(community.at(i)),*neighbourIt)==1)
  472. cpt_comm_out+=(*g)[e1]._weight;
  473. }
  474. tmp_cut+=cpt_comm_in;
  475. tmp_cut-=cpt_comm_out;
  476. modif_cut.at(i)=tmp_cut;
  477. }
  478. return modif_cut;
  479. }
  480. else if(name == "norm"){
  481. std::vector<double> modif_cut(community.size());
  482. double cpt_comm_in;
  483. double cpt_comm_out;
  484. double tmp_cut;
  485. for(uint i =0; i<community.size(); i++){
  486. std::vector<std::vector<double> > tab_cut = tabe_cut;
  487. tmp_cut =0.;
  488. cpt_comm_in=0.;
  489. cpt_comm_out=0.;
  490. tie(neighbourIt, neighbourEnd) = adjacent_vertices(vertexs,*g);
  491. for (; neighbourIt != neighbourEnd; ++neighbourIt){
  492. tie(e1,found)=edge(vertex(vertexs,*g),vertex(*neighbourIt,*g),*g);
  493. if(In_tab(*Partition.at(comm_in),*neighbourIt)==1)
  494. cpt_comm_in+=(*g)[e1]._weight;
  495. else if(In_tab(*Partition.at(community.at(i)),*neighbourIt)==1)
  496. cpt_comm_out+=(*g)[e1]._weight;
  497. }
  498. cpt_comm_in/=2.;
  499. cpt_comm_out/=2.;
  500. tab_cut.at(comm_in).at(0)+=cpt_comm_in;
  501. tab_cut.at(comm_in).at(0)-=cpt_comm_out;
  502. tab_cut.at(comm_in).at(1)-= Degree(*g ,vertexs);
  503. tab_cut.at(community.at(i)).at(0)+=cpt_comm_in;
  504. tab_cut.at(community.at(i)).at(0)-=cpt_comm_out;
  505. tab_cut.at(community.at(i)).at(1)+= Degree(*g ,vertexs);
  506. for(uint j = 0; j < tab_cut.size();j++){
  507. tmp_cut+=((tab_cut.at(j).at(0))/(tab_cut.at(j).at(1)));
  508. }
  509. modif_cut.at(i)=tmp_cut;
  510. }
  511. }else if(name == "ratio"){
  512. std::vector<double> modif_cut(community.size());
  513. double cpt_comm_in;
  514. double cpt_comm_out;
  515. double tmp_cut;
  516. for(uint i =0; i<community.size(); i++){
  517. std::vector<std::vector<double> > tab_cut = tabe_cut;
  518. tmp_cut =0.;
  519. cpt_comm_in=0.;
  520. cpt_comm_out=0.;
  521. tie(neighbourIt, neighbourEnd) = adjacent_vertices(vertexs,*g);
  522. for (; neighbourIt != neighbourEnd; ++neighbourIt){
  523. tie(e1,found)=edge(vertex(vertexs,*g),vertex(*neighbourIt,*g),*g);
  524. if(In_tab(*Partition.at(comm_in),*neighbourIt)==1)
  525. cpt_comm_in+=(*g)[e1]._weight;
  526. else if(In_tab(*Partition.at(community.at(i)),*neighbourIt)==1)
  527. cpt_comm_out+=(*g)[e1]._weight;
  528. }
  529. /*cpt_comm_in/=2.;
  530. cpt_comm_out/=2.;*/
  531. tab_cut.at(comm_in).at(0)+=cpt_comm_in;
  532. tab_cut.at(comm_in).at(0)-=cpt_comm_out;
  533. tab_cut.at(comm_in).at(1)-= (*g)[vertexs]._weight;
  534. tab_cut.at(community.at(i)).at(0)+=cpt_comm_in;
  535. tab_cut.at(community.at(i)).at(0)-=cpt_comm_out;
  536. tab_cut.at(community.at(i)).at(1)+= (*g)[vertexs]._weight;
  537. for(uint j = 0; j < tab_cut.size();j++){
  538. tmp_cut+=((tab_cut.at(j).at(0))/(tab_cut.at(j).at(1)));
  539. }
  540. modif_cut.at(i)=tmp_cut;
  541. }
  542. return modif_cut;
  543. }
  544. }
  545. void Modif_fonction_Gain_Cut(EntiersEntiers &Partition,UnorientedGraph *g, Entiers &community, int val, double &cut,std::string name)
  546. {
  547. /*std::cout<<"Nombre de communauté voisine : "<<community.size()<<std::endl;
  548. std::cout<<"\n"<<std::endl;*/
  549. for(uint i = 0; i<community.size();i++){
  550. EntiersEntiers new_partition;
  551. for(uint k = 0; k < Partition.size();k++){
  552. Entiers * tmp = new Entiers();
  553. for(uint j = 0;j<Partition.at(k)->size();j++){
  554. tmp->push_back(Partition.at(k)->at(j));
  555. }
  556. new_partition.push_back(tmp);
  557. }
  558. new_partition.at(community.at(i))->push_back(val);
  559. suprim_val(*new_partition.at(In_community_dichotomie(Partition,val)),val);
  560. std::sort(new_partition.at(community.at(i))->begin(),
  561. new_partition.at(community.at(i))->end());
  562. double coupe = Cut_cluster(new_partition,*g,name);
  563. //std::cout<<"cout de coupe : "<<coupe<<std::endl;
  564. if(coupe<cut)
  565. {
  566. for(EntiersEntiers::iterator it = Partition.begin(); it != Partition.end(); it++)
  567. {
  568. delete *it;
  569. *it = NULL;
  570. }
  571. Partition = new_partition;
  572. cut = coupe;
  573. }
  574. else
  575. {
  576. for(EntiersEntiers::iterator it = new_partition.begin(); it != new_partition.end(); it++)
  577. {
  578. delete *it;
  579. *it = NULL;
  580. }
  581. }
  582. }
  583. }
  584. bool contraction_HEM(UnorientedGraph *g, Base_Graph &baseg, ListEntiersEntiers &liste_corr, int val_reduc, int &val_cpt){
  585. UnorientedGraph *gtmp = new UnorientedGraph();
  586. boost::copy_graph(*g, *gtmp);//, Index_Vertex; // Initialisation du tableau de sommets rangés aléatoirements
  587. EntiersEntiers *tableau_de_correspondance = new EntiersEntiers();
  588. edge_t e1,e2; // Iterateurs sur les arcs
  589. bool found;
  590. uint nbr_vertex = num_vertices(*gtmp);
  591. Entiers sommets_a_detruire; // Initialisation d'un tableau pret à recevoir les "sommets à détruire"
  592. /*
  593. * Création d'un vecteur contenant l'ensemble des sommets du graphe. Ces sommets sont rangés
  594. * aléatoirement afin de simuler un tirage aléatoire
  595. */
  596. Entiers Random_list_vertices = Random_Sort_Vector(nbr_vertex);
  597. /*
  598. * Pour chaque sommet non verrouiller faire ....
  599. */
  600. //std::cout<<"Nouvelle contraction !!!"<<std::endl;
  601. //std::cout<<std::endl;
  602. for(uint i=0; i<nbr_vertex; i++){
  603. int vertexs = Random_list_vertices[i]; // Index_Vertex.at(Random_list_vertices.at(i));
  604. //std::cout<<"Le sommet tiré est : "<<vertexs<<std::endl;
  605. if(vertexs!=-1){
  606. Entiers liste_voisin = Liste_adjacence(*gtmp,vertexs,Random_list_vertices); // Recherche des sommets adjacents au sommets tiré
  607. if(liste_voisin.size()!=0){
  608. /*
  609. * S'il en existe au mois un sommet adjacent au sommet tiré qui n'est pas verrouillé, on
  610. * choisi celui dont l'arc les reliants est le plus fort. Dans le cas où les arcs ont tous
  611. * le même poids, on selectionne le sommet d'index le plus petit
  612. */
  613. double poids_a = 0.;
  614. int best_vertexs = -1;
  615. for(uint j=0;j<liste_voisin.size();j++){
  616. tie(e1,found)=edge(vertex(vertexs,*gtmp),vertex(liste_voisin[j],*gtmp),*gtmp);
  617. if((*gtmp)[e1]._weight>poids_a){
  618. best_vertexs = liste_voisin[j];
  619. poids_a = (*gtmp)[e1]._weight;
  620. }
  621. }
  622. Entiers * couple = new Entiers(); // Initialisation du vecteur contenant le couple de sommet fusionné
  623. int vertex_delete = std::max(vertexs, best_vertexs); // Sommet d'index le plus grand (qui sera détruit)
  624. //std::cout<<"sommet détruit : "<<(*gtmp)[vertex_delete]._index<<std::endl;
  625. int vertex_save = std::min(vertexs,best_vertexs); // Sommet d'identifiant le plus petit (qui sera conservé)
  626. //std::cout<<"sommet sauvé : "<<(*gtmp)[vertex_save]._index<<std::endl;
  627. sommets_a_detruire.push_back(vertex_delete); // On ajoute le sommet détruit au tableau des sommets à détruire
  628. /*
  629. * On ajoute au tableau "couple" le couple de sommet à fusionner
  630. */
  631. couple->push_back(vertex_save);
  632. couple->push_back(vertex_delete);
  633. tableau_de_correspondance->push_back(couple); // Ajout du "couple" à la liste de correspondance
  634. remove_edge(vertex_save,vertex_delete,*gtmp); // Suppression de l'arc reliant le couple de sommets
  635. Entiers neigh_vertex_save; // Initialisation du vecteur contenant les sommets adjacents au "sommet sauvegardé"
  636. Entiers neigh_vertex_delete; // Initialisation du vecteur contenant les somemts adjacents au "sommet à détruire"
  637. tie(neighbourIt, neighbourEnd) = adjacent_vertices(vertex_save,*gtmp);
  638. /*
  639. * Remplissage de ces deux tableaux à l'aide de la fonction adjacent_vertices de boost graph
  640. * [La création de ces tableaux est nécéssaire du fait que certains arcs sont détruit au cours
  641. * du processus]
  642. */
  643. for (; neighbourIt != neighbourEnd; ++neighbourIt){
  644. neigh_vertex_save.push_back(*neighbourIt);
  645. }
  646. tie(neighbourIt, neighbourEnd) = adjacent_vertices(vertex_delete,*gtmp);
  647. for (; neighbourIt != neighbourEnd; ++neighbourIt){
  648. neigh_vertex_delete.push_back(*neighbourIt);
  649. }
  650. /*
  651. * Recherche de sommets communs entre le "sommet sauvegardé" et le "sommet à détruire"
  652. * S'il existe un tel sommet "v" alors on ajoute le poids de l'arcs (vertex_delet,v)
  653. * à celui de l'arcs (vertex_save,v) et on détruit l'arcs reliant "v" au "sommet à détruire"
  654. */
  655. for(uint j=0;j<neigh_vertex_delete.size();j++){
  656. if(In_tab(neigh_vertex_save,neigh_vertex_delete[j])==1){
  657. tie(e2,found)=edge(vertex(vertex_save,*gtmp),vertex(neigh_vertex_delete[j],*gtmp),*gtmp);
  658. tie(e1,found)=edge(vertex(vertex_delete,*gtmp),vertex(neigh_vertex_delete[j],*gtmp),*gtmp);
  659. (*gtmp)[e2]._weight+=(*gtmp)[e1]._weight;
  660. remove_edge(vertex_delete,neigh_vertex_delete[j],*gtmp);
  661. }
  662. else
  663. {
  664. tie(e1,found)=edge(vertex(vertex_delete,*gtmp),vertex(neigh_vertex_delete[j],*gtmp),*gtmp);
  665. add_edge(vertex_save,neigh_vertex_delete[j],EdgeProperties((*gtmp)[e1]._weight),*gtmp);
  666. remove_edge(vertex_delete,neigh_vertex_delete[j],*gtmp);
  667. }
  668. }
  669. (*gtmp)[vertex_save]._weight+=(*gtmp)[vertex_delete]._weight; // ajout du poids du sommet détruit au sommet conservé
  670. /*
  671. * Vérouillage du "sommet sauvegardé" et du "sommet à détruire"
  672. */
  673. Random_list_vertices[i]=-1;
  674. Random_list_vertices[recherche_val(Random_list_vertices,best_vertexs)]=-1;
  675. val_cpt--;
  676. // std::cout<<val_cpt<<std::endl;
  677. }
  678. else{
  679. /*
  680. * Et si le sommet tiré ne possède pas de sommet adjacent non verrouillé
  681. * alors on l'ajoute à la liste de correspondance des sommets et on
  682. * le verrouille
  683. */
  684. Entiers *couple = new Entiers();
  685. couple->push_back(Random_list_vertices.at(i));
  686. tableau_de_correspondance->push_back(couple);
  687. Random_list_vertices[i]=-1;
  688. }
  689. }
  690. if(val_cpt == val_reduc){
  691. for(uint j=i+1; j <nbr_vertex; j++){
  692. if(Random_list_vertices[j] !=-1){
  693. Entiers *couple = new Entiers();
  694. couple->push_back(Random_list_vertices.at(j));
  695. tableau_de_correspondance->push_back(couple);}
  696. }
  697. break;
  698. }
  699. }
  700. std::sort(sommets_a_detruire.begin(), sommets_a_detruire.end()); // Trie dans l'ordre croissant des "sommets à détruire"
  701. // std::cout<<"\n"<<std::endl;
  702. /*
  703. * Suppression des sommets de la liste "sommets à détruire". Cette suppression est
  704. * effectuée dans l'ordre décroissant afin à maintenir à jour la renumérotation
  705. * des sommets
  706. */
  707. for(int j=(sommets_a_detruire.size()-1);j>-1;j--){
  708. //std::cout<<"Noeuds a supprimer : "<<sommets_a_detruire.at(j)<<std::endl;
  709. remove_vertex(sommets_a_detruire[j],*gtmp);
  710. }
  711. 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
  712. liste_corr.push_back(tableau_de_correspondance);
  713. // std::cout<<"\n"<<std::endl;
  714. baseg.push_back(gtmp); // Ajout du graphe modifié à la "base des graphe"
  715. if(val_cpt == val_reduc)
  716. return true;
  717. else
  718. return false;
  719. }
  720. bool contraction_HEM_tests(UnorientedGraph *g, Base_Graph &baseg, ListEntiersEntiers &liste_corr, int val_reduc, int &val_cpt){
  721. UnorientedGraph *gtmp = new UnorientedGraph();
  722. boost::copy_graph(*g, *gtmp);
  723. Entiers Index_Vertex; // Initialisation du tableau de sommets rangés aléatoirements
  724. EntiersEntiers *tableau_de_correspondance = new EntiersEntiers();
  725. edge_t e1,e2; // Iterateurs sur les arcs
  726. bool found;
  727. uint nbr_vertex = num_vertices(*gtmp);
  728. //std::cout<<"val_reduc : "<<val_reduc<<std::endl;
  729. //std::cout<<"nbr_vertex : "<<nbr_vertex<<std::endl;
  730. Entiers sommets_a_detruire; // Initialisation d'un tableau pret à recevoir les "sommets à détruire"
  731. /*
  732. * Création d'un vecteur contenant l'ensemble des sommets du graphe. Ces sommets sont rangés
  733. * aléatoirement afin de simuler un tirage aléatoire
  734. */
  735. for (uint i=0 ; i<nbr_vertex ; i++)
  736. Index_Vertex.push_back(i);
  737. Entiers Random_list_vertices = Random_Sort_Vector(nbr_vertex);
  738. /*
  739. * Pour chaque sommet non verrouiller faire ....
  740. */
  741. //std::cout<<"Nouvelle contraction !!!"<<std::endl;
  742. //std::cout<<std::endl;
  743. for(uint i=0; i<nbr_vertex; i++){
  744. int vertexs = Index_Vertex.at(Random_list_vertices.at(i));
  745. //std::cout<<"Le sommet tiré est : "<<(*gtmp)[vertexs]._index<<" ça place est : "<<vertexs<<" place : "<<i<<std::endl;
  746. if(vertexs!=-1){
  747. Entiers liste_voisin = Liste_adjacence_tests(*gtmp,vertexs,Index_Vertex); // Recherche des sommets adjacents au sommets tiré
  748. if(liste_voisin.size()!=0){
  749. /*
  750. * S'il en existe au mois un sommet adjacent au sommet tiré qui n'est pas verrouillé, on
  751. * choisi celui dont l'arc les reliants est le plus fort. Dans le cas où les arcs ont tous
  752. * le même poids, on selectionne le sommet d'index le plus petit
  753. */
  754. double poids_a = 0.;
  755. int best_vertexs = -1;
  756. for(uint j=0;j<liste_voisin.size();j++){
  757. tie(e1,found)=edge(vertex(vertexs,*gtmp),vertex(liste_voisin[j],*gtmp),*gtmp);
  758. if((*gtmp)[e1]._weight>poids_a){
  759. best_vertexs = liste_voisin[j];
  760. poids_a = (*gtmp)[e1]._weight;
  761. }
  762. }
  763. Entiers *couple = new Entiers(); // Initialisation du vecteur contenant le couple de sommet fusionné
  764. int vertex_delete = std::max(vertexs, best_vertexs); // Sommet d'index le plus grand (qui sera détruit)
  765. //std::cout<<"sommet détruit : "<<(*gtmp)[vertex_delete]._index<<std::endl;
  766. int vertex_save = std::min(vertexs,best_vertexs); // Sommet d'identifiant le plus petit (qui sera conservé)
  767. //std::cout<<"sommet sauvé : "<<(*gtmp)[vertex_save]._index<<std::endl;
  768. sommets_a_detruire.push_back(vertex_delete); // On ajoute le sommet détruit au tableau des sommets à détruire
  769. /*
  770. * On ajoute au tableau "couple" le couple de sommet à fusionner
  771. */
  772. couple->push_back(vertex_save);
  773. couple->push_back(vertex_delete);
  774. tableau_de_correspondance->push_back(couple); // Ajout du "couple" à la liste de correspondance
  775. remove_edge(vertex_save,vertex_delete,*gtmp); // Suppression de l'arc reliant le couple de sommets
  776. Entiers neigh_vertex_save; // Initialisation du vecteur contenant les sommets adjacents au "sommet sauvegardé"
  777. Entiers neigh_vertex_delete; // Initialisation du vecteur contenant les somemts adjacents au "sommet à détruire"
  778. tie(neighbourIt, neighbourEnd) = adjacent_vertices(vertex_save,*gtmp);
  779. /*
  780. * Remplissage de ces deux tableaux à l'aide de la fonction adjacent_vertices de boost graph
  781. * [La création de ces tableaux est nécéssaire du fait que certains arcs sont détruit au cours
  782. * du processus]
  783. */
  784. for (; neighbourIt != neighbourEnd; ++neighbourIt){
  785. neigh_vertex_save.push_back(*neighbourIt);
  786. //std::cout<<(*gtmp)[*neighbourIt]._index<<" ";
  787. }
  788. //std::cout<<std::endl;
  789. tie(neighbourIt, neighbourEnd) = adjacent_vertices(vertex_delete,*gtmp);
  790. for (; neighbourIt != neighbourEnd; ++neighbourIt){
  791. neigh_vertex_delete.push_back(*neighbourIt);
  792. //std::cout<<(*gtmp)[*neighbourIt]._index<<" ";
  793. }
  794. //std::cout<<std::endl;
  795. sort(neigh_vertex_save.begin(),neigh_vertex_save.end());
  796. sort(neigh_vertex_delete.begin(),neigh_vertex_delete.end());
  797. /*
  798. * Recherche de sommets communs entre le "sommet sauvegardé" et le "sommet à détruire"
  799. * S'il existe un tel sommet "v" alors on ajoute le poids de l'arcs (vertex_delet,v)
  800. * à celui de l'arcs (vertex_save,v) et on détruit l'arcs reliant "v" au "sommet à détruire"
  801. */
  802. for(uint j=0;j<neigh_vertex_delete.size();j++){
  803. //std::cout<<"* "<<neigh_vertex_delete.size()<<" "<<(*gtmp)[neigh_vertex_delete[j]]._index<<std::endl;
  804. if(neigh_vertex_save.size() != 0){
  805. if(In_tab_dichotomie(neigh_vertex_save,neigh_vertex_delete[j])==1){
  806. // std::cout<<"*p"<<std::endl;
  807. tie(e2,found)=edge(vertex(vertex_save,*gtmp),vertex(neigh_vertex_delete[j],*gtmp),*gtmp);
  808. tie(e1,found)=edge(vertex(vertex_delete,*gtmp),vertex(neigh_vertex_delete[j],*gtmp),*gtmp);
  809. (*gtmp)[e2]._weight+=(*gtmp)[e1]._weight;
  810. remove_edge(vertex_delete,neigh_vertex_delete[j],*gtmp);
  811. }
  812. else
  813. {
  814. //std::cout<<"*t"<<std::endl;
  815. tie(e1,found)=edge(vertex(vertex_delete,*gtmp),vertex(neigh_vertex_delete[j],*gtmp),*gtmp);
  816. add_edge(vertex_save,neigh_vertex_delete[j],EdgeProperties((*gtmp)[e1]._weight),*gtmp);
  817. remove_edge(vertex_delete,neigh_vertex_delete[j],*gtmp);
  818. }
  819. }else{
  820. //std::cout<<"*t"<<std::endl;
  821. tie(e1,found)=edge(vertex(vertex_delete,*gtmp),vertex(neigh_vertex_delete[j],*gtmp),*gtmp);
  822. add_edge(vertex_save,neigh_vertex_delete[j],EdgeProperties((*gtmp)[e1]._weight),*gtmp);
  823. remove_edge(vertex_delete,neigh_vertex_delete[j],*gtmp);
  824. }
  825. }
  826. //std::cout<<"**"<<std::endl;
  827. (*gtmp)[vertex_save]._weight+=(*gtmp)[vertex_delete]._weight; // ajout du poids du sommet détruit au sommet conservé
  828. /*
  829. * Vérouillage du "sommet sauvegardé" et du "sommet à détruire"
  830. */
  831. Index_Vertex.at(Random_list_vertices.at(i))=-1;
  832. Index_Vertex.at(best_vertexs)=-1;
  833. val_cpt--;
  834. //std::cout<<"***"<<std::endl;
  835. //std::cout<<std::endl;
  836. }
  837. else{
  838. /*
  839. * Et si le sommet tiré ne possède pas de sommet adjacent non verrouillé
  840. * alors on l'ajoute à la liste de correspondance des sommets et on
  841. * le verrouille
  842. */
  843. Entiers *couple = new Entiers();
  844. couple->push_back(vertexs);
  845. tableau_de_correspondance->push_back(couple);
  846. Index_Vertex.at(Random_list_vertices.at(i))=-1;
  847. }
  848. }
  849. if(val_cpt == val_reduc){
  850. //std::cout<<"égalité"<<std::endl;
  851. for(uint j=i+1; j < nbr_vertex; j++){
  852. if(Index_Vertex.at(Random_list_vertices.at(j)) != -1){
  853. Entiers *couple = new Entiers();
  854. couple->push_back(Index_Vertex.at(Random_list_vertices.at(j)));
  855. tableau_de_correspondance->push_back(couple);}
  856. }
  857. break;
  858. }
  859. }
  860. std::sort(sommets_a_detruire.begin(), sommets_a_detruire.end()); // Trie dans l'ordre croissant des "sommets à détruire"
  861. // std::cout<<"\n"<<std::endl;
  862. /*
  863. * Suppression des sommets de la liste "sommets à détruire". Cette suppression est
  864. * effectuée dans l'ordre décroissant afin à maintenir à jour la renumérotation
  865. * des sommets
  866. */
  867. for(int j=(sommets_a_detruire.size()-1);j>-1;j--){
  868. //std::cout<<"Noeuds a supprimer : "<<sommets_a_detruire.at(j)<<std::endl;
  869. remove_vertex(sommets_a_detruire[j],*gtmp);
  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. liste_corr.push_back(tableau_de_correspondance);
  873. // std::cout<<"\n"<<std::endl;
  874. baseg.push_back(gtmp); // Ajout du graphe modifié à la "base des graphe"
  875. if(val_cpt == val_reduc)
  876. return true;
  877. else
  878. return false;
  879. }
  880. bool contraction_HEM_max_degree_selection(UnorientedGraph *g, Base_Graph &baseg, ListEntiersEntiers &liste_corr, int val_reduc, int &val_cpt){
  881. UnorientedGraph *gtmp = new UnorientedGraph();
  882. boost::copy_graph(*g, *gtmp);
  883. Entiers Index_Vertex; // Initialisation du tableau de sommets rangés aléatoirements
  884. EntiersEntiers *tableau_de_correspondance = new EntiersEntiers();
  885. edge_t e1,e2; // Iterateurs sur les arcs
  886. bool found;
  887. uint nbr_vertex = num_vertices(*gtmp);
  888. Entiers sommets_a_detruire; // Initialisation d'un tableau pret à recevoir les "sommets à détruire"
  889. /*
  890. * Création d'un vecteur contenant l'ensemble des sommets du graphe. Ces sommets sont rangés
  891. * aléatoirement afin de simuler un tirage aléatoire
  892. */
  893. for (uint i=0 ; i<nbr_vertex ; i++)
  894. Index_Vertex.push_back(i);
  895. Entiers Random_list_vertices = Random_Sort_Vector(nbr_vertex);
  896. /*
  897. * Pour chaque sommet non verrouiller faire ....
  898. */
  899. //std::cout<<"Nouvelle contraction !!!"<<std::endl;
  900. for(uint i=0; i<nbr_vertex; i++){
  901. int vertexs = Index_Vertex.at(Random_list_vertices.at(i));
  902. //std::cout<<"Le sommet tiré est : "<<(*gtmp)[vertexs]._index<<" ça place est : "<<Random_list_vertices.at(i)<<" place : "<<i<<std::endl;
  903. if(vertexs!=-1){
  904. Entiers liste_voisin = Liste_adjacence_tests(*gtmp,vertexs,Index_Vertex); // Recherche des sommets adjacents au sommets tiré
  905. if(liste_voisin.size()!=0){
  906. /*
  907. * S'il en existe au mois un sommet adjacent au sommet tiré qui n'est pas verrouillé, on
  908. * choisi celui dont l'arc les reliants est le plus fort. Dans le cas où les arcs ont tous
  909. * le même poids, on selectionne le sommet d'index le plus petit
  910. */
  911. double poids_a = -1.;
  912. int best_vertexs = -1;
  913. for(uint j=0;j<liste_voisin.size();j++){
  914. tie(e1,found)=edge(vertex(vertexs,*gtmp),vertex(liste_voisin[j],*gtmp),*gtmp);
  915. if((*gtmp)[e1]._weight>poids_a){
  916. best_vertexs = liste_voisin[j];
  917. poids_a = (*gtmp)[e1]._weight;
  918. }
  919. }
  920. Entiers *couple = new Entiers(); // Initialisation du vecteur contenant le couple de sommet fusionné
  921. /* Sélection du sommet possedant un degrès maximum */
  922. std::pair<double,int> couple1, couple2, best_min, best_max;
  923. couple1.first = Degree(*gtmp,vertexs);
  924. couple1.second = vertexs;
  925. couple2.first = Degree(*gtmp,best_vertexs);
  926. couple2.second = best_vertexs;
  927. best_min = std::min(couple1,couple2);
  928. best_max = std::max(couple1,couple2);
  929. int vertex_delete = best_min.second; // Sommet d'index le plus grand (qui sera détruit)
  930. //std::cout<<"sommet détruit : "<<(*gtmp)[vertex_delete]._index<<std::endl;
  931. int vertex_save = best_max.second; // Sommet d'identifiant le plus petit (qui sera conservé)
  932. //std::cout<<"sommet sauvé : "<<(*gtmp)[vertex_save]._index<<std::endl;
  933. sommets_a_detruire.push_back(vertex_delete); // On ajoute le sommet détruit au tableau des sommets à détruire
  934. /*
  935. * On ajoute au tableau "couple" le couple de sommet à fusionner
  936. */
  937. couple->push_back(vertex_save);
  938. couple->push_back(vertex_delete);
  939. tableau_de_correspondance->push_back(couple); // Ajout du "couple" à la liste de correspondance
  940. remove_edge(vertex_save,vertex_delete,*gtmp); // Suppression de l'arc reliant le couple de sommets
  941. Entiers neigh_vertex_save; // Initialisation du vecteur contenant les sommets adjacents au "sommet sauvegardé"
  942. Entiers neigh_vertex_delete; // Initialisation du vecteur contenant les somemts adjacents au "sommet à détruire"
  943. /*
  944. * Remplissage de ces deux tableaux à l'aide de la fonction adjacent_vertices de boost graph
  945. * [La création de ces tableaux est nécéssaire du fait que certains arcs sont détruit au cours
  946. * du processus]
  947. */
  948. tie(neighbourIt, neighbourEnd) = adjacent_vertices(vertex_save,*gtmp);
  949. for (; neighbourIt != neighbourEnd; ++neighbourIt){
  950. neigh_vertex_save.push_back(*neighbourIt);
  951. }
  952. tie(neighbourIt, neighbourEnd) = adjacent_vertices(vertex_delete,*gtmp);
  953. for (; neighbourIt != neighbourEnd; ++neighbourIt){
  954. neigh_vertex_delete.push_back(*neighbourIt);
  955. }
  956. sort(neigh_vertex_save.begin(),neigh_vertex_save.end());
  957. sort(neigh_vertex_delete.begin(),neigh_vertex_delete.end());
  958. /*
  959. * Recherche de sommets communs entre le "sommet sauvegardé" et le "sommet à détruire"
  960. * S'il existe un tel sommet "v" alors on ajoute le poids de l'arcs (vertex_delet,v)
  961. * à celui de l'arcs (vertex_save,v) et on détruit l'arcs reliant "v" au "sommet à détruire"
  962. */
  963. for(uint j=0;j<neigh_vertex_delete.size();j++){
  964. if(In_tab_dichotomie(neigh_vertex_save,neigh_vertex_delete[j])==1){
  965. tie(e2,found)=edge(vertex(vertex_save,*gtmp),vertex(neigh_vertex_delete[j],*gtmp),*gtmp);
  966. tie(e1,found)=edge(vertex(vertex_delete,*gtmp),vertex(neigh_vertex_delete[j],*gtmp),*gtmp);
  967. (*gtmp)[e2]._weight+=(*gtmp)[e1]._weight;
  968. remove_edge(vertex_delete,neigh_vertex_delete[j],*gtmp);
  969. }
  970. else
  971. {
  972. tie(e1,found)=edge(vertex(vertex_delete,*gtmp),vertex(neigh_vertex_delete[j],*gtmp),*gtmp);
  973. add_edge(vertex_save,neigh_vertex_delete[j],EdgeProperties((*gtmp)[e1]._weight),*gtmp);
  974. remove_edge(vertex_delete,neigh_vertex_delete[j],*gtmp);
  975. }
  976. }
  977. (*gtmp)[vertex_save]._weight+=(*gtmp)[vertex_delete]._weight; // ajout du poids du sommet détruit au sommet conservé
  978. /*
  979. * Vérouillage du "sommet sauvegardé" et du "sommet à détruire"
  980. */
  981. Index_Vertex.at(Random_list_vertices.at(i))=-1;
  982. Index_Vertex.at(best_vertexs)=-1;
  983. val_cpt--;
  984. }
  985. else{
  986. /*
  987. * Et si le sommet tiré ne possède pas de sommet adjacent non verrouillé
  988. * alors on l'ajoute à la liste de correspondance des sommets et on
  989. * le verrouille
  990. */
  991. Entiers *couple = new Entiers();
  992. couple->push_back(vertexs);
  993. tableau_de_correspondance->push_back(couple);
  994. Index_Vertex.at(Random_list_vertices.at(i))=-1;
  995. }
  996. }
  997. if(val_cpt == val_reduc){
  998. for(uint j=i+1; j < nbr_vertex; j++){
  999. if(Index_Vertex.at(Random_list_vertices.at(j)) != -1){
  1000. Entiers *couple = new Entiers();
  1001. couple->push_back(Index_Vertex.at(Random_list_vertices.at(j)));
  1002. tableau_de_correspondance->push_back(couple);}
  1003. }
  1004. break;
  1005. }
  1006. }
  1007. std::sort(sommets_a_detruire.begin(), sommets_a_detruire.end()); // Trie dans l'ordre croissant des "sommets à détruire"
  1008. /*
  1009. * Suppression des sommets de la liste "sommets à détruire". Cette suppression est
  1010. * effectuée dans l'ordre décroissant afin à maintenir à jour la renumérotation
  1011. * des sommets
  1012. */
  1013. for(int j=(sommets_a_detruire.size()-1);j>-1;j--){
  1014. remove_vertex(sommets_a_detruire[j],*gtmp);
  1015. }
  1016. 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
  1017. liste_corr.push_back(tableau_de_correspondance);
  1018. baseg.push_back(gtmp); // Ajout du graphe modifié à la "base des graphe"
  1019. if(val_cpt == val_reduc)
  1020. return true;
  1021. else
  1022. return false;
  1023. }
  1024. bool contraction_HEM_degree(UnorientedGraph *g, Base_Graph &baseg, ListEntiersEntiers &liste_corr, int val_reduc, int &val_cpt){
  1025. UnorientedGraph *gtmp = new UnorientedGraph();
  1026. boost::copy_graph(*g, *gtmp);
  1027. Entiers Index_Vertex; // Initialisation du tableau de sommets rangés aléatoirements
  1028. std::vector<double> vertex_degree;
  1029. EntiersEntiers *tableau_de_correspondance = new EntiersEntiers();
  1030. edge_t e1,e2; // Iterateurs sur les arcs
  1031. bool found;
  1032. uint nbr_vertex = num_vertices(*gtmp);
  1033. Entiers sommets_a_detruire; // Initialisation d'un tableau pret à recevoir les "sommets à détruire"
  1034. int cpt = nbr_vertex;
  1035. /*
  1036. * Création d'un vecteur contenant l'ensemble des sommets du graphe. Ces sommets sont rangés
  1037. * aléatoirement afin de simuler un tirage aléatoire
  1038. */
  1039. for (uint i=0 ; i<nbr_vertex ; i++){
  1040. Index_Vertex.push_back(i);
  1041. vertex_degree.push_back(Degree(*g,i));
  1042. }
  1043. while(cpt != 0){
  1044. double max_weight = *std::max_element(vertex_degree.begin(),vertex_degree.end());
  1045. int vertexs, compteur;
  1046. //std::cout<<"max_weight : "<<max_weight<<std::endl;
  1047. //Entiers Vertex_select;
  1048. for(uint id = 0; id <vertex_degree.size(); id++){
  1049. if(vertex_degree.at(id) == max_weight){
  1050. compteur = id;
  1051. vertexs = Index_Vertex.at(id);
  1052. break;
  1053. }
  1054. }
  1055. //std::cout<<"min : "<<max_weight<<" - compteur : "<<(*gtmp)[compteur]._index;
  1056. //std::cout<<"Le sommet tiré est : "<<(*gtmp)[vertexs]._index<<" ça place est : "<<compteur<<std::endl;
  1057. Entiers liste_voisin = Liste_adjacence_tests(*gtmp,vertexs,Index_Vertex); // Recherche des sommets adjacents au sommets tiré
  1058. if(liste_voisin.size() != 0){
  1059. /*
  1060. * S'il en existe au mois un sommet adjacent au sommet tiré qui n'est pas verrouillé, on
  1061. * choisi celui dont l'arc les reliants est le plus fort. Dans le cas où les arcs ont tous
  1062. * le même poids, on selectionne le sommet d'index le plus petit
  1063. */
  1064. std::vector<double> Neight_weight, Best_neight;
  1065. int best_vertexs;
  1066. for(uint j=0;j<liste_voisin.size();j++){
  1067. tie(e1,found)=edge(vertex(vertexs,*gtmp),vertex(liste_voisin[j],*gtmp),*gtmp);
  1068. Neight_weight.push_back((*gtmp)[e1]._weight);
  1069. }
  1070. max_weight = *std::max_element(Neight_weight.begin(),Neight_weight.end());
  1071. for(uint j=0;j<liste_voisin.size();j++){
  1072. if(Neight_weight.at(j) == max_weight)
  1073. Best_neight.push_back(liste_voisin.at(j));
  1074. }
  1075. if(Best_neight.size() > 1){
  1076. int ind;
  1077. double deg =1000000000;
  1078. double tmp_deg;
  1079. for(uint j=0;j<Best_neight.size();j++){
  1080. tmp_deg = Degree(*gtmp,Best_neight.at(j));
  1081. if(tmp_deg < deg){
  1082. deg = tmp_deg;
  1083. ind = j;
  1084. }
  1085. }
  1086. best_vertexs = Best_neight.at(ind);
  1087. }else{
  1088. best_vertexs = Best_neight.at(0);
  1089. }
  1090. //std::cout<<" -> "<<(*gtmp)[best_vertexs]._index;
  1091. Entiers *couple = new Entiers(); // Initialisation du vecteur contenant le couple de sommet fusionné
  1092. /* Sélection du sommet possedant un degrès maximum */
  1093. std::pair<double,int> couple1, couple2, best_min, best_max;
  1094. couple1.first = Degree(*gtmp,vertexs);
  1095. couple1.second = vertexs;
  1096. couple2.first = Degree(*gtmp,best_vertexs);
  1097. couple2.second = best_vertexs;
  1098. best_min = std::min(couple1,couple2);
  1099. best_max = std::max(couple1,couple2);
  1100. int vertex_delete = best_min.second; // Sommet d'index le plus grand (qui sera détruit)
  1101. //std::cout<<"sommet détruit : "<<(*gtmp)[vertex_delete]._index<<std::endl;
  1102. int vertex_save = best_max.second; // Sommet d'identifiant le plus petit (qui sera conservé)
  1103. //std::cout<<"sommet sauvé : "<<(*gtmp)[vertex_save]._index<<std::endl;
  1104. sommets_a_detruire.push_back(vertex_delete); // On ajoute le sommet détruit au tableau des sommets à détruire
  1105. /*
  1106. * On ajoute au tableau "couple" le couple de sommet à fusionner
  1107. */
  1108. couple->push_back(vertex_save);
  1109. couple->push_back(vertex_delete);
  1110. tableau_de_correspondance->push_back(couple); // Ajout du "couple" à la liste de correspondance
  1111. remove_edge(vertex_save,vertex_delete,*gtmp); // Suppression de l'arc reliant le couple de sommets
  1112. Entiers neigh_vertex_save; // Initialisation du vecteur contenant les sommets adjacents au "sommet sauvegardé"
  1113. Entiers neigh_vertex_delete; // Initialisation du vecteur contenant les somemts adjacents au "sommet à détruire"
  1114. /*
  1115. * Remplissage de ces deux tableaux à l'aide de la fonction adjacent_vertices de boost graph
  1116. * [La création de ces tableaux est nécéssaire du fait que certains arcs sont détruit au cours
  1117. * du processus]
  1118. */
  1119. tie(neighbourIt, neighbourEnd) = adjacent_vertices(vertex_save,*gtmp);
  1120. for (; neighbourIt != neighbourEnd; ++neighbourIt){
  1121. neigh_vertex_save.push_back(*neighbourIt);
  1122. }
  1123. tie(neighbourIt, neighbourEnd) = adjacent_vertices(vertex_delete,*gtmp);
  1124. for (; neighbourIt != neighbourEnd; ++neighbourIt){
  1125. neigh_vertex_delete.push_back(*neighbourIt);
  1126. }
  1127. sort(neigh_vertex_save.begin(),neigh_vertex_save.end());
  1128. sort(neigh_vertex_delete.begin(),neigh_vertex_delete.end());
  1129. /*
  1130. * Recherche de sommets communs entre le "sommet sauvegardé" et le "sommet à détruire"
  1131. * S'il existe un tel sommet "v" alors on ajoute le poids de l'arcs (vertex_delet,v)
  1132. * à celui de l'arcs (vertex_save,v) et on détruit l'arcs reliant "v" au "sommet à détruire"
  1133. */
  1134. for(uint j=0;j<neigh_vertex_delete.size();j++){
  1135. if(neigh_vertex_save.size() != 0){
  1136. if(In_tab_dichotomie(neigh_vertex_save,neigh_vertex_delete[j])==1){
  1137. tie(e2,found)=edge(vertex(vertex_save,*gtmp),vertex(neigh_vertex_delete[j],*gtmp),*gtmp);
  1138. tie(e1,found)=edge(vertex(vertex_delete,*gtmp),vertex(neigh_vertex_delete[j],*gtmp),*gtmp);
  1139. (*gtmp)[e2]._weight+=(*gtmp)[e1]._weight;
  1140. remove_edge(vertex_delete,neigh_vertex_delete[j],*gtmp);
  1141. }
  1142. else
  1143. {
  1144. tie(e1,found)=edge(vertex(vertex_delete,*gtmp),vertex(neigh_vertex_delete[j],*gtmp),*gtmp);
  1145. add_edge(vertex_save,neigh_vertex_delete[j],EdgeProperties((*gtmp)[e1]._weight),*gtmp);
  1146. remove_edge(vertex_delete,neigh_vertex_delete[j],*gtmp);
  1147. }
  1148. }else{
  1149. tie(e1,found)=edge(vertex(vertex_delete,*gtmp),vertex(neigh_vertex_delete[j],*gtmp),*gtmp);
  1150. add_edge(vertex_save,neigh_vertex_delete[j],EdgeProperties((*gtmp)[e1]._weight),*gtmp);
  1151. remove_edge(vertex_delete,neigh_vertex_delete[j],*gtmp);
  1152. }
  1153. }
  1154. (*gtmp)[vertex_save]._weight+=(*gtmp)[vertex_delete]._weight; // ajout du poids du sommet détruit au sommet conservé
  1155. /*
  1156. * Vérouillage du "sommet sauvegardé" et du "sommet à détruire"
  1157. */
  1158. Index_Vertex.at(compteur)=-1;
  1159. vertex_degree.at(compteur)=-1;
  1160. Index_Vertex.at(best_vertexs)=-1;
  1161. vertex_degree.at(best_vertexs)=-1;
  1162. val_cpt--;
  1163. cpt -= 2;
  1164. //std::cout<<" ** "<<std::endl;
  1165. //std::cout<<cpt<<std::endl;
  1166. }
  1167. else{
  1168. /*
  1169. * Et si le sommet tiré ne possède pas de sommet adjacent non verrouillé
  1170. * alors on l'ajoute à la liste de correspondance des sommets et on
  1171. * le verrouille
  1172. */
  1173. Entiers *couple = new Entiers();
  1174. couple->push_back(vertexs);
  1175. tableau_de_correspondance->push_back(couple);
  1176. Index_Vertex.at(compteur)=-1;
  1177. vertex_degree.at(compteur)=-1;
  1178. cpt --;
  1179. //std::cout<<" * "<<std::endl;
  1180. }
  1181. if(val_cpt == val_reduc){
  1182. for(uint j=0; j < nbr_vertex; j++){
  1183. if(Index_Vertex.at(j) != -1){
  1184. Entiers *couple = new Entiers();
  1185. couple->push_back(Index_Vertex.at(j));
  1186. tableau_de_correspondance->push_back(couple);}
  1187. }
  1188. break;
  1189. }
  1190. }
  1191. //std::cout<<"cpt : "<<cpt<<std::endl;
  1192. std::sort(sommets_a_detruire.begin(), sommets_a_detruire.end()); // Trie dans l'ordre croissant des "sommets à détruire"
  1193. /*
  1194. * Suppression des sommets de la liste "sommets à détruire". Cette suppression est
  1195. * effectuée dans l'ordre décroissant afin à maintenir à jour la renumérotation
  1196. * des sommets
  1197. */
  1198. for(int j=(sommets_a_detruire.size()-1);j>-1;j--){
  1199. remove_vertex(sommets_a_detruire[j],*gtmp);
  1200. }
  1201. 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
  1202. liste_corr.push_back(tableau_de_correspondance);
  1203. baseg.push_back(gtmp); // Ajout du graphe modifié à la "base des graphe"
  1204. if(val_cpt == val_reduc)
  1205. return true;
  1206. else
  1207. return false;
  1208. }
  1209. bool contraction_HEM_mds_ameliore_KK(UnorientedGraph *g, Base_Graph &baseg, ListEntiersEntiers &liste_corr, int val_reduc, int &val_cpt){
  1210. UnorientedGraph *gtmp = new UnorientedGraph();
  1211. boost::copy_graph(*g, *gtmp);
  1212. Entiers Index_Vertex; // Initialisation du tableau de sommets rangés aléatoirements
  1213. EntiersEntiers *tableau_de_correspondance = new EntiersEntiers();
  1214. edge_t e1,e2; // Iterateurs sur les arcs
  1215. bool found;
  1216. uint nbr_vertex = num_vertices(*gtmp);
  1217. Entiers sommets_a_detruire; // Initialisation d'un tableau pret à recevoir les "sommets à détruire"
  1218. /*
  1219. * Création d'un vecteur contenant l'ensemble des sommets du graphe. Ces sommets sont rangés
  1220. * aléatoirement afin de simuler un tirage aléatoire
  1221. */
  1222. for (uint i=0 ; i<nbr_vertex ; i++)
  1223. Index_Vertex.push_back(i);
  1224. Entiers Random_list_vertices = Random_Sort_Vector(nbr_vertex);
  1225. /*
  1226. * Pour chaque sommet non verrouiller faire ....
  1227. */
  1228. //std::cout<<"Nouvelle contraction !!!"<<std::endl;
  1229. for(uint i=0; i<nbr_vertex; i++){
  1230. int vertexs = Index_Vertex.at(Random_list_vertices.at(i));
  1231. //std::cout<<"Le sommet tiré est : "<<(*gtmp)[vertexs]._index<<" ça place est : "<<Random_list_vertices.at(i)<<" place : "<<i<<std::endl;
  1232. if(vertexs!=-1){
  1233. Entiers liste_voisin = Liste_adjacence_tests(*gtmp,vertexs,Index_Vertex); // Recherche des sommets adjacents au sommets tiré
  1234. sort(liste_voisin.begin(),liste_voisin.end());
  1235. if(liste_voisin.size()!=0){
  1236. /*
  1237. * S'il en existe au mois un sommet adjacent au sommet tiré qui n'est pas verrouillé, on
  1238. * choisi celui dont l'arc les reliants est le plus fort. Dans le cas où les arcs ont tous
  1239. * le même poids, on selectionne le sommet d'index le plus petit
  1240. */
  1241. /*std::cout<<"Le sommet tiré a des voisins "<<std::endl;
  1242. for(uint id = 0; id<liste_voisin.size(); id++){
  1243. std::cout<<(*gtmp)[liste_voisin.at(id)]._index<<" ";
  1244. }
  1245. std::cout<<std::endl;*/
  1246. double poids_a = -1.;
  1247. std::vector<double> adjacent_weight;
  1248. //std::cout<<"adjacent_weight"<<std::endl;
  1249. for(uint j=0;j<liste_voisin.size();j++){
  1250. tie(e1,found)=edge(vertex(vertexs,*gtmp),vertex(liste_voisin[j],*gtmp),*gtmp);
  1251. adjacent_weight.push_back((*gtmp)[e1]._weight);
  1252. //std::cout<<(*gtmp)[e1]._weight<<" ";
  1253. }
  1254. //std::cout<<std::endl;
  1255. //std::cout<<"Top *"<<std::endl;
  1256. double max_weight = *std::max_element(adjacent_weight.begin(),adjacent_weight.end());
  1257. //std::cout<<"max_weight : "<<max_weight<<std::endl;
  1258. Entiers Vertex_select;
  1259. for(uint id = 0; id <adjacent_weight.size(); id++){
  1260. if(adjacent_weight.at(id) == max_weight)
  1261. Vertex_select.push_back(liste_voisin.at(id));
  1262. }
  1263. int index = 0;
  1264. if(Vertex_select.size()>1){
  1265. //std::cout<<"Top **"<<std::endl;
  1266. for(uint id = 0; id<Vertex_select.size(); id++){
  1267. suprim_val(liste_voisin,Vertex_select.at(id)); /*** modification possible ***/
  1268. }
  1269. //std::cout<<"Top ***"<<std::endl;
  1270. adjacent_weight.clear();
  1271. for(uint id_Vs = 0; id_Vs<Vertex_select.size(); id_Vs++){
  1272. double neigh_weight = 0.;
  1273. for(uint id_Lv = 0; id_Lv<liste_voisin.size(); id_Lv++){
  1274. //std::cout<<"Top ***!"<<std::endl;
  1275. bool rep = Est_voisin(gtmp,liste_voisin.at(id_Lv),Vertex_select.at(id_Vs));
  1276. if(rep == true){
  1277. tie(e1,found)=edge(vertex(Vertex_select.at(id_Vs),*gtmp),vertex(liste_voisin.at(id_Lv),*gtmp),*gtmp);
  1278. //std::cout<<"Top ***!!"<<std::endl;
  1279. //std::cout<<e1<<std::endl;
  1280. //std::cout<<"Top ***!!!"<<std::endl;
  1281. neigh_weight += (*gtmp)[e1]._weight;
  1282. }
  1283. //std::cout<<"Top ***!!!!"<<std::endl;
  1284. }
  1285. adjacent_weight.push_back(neigh_weight);
  1286. }
  1287. //std::cout<<"Top ****"<<std::endl;
  1288. max_weight = *std::max_element(adjacent_weight.begin(),adjacent_weight.end());
  1289. for(uint id = 0; id <adjacent_weight.size(); id++){
  1290. if(adjacent_weight.at(id) == max_weight){
  1291. index = id;
  1292. break;
  1293. }
  1294. }
  1295. }
  1296. //std::cout<<"Index "<<index<<std::endl;
  1297. //std::cout<<"Top *****"<<std::endl;
  1298. int best_vertexs = Vertex_select.at(index);
  1299. //std::cout<<"Index "<<best_vertexs<<std::endl;
  1300. Entiers *couple = new Entiers(); // Initialisation du vecteur contenant le couple de sommet fusionné
  1301. /* Sélection du sommet possedant un degrès maximum */
  1302. std::pair<double,int> couple1, couple2, best_min, best_max;
  1303. couple1.first = Degree(*gtmp,vertexs);
  1304. couple1.second = vertexs;
  1305. couple2.first = Degree(*gtmp,best_vertexs);
  1306. couple2.second = best_vertexs;
  1307. best_min = std::min(couple1,couple2);
  1308. best_max = std::max(couple1,couple2);
  1309. int vertex_delete = best_min.second; // Sommet d'index le plus grand (qui sera détruit)
  1310. //std::cout<<"sommet détruit : "<<(*gtmp)[vertex_delete]._index<<std::endl;
  1311. int vertex_save = best_max.second; // Sommet d'identifiant le plus petit (qui sera conservé)
  1312. //std::cout<<"sommet sauvé : "<<(*gtmp)[vertex_save]._index<<std::endl;
  1313. sommets_a_detruire.push_back(vertex_delete); // On ajoute le sommet détruit au tableau des sommets à détruire
  1314. /*
  1315. * On ajoute au tableau "couple" le couple de sommet à fusionner
  1316. */
  1317. couple->push_back(vertex_save);
  1318. couple->push_back(vertex_delete);
  1319. tableau_de_correspondance->push_back(couple); // Ajout du "couple" à la liste de correspondance
  1320. remove_edge(vertex_save,vertex_delete,*gtmp); // Suppression de l'arc reliant le couple de sommets
  1321. Entiers neigh_vertex_save; // Initialisation du vecteur contenant les sommets adjacents au "sommet sauvegardé"
  1322. Entiers neigh_vertex_delete; // Initialisation du vecteur contenant les somemts adjacents au "sommet à détruire"
  1323. /*
  1324. * Remplissage de ces deux tableaux à l'aide de la fonction adjacent_vertices de boost graph
  1325. * [La création de ces tableaux est nécéssaire du fait que certains arcs sont détruit au cours
  1326. * du processus]
  1327. */
  1328. tie(neighbourIt, neighbourEnd) = adjacent_vertices(vertex_save,*gtmp);
  1329. for (; neighbourIt != neighbourEnd; ++neighbourIt){
  1330. neigh_vertex_save.push_back(*neighbourIt);
  1331. }
  1332. tie(neighbourIt, neighbourEnd) = adjacent_vertices(vertex_delete,*gtmp);
  1333. for (; neighbourIt != neighbourEnd; ++neighbourIt){
  1334. neigh_vertex_delete.push_back(*neighbourIt);
  1335. }
  1336. sort(neigh_vertex_save.begin(),neigh_vertex_save.end());
  1337. sort(neigh_vertex_delete.begin(),neigh_vertex_delete.end());
  1338. /*
  1339. * Recherche de sommets communs entre le "sommet sauvegardé" et le "sommet à détruire"
  1340. * S'il existe un tel sommet "v" alors on ajoute le poids de l'arcs (vertex_delet,v)
  1341. * à celui de l'arcs (vertex_save,v) et on détruit l'arcs reliant "v" au "sommet à détruire"
  1342. */
  1343. for(uint j=0;j<neigh_vertex_delete.size();j++){
  1344. if(In_tab_dichotomie(neigh_vertex_save,neigh_vertex_delete[j])==1){
  1345. tie(e2,found)=edge(vertex(vertex_save,*gtmp),vertex(neigh_vertex_delete[j],*gtmp),*gtmp);
  1346. tie(e1,found)=edge(vertex(vertex_delete,*gtmp),vertex(neigh_vertex_delete[j],*gtmp),*gtmp);
  1347. (*gtmp)[e2]._weight+=(*gtmp)[e1]._weight;
  1348. remove_edge(vertex_delete,neigh_vertex_delete[j],*gtmp);
  1349. }
  1350. else
  1351. {
  1352. tie(e1,found)=edge(vertex(vertex_delete,*gtmp),vertex(neigh_vertex_delete[j],*gtmp),*gtmp);
  1353. add_edge(vertex_save,neigh_vertex_delete[j],EdgeProperties((*gtmp)[e1]._weight),*gtmp);
  1354. remove_edge(vertex_delete,neigh_vertex_delete[j],*gtmp);
  1355. }
  1356. }
  1357. (*gtmp)[vertex_save]._weight+=(*gtmp)[vertex_delete]._weight; // ajout du poids du sommet détruit au sommet conservé
  1358. /*
  1359. * Vérouillage du "sommet sauvegardé" et du "sommet à détruire"
  1360. */
  1361. Index_Vertex.at(Random_list_vertices.at(i))=-1;
  1362. Index_Vertex.at(best_vertexs)=-1;
  1363. val_cpt--;
  1364. }
  1365. else{
  1366. /*
  1367. * Et si le sommet tiré ne possède pas de sommet adjacent non verrouillé
  1368. * alors on l'ajoute à la liste de correspondance des sommets et on
  1369. * le verrouille
  1370. */
  1371. //std::cout<<"Le sommet tiré est isolé "<<std::endl;
  1372. Entiers *couple = new Entiers();
  1373. couple->push_back(vertexs);
  1374. tableau_de_correspondance->push_back(couple);
  1375. Index_Vertex.at(Random_list_vertices.at(i))=-1;
  1376. }
  1377. }else{
  1378. //std::cout<<"Le sommet est bloqué "<<std::endl;
  1379. //std::cout<<" ça place est : "<<Random_list_vertices.at(i)<<" valeur : "<<Index_Vertex.at(Random_list_vertices.at(i))<<std::endl;
  1380. }
  1381. if(val_cpt == val_reduc){
  1382. //std::cout<<"Taille obtenue !"<<std::endl;
  1383. for(uint j=i+1; j < nbr_vertex; j++){
  1384. if(Index_Vertex.at(Random_list_vertices.at(j)) != -1){
  1385. Entiers *couple = new Entiers();
  1386. couple->push_back(vertexs);
  1387. tableau_de_correspondance->push_back(couple);}
  1388. }
  1389. break;
  1390. }
  1391. }
  1392. std::sort(sommets_a_detruire.begin(), sommets_a_detruire.end()); // Trie dans l'ordre croissant des "sommets à détruire"
  1393. /*
  1394. * Suppression des sommets de la liste "sommets à détruire". Cette suppression est
  1395. * effectuée dans l'ordre décroissant afin à maintenir à jour la renumérotation
  1396. * des sommets
  1397. */
  1398. for(int j=(sommets_a_detruire.size()-1);j>-1;j--){
  1399. remove_vertex(sommets_a_detruire[j],*gtmp);
  1400. }
  1401. 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
  1402. liste_corr.push_back(tableau_de_correspondance);
  1403. baseg.push_back(gtmp); // Ajout du graphe modifié à la "base des graphe"
  1404. if(val_cpt == val_reduc)
  1405. return true;
  1406. else
  1407. return false;
  1408. }
  1409. bool Est_voisin(UnorientedGraph *g, int vertex, int vertex_select){
  1410. bool reponse = false;
  1411. tie(neighbourIt, neighbourEnd) = adjacent_vertices(vertex, *g);
  1412. for (; neighbourIt != neighbourEnd; ++neighbourIt){
  1413. if(*neighbourIt == vertex_select)
  1414. reponse = true;
  1415. }
  1416. return reponse;
  1417. }
  1418. bool contraction_Random_Maching(UnorientedGraph *g, Base_Graph &baseg, ListEntiersEntiers &liste_corr, int val_reduc, int &val_cpt){
  1419. UnorientedGraph *gtmp = new UnorientedGraph();
  1420. boost::copy_graph(*g, *gtmp);
  1421. EntiersEntiers *tableau_de_correspondance = new EntiersEntiers();
  1422. edge_t e1,e2; // Iterateurs sur les arcs
  1423. bool found;
  1424. uint nbr_vertex = num_vertices(*gtmp);
  1425. Entiers sommets_a_detruire; // Initialisation d'un tableau pret à recevoir les "sommets à détruire"
  1426. /*
  1427. * Création d'un vecteur contenant l'ensemble des sommets du graphe. Ces sommets sont rangés
  1428. * aléatoirement afin de simuler un tirage aléatoire
  1429. */
  1430. Entiers Random_list_vertices = Random_Sort_Vector(nbr_vertex);
  1431. /*
  1432. * Pour chaque sommet non verrouiller faire ....
  1433. */
  1434. for(uint i=0; i<nbr_vertex; i++){
  1435. int vertexs = Random_list_vertices[i];
  1436. if(vertexs!=-1){
  1437. Entiers liste_voisin = Liste_adjacence(*gtmp,vertexs,Random_list_vertices); // Recherche des sommets adjacents au sommets tiré
  1438. if(liste_voisin.size()!=0){
  1439. /*
  1440. * S'il en existe au mois un sommet adjacent au sommet tiré qui n'est pas verrouillé, on
  1441. * choisi celui dont l'arc les reliants est le plus fort. Dans le cas où les arcs ont tous
  1442. * le même poids, on selectionne le sommet d'identifiant le plus petit
  1443. */
  1444. int tmp;
  1445. if(liste_voisin.size()==1)
  1446. tmp = 0;
  1447. else
  1448. tmp = rand_fini(0,liste_voisin.size()-1);
  1449. int best_vertexs = liste_voisin.at(tmp);
  1450. Entiers * couple = new Entiers(); // Initialisation du vecteur contenant le couple de sommet fusionné
  1451. int vertex_delete = std::max(vertexs, best_vertexs); // Sommet d'indentifiant le plus grand (qui sera détruit)
  1452. int vertex_save = std::min(vertexs,best_vertexs); // Sommet d'identifiant le plus petit (qui sera conservé)
  1453. sommets_a_detruire.push_back(vertex_delete); // On ajoute le sommet détruit au tableau des sommets à détruire
  1454. /*
  1455. * On ajoute au tableau "couple" le couple de sommet à fusionner
  1456. */
  1457. couple->push_back(vertex_save);
  1458. couple->push_back(vertex_delete);
  1459. tableau_de_correspondance->push_back(couple); // Ajout du "couple" à la liste de correspondance
  1460. remove_edge(vertex_save,vertex_delete,*gtmp); // Suppression de l'arc reliant le couple de sommets
  1461. Entiers neigh_vertex_save; // Initialisation du vecteur contenant les somemts adjacents au "sommet sauvegardé"
  1462. Entiers neigh_vertex_delete; // Initialisation du vecteur contenant les somemts adjacents au "sommet à détruire"
  1463. tie(neighbourIt, neighbourEnd) = adjacent_vertices(vertex_save,*gtmp);
  1464. /*
  1465. * Remplissage de ces deux tableaux à l'aide de la fonction adjacent_vertices de boost graph
  1466. * [La création de ces tableaux est nécéssaire du fait que certains arcs sont détruit au cours
  1467. * du processus]
  1468. */
  1469. for (; neighbourIt != neighbourEnd; ++neighbourIt){
  1470. neigh_vertex_save.push_back(*neighbourIt);
  1471. }
  1472. tie(neighbourIt, neighbourEnd) = adjacent_vertices(vertex_delete,*gtmp);
  1473. for (; neighbourIt != neighbourEnd; ++neighbourIt){
  1474. neigh_vertex_delete.push_back(*neighbourIt);
  1475. }
  1476. /*
  1477. * Recherche de sommets communs entre le "sommet sauvegardé" et le "sommet à détruire"
  1478. * S'il existe un tel sommet "v" alors on ajoute le poids de l'arcs (vertex_delet,v)
  1479. * à celui de l'arcs (vertex_save,v) et on détruit l'arcs reliant "v" au "sommet à détruire"
  1480. */
  1481. for(uint j=0;j<neigh_vertex_delete.size();j++){
  1482. if(In_tab(neigh_vertex_save,neigh_vertex_delete[j])==1){
  1483. tie(e2,found)=edge(vertex(vertex_save,*gtmp),vertex(neigh_vertex_delete[j],*gtmp),*gtmp);
  1484. tie(e1,found)=edge(vertex(vertex_delete,*gtmp),vertex(neigh_vertex_delete[j],*gtmp),*gtmp);
  1485. (*gtmp)[e2]._weight+=(*gtmp)[e1]._weight;
  1486. remove_edge(vertex_delete,neigh_vertex_delete[j],*gtmp);
  1487. }
  1488. else
  1489. {
  1490. tie(e1,found)=edge(vertex(vertex_delete,*gtmp),vertex(neigh_vertex_delete[j],*gtmp),*gtmp);
  1491. add_edge(vertex_save,neigh_vertex_delete[j],EdgeProperties((*gtmp)[e1]._weight),*gtmp);
  1492. remove_edge(vertex_delete,neigh_vertex_delete[j],*gtmp);
  1493. }
  1494. }
  1495. (*gtmp)[vertex_save]._weight+=(*gtmp)[vertex_delete]._weight; // ajout du poids du sommet détruit au sommet conservé
  1496. /*
  1497. * Vérouillage du "sommet sauvegardé" et du "sommet à détruire"
  1498. */
  1499. Random_list_vertices[i]=-1;
  1500. Random_list_vertices[recherche_val(Random_list_vertices,best_vertexs)]=-1;
  1501. val_cpt--;
  1502. // std::cout<<val_cpt<<std::endl;
  1503. }
  1504. else{
  1505. /*
  1506. * Et si le sommet tiré ne possède pas de sommet adjacent non verrouillé
  1507. * alors on l'ajoute à la liste de correspondance des sommets et on
  1508. * le verrouille
  1509. */
  1510. Entiers *couple = new Entiers();
  1511. couple->push_back(Random_list_vertices.at(i));
  1512. tableau_de_correspondance->push_back(couple);
  1513. Random_list_vertices[i]=-1;
  1514. }
  1515. }
  1516. if(val_cpt == val_reduc){
  1517. for(uint j=i+1; j <nbr_vertex; j++){
  1518. if(Random_list_vertices[j] !=-1){
  1519. Entiers *couple = new Entiers();
  1520. couple->push_back(Random_list_vertices.at(j));
  1521. tableau_de_correspondance->push_back(couple);}
  1522. }
  1523. break;
  1524. }
  1525. }
  1526. std::sort(sommets_a_detruire.begin(), sommets_a_detruire.end()); // Trie dans l'ordre croissant des "sommets à détruire"
  1527. //std::cout<<"\n"<<std::endl;
  1528. /*
  1529. * Suppression des sommets de la liste "sommets à détruire". Cette suppression est
  1530. * effectuée dans l'ordre décroissant afin à maintenir à jour la renumérotation
  1531. * des sommets
  1532. */
  1533. for(int j=(sommets_a_detruire.size()-1);j>-1;j--){
  1534. //std::cout<<"Noeuds a supprimer : "<<sommets_a_detruire.at(j)<<std::endl;
  1535. remove_vertex(sommets_a_detruire[j],*gtmp);
  1536. }
  1537. 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
  1538. liste_corr.push_back(tableau_de_correspondance);
  1539. baseg.push_back(gtmp); // Ajout du graphe modifié à la "base des graphe"
  1540. if(val_cpt == val_reduc)
  1541. return true;
  1542. else
  1543. return false;
  1544. }
  1545. Entiers Liste_adjacence(UnorientedGraph &g, int vertexs,const Entiers &random_vertices){ // a revoir !!!!
  1546. Entiers liste_voisin;
  1547. tie(neighbourIt, neighbourEnd) = adjacent_vertices(vertexs, g);
  1548. for (; neighbourIt != neighbourEnd; ++neighbourIt){
  1549. if(In_tab(random_vertices,*neighbourIt)==1)
  1550. liste_voisin.push_back(*neighbourIt);
  1551. }
  1552. return liste_voisin;
  1553. }
  1554. Entiers Liste_adjacence_tests(UnorientedGraph &g, int vertexs,const Entiers &Index_Vertex){ // a revoir !!!!
  1555. Entiers liste_voisin;
  1556. tie(neighbourIt, neighbourEnd) = adjacent_vertices(vertexs, g);
  1557. for (; neighbourIt != neighbourEnd; ++neighbourIt){
  1558. if(Index_Vertex.at(*neighbourIt)!=-1)
  1559. liste_voisin.push_back(*neighbourIt);
  1560. }
  1561. return liste_voisin;
  1562. }
  1563. int rand_fini(int a, int b){
  1564. return rand()%(b-a)+a;
  1565. }
  1566. /**
  1567. * Fonction de recherche d'une valeur dans un tableau.
  1568. * @param tab
  1569. * @param val
  1570. * @return
  1571. */
  1572. int recherche_val2(const std::vector<float> &tab,float val){
  1573. int cpt=0;
  1574. while(tab[cpt]!=val)
  1575. cpt++;
  1576. return cpt;
  1577. }
  1578. int recherche_val_double(const std::vector<double> &tab,double val){
  1579. int cpt=0;
  1580. while(tab[cpt]!=val)
  1581. cpt++;
  1582. return cpt;
  1583. }
  1584. int recherche_val(const Entiers &tab,int val){
  1585. int cpt=0;
  1586. while(tab[cpt]!=val)
  1587. cpt++;
  1588. return cpt;
  1589. }
  1590. /**
  1591. * @param tab
  1592. * @param i
  1593. * @return
  1594. */
  1595. int dichotomie(const Entiers &tab, int i){
  1596. /* déclaration des variables locales à la fonction */
  1597. int id; //indice de début
  1598. int ifin; //indice de fin
  1599. int im; //indice de "milieu"
  1600. /* initialisation de ces variables avant la boucle de recherche */
  1601. id = 0; //intervalle de recherche compris entre 0...
  1602. ifin = tab.size(); //...et nbVal
  1603. /* boucle de recherche */
  1604. while ((ifin - id) > 1){
  1605. im = (id + ifin)/2; //on détermine l'indice de milieu
  1606. 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
  1607. 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
  1608. }
  1609. /* test conditionnant la valeur que la fonction va renvoyer */
  1610. if (tab[id] == i) return id; //si on a trouvé la bonne valeur, on retourne l'indice
  1611. else return -1; //sinon on retourne -1
  1612. }
  1613. /**
  1614. * Fonction permettant de supprimer une case d'un tableau.
  1615. * @param tab une référence sur un tableau d'entiers
  1616. * @param i un indice dans tab
  1617. */
  1618. void suprim_val(Entiers &tab,int i) {
  1619. tab.erase(tab.begin() + dichotomie(tab,i));
  1620. }
  1621. /**
  1622. * Détermine si une valeur se trouve dans un tableau.
  1623. * @param tab une référence sur un tableau d'entiers
  1624. * @param val une valeur
  1625. * @return true si la valeur a été trouvée, false sinon
  1626. */
  1627. bool In_tab(const Entiers &tab, int val)
  1628. {
  1629. for (uint i=0; i < tab.size(); i++)
  1630. if(tab[i]==val)
  1631. return true;
  1632. return false;
  1633. }
  1634. bool In_tab_dichotomie(const Entiers &tab, int val)
  1635. {
  1636. if(dichotomie(tab,val)!=-1)
  1637. return true;
  1638. else
  1639. return false;
  1640. }
  1641. void Liste_Voisin(const Entiers &P,Entiers &tab,const UnorientedGraph &g)
  1642. {
  1643. tie(neighbourIt, neighbourEnd) = adjacent_vertices(P.at(P.size()-1), g);
  1644. for (; neighbourIt != neighbourEnd; ++neighbourIt)
  1645. {
  1646. if((In_tab(tab,*neighbourIt) == false ) && (In_tab(P,*neighbourIt) == false ))
  1647. tab.push_back(*neighbourIt);
  1648. }
  1649. }
  1650. int Cout_coupe(Entiers P,int val, UnorientedGraph &g)
  1651. {
  1652. int cpt=0;
  1653. P.push_back(val);
  1654. for(uint i=0;i<P.size();i++){
  1655. tie(neighbourIt, neighbourEnd) = adjacent_vertices(P[i], g);
  1656. for (; neighbourIt != neighbourEnd; ++neighbourIt){
  1657. if(In_tab(P,*neighbourIt)!=1){
  1658. cpt++;
  1659. }
  1660. }
  1661. }
  1662. return cpt;
  1663. }
  1664. double Cut_one_cluster(const Entiers &cluster, UnorientedGraph &g, std::string name)
  1665. {
  1666. if(name=="norm"){
  1667. edge_t e1;
  1668. bool found;
  1669. double cpt=0.;
  1670. for(uint i=0;i<cluster.size();i++){
  1671. tie(neighbourIt, neighbourEnd) = adjacent_vertices(cluster.at(i), g);
  1672. for (; neighbourIt != neighbourEnd; ++neighbourIt){
  1673. tie(e1,found)=edge(vertex(cluster[i],g),vertex(*neighbourIt,g),g);
  1674. if(In_tab(cluster,*neighbourIt)!=1){
  1675. cpt+=g[e1]._weight;
  1676. }
  1677. }
  1678. }
  1679. double deg = Cluster_Degree(g,cluster);
  1680. return cpt/deg;
  1681. }
  1682. else if(name == "cut"){
  1683. edge_t e1;
  1684. bool found;
  1685. double cpt=0.;
  1686. for(uint i=0;i<cluster.size();i++){
  1687. tie(neighbourIt, neighbourEnd) = adjacent_vertices(cluster.at(i), g);
  1688. for (; neighbourIt != neighbourEnd; ++neighbourIt){
  1689. tie(e1,found)=edge(vertex(cluster.at(i),g),vertex(*neighbourIt,g),g);
  1690. if(In_tab(cluster,*neighbourIt)!=1){
  1691. cpt+=g[e1]._weight;
  1692. }
  1693. }
  1694. }
  1695. return cpt/2.;
  1696. }
  1697. else if(name == "ratio"){
  1698. edge_t e1;
  1699. bool found;
  1700. double cpt=0.;
  1701. for(uint i=0;i<cluster.size();i++){
  1702. tie(neighbourIt, neighbourEnd) = adjacent_vertices(cluster.at(i), g);
  1703. for (; neighbourIt != neighbourEnd; ++neighbourIt){
  1704. tie(e1,found)=edge(vertex(cluster.at(i),g),vertex(*neighbourIt,g),g);
  1705. if(In_tab(cluster,*neighbourIt)!=1){
  1706. cpt+=g[e1]._weight;
  1707. }
  1708. }
  1709. }
  1710. double vol = Cluster_Weight(g,cluster);
  1711. return (cpt/2.)/vol;
  1712. }
  1713. /*Vérification de la formule : doute sur le /2.*/
  1714. }
  1715. double Cut_cluster(const EntiersEntiers &tab_cluster,UnorientedGraph &g,std::string name)
  1716. {
  1717. double cpt=0.;
  1718. for(uint i=0;i<tab_cluster.size();i++){
  1719. cpt+=Cut_one_cluster(*tab_cluster[i],g,name);
  1720. }
  1721. return cpt;
  1722. }
  1723. double Cout_coupe_pond(Entiers P, int val, UnorientedGraph &g)
  1724. {
  1725. edge_t e1;
  1726. bool found;
  1727. double cpt=0;
  1728. P.push_back(val);
  1729. for(uint i=0;i<P.size();i++){
  1730. tie(neighbourIt, neighbourEnd) = adjacent_vertices(P[i], g);
  1731. for (; neighbourIt != neighbourEnd; ++neighbourIt){
  1732. tie(e1,found)=edge(vertex(P[i],g),vertex(*neighbourIt,g),g);
  1733. if(In_tab(P,*neighbourIt)!=1){
  1734. cpt+=g[e1]._weight;
  1735. }
  1736. }
  1737. }
  1738. return cpt;
  1739. }
  1740. int In_community_dichotomie(const EntiersEntiers &part, int val)
  1741. {
  1742. for (uint i = 0; i < part.size() ; i++) {
  1743. if (In_tab_dichotomie(*part[i], val)) {
  1744. return i;
  1745. }
  1746. }
  1747. return -1;
  1748. }
  1749. double Degree(UnorientedGraph& g, int node)
  1750. {
  1751. edge_t e1;
  1752. bool found;
  1753. double val = 0.;
  1754. tie(neighbourIt, neighbourEnd) = adjacent_vertices(node, g);
  1755. for (; neighbourIt != neighbourEnd; ++neighbourIt) {
  1756. tie(e1, found) = edge(vertex(node, g), vertex(*neighbourIt, g), g);
  1757. val += g[e1]._weight;
  1758. }
  1759. return val;
  1760. }
  1761. double Cluster_Degree(UnorientedGraph &g , const Entiers &cluster)
  1762. {
  1763. double val = 0.;
  1764. for(uint i = 0; i < cluster.size(); i++){
  1765. val += Degree(g, cluster.at(i));
  1766. }
  1767. return val;
  1768. }
  1769. double Cluster_Weight(UnorientedGraph &g , const Entiers &cluster)
  1770. {
  1771. double val = 0.;
  1772. for(uint i = 0; i < cluster.size(); i++){
  1773. val += g[cluster.at(i)]._weight;;
  1774. }
  1775. return val;
  1776. }
  1777. void List_edge_partie(Entiers *Partie, OrientedGraph *go, Edges &edge_partie,
  1778. OutputEdges &outputedgespartie){
  1779. edge_to e1;
  1780. //bool found;
  1781. for(uint i = 0; i < Partie->size(); i++) {
  1782. tie(neighbourIto, neighbourEndo) = adjacent_vertices(Partie->at(i),
  1783. *go);
  1784. for (; neighbourIto != neighbourEndo; ++neighbourIto) {
  1785. if(In_tab_dichotomie(*Partie,*neighbourIto)) {
  1786. Edge new_edge;
  1787. new_edge.first = Partie->at(i);
  1788. new_edge.second = *neighbourIto;
  1789. edge_partie.push_back(new_edge);
  1790. } else {
  1791. Edge new_edge;
  1792. new_edge.first = Partie->at(i);
  1793. new_edge.second = *neighbourIto;
  1794. outputedgespartie.push_back(new_edge);
  1795. }
  1796. }
  1797. }
  1798. }
  1799. void Global_Neigh_community(UnorientedGraph *g,
  1800. const EntiersEntiers &Partition,
  1801. Entiers *community, int vertex, int comm_in)
  1802. {
  1803. int comm;
  1804. tie(neighbourIt, neighbourEnd) = adjacent_vertices(vertex, *g);
  1805. for (; neighbourIt != neighbourEnd; ++neighbourIt){
  1806. comm = In_community_dichotomie(Partition, *neighbourIt);
  1807. if (In_tab(*community,comm) != 1 and comm != comm_in)
  1808. community->push_back(comm);
  1809. }
  1810. }
  1811. OrientedGraphs Graph_Partition(const EntiersEntiers& Partition,
  1812. OrientedGraph *go,
  1813. UnorientedGraph *g,
  1814. OutputEdgeList &outputedgelist,
  1815. InputEdgeList &inputedgelist,
  1816. Connections &connections)
  1817. {
  1818. OrientedGraphs graph_partie;
  1819. EntiersEntiers neigh_community;
  1820. for (uint i = 0; i < Partition.size();i++){
  1821. Edges edge_partie;
  1822. List_edge_partie(Partition.at(i),go,edge_partie,outputedgelist.at(i));
  1823. OrientedGraph graph;
  1824. std::vector<vertex_to> tab_vertex_to;
  1825. Entiers *community = new Entiers();
  1826. for (uint j = 0; j < Partition.at(i)->size(); j++) {
  1827. Global_Neigh_community(g, Partition, community,
  1828. Partition.at(i)->at(j),i);
  1829. vertex_to v = add_vertex(graph);
  1830. tab_vertex_to.push_back(v);
  1831. graph[v] = VertexProperties((*go)[Partition.at(i)->at(j)]._index,
  1832. (*go)[Partition.at(i)->at(j)]._weight,
  1833. (*go)[Partition.at(i)->at(j)]._type);
  1834. }
  1835. neigh_community.push_back(community);
  1836. for(uint k = 0; k < edge_partie.size(); k++) {
  1837. add_edge(tab_vertex_to.at(recherche_val(*Partition.at(i),
  1838. edge_partie.at(k).first)),
  1839. tab_vertex_to.at(recherche_val(*Partition.at(i),
  1840. edge_partie.at(k).second)),
  1841. graph);
  1842. }
  1843. graph_partie.push_back(graph);
  1844. }
  1845. for (uint i = 0; i < neigh_community.size(); i++) {
  1846. InputEdges inputedges;
  1847. for (uint j = 0; j < neigh_community.at(i)->size(); j++) {
  1848. for (uint k = 0;
  1849. k < outputedgelist.at(neigh_community.at(i)->at(j)).size();
  1850. k++) {
  1851. if (In_tab_dichotomie(
  1852. *Partition.at(i),
  1853. outputedgelist.at(
  1854. neigh_community.at(i)->at(j)).at(k).second))
  1855. inputedges.push_back(
  1856. outputedgelist.at(
  1857. neigh_community.at(i)->at(j)).at(k));
  1858. }
  1859. }
  1860. inputedgelist.push_back(inputedges);
  1861. }
  1862. for (uint i = 0; i < outputedgelist.size(); i++){
  1863. Connection connec;
  1864. for(uint j = 0; j < outputedgelist.at(i).size(); j++){
  1865. Port port1;
  1866. port1.first = i + 1;
  1867. port1.second = outputedgelist.at(i).at(j).first;
  1868. Port port2;
  1869. port2.first = In_community_dichotomie(
  1870. Partition,outputedgelist.at(i).at(j).second) + 1;
  1871. port2.second = outputedgelist.at(i).at(j).second;
  1872. connec.first = port1;
  1873. connec.second = port2;
  1874. connections.push_back(connec);
  1875. }
  1876. }
  1877. for (EntiersEntiers::iterator it = neigh_community.begin();
  1878. it != neigh_community.end(); it++) {
  1879. delete *it;
  1880. *it = NULL;
  1881. }
  1882. return graph_partie;
  1883. }
  1884. double Best_Cut_cluster(EntiersEntiers &tab_cluster,Entiers *cluster1, Entiers *cluster2, int index_cluster1, UnorientedGraph &g,std::string name)
  1885. {
  1886. tab_cluster.push_back(cluster2);
  1887. double cpt=0.;
  1888. for(int i=0;i<tab_cluster.size();i++){
  1889. if(i!=index_cluster1){
  1890. cpt+=Cut_one_cluster(*tab_cluster[i],g,name);
  1891. }
  1892. }
  1893. cpt+=Cut_one_cluster(*cluster1,g,name);
  1894. tab_cluster.pop_back();
  1895. return cpt;
  1896. }
  1897. double In_modularity(UnorientedGraph *g , const Entiers &cluster){
  1898. //property_map<UnorientedGraph,edge_weight_t>::type poids_arc=get(edge_weight_t(),g);
  1899. edge_t e1;
  1900. bool found;
  1901. int val=0;
  1902. for(uint i=0;i<cluster.size();i++){
  1903. tie(neighbourIt, neighbourEnd) = adjacent_vertices(cluster.at(i),*g);
  1904. for (; neighbourIt != neighbourEnd; ++neighbourIt){
  1905. tie(e1,found)=edge(vertex(cluster[i],*g),vertex(*neighbourIt,*g),*g);
  1906. if(In_tab(cluster,*neighbourIt)==1)
  1907. val+=(*g)[e1]._weight;
  1908. //val+=get(poids_arc,e1);
  1909. }
  1910. }
  1911. return val/2.;
  1912. }
  1913. /**
  1914. *
  1915. * @param g
  1916. * @param cluster
  1917. * @return
  1918. */
  1919. /**
  1920. *
  1921. * @param g
  1922. * @param part
  1923. * @return
  1924. */
  1925. double Modularity(UnorientedGraph *g,const EntiersEntiers &part){
  1926. double q = 0.;
  1927. int tmp=num_edges(*g);
  1928. for(uint i=0;i<part.size();i++){
  1929. q+=In_modularity(g,*part.at(i))/tmp-(Cluster_Degree(*g,*part.at(i))/(2*tmp))*(Cluster_Degree(*g,*part.at(i))/(2*tmp));
  1930. }
  1931. return q;
  1932. }
  1933. /**
  1934. *
  1935. * @param part
  1936. * @param val
  1937. * @return
  1938. */
  1939. /**
  1940. * Fonction de calcul du gain de modularité de déplacement d'un sommet d'une communoté à une autre !!!!!
  1941. * ajoute le sommet à part[val] et on calcul la nouvelle modularité
  1942. * on prend la différence entre la modularité et la nouvouvelle !
  1943. * @param cur_mod
  1944. * @param val
  1945. * @param neight
  1946. * @param node_comm
  1947. * @param part
  1948. * @param g
  1949. */
  1950. /*double Modularity_gain(double cur_mod , int val , int neight , int node_comm , EntiersEntiers part , UnorientedGraph &g) {
  1951. double q;
  1952. part[neight]->push_back(val);
  1953. std::sort(*part[neight]);
  1954. q=Modularity(g,part);
  1955. return q-cur_mod;
  1956. }*/
  1957. /**
  1958. * Fonction de calcul du gain de modularité de déplacement d'un sommet d'une communoté à une autre !!!!!
  1959. * ajoute le sommet à part[val] et on calcul la nouvelle modularité
  1960. * on prend la différence entre la modularité et la nouvouvelle !
  1961. * @param cur_mod
  1962. * @param tmp_community
  1963. * @param neight
  1964. * @param node_comm
  1965. * @param part
  1966. * @param g
  1967. */
  1968. /*double Modularity_gain_phase_2(double cur_mod, Entiers tmp_community, int neight, int node_comm, EntiersEntiers part, UnorientedGraph &g) {
  1969. double q;
  1970. for (uint i=0;i<tmp_community.size();i++)
  1971. part[neight]->push_back(tmp_community[i]);
  1972. std::sort(*part[neight]);
  1973. q = Modularity(g,part);
  1974. return q - cur_mod;
  1975. }*/
  1976. /**
  1977. * Donne la liste des communautés voisines à celle contenant le sommet val.
  1978. * @param part
  1979. * @param val
  1980. * @param g
  1981. * @return
  1982. */
  1983. /*Entiers Neight_community(const EntiersEntiers &part, int val , UnorientedGraph &g){
  1984. Entiers Neight;
  1985. tie(neighbourIt, neighbourEnd) = adjacent_vertices(val, g);
  1986. for (; neighbourIt != neighbourEnd; ++neighbourIt){
  1987. int tmp=In_community(part,*neighbourIt);
  1988. if(In_tab(Neight,tmp)!=1 && In_tab(*part[In_community(part,val)],*neighbourIt)!=1)
  1989. Neight.push_back(tmp);
  1990. }
  1991. std::sort(Neight);
  1992. return Neight;
  1993. }*/
  1994. /**
  1995. *
  1996. * @param part
  1997. * @param community
  1998. * @param g
  1999. * @return
  2000. */
  2001. /*Entiers Part_Neight_community(const EntiersEntiers &part,int community, UnorientedGraph &g){
  2002. Entiers Neight;
  2003. for(uint i =0;i<part[community]->size();i++){
  2004. tie(neighbourIt, neighbourEnd) = adjacent_vertices(part[community]->at(i), g);
  2005. for (; neighbourIt != neighbourEnd; ++neighbourIt){
  2006. int tmp=In_community(part,*neighbourIt);
  2007. if(In_tab(Neight,tmp)!=1 && tmp!=community)
  2008. Neight.push_back(tmp);
  2009. }
  2010. }
  2011. std::sort(Neight);
  2012. return Neight;
  2013. }*/
  2014. void make_unoriented_graph(const OrientedGraph& og, UnorientedGraph& ug)
  2015. {
  2016. std::vector < vertex_t > ug_vertex_list;
  2017. std::vector < vertex_t > og_vertex_list;
  2018. for (uint i = 0; i < num_vertices(og); ++i) {
  2019. ug_vertex_list.push_back(add_vertex(ug));
  2020. }
  2021. OrientedGraph::vertex_iterator it_og, end_og;
  2022. UnorientedGraph::vertex_iterator it_ug, end_ug;
  2023. tie(it_og, end_og) = vertices(og);
  2024. tie(it_ug, end_ug) = vertices(ug);
  2025. for (; it_og != end_og; ++it_og, ++it_ug) {
  2026. ug[*it_ug] = og[*it_og];
  2027. og_vertex_list.push_back(*it_og);
  2028. }
  2029. OrientedGraph::edge_iterator ite_og, ende_og;
  2030. tie(ite_og, ende_og) = edges(og);
  2031. for (; ite_og != ende_og; ++ite_og) {
  2032. boost::add_edge(source(*ite_og, og), target(*ite_og, og),
  2033. og[*ite_og], ug);
  2034. }
  2035. // std::cout << "Oriented graph: " << std::endl;
  2036. // tie(it_og, end_og) = vertices(og);
  2037. // for (; it_og != end_og; ++it_og) {
  2038. // OrientedGraph::adjacency_iterator neighbour_it, neighbour_end;
  2039. // std::cout << og[*it_og]._index << " is connected with ";
  2040. // tie(neighbour_it, neighbour_end) = adjacent_vertices(*it_og, og);
  2041. // for (; neighbour_it != neighbour_end; ++neighbour_it)
  2042. // std::cout << og[*neighbour_it]._index << " ";
  2043. // std::cout << " and weight = " << og[*it_og]._weight << std::endl;
  2044. // }
  2045. // std::cout << std::endl;
  2046. // std::cout << "Unoriented graph: " << std::endl;
  2047. // tie(it_ug, end_ug) = vertices(ug);
  2048. // for (; it_ug != end_ug; ++it_ug) {
  2049. // UnorientedGraph::adjacency_iterator neighbour_it, neighbour_end;
  2050. // std::cout << ug[*it_ug]._index << " is connected with ";
  2051. // tie(neighbour_it, neighbour_end) = adjacent_vertices(*it_ug, ug);
  2052. // for (; neighbour_it != neighbour_end; ++neighbour_it)
  2053. // std::cout << ug[*neighbour_it]._index << " ";
  2054. // std::cout << " and weight = " << ug[*it_ug]._weight << std::endl;
  2055. // }
  2056. // std::cout << std::endl;
  2057. }
  2058. void adjacence_ggp(int vertex, Entiers &sommets_adj, UnorientedGraph *g)
  2059. {
  2060. tie(neighbourIt, neighbourEnd) = adjacent_vertices(vertex, *g);
  2061. for (; neighbourIt != neighbourEnd; ++neighbourIt)
  2062. {
  2063. sommets_adj.push_back(*neighbourIt);
  2064. }
  2065. }
  2066. double modif_Cout_coupe(const Entiers &P, int val, double cut, UnorientedGraph *g)
  2067. {
  2068. //std::cout<<"Cout de coupe initiale : "<<cut<<std::endl;
  2069. //std::cout<<"degré du sommet tiré : "<<Degree(*g,val)<<std::endl;
  2070. double cpt = 0.;
  2071. double new_cut;
  2072. bool found;
  2073. edge_t e1;
  2074. tie(neighbourIt, neighbourEnd) = adjacent_vertices(val, *g);
  2075. for (; neighbourIt != neighbourEnd; neighbourIt++){
  2076. if(In_tab(P,*neighbourIt)==1){
  2077. tie(e1,found)=edge(vertex(val,*g),vertex(*neighbourIt,*g),*g);
  2078. cpt += (*g)[e1]._weight;
  2079. }
  2080. }
  2081. new_cut = cut + (Degree(*g,val) - 2*cpt);
  2082. return new_cut;
  2083. }
  2084. int decimal(int valeur){
  2085. int res;
  2086. switch(valeur){
  2087. case 0 ... 9 : res = 0;
  2088. break;
  2089. case 10 ... 99 : res = 1;
  2090. break;
  2091. case 100 ... 999 : res = 2;
  2092. break;
  2093. case 1000 ... 9999 : res = 3;
  2094. break;
  2095. case 10000 ... 99999 : res = 4;
  2096. break;
  2097. case 100000 ... 999999 : res = 5;
  2098. break;
  2099. case 1000000 ... 9999999 : res = 6;
  2100. break;
  2101. case 10000000 ... 99999999 : res = 7;
  2102. break;
  2103. case 100000000 ... 999999999 : res = 8;
  2104. break;
  2105. default :
  2106. std::cout<<"L'interval n'est pas de taille suffisante"<<std::endl;
  2107. break;
  2108. }
  2109. return res;
  2110. }
  2111. void Graph_constructor_txt(const char* text, OrientedGraph * Og){
  2112. //Traitement initial
  2113. std::ifstream fichier (text, std::ios::in);
  2114. int lines = std::count(std::istreambuf_iterator<char>( fichier ),
  2115. std::istreambuf_iterator<char>(),'\n' );
  2116. //std::cout<<"Nombre de ligne : "<<lines<<std::endl;
  2117. fichier.seekg(0, std::ios::beg);
  2118. std::string caractere;
  2119. getline(fichier, caractere);
  2120. int caractere_size = caractere.size()+1;
  2121. fichier.seekg(0, std::ios::beg);
  2122. int nbr_vertices;
  2123. fichier >> nbr_vertices;
  2124. //std::cout << "Nombre de sommets : "<< nbr_vertices<< std::endl;
  2125. //Création des sommets
  2126. std::vector<vertex_to> vect_vertex;
  2127. for(int i =0; i<nbr_vertices; i++){
  2128. vertex_to v0 = boost::add_vertex(*Og);
  2129. vect_vertex.push_back(v0);
  2130. }
  2131. //Création des arcs
  2132. int deplacement_sup = 0;
  2133. for(int i = 0; i <(lines-nbr_vertices-1); i++){
  2134. fichier.seekg((8)*i+caractere_size+deplacement_sup, std::ios::beg);
  2135. int vertex_in, vertex_out;
  2136. double weight;
  2137. fichier >> vertex_in >> vertex_out >> weight ;
  2138. add_edge(vect_vertex.at(vertex_in), vect_vertex.at(vertex_out), EdgeProperties(weight), *Og);
  2139. //std::cout << vertex_in << " " << vertex_out << " " << weight << std::endl;
  2140. int tmp = decimal(vertex_in) + decimal(vertex_out) + decimal(floor(weight));
  2141. deplacement_sup += tmp;
  2142. }
  2143. //Pondération des sommets
  2144. int cpt =0;
  2145. for(int i = lines-nbr_vertices-1; i <lines-1; i++){
  2146. fichier.seekg((8)*(lines-nbr_vertices-1)+caractere_size+deplacement_sup, std::ios::beg);
  2147. double poids;
  2148. std::string txt;
  2149. fichier >> poids >> txt ;
  2150. int type;
  2151. if(txt == "NORMAL_PIXEL"){
  2152. type = 1;
  2153. // type = NORMAL_PIXEL;
  2154. }else{
  2155. type = 0;
  2156. // type = TOP_PIXEL;
  2157. }
  2158. (*Og)[vect_vertex.at(cpt)] = VertexProperties(cpt, poids, type);
  2159. //std::cout << poids << std::endl;
  2160. int tmp = decimal(floor(poids)) + 17;
  2161. deplacement_sup += tmp;
  2162. cpt++;
  2163. }
  2164. fichier.close();
  2165. }
  2166. void Text_generator_graph(const char *texte, OrientedGraph *go){
  2167. bool found;
  2168. edge_to e1;
  2169. std::ofstream fichier (texte, std::ios::out);
  2170. fichier<<num_vertices(*go)<<std::endl;
  2171. tie(vertexIto, vertexEndo) = vertices(*go);
  2172. for (; vertexIto != vertexEndo; ++vertexIto) {
  2173. tie(neighbourIto, neighbourEndo) = adjacent_vertices(*vertexIto,
  2174. *go);
  2175. for (; neighbourIto != neighbourEndo; ++neighbourIto){
  2176. tie(e1,found)=edge(vertex(*vertexIto,*go),vertex(*neighbourIto,*go),*go);
  2177. if(((*go)[e1]._weight - floor((*go)[e1]._weight)) == 0 ){
  2178. fichier<<(*go)[*vertexIto]._index<<" "<<(*go)[*neighbourIto]._index<<" "<<(*go)[e1]._weight<<".0"<<std::endl;
  2179. }else{
  2180. fichier<<(*go)[*vertexIto]._index<<" "<<(*go)[*neighbourIto]._index<<" "<<(*go)[e1]._weight<<std::endl;
  2181. }
  2182. }
  2183. }
  2184. tie(vertexIto, vertexEndo) = vertices(*go);
  2185. for (; vertexIto != vertexEndo; ++vertexIto) {
  2186. if(((*go)[*vertexIto]._weight - floor((*go)[*vertexIto]._weight)) == 0 && (*go)[*vertexIto]._type == 0 /*TOP_PIXEL*/){
  2187. fichier<<(*go)[*vertexIto]._weight<<".0"<<" "<<"TOP_PIXEL"<<" "<<std::endl;
  2188. }else if(((*go)[*vertexIto]._weight - floor((*go)[*vertexIto]._weight)) == 0 && (*go)[*vertexIto]._type == 1 /*NORMAL_PIXEL*/){
  2189. fichier<<(*go)[*vertexIto]._weight<<".0"<<" "<<"NORMAL_PIXEL"<<std::endl;
  2190. }else if(((*go)[*vertexIto]._weight - floor((*go)[*vertexIto]._weight)) != 0 && (*go)[*vertexIto]._type == 0 /*TOP_PIXEL*/){
  2191. fichier<<(*go)[*vertexIto]._weight<<" "<<"TOP_PIXEL"<<std::endl;
  2192. }else{
  2193. fichier<<(*go)[*vertexIto]._weight<<" "<<"NORMAL_PIXEL"<<std::endl;
  2194. }
  2195. }
  2196. fichier.close();
  2197. }
  2198. double Diff_cut_ratio(UnorientedGraph *g, const EntiersEntiers &Partition, int partie, int node, std::string name){
  2199. double Dif;
  2200. double Int = 0.;
  2201. double Ext = 0.;
  2202. edge_t e1;
  2203. bool found;
  2204. tie(neighbourIt, neighbourEnd) = adjacent_vertices(node, *g);
  2205. for (; neighbourIt != neighbourEnd; ++neighbourIt){
  2206. tie(e1, found) = edge(vertex(node, *g), vertex(*neighbourIt, *g), *g);
  2207. if(In_tab_dichotomie(*Partition.at(partie),*neighbourIt) == 1){
  2208. Int+= (*g)[e1]._weight;
  2209. }else{
  2210. Ext+= (*g)[e1]._weight;
  2211. }
  2212. }
  2213. if(name == "ratio"){
  2214. Int/=Cluster_Weight(*g,*Partition.at(partie));
  2215. Ext/=Cluster_Weight(*g,*Partition.at(partie));
  2216. }
  2217. Dif = Ext - Int;
  2218. return Dif;
  2219. }
  2220. double Diff_cut_ratio_bissection(UnorientedGraph *g, Entiers *part, int node, std::string name){
  2221. double Ext = 0.;
  2222. edge_t e1;
  2223. bool found;
  2224. tie(neighbourIt, neighbourEnd) = adjacent_vertices(node, *g);
  2225. for (; neighbourIt != neighbourEnd; ++neighbourIt){
  2226. tie(e1, found) = edge(vertex(node, *g), vertex(*neighbourIt, *g), *g);
  2227. if(In_tab_dichotomie(*part,*neighbourIt) != 1){
  2228. Ext+= (*g)[e1]._weight;
  2229. }
  2230. }
  2231. return Ext;
  2232. }
  2233. std::vector<std::vector<int>> Vector_diff_cut_ratio(UnorientedGraph *g, const EntiersEntiers &Partition, std::string name){
  2234. std::vector<std::vector<int>> Diff_vector;
  2235. for(uint i = 0; i < Partition.size(); i++){
  2236. std::vector<std::pair<double,int>> D_vector;
  2237. for(uint j = 0; j < Partition.at(i)->size(); j++){
  2238. double gain_d = Diff_cut_ratio(g, Partition, i, Partition.at(i)->at(j), name);
  2239. //std::cout<<gain_d<<std::endl;
  2240. if(gain_d > 0){
  2241. std::pair<double, int> D;
  2242. D.first = gain_d;
  2243. D.second = Partition.at(i)->at(j);
  2244. D_vector.push_back(D);
  2245. }
  2246. }
  2247. sort(D_vector.begin(),D_vector.end());
  2248. std::reverse(D_vector.begin(),D_vector.end());
  2249. std::vector<int> index_vector;
  2250. for(uint id = 0; id < D_vector.size(); id++){
  2251. index_vector.push_back(D_vector.at(id).second);
  2252. }
  2253. Diff_vector.push_back(index_vector);
  2254. }
  2255. /*std::cout<<"Tableau des différences "<<std::endl;
  2256. for(uint i = 0; i<Diff_vector.size(); i++){
  2257. std::cout<<"*"<<i<<"* ";
  2258. for(uint j = 0; j<Diff_vector.at(i).size(); j++){
  2259. std::cout<<Diff_vector.at(i).at(j)<<" ";
  2260. }
  2261. std::cout<<std::endl;
  2262. }*/
  2263. return Diff_vector;
  2264. }
  2265. std::vector<int> Vector_diff_cut_ratio_2(UnorientedGraph *g, const EntiersEntiers &Partition, std::string name){
  2266. std::vector<int> Diff_vector;
  2267. std::vector<std::pair<double,int>> D_vector;
  2268. for(uint i = 0; i < Partition.size(); i++){
  2269. for(uint j = 0; j < Partition.at(i)->size(); j++){
  2270. double gain_d = Diff_cut_ratio(g, Partition, i, Partition.at(i)->at(j), name);
  2271. //std::cout<<gain_d<<std::endl;
  2272. if(gain_d > 0){
  2273. std::pair<double, int> D;
  2274. D.first = gain_d;
  2275. D.second = Partition.at(i)->at(j);
  2276. D_vector.push_back(D);
  2277. }
  2278. }
  2279. }
  2280. sort(D_vector.begin(),D_vector.end());
  2281. for(uint id = 0; id < D_vector.size(); id++){
  2282. Diff_vector.push_back(D_vector.at(id).second);
  2283. }
  2284. /*std::cout<<"Tableau des différences "<<std::endl;
  2285. for(uint i = 0; i<Diff_vector.size(); i++){
  2286. std::cout<<"*"<<i<<"* ";
  2287. for(uint j = 0; j<Diff_vector.at(i).size(); j++){
  2288. std::cout<<Diff_vector.at(i).at(j)<<" ";
  2289. }
  2290. std::cout<<std::endl;
  2291. }*/
  2292. /*for(uint j = 0; j<Diff_vector.size(); j++){
  2293. std::cout<<Diff_vector.at(j)<<" ";
  2294. }
  2295. std::cout<<std::endl;*/
  2296. return Diff_vector;
  2297. }
  2298. void Modif_vector_diff_cut_ratio_2(UnorientedGraph *g, const EntiersEntiers &Partition, std::vector<int> &Diff_vector, int node, std::string name){
  2299. std::vector<std::pair<double,int>> D_vector;
  2300. tie(neighbourIt, neighbourEnd) = adjacent_vertices(node, *g);
  2301. for (; neighbourIt != neighbourEnd; ++neighbourIt){
  2302. //std::cout<<"node : "<<node<<std::endl;
  2303. //std::cout<<"voisin : "<<*neighbourIt<<std::endl;
  2304. int neigh_ind = In_community_dichotomie(Partition, *neighbourIt);
  2305. //std::cout<<"dans : "<<neigh_ind<<std::endl;
  2306. double gain_d = Diff_cut_ratio(g, Partition, neigh_ind, *neighbourIt, name);
  2307. //std::cout<<"gain_d : "<<gain_d<<std::endl;
  2308. if(gain_d > 0){
  2309. std::pair<double, int> D;
  2310. D.first = gain_d;
  2311. D.second = *neighbourIt;
  2312. D_vector.push_back(D);
  2313. }
  2314. //suprim_val(Diff_vector,*neighbourIt);
  2315. }
  2316. if(D_vector.size() == 0){
  2317. Diff_vector.erase(Diff_vector.begin());
  2318. return;
  2319. }
  2320. //std::cout<<"**"<<std::endl;
  2321. sort(D_vector.begin(),D_vector.end());
  2322. for(uint id = 0; id < D_vector.size(); id++){
  2323. if(In_tab(Diff_vector,D_vector.at(id).second) != 1)
  2324. Diff_vector.push_back(D_vector.at(id).second);
  2325. }
  2326. //std::cout<<"***"<<std::endl;
  2327. Diff_vector.erase(Diff_vector.begin());
  2328. //std::cout<<"**!**"<<std::endl;
  2329. sort(Diff_vector.begin(),Diff_vector.end());
  2330. for(uint j = 0; j<Diff_vector.size(); j++){
  2331. std::cout<<Diff_vector.at(j)<<" ";
  2332. }
  2333. //std::cout<<std::endl;
  2334. }
  2335. 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){
  2336. std::vector<std::pair<double,int>> D_vector;
  2337. for(uint j = 0; j < Partition.at(recalcul1)->size(); j++){
  2338. double gain_d = Diff_cut_ratio(g, Partition, recalcul1, Partition.at(recalcul1)->at(j), name);
  2339. //std::cout<<gain_d<<std::endl;
  2340. if(gain_d > 0){
  2341. std::pair<double, int> D;
  2342. D.first = gain_d;
  2343. D.second = Partition.at(recalcul1)->at(j);
  2344. D_vector.push_back(D);
  2345. }
  2346. }
  2347. sort(D_vector.begin(),D_vector.end());
  2348. std::reverse(D_vector.begin(),D_vector.end());
  2349. std::vector<int> index_vector;
  2350. for(uint id = 0; id < D_vector.size(); id++){
  2351. index_vector.push_back(D_vector.at(id).second);
  2352. }
  2353. Diff_vector.at(recalcul1) = index_vector;
  2354. std::vector<std::pair<double,int>> D_vector2;
  2355. for(uint j = 0; j < Partition.at(recalcul2)->size(); j++){
  2356. double gain_d = Diff_cut_ratio(g, Partition, recalcul2, Partition.at(recalcul2)->at(j), name);
  2357. //std::cout<<gain_d<<std::endl;
  2358. if(gain_d > 0){
  2359. std::pair<double, int> D;
  2360. D.first = gain_d;
  2361. D.second = Partition.at(recalcul2)->at(j);
  2362. D_vector2.push_back(D);
  2363. }
  2364. }
  2365. sort(D_vector2.begin(),D_vector2.end());
  2366. std::reverse(D_vector2.begin(),D_vector2.end());
  2367. std::vector<int> index_vector2;
  2368. for(uint id = 0; id < D_vector2.size(); id++){
  2369. index_vector2.push_back(D_vector2.at(id).second);
  2370. }
  2371. Diff_vector.at(recalcul2) = index_vector2;
  2372. /*std::cout<<"Tableau des différences modifié "<<std::endl;
  2373. for(uint i = 0; i<Diff_vector.size(); i++){
  2374. std::cout<<"*"<<i<<"* ";
  2375. for(uint j = 0; j<Diff_vector.at(i).size(); j++){
  2376. std::cout<<Diff_vector.at(i).at(j)<<" ";
  2377. }
  2378. std::cout<<std::endl;
  2379. }*/
  2380. }
  2381. void Affinache_gain_diff(UnorientedGraph *g, EntiersEntiers &Partition, double &cut, std::string name, double poids_moy){
  2382. double old_cut = -1.;
  2383. while(old_cut != cut){
  2384. //std::cout<<"Boucle d'ammélioration "<<std::endl;
  2385. old_cut = cut;
  2386. sort(Partition.begin(), Partition.end(), myobject_taille);
  2387. /*for(uint i=0;i<Partition.size();i++){
  2388. std::cout<<Partition.at(i)->size()<<std::endl;
  2389. }*/
  2390. std::vector<std::vector<int>> diff_vector;
  2391. diff_vector = Vector_diff_cut_ratio(g, Partition, name);
  2392. /*for(uint i = 0; i<diff_vector.size(); i++){
  2393. std::cout<<diff_vector.at(i)<<std::endl;
  2394. }*/
  2395. for(uint indice = 0; indice < diff_vector.size(); indice ++){
  2396. if(diff_vector.at(indice).size() != 0 && Partition.at(indice)->size() >1){
  2397. //for(uint i = 0; i < diff_vector.at(indice).size(); i++){
  2398. int i =0;
  2399. while(diff_vector.at(indice).size() != 0 && Partition.at(indice)->size() >1 && i < diff_vector.at(indice).size() &&
  2400. Cluster_Weight(*g,*Partition.at(indice)) > (poids_moy-poids_moy/Partition.size())){
  2401. //std::cout<<"Sommet de départ : "<< (*g)[diff_vector.at(indice).at(i)]._index <<" dans "<<indice<<std::endl;
  2402. Entiers neigh_part;
  2403. neigh_part = Neigh_community(g, Partition, diff_vector.at(indice).at(i), indice);
  2404. int best_neigh_part = neigh_part.at(0);
  2405. double gain = -10000000.;
  2406. for(uint ind_neigh = 0; ind_neigh < neigh_part.size(); ind_neigh++){
  2407. double tmp_gain;
  2408. if(name == "ratio"){
  2409. tmp_gain = Gain_ratio(g,Partition,indice,neigh_part.at(ind_neigh),diff_vector.at(indice).at(i),cut);
  2410. }else{
  2411. double Int = 0.;
  2412. double Ext = 0.;
  2413. edge_t e1;
  2414. bool found;
  2415. tie(neighbourIt, neighbourEnd) = adjacent_vertices(diff_vector.at(indice).at(i), *g);
  2416. for (; neighbourIt != neighbourEnd; ++neighbourIt){
  2417. tie(e1, found) = edge(vertex(diff_vector.at(indice).at(i), *g), vertex(*neighbourIt, *g), *g);
  2418. if(In_tab_dichotomie(*Partition.at(neigh_part.at(ind_neigh)),*neighbourIt) == 1){
  2419. Ext+= (*g)[e1]._weight;
  2420. }else if(In_tab_dichotomie(*Partition.at(indice),*neighbourIt) == 1){
  2421. Int+= (*g)[e1]._weight;
  2422. }
  2423. }
  2424. tmp_gain = Ext - Int;
  2425. }
  2426. if(tmp_gain > gain & tmp_gain > 0){
  2427. gain = tmp_gain;
  2428. best_neigh_part = neigh_part.at(ind_neigh);
  2429. }
  2430. }
  2431. //std::cout<<" Ensemble de déstination "<<best_neigh_part<<" gain de : "<<gain<<std::endl;
  2432. if(gain > 0){
  2433. //std::cout<<"Modification"<<std::endl;
  2434. cut -= gain; /*Grosse modification a apporté de ce coté la*/
  2435. //std::cout<<"Ratio de coupe : "<<cut<<std::endl;
  2436. suprim_val(*Partition.at(indice),diff_vector.at(indice).at(i));
  2437. Partition.at(best_neigh_part)->push_back(diff_vector.at(indice).at(i));
  2438. sort(Partition.at(best_neigh_part)->begin(),Partition.at(best_neigh_part)->end());
  2439. //double cut2 = Cut_cluster(Partition,*g,"ratio");
  2440. //std::cout<<"Vrai ratio de coupe : "<<cut2<<std::endl;
  2441. Modif_vector_diff_cut_ratio(g,Partition,diff_vector,best_neigh_part,indice,name);
  2442. i = 0;
  2443. }else{
  2444. i++;
  2445. }
  2446. }
  2447. }
  2448. }
  2449. //std::cout<<cut<<std::endl;
  2450. }
  2451. }
  2452. void Affinache_gain_diff_2(UnorientedGraph *g, EntiersEntiers &Partition, double &cut, std::string name, double poids_moy){
  2453. double old_cut = -1.;
  2454. //while(old_cut != cut){
  2455. //std::cout<<"Boucle d'ammélioration "<<std::endl;
  2456. //old_cut = cut;
  2457. sort(Partition.begin(), Partition.end(), myobject_taille);
  2458. std::vector<int> diff_vector;
  2459. diff_vector = Vector_diff_cut_ratio_2(g, Partition, name);
  2460. //for(uint indice = 0; indice < diff_vector.size(); indice ++){
  2461. int indice = 0;
  2462. while(/*indice < diff_vector.size() &&*/ diff_vector.size() != 0){
  2463. int com = In_community_dichotomie(Partition,diff_vector.at(indice));
  2464. std::cout<<" Ensemble de départ "<<com<<" sommet : "<<diff_vector.at(indice)<<std::endl;
  2465. if(Partition.at(com)->size() >1 && Cluster_Weight(*g,*Partition.at(com)) > (poids_moy-poids_moy/Partition.size())){
  2466. Entiers neigh_part;
  2467. neigh_part = Neigh_community(g, Partition, diff_vector.at(indice), com);
  2468. int best_neigh_part = neigh_part.at(0);
  2469. double gain = -10000000.;
  2470. for(uint ind_neigh = 0; ind_neigh < neigh_part.size(); ind_neigh++){
  2471. double tmp_gain;
  2472. if(name == "ratio"){
  2473. tmp_gain = Gain_ratio(g,Partition,com,neigh_part.at(ind_neigh),diff_vector.at(indice),cut);
  2474. }else{
  2475. double Int = 0.;
  2476. double Ext = 0.;
  2477. edge_t e1;
  2478. bool found;
  2479. tie(neighbourIt, neighbourEnd) = adjacent_vertices(diff_vector.at(indice), *g);
  2480. for (; neighbourIt != neighbourEnd; ++neighbourIt){
  2481. tie(e1, found) = edge(vertex(diff_vector.at(indice), *g), vertex(*neighbourIt, *g), *g);
  2482. if(In_tab_dichotomie(*Partition.at(neigh_part.at(ind_neigh)),*neighbourIt) == 1){
  2483. Ext+= (*g)[e1]._weight;
  2484. }else if(In_tab_dichotomie(*Partition.at(com),*neighbourIt) == 1){
  2485. Int+= (*g)[e1]._weight;
  2486. }
  2487. }
  2488. tmp_gain = Ext - Int;
  2489. }
  2490. if(tmp_gain > gain & tmp_gain > 0){
  2491. gain = tmp_gain;
  2492. best_neigh_part = neigh_part.at(ind_neigh);
  2493. }
  2494. }
  2495. std::cout<<" Ensemble de déstination "<<best_neigh_part<<" gain de : "<<gain<<std::endl;
  2496. if(gain > 0){
  2497. std::cout<<"Modification"<<std::endl;
  2498. cut -= gain; /*Grosse modification a apporté de ce coté la*/
  2499. std::cout<<"Ratio de coupe : "<<cut<<std::endl;
  2500. suprim_val(*Partition.at(com),diff_vector.at(indice));
  2501. Partition.at(best_neigh_part)->push_back(diff_vector.at(indice));
  2502. sort(Partition.at(best_neigh_part)->begin(),Partition.at(best_neigh_part)->end());
  2503. double cut2 = Cut_cluster(Partition,*g,"ratio");
  2504. std::cout<<"Vrai ratio de coupe : "<<cut2<<std::endl;
  2505. //Modif_vector_diff_cut_ratio_2(g,Partition,diff_vector,diff_vector.at(indice),name);
  2506. //indice = 0;
  2507. diff_vector.erase(diff_vector.begin());
  2508. }else{
  2509. diff_vector.erase(diff_vector.begin());
  2510. }
  2511. }
  2512. }
  2513. //std::cout<<cut<<std::endl;
  2514. // }
  2515. }
  2516. double Gain_ratio(UnorientedGraph *g,const EntiersEntiers &Partition, int in, int out, int node, double ratio){
  2517. double new_ratio = ratio;
  2518. double poids_in = Cluster_Weight(*g,*Partition.at(in));
  2519. double poids_out = Cluster_Weight(*g,*Partition.at(out));
  2520. double tmp_poids_in = poids_in - (*g)[node]._weight;
  2521. double tmp_poids_out = poids_out + (*g)[node]._weight;
  2522. //std::cout<<"tmp_poids_in "<< tmp_poids_in <<std::endl;
  2523. //std::cout<<"tmp_poids_out "<< tmp_poids_out <<std::endl;
  2524. double cut_in = 0.;
  2525. double cut_out = 0.;
  2526. double tmp_cut_in = 0.;
  2527. double tmp_cut_out = 0.;
  2528. edge_t e1;
  2529. bool found;
  2530. for(uint i = 0; i < Partition.at(in)->size(); i++){
  2531. tie(neighbourIt, neighbourEnd) = adjacent_vertices(Partition.at(in)->at(i), *g);
  2532. for (; neighbourIt != neighbourEnd; ++neighbourIt){
  2533. tie(e1,found)=edge(vertex(Partition.at(in)->at(i),*g),vertex(*neighbourIt,*g),*g);
  2534. if(In_tab_dichotomie(*Partition.at(in),*neighbourIt) != 1){
  2535. if(Partition.at(in)->at(i) != node){
  2536. tmp_cut_in += (*g)[e1]._weight;
  2537. }
  2538. cut_in += (*g)[e1]._weight;
  2539. }else if(*neighbourIt == node){
  2540. tmp_cut_in += (*g)[e1]._weight;
  2541. }
  2542. }
  2543. }
  2544. for(uint i = 0; i < Partition.at(out)->size(); i++){
  2545. tie(neighbourIt, neighbourEnd) = adjacent_vertices(Partition.at(out)->at(i), *g);
  2546. for (; neighbourIt != neighbourEnd; ++neighbourIt){
  2547. tie(e1,found)=edge(vertex(Partition.at(out)->at(i),*g),vertex(*neighbourIt,*g),*g);
  2548. if(In_tab_dichotomie(*Partition.at(out),*neighbourIt) != 1){
  2549. if(*neighbourIt != node){
  2550. tmp_cut_out += (*g)[e1]._weight;
  2551. }
  2552. cut_out += (*g)[e1]._weight;
  2553. }
  2554. }
  2555. }
  2556. tie(neighbourIt, neighbourEnd) = adjacent_vertices(node, *g);
  2557. for (; neighbourIt != neighbourEnd; ++neighbourIt){
  2558. tie(e1,found)=edge(vertex(node,*g),vertex(*neighbourIt,*g),*g);
  2559. if(In_tab_dichotomie(*Partition.at(out),*neighbourIt) != 1){
  2560. tmp_cut_out += (*g)[e1]._weight;
  2561. }
  2562. }
  2563. //std::cout<<"tmp_cut_in "<< tmp_cut_in/2. <<std::endl;
  2564. //std::cout<<"tmp_cut_out "<< tmp_cut_out/2. <<std::endl;
  2565. new_ratio -= cut_in/2./poids_in;
  2566. new_ratio -= cut_out/2./poids_out;
  2567. new_ratio += tmp_cut_in/2./tmp_poids_in;
  2568. new_ratio += tmp_cut_out/2./tmp_poids_out;
  2569. //std::cout<<"Nouveau ratio : " <<new_ratio<<std::endl;
  2570. return ratio - new_ratio;
  2571. }
  2572. 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 !!!*/
  2573. double new_ratio;
  2574. double poids_in = Cluster_Weight(*g,*Ss);
  2575. double poids_out = Cluster_Weight(*g,*Sd);
  2576. double tmp_poids_in = poids_in - (*g)[node]._weight;
  2577. double tmp_poids_out = poids_out + (*g)[node]._weight;
  2578. //std::cout<<"tmp_poids_in "<< tmp_poids_in <<std::endl;
  2579. //std::cout<<"tmp_poids_out "<< tmp_poids_out <<std::endl;
  2580. double new_cut = 0.;
  2581. //double new_cut_out = 0.;
  2582. //double tmp_cut_in = 0.;
  2583. //double tmp_cut_out = 0.;
  2584. edge_t e1;
  2585. bool found;
  2586. for(uint i = 0; i < Ss->size(); i++){
  2587. if(Ss->at(i) != node){
  2588. tie(neighbourIt, neighbourEnd) = adjacent_vertices(Ss->at(i), *g);
  2589. for (; neighbourIt != neighbourEnd; ++neighbourIt){
  2590. tie(e1,found)=edge(vertex(Ss->at(i),*g),vertex(*neighbourIt,*g),*g);
  2591. if(In_tab_dichotomie(*Ss,*neighbourIt) != 1){
  2592. new_cut += (*g)[e1]._weight;
  2593. }else if(*neighbourIt == node){
  2594. new_cut += (*g)[e1]._weight;
  2595. }
  2596. }
  2597. }
  2598. }
  2599. /*for(uint i = 0; i < Sd->size(); i++){
  2600. tie(neighbourIt, neighbourEnd) = adjacent_vertices(Sd->at(i), *g);
  2601. for (; neighbourIt != neighbourEnd; ++neighbourIt){
  2602. tie(e1,found)=edge(vertex(Sd->at(i),*g),vertex(*neighbourIt,*g),*g);
  2603. if(In_tab(*Sd,*neighbourIt) != 1){
  2604. if(*neighbourIt != node){
  2605. tmp_cut_out += (*g)[e1]._weight;
  2606. }
  2607. cut_out += (*g)[e1]._weight;
  2608. }
  2609. }
  2610. }
  2611. tie(neighbourIt, neighbourEnd) = adjacent_vertices(node, *g);
  2612. for (; neighbourIt != neighbourEnd; ++neighbourIt){
  2613. tie(e1,found)=edge(vertex(node,*g),vertex(*neighbourIt,*g),*g);
  2614. if(In_tab(*Sd,*neighbourIt) != 1){
  2615. tmp_cut_out += (*g)[e1]._weight;
  2616. }
  2617. }*/
  2618. //std::cout<<"tmp_cut_in "<< tmp_cut_in/2. <<std::endl;
  2619. //std::cout<<"tmp_cut_out "<< tmp_cut_out/2. <<std::endl;
  2620. new_ratio = new_cut/2./tmp_poids_in + new_cut/2./tmp_poids_out;
  2621. /*new_ratio -= cut_out/2./poids_out;
  2622. new_ratio += tmp_cut_in/2./tmp_poids_in;
  2623. new_ratio += tmp_cut_out/2./tmp_poids_out;*/
  2624. //std::cout<<"Nouveau ratio : " <<new_ratio<<std::endl;
  2625. return new_ratio;
  2626. }
  2627. EntiersEntiers Spectral_Partition(const char* text){
  2628. //Traitement initial
  2629. EntiersEntiers Partition;
  2630. std::ifstream fichier (text, std::ios::in);
  2631. if(fichier){
  2632. int lines = std::count(std::istreambuf_iterator<char>( fichier ),
  2633. std::istreambuf_iterator<char>(),'\n' );
  2634. std::cout<<"Nombre de ligne : "<<lines<<std::endl;
  2635. /*** Récupération du dernier caractère ***/
  2636. /*** Création des paramétres contenant les informations ***/
  2637. int nmax_vertex;
  2638. fichier.seekg(0, std::ios::beg);
  2639. fichier >> nmax_vertex;
  2640. std::cout<<"nmax_vertex : "<<nmax_vertex<<std::endl;
  2641. int nmax_size = decimal(nmax_vertex) + 1;
  2642. /*** Récupération des informations ***/
  2643. int cpt = 1;
  2644. int length;
  2645. fichier.seekg(nmax_size, std::ios::beg);
  2646. while(cpt < lines){
  2647. Entiers *part = new Entiers();
  2648. for(uint i =0; i<nmax_vertex; i++){
  2649. int edge;
  2650. fichier >> edge;
  2651. if(edge != -1)
  2652. part->push_back(edge);
  2653. }
  2654. Partition.push_back(part);
  2655. length = fichier.tellg();
  2656. fichier.seekg(length+1, std::ios::beg);
  2657. cpt++;
  2658. }
  2659. }else{
  2660. std::cerr << "Impossible d'ouvrir le fichier dans Spectral_Partition !" << std::endl;
  2661. }
  2662. return(Partition);
  2663. }
  2664. void Adjacent_Matrix_Txt(UnorientedGraph *g, const char* text){
  2665. std::ofstream GRAPH4 (text, std::ios::out);
  2666. if(GRAPH4){
  2667. tie(vertexIt, vertexEnd) = vertices(*g);
  2668. edge_t e1;
  2669. bool found;
  2670. for (; vertexIt != vertexEnd; ++vertexIt) {
  2671. int cpt = 0;
  2672. tie(neighbourIt, neighbourEnd) = adjacent_vertices(*vertexIt,
  2673. *g);
  2674. for(int i = cpt; i<num_vertices(*g); i++){
  2675. if(i == *neighbourIt){
  2676. tie(e1,found)=edge(vertex(*vertexIt,*g),vertex(*neighbourIt,*g),*g);
  2677. GRAPH4<<(*g)[e1]._weight<<" ";
  2678. cpt = *neighbourIt +1;
  2679. ++neighbourIt;
  2680. if(*neighbourIt == *neighbourEnd){
  2681. for(int j = cpt; j<num_vertices(*g); j++)
  2682. GRAPH4<<0<<" ";
  2683. break;
  2684. }
  2685. }else{
  2686. GRAPH4<<0<<" ";
  2687. }
  2688. }
  2689. GRAPH4<<std::endl;
  2690. }
  2691. GRAPH4.close();
  2692. }else
  2693. std::cerr << "Impossible d'ouvrir le fichier dans Adjacent_Matrix_Txt !" << std::endl;
  2694. }
  2695. void Weight_Matrix_Txt(UnorientedGraph *g, const char* text){
  2696. std::ofstream GRAPH4 (text, std::ios::out);
  2697. if(GRAPH4){
  2698. for (int i =0 ; i<num_vertices(*g); i++) {
  2699. GRAPH4<<(*g)[i]._weight<<" ";
  2700. }
  2701. GRAPH4.close();
  2702. }else
  2703. std::cerr << "Impossible d'ouvrir le fichier dans Weight_Matrix_Txt !" << std::endl;
  2704. }
  2705. void Plot_OrientedGraph(OrientedGraph *go, const char* text){
  2706. edge_to e1;
  2707. bool found;
  2708. std::ofstream fichier2 (text, std::ios::out);
  2709. fichier2<<"digraph G {"<<std::endl;
  2710. tie(vertexIto, vertexEndo) = vertices(*go);
  2711. for (; vertexIto != vertexEndo; ++vertexIto) {
  2712. tie(neighbourIto, neighbourEndo) = adjacent_vertices(*vertexIto,
  2713. *go);
  2714. for (; neighbourIto != neighbourEndo; ++neighbourIto){
  2715. tie(e1,found)=edge(vertex(*vertexIto,*go),
  2716. vertex(*neighbourIto,*go),*go);
  2717. fichier2<<(*go)[*vertexIto]._index<<" -> "
  2718. <<(*go)[*neighbourIto]._index<<" [label="
  2719. <<(*go)[e1]._weight
  2720. <<", fontsize=10, fontcolor= blue];"<<std::endl;
  2721. }
  2722. }
  2723. fichier2<<"}";
  2724. fichier2.close();
  2725. }
  2726. void Plot_UnorientedGraph(UnorientedGraph *g, const char* text){
  2727. edge_t e1;
  2728. bool found;
  2729. std::ofstream GRAPH2 (text, std::ios::out);
  2730. GRAPH2<<"graph G {"<<std::endl;
  2731. tie(vertexIt, vertexEnd) = vertices(*g);
  2732. for (; vertexIt != vertexEnd; ++vertexIt) {
  2733. tie(neighbourIt, neighbourEnd) = adjacent_vertices(*vertexIt,*g);
  2734. for (; neighbourIt != neighbourEnd; ++neighbourIt){
  2735. if((*g)[*neighbourIt]._index>(*g)[*vertexIt]._index){
  2736. tie(e1,found)=edge(vertex(*vertexIt,*g),vertex(*neighbourIt,*g),*g);
  2737. GRAPH2<<(*g)[*vertexIt]._index<<" -- "<<(*g)[*neighbourIt]._index<<" [label="<<(*g)[e1]._weight<<", fontsize=10, fontcolor= blue];"<<std::endl;
  2738. }
  2739. }
  2740. }
  2741. GRAPH2<<"}";
  2742. GRAPH2.close();
  2743. }
  2744. void Plot_UnorientedGraph_All(UnorientedGraph *g, const EntiersEntiers &Partition, const char* text, bool Color){
  2745. edge_t e1;
  2746. bool found;
  2747. if(Partition.size()<17){
  2748. std::ofstream GRAPH2 (text, std::ios::out);
  2749. GRAPH2<<"graph G {"<<std::endl;
  2750. tie(vertexIt, vertexEnd) = vertices(*g);
  2751. for (; vertexIt != vertexEnd; ++vertexIt) {
  2752. tie(neighbourIt, neighbourEnd) = adjacent_vertices(*vertexIt,*g);
  2753. for (; neighbourIt != neighbourEnd; ++neighbourIt){
  2754. if((*g)[*neighbourIt]._index>(*g)[*vertexIt]._index){
  2755. tie(e1,found)=edge(vertex(*vertexIt,*g),vertex(*neighbourIt,*g),*g);
  2756. GRAPH2<<(*g)[*vertexIt]._index<<" -- "<<(*g)[*neighbourIt]._index<<" [label="<<(*g)[e1]._weight<<", fontsize=10, fontcolor= blue];"<<std::endl;}
  2757. }
  2758. }
  2759. if(Color == true){
  2760. std::vector<std::string> color;
  2761. color.push_back(", color=blue2, fontcolor=blue2];");
  2762. color.push_back(", color=red, fontcolor=red];");
  2763. color.push_back(", color=green, fontcolor=green];");
  2764. color.push_back(", color=turquoise, fontcolor=turquoise];");
  2765. color.push_back(", color=saddlebrown, fontcolor=saddlebrown];");
  2766. color.push_back(", color=indigo, fontcolor=indigo];");
  2767. color.push_back(", color=yellow, fontcolor=yellow2];");
  2768. color.push_back(", color=orange, fontcolor=orange];");
  2769. color.push_back(", color=olivedrab, fontcolor=olivedrab];");
  2770. color.push_back(", color=gold, fontcolor=gold];");
  2771. color.push_back(", color=slateblue2, fontcolor=slateblue2];");
  2772. color.push_back(", color=dimgrey, fontcolor=dimgrey];");
  2773. color.push_back(", color=cyan, fontcolor=cyan];");
  2774. color.push_back(", color=purple1, fontcolor=purpule1];");
  2775. color.push_back(", color=crimson, fontcolor=crimson];");
  2776. color.push_back(", color=black, fontcolor=black];");
  2777. for(uint k=0; k<Partition.size(); k++){
  2778. for(uint t=0; t<Partition.at(k)->size(); t++)
  2779. {
  2780. GRAPH2<<(*g)[Partition.at(k)->at(t)]._index<<" [label="<<(*g)[Partition.at(k)->at(t)]._weight<<color.at(k)<<std::endl;
  2781. }
  2782. }
  2783. }else{
  2784. for(uint k=0; k<num_vertices(*g); k++){
  2785. GRAPH2<<(*g)[k]._index<<" [label="<<(*g)[k]._index<<", weight="<<(*g)[k]._weight<<"];"<<std::endl;
  2786. }
  2787. }
  2788. GRAPH2<<"}";
  2789. GRAPH2.close();
  2790. }else{
  2791. std::cout<<"Error : Le nombre de couleur est insuffisant pour réaliser l'affichange"<<std::endl;
  2792. }
  2793. }
  2794. void Plot_OrientedGraph_All(OrientedGraph *go, const EntiersEntiers &Partition, const char* text, bool Color){
  2795. edge_to e1;
  2796. bool found;
  2797. if(Partition.size()<17){
  2798. std::vector<std::string> color;
  2799. color.push_back("[color=blue2, fontcolor=blue2];");
  2800. color.push_back("[color=red, fontcolor=red];");
  2801. color.push_back("[color=green, fontcolor=green];");
  2802. color.push_back("[color=turquoise, fontcolor=turquoise];");
  2803. color.push_back("[color=saddlebrown, fontcolor=saddlebrown];");
  2804. color.push_back("[color=indigo, fontcolor=indigo];");
  2805. color.push_back("[color=yellow, fontcolor=yellow2];");
  2806. color.push_back("[color=orange, fontcolor=orange];");
  2807. color.push_back("[color=olivedrab, fontcolor=olivedrab];");
  2808. color.push_back("[color=gold, fontcolor=gold];");
  2809. color.push_back("[color=slateblue2, fontcolor=slateblue2];");
  2810. color.push_back("[color=dimgrey, fontcolor=dimgrey];");
  2811. color.push_back("[color=cyan, fontcolor=cyan];");
  2812. color.push_back("[color=purple1, fontcolor=purpule1];");
  2813. color.push_back("[color=crimson, fontcolor=crimson];");
  2814. color.push_back("[color=black, fontcolor=black];");
  2815. std::ofstream fichier2 (text, std::ios::out);
  2816. fichier2<<"digraph G {"<<std::endl;
  2817. tie(vertexIto, vertexEndo) = vertices(*go);
  2818. for (; vertexIto != vertexEndo; ++vertexIto) {
  2819. tie(neighbourIto, neighbourEndo) = adjacent_vertices(*vertexIto,
  2820. *go);
  2821. for (; neighbourIto != neighbourEndo; ++neighbourIto){
  2822. tie(e1,found)=edge(vertex(*vertexIto,*go),vertex(*neighbourIto,*go),*go);
  2823. fichier2<<(*go)[*vertexIto]._index<<" -> "<<(*go)[*neighbourIto]._index<<" [label="<<(*go)[e1]._weight<<", fontsize=10, fontcolor= blue];"<<std::endl;
  2824. }
  2825. }
  2826. if(Color == true){
  2827. for(uint k=0; k<Partition.size(); k++){
  2828. for(uint j=0; j<Partition.at(k)->size(); j++)
  2829. {
  2830. fichier2<<Partition.at(k)->at(j)<<color.at(k)<<std::endl;
  2831. }
  2832. }
  2833. }
  2834. fichier2<<"}";
  2835. fichier2.close();
  2836. }else{
  2837. std::cout<<"Error : Le nombre de couleur est insuffisant pour réaliser l'affichange"<<std::endl;
  2838. }
  2839. }
  2840. void Affichage_OrientedGraph(OrientedGraph *go){
  2841. tie(vertexIto, vertexEndo) = vertices(*go);
  2842. for (; vertexIto != vertexEndo; ++vertexIto) {
  2843. std::cout<<(*go)[*vertexIto]._index<<" -> ";
  2844. tie(neighbourIto, neighbourEndo) = adjacent_vertices(*vertexIto,
  2845. *go);
  2846. for (; neighbourIto != neighbourEndo; ++neighbourIto){
  2847. std::cout<<(*go)[*neighbourIto]._index<<" ";
  2848. }
  2849. std::cout<<std::endl;
  2850. }
  2851. std::cout<<std::endl;
  2852. }
  2853. void Affichage_UnorientedGraph(UnorientedGraph *g){
  2854. tie(vertexIt, vertexEnd) = vertices(*g);
  2855. for (; vertexIt != vertexEnd; ++vertexIt) {
  2856. std::cout<<(*g)[*vertexIt]._index<<" -> ";
  2857. tie(neighbourIt, neighbourEnd) = adjacent_vertices(*vertexIt,
  2858. *g);
  2859. for (; neighbourIt != neighbourEnd; ++neighbourIt){
  2860. std::cout<<(*g)[*neighbourIt]._index<<" ";
  2861. }
  2862. std::cout<<std::endl;
  2863. }
  2864. std::cout<<std::endl;
  2865. }
  2866. double Total_weight_edges(UnorientedGraph *g){
  2867. double Sum_weight_edges = 0.;
  2868. edge_t e1;
  2869. bool found;
  2870. tie(vertexIt, vertexEnd) = vertices(*g);
  2871. for (; vertexIt != vertexEnd; ++vertexIt) {
  2872. tie(neighbourIt, neighbourEnd) = adjacent_vertices(*vertexIt,*g);
  2873. for (; neighbourIt != neighbourEnd; ++neighbourIt){
  2874. if((*g)[*neighbourIt]._index>(*g)[*vertexIt]._index){
  2875. tie(e1,found)=edge(vertex(*vertexIt,*g),vertex(*neighbourIt,*g),*g);
  2876. Sum_weight_edges += (*g)[e1]._weight;
  2877. }
  2878. }
  2879. }
  2880. return Sum_weight_edges;
  2881. }
  2882. void Merge_Boost_Graph(OrientedGraph *go1, OrientedGraph *go2, std::vector<std::pair<int,int>> &connection, std::vector<double> &connection_weight){
  2883. edge_to e1;
  2884. bool found;
  2885. int nbr_go1 = num_vertices(*go1);
  2886. int nbr_go2 = num_vertices(*go2);
  2887. /*** Fusion ***/
  2888. if(nbr_go1 >= nbr_go2){
  2889. tie(vertexIto, vertexEndo) = vertices(*go2);
  2890. for (; vertexIto != vertexEndo; ++vertexIto){
  2891. vertex_to v0 = boost::add_vertex(*go1);
  2892. (*go1)[v0] = VertexProperties((*go2)[*vertexIto]._index, (*go2)[*vertexIto]._weight, 1 /*NORMAL_PIXEL*/);
  2893. }
  2894. tie(vertexIto, vertexEndo) = vertices(*go2);
  2895. for (; vertexIto != vertexEndo; ++vertexIto){
  2896. tie(neighbourIto, neighbourEndo) = adjacent_vertices(*vertexIto,*go2);
  2897. for (; neighbourIto != neighbourEndo; ++neighbourIto){
  2898. tie(e1,found)=edge(vertex(*vertexIto,*go2),vertex(*neighbourIto,*go2),*go2);
  2899. add_edge(*vertexIto + nbr_go1, *neighbourIto + nbr_go1, (*go2)[e1]._weight, *go1);
  2900. }
  2901. }
  2902. /*** Connection ***/
  2903. /* Fonctionne si l'ordre de nomation respecte l'ordre boost sinon possibilité d'identification par nom*/
  2904. for(uint i = 0; i < connection.size(); i++){
  2905. add_edge(connection.at(i).first, connection.at(i).second, connection_weight.at(i) , *go1);
  2906. }
  2907. }else{
  2908. tie(vertexIto, vertexEndo) = vertices(*go1);
  2909. for (; vertexIto != vertexEndo; ++vertexIto){
  2910. vertex_to v0 = boost::add_vertex(*go2);
  2911. (*go2)[v0] = VertexProperties((*go1)[*vertexIto]._index, (*go1)[*vertexIto]._weight, 1 /*NORMAL_PIXEL*/);
  2912. }
  2913. tie(vertexIto, vertexEndo) = vertices(*go1);
  2914. for (; vertexIto != vertexEndo; ++vertexIto){
  2915. tie(neighbourIto, neighbourEndo) = adjacent_vertices(*vertexIto,*go1);
  2916. for (; neighbourIto != neighbourEndo; ++neighbourIto){
  2917. tie(e1,found)=edge(vertex(*vertexIto,*go1),vertex(*neighbourIto,*go1),*go1);
  2918. add_edge(*vertexIto + nbr_go2, *neighbourIto + nbr_go2, (*go1)[e1]._weight, *go2);
  2919. }
  2920. }
  2921. /*** Connection ***/
  2922. /* Fonctionne si l'ordre de nomation respecte l'ordre boost sinon possibilité d'identification par nom*/
  2923. for(uint i = 0; i < connection.size(); i++){
  2924. add_edge(connection.at(i).first, connection.at(i).second, connection_weight.at(i) , *go2);
  2925. }
  2926. }
  2927. }
  2928. Entiers Random_Sort_Vector(uint size){
  2929. Entiers random_order;
  2930. for (uint i = 0 ; i< size ; i++)
  2931. random_order.push_back(i);
  2932. for (uint j=0 ; j < random_order.size()-1 ; j++) {
  2933. int rand_pos = rand()%(size-j)+j;
  2934. int tmp = random_order.at(j);
  2935. random_order.at(j) = random_order.at(rand_pos);
  2936. random_order.at(rand_pos) = tmp;
  2937. }
  2938. return random_order;
  2939. }
  2940. Entiers Random_Sort_Vector2(uint min, uint size){
  2941. Entiers random_order;
  2942. for (uint i = min ; i< size ; i++)
  2943. random_order.push_back(i);
  2944. for (uint j = 0 ; j < random_order.size()-1 ; j++) {
  2945. int rand_pos = rand()%(random_order.size()-j)+j;
  2946. int tmp = random_order.at(j);
  2947. random_order.at(j) = random_order.at(rand_pos);
  2948. random_order.at(rand_pos) = tmp;
  2949. }
  2950. return random_order;
  2951. }
  2952. double distance_t(std::pair<double,double> x, std::pair<double,double> y)
  2953. {
  2954. double total = (x.first - y.first) * (x.first - y.first) ;
  2955. double diff2 = (x.second - y.second) * (x.second - y.second);
  2956. total += diff2;
  2957. return sqrt(total);
  2958. }
  2959. } } } // namespace paradevs tests boost_graph