Graphe.cpp (7082B)
1 #include "Graphe.H" 2 #include "GRapheEcart.h" 3 4 /* Constructeur par défaut. 5 */ 6 Graphe::Graphe(string nom) 7 { 8 this->nom = nom; 9 } 10 11 /* Constructeur par copie d'un graphe. 12 */ 13 Graphe::Graphe(string nom, const Graphe *g) 14 { 15 this->s = g->s; 16 this->p = g->p; 17 listeArcs_t lArcs; 18 this->nom = nom; 19 20 arcs_t arcsTmp = g->arcs; 21 22 for(unsigned int i = 0; i < arcsTmp.size(); i++) 23 { 24 lArcs.clear(); 25 26 for(unsigned int j = 0; j < arcsTmp[i].size(); j++) 27 lArcs.push_back(new Arc(arcsTmp[i][j])); 28 29 this->arcs.push_back(lArcs); 30 } 31 } 32 33 Graphe::~Graphe() 34 { 35 36 } 37 38 arcs_t Graphe::getArcs() const { return this->arcs; }; 39 40 41 //------- Fonctions du TP --------// 42 //================================// 43 44 /* Q1 | Retourne le graphe d'écart associé pour un flot nul. 45 * Prerequis : le graphe doit être orienté et ne pas contenir d'ars retour. TODO revoir l'histoire de pas d'arcs retour. 46 * Seconde partie de la fonction dans le constructeur de la classe GrapheEcart*/ 47 GrapheEcart* Graphe::grapheEcartFlotNul() const 48 { 49 string nom; // Nom du graphe. 50 51 nom = "Graphe d'écart du graphe : " + this->nom; 52 GrapheEcart *gEcart = new GrapheEcart(nom,this); 53 54 return gEcart; 55 } 56 57 58 /* Q2 | Détermineur un plus court chemin entre les sommets s et p. 59 * Prerequis : le graphe ne doit pas être vide.*/ 60 listeArcs_t Graphe::PCCsp(unsigned int s, unsigned int p) const 61 { 62 listeArcs_t pcc; 63 listeArcs_t arcsParcourus; 64 vector<unsigned int> file; 65 vector<bool> sVu; // Sommets déjà vu. 66 unsigned int sommet; 67 68 if(s == p) 69 return pcc; 70 71 // Initialisation du vecteur de sommets déjà vus.. 72 for(unsigned int i = 0; i < this->arcs.size(); i++) 73 sVu.push_back(false); 74 75 // Mise dans la file du sommet de départ. 76 file.push_back(s); 77 78 while(file.size() > 0) 79 { 80 sommet = file[0]; 81 82 for(unsigned int i = 0; i < this->arcs[sommet].size(); i++) 83 if(this->arcs[sommet][i]->getS2() == p) 84 { 85 arcsParcourus.push_back(this->arcs[sommet][i]); 86 unCheminSaP(s,p,arcsParcourus,pcc); 87 return pcc; 88 } 89 else 90 if(sVu[this->arcs[sommet][i]->getS2()] == false) 91 { 92 file.push_back(this->arcs[sommet][i]->getS2()); 93 arcsParcourus.push_back(this->arcs[sommet][i]); 94 sVu[this->arcs[sommet][i]->getS2()] = true; 95 } 96 97 file.erase(file.begin()); 98 } 99 100 return pcc; 101 } 102 103 104 /* Q3 | Donne la plus petite valuation (capacité) sur le chemin. 105 * Prerequis : Le chemin doit contenir au moins un arc.*/ 106 unsigned int Graphe::capaciteMinDuChemin(listeArcs_t chemin) const 107 { 108 unsigned int c = chemin[0]->getCapacite(); 109 110 for(unsigned int i = 1; i < chemin.size(); i++) 111 c = min(c,chemin[i]->getCapacite()); 112 113 return c; 114 } 115 116 117 /* Q5 | Met à jour à partir du graphe d'écart final le graphe et retourne le flot maximum. 118 */ 119 int Graphe::miseAJour(GrapheEcart *ge) 120 { 121 arcs_t la = ge->getListeArcs(); 122 int flotMax = 0; 123 124 for(unsigned int k = 0; k < la.size(); k++) 125 for(unsigned int l = 0; l < la[k].size(); l++) 126 { 127 this->arcDansGraphe(la[k][l])->setFlot(la[k][l]->getFlot()); 128 129 if(la[k][l]->getS2() == this->p) 130 flotMax += la[k][l]->getFlot(); 131 } 132 133 return flotMax; 134 } 135 136 //================================// 137 138 139 140 141 /* Ajoute une arc au graphe 142 * L'arc est palcée en fonction de son sommets de départ puis de celui d'arrivé 143 */ 144 bool Graphe::ajouteArc(Arc *arc) 145 { 146 // Si les deux sommets de l'arc appartiennent au graphe. 147 if(arc->getS1() <= (this->arcs.size() -1) && arc->getS2() <= (this->arcs.size() -1)) 148 { 149 // On place l'arc dans la liste correspondante au sommet de départ 150 // et on détermine la position da l'arc dans cette liste selon le sommet d'arrivé. 151 for(unsigned int j = 0; j < this->arcs[arc->getS1()].size(); j++) 152 if(this->arcs[arc->getS1()][j]->getS2() > arc->getS2()) 153 { 154 this->arcs[arc->getS1()].insert(this->arcs[arc->getS1()].begin()+j,arc); 155 return true; 156 } 157 158 this->arcs[arc->getS1()].push_back(arc); 159 } 160 else 161 return false; // Le ne peut être ajouté. 162 163 return true; 164 } 165 166 167 /* Charge un graphe fixe quelconque permettant de tester les différentes fonctions 168 */ 169 void Graphe::chargeG1() 170 { 171 /* Un graphe constitué de 4 sommets et 3 arrêtes */ 172 // TODO Ajouter des sommets et des arrêtes afin de pouvoir tester les différents cas limite. 173 174 listeArcs_t lArcs; // Liste d'arcs. 175 176 // Création de la liste d'arcs sortants pour le sommet 0. 177 Arc *arc = new Arc(0,1,1,0); 178 lArcs.push_back(arc); 179 180 Arc *arc2 = new Arc(0,2,5,0); 181 lArcs.push_back(arc2); 182 183 arcs.push_back(lArcs); 184 185 // Création de la liste d'arcs sortants pour le sommet 1. 186 lArcs.clear(); 187 188 Arc *arc3 = new Arc(1,3,3,2); 189 lArcs.push_back(arc3); 190 191 arcs.push_back(lArcs); 192 193 // Création de la liste d'arcs sortants pour le sommet 2 et 3. 194 lArcs.clear(); 195 196 arcs.push_back(lArcs); 197 arcs.push_back(lArcs); 198 } 199 200 201 /* Affichage du graphe. 202 */ 203 void Graphe::afficheGraphe() const 204 { 205 cout << " - " << nom << endl; 206 207 for(unsigned int i = 0; i < arcs.size(); i++) // Pour chaques sommets. 208 for(unsigned int j = 0; j < arcs[i].size(); j++) // Pour chaque arcs. 209 this->arcs[i][j]->afficheArc(); // Dessin de l'arc. 210 } 211 212 bool Graphe::estDansListe(Arc *arc, listeArcs_t lArcs) const 213 { 214 for(unsigned int i = 0; i < lArcs.size(); i++) 215 if(lArcs[i] == arc) 216 return true; 217 218 return false; 219 } 220 221 void Graphe::unCheminSaP(unsigned int s, unsigned int p, listeArcs_t l, listeArcs_t &pcc) const 222 { 223 // Condition d'arrêt de la récursion. 224 if(s == p) 225 return; 226 227 for(unsigned int i = 0; i < l.size(); i++) 228 if(l[i]->getS2() == p) 229 { 230 pcc.insert(pcc.begin(),l[i]); 231 unCheminSaP(s,l[i]->getS1(),l,pcc); 232 return; 233 } 234 } 235 236 Arc* Graphe::arcInverse(Arc *arc) 237 { 238 for(unsigned int s = 0; s < this->arcs[arc->getS2()].size(); s++) 239 if(this->arcs[arc->getS2()][s]->getS2() == arc->getS1()) 240 return this->arcs[arc->getS2()][s]; 241 242 return NULL; 243 } 244 245 Arc* Graphe::arcDansGraphe(Arc *a) 246 { 247 for(unsigned int s = 0; s < this->arcs[a->getS1()].size(); s++) 248 if(this->arcs[a->getS1()][s]->getS2() == a->getS2()) 249 return this->arcs[a->getS1()][s]; 250 251 return NULL; 252 } 253 254 255 256 257 258 259 260