Programme Pimp A - info121a Programmation IMPérative Avancée Frédéric Vernier inspiré du cours de Burkhart Wolff Tri Récursivité Dichotomie Arbre Graphes Examen blanc xxx yyy Traverse et Calculs dans Arbres Graphes omniprésent! Exemples Représentations de graphes Parcours et Calculs etc. Exemple: Graphes de Réseaux Réseau de transport Stations (+type) Connexions Routes
Exemple: Graphes Exemple: Recherche Labyrinthe La recherche d une sortie d un labyrinthe Réseau sociaux (mais qui te like?) Exemple: Recherche Labyrinthe Exemple: Configurations en Jeux Recherche d une sortie = arbre ensemble des chemins = graphe n queens peut avoir des cycles Graphe implicite
Graphes : Définition Graphs : Definitions consistent d un ensemble de sommets (noeuds) V et de liens entre eux, des arêtes (arcs) E entre eux, i.e. un ensemble de paires entre les V. peuvent être orientés (E non-symétrique) ou non-orientés (E symétrique) peuvent avoir (en plus des arbres): boucles ([4,5,2,3]), peuvent avoir: cas: orientés - in-degré (example: 2) - out-degré (example: 2) cas non-orientés - degré (example: 2) des attributs sur des sommets (ex.: graph coloré ) des attributs sur des arêtes (ex.: graph pondéré ) sommets avec plusieurs pères (2) Graphe : Représentation Graphe : Représentation Représentation de Graphes: G = (V,E) ou V = {1,2,3,4,5,6 E = {(6,4),(4,3),(4,5),(5,2),(5,1),(2,1), (4,6),(3,4),(5,4),(2,5),(1,5),(1,2) Et, bien sur, une représentation par référence (position dans tableaux): [[2,5], [5,1], [2,4], [3,5,6], [1,2,4], [4]] ou par une fonction: vector<ref> voisins(<ref>)
Exemple de problème Différentes formes de graphes et de problèmes [Wikipedia] Route problems!!hamiltonian path and cycle problems!!minimum spanning tree!!route inspection problem (also called the "Chinese Postman Problem")!!Seven Bridges of Königsberg!!Shortest path problem!!steiner tree!!three-cottage problem!!traveling salesman problem (NP-hard) Exemple de problème Problème du chemin Hamiltonien: (pour des graphes orientés et non-orientés): trouver un chemin qui passe par tous les sommets exactement une fois. n existe pas dans tous les graphes. Certaines Graph-Problèmes Problème du voyageur de commerce: pour un graphe pondéré G = (V, A,!) typiquement non-orienté, mais visiter chaque sommet qu une seule fois (sauf le départ et fin, qui sont égaux) minimiser le cout du chemin problème d optimisation récurrent et complexe (NP) graphe pondéré: Arbre couvrant de poids minimal (angl: Minimum spanning tree) sommets tous liés poids minimal Autre exemple
Graphes & Arbres Graphs vs. Arbres: Marquages Arbres faciles à explorer par des algorithmes récursives Idée: explorer les graphes par construction de sous-arbres marquer les sommets déjà visitées marquer(a) de-marquer(a) est-marqué(a) Explicites et implicites Graphs Comme dans le cas des arbres, les sommets et les arrêtes peuvent être explicitement représentés (métro, shortest path navigation ) implicitement représentés: (jeux, labyrinthes ) vector<ref> voisins(sommets S) visiter(s, op) Schéma de parcours d arbres Parcours en profondeur (depth-first) Variante: Parcours Postfixe. (Variantes infixe et prefixe analog arbres) void visitergraph(sommet A){ marquer(a) foreach(sommet S : voisins(a)) if(nonmarque(s)) visitergraph(s); visiter(a); de-marquer(a);
Schema evaluation de graphes code C++ Parcours en profondeur (depth-first) Variante : Parcours Postfixe. (Variantes infixe et prefixe analogue aux arbres) <Res> evalgraph(sommet A){ marquer(a); foreach(sommet S : voisins(a)) if(nonmarque(a)) vector<res> res=evalarete(a,s,evalgraph(s)); de-marquer(a); return eval(a, res); /* Rappel d un algorithme de recherche: */ char MUR = '#'; char VIDE = ' '; char EN_CONSTR = '?'; char IMPASSE = '@'; char CHEMIN = 'o'; typedef vector<vector<char> > Labyrinthe; Labyrinthe laby; code C++ code C++ /* Rappel d un algorithme de recherche: */ bool chemin1_r(int x, int y){ //cout << x << "," << y << endl; laby[y][x] = EN_COURS; bool trouve = false; if (x==laby[laby.size()-2].size()-2 && y==laby.size()-2){ laby[y][x] = CHEMIN; return true; if (laby[y][x+1]==vide) trouve=chemin1_r(x+1, y); if (! trouve && laby[y+1][x]==vide) trouve=chemin1_r(x,y+1); if (! trouve && laby[y][x-1]==vide) trouve=chemin1_r(x-1,y); if (! trouve && laby[y-1][x]==vide) trouve=chemin1_r(x,y-1); /* Rappel d un algorithme de recherche: */ bool chemin1_r(int x, int y){ laby[y][x] = EN_COURS; bool trouve = false; if (x==laby[laby.size()-2].size()-2 && y==laby.size()-2){ laby[y][x] = CHEMIN; return true; marquer(x,y) le résultat donc voisin pas marqué if (laby[y][x+1]==vide) trouve=chemin1_r(x+1, y); if (! trouve && laby[y+1][x]==vide) trouve=chemin1_r(x,y+1); if (! trouve && laby[y][x-1]==vide) trouve=chemin1_r(x-1,y); if (! trouve && laby[y-1][x]==vide) trouve=chemin1_r(x,y-1); if (trouve)laby[y][x] = CHEMIN return trouve; if (trouve)laby[y][x] = CHEMIN; return trouve; de-marquer(x,y)
Parcours Labyrinthe Parcours de graphes Les Sommets: une configuration, i.e. un pair de: l état du labyrinthe, avec ses murs, ses cases encore vides, ses cases déjà visités la position actuelle: x et y calculer les voisins de (x,y) : trouver positions voisins qui sont ni déjà visité ni mur! Graph implicite!!! Intérêt particulier: Parcours en largeur (breadth first) Rappel: Structure de donné auxiliaire: File <X> (angl: Queue) First-in-first-out principle (FIFO) elements clé: operations File<X> FileVide Parcours de graphes Calculs dans graphes Schéma d un parcours en largeur (breadth first) ParcoursLargeur(Sommet A){ f = FileVide; enfiler(a, f); while (f!= FileVide) { nœud = defiler(f); marquer(nœud); Visiter(nœud); //On choisit de faire une opération foreach(s:voisins(nœud) if (non_marque(s)) enfiler(s, f) de-marquer(nœud) Schéma pour évaluation en largeur <res> evallargeur(sommet A){ File<Pair<Sommet, res_tmp>> f = FileVide; <res> res = initres() enfiler(a, f); while (f!= FileVide) { nœud = defiler(f); marquer(nœud) foreach(s:voisins(nœud) if (non_marque(s)) <res_tmp> res_tmp = eval(nœud, S, res, f) res = update(nœud, S, res, res_tmp) enfiler((s, res_tmp),f) de-marquer(nœud) return res
Parcours de graphes Résumé Quelle stratégie de parcours est meilleur pour find_shortest_path - parcours en profondeur parcours en largeur??? Graphes sont une structure de donnée (récurrente :-) en informatique Algorithmes efficaces de grand intérêt une approche de leur parcours et utilisation : réduction en arbre (via marqueur) et exploration avec des stratégies connues