Vous êtes sur la page 1sur 9

Travaux Pratiques

Intelligence Artificielle

Filière d’ingénieur
Systèmes Intelligents, Communicants et Mobiles
(SICoM)

Pr : Aicha ALAMI HASSANI

AU : 2020/2021
Département de Génie Electrique, Faculté des Sciences et Techniques Fès B.P. 2202, Route d’Imouzzer FES
212 (35) 60 80 14 – 212 (35) 60 96 35 7 212 (35) 60 82 14
Email: alamiaicha3@yahoo.fr URL: www .fst-usmba.ac.ma
I. Algorithmes de recherche
1. Arbre en Python:

Soit l’arbre suivant: On va le représenter en Python


sous forme de listes imbriquées :

1  arbre  =  [’A’,  [  
2       [’B’,     [  
3         [’E’,  [  ]  ],  
4         [’F’,  [  ]  ]  
5         ]  
6       ]  ,  #  fin  de  B  
7       [’C’,  [  ]  ],  #  fin  de  C  
8     [’D’,     [  
9         [’G’,[  ]  ]  
10       ]  
C.-à-d. que: 11       ]  #  fin  de  D  
§ chaque sous-arbre sera sous forme d’une liste : 12     ]  
[ sommet , [ liste sous arbre ] ] 13            ]  
§ une feuille est notée sous la forme :
[ feuille , [ ] ]

Une fois cette notation adoptée, les algorithmes de parcours s’écrivent très simplement :

Parcours récursif en profondeur d’abord Parcours itératif en largeur

1  def  ParcoursArbreRecursif(racine):   1  def  ParcoursArbreIteratif(racine):  


2     sommet  =  racine[0]   2     while  file_sommets:  
3     enfants  =  racine[1]   3     arbre_courant  =  file_sommets.pop(0)  
4     print  sommet   4     sommet_courant  =  arbre_courant[0]  
5     for  noeud  in  enfants:   5     enfants_courant  =  arbre_courant[1]  
6                ParcoursArbreRecursif(noeud)   6     print  sommet_courant  
8  ParcoursArbreRecursif(arbre)   7     for  enfant  in  enfants_courant:  
8              if  enfant:  
9                          file_sommets.append(enfant)  
11  file_sommets  =  [arbre]  
12  ParcoursArbreIteratif(arbre)  

2. Graphe en Python:

Soit le graphe suivant: On va le représenter en Python sous forme d’un


dictionnaire Python :

1  dico_graph  =  {  ’A’  :  [’B’],  ’B’  :  [’A’,’C’,’D’],  


’C’:  [’B’,’D’],  ’D’:[’B’,’C’]}  
C.-à-d. que:
§ chaque association du dictionnaire est une paire (sommet, liste d’adjacence) ;
§ les clés sont les noms des sommets ce qui permet un accès direct au travers du
dictionnaire.

Une fois cette notation adoptée, les algorithmes de parcours s’écrivent très simplement :

Parcours récursif en profondeur d’abord

1  def  TraverserDepuisRecursive(graphe,sommet):  
2    sommets_visites.append(sommet)  
3     print  sommet  
4     for  voisin  in  graphe[sommet]:  
5                  if  (not  voisin  in  sommets_visites):  
6       TraverserDepuisRecursive(graphe,  voisin)  
8  sommets_visites  =  [  ]  
9  TraverserDepuisRecursive(dico_graph,  ’A’)  

Parcours itératif en largeur

1  def  TraverserDepuisIterative(graphe,sommet):  
2     sommets_a_visiter  =  [sommet]  
3     while  sommets_a_visiter:  
4       sommet_courant  =  sommets_a_visiter.pop(0)  
5       if  (not  sommet_courant  in  sommets_visites):  
6         sommets_visites.append(sommet_courant)  
7         print  sommet_courant  
8         sommets_a_visiter.extend(graphe[sommet_courant])  
 
10  sommets_visites  =  [  ]  
11  TraverserDepuisIterative(dico_graph,  ’A’)  

3. Parcours d'un graphe :


3.1. Parcours en largeur BFS (breadth first search)

A l’aide de l'exemple de codage suivant utilisant un dictionnaire python :

G=dict()  
G['a']=['b','c']  
G['b']=['a','d','e']  
G['c']=['a','d']  
G['d']=['b','c','e']  
G['e']=['b','d','f','g']  
G['f']=['e','g']  
G['g']=['e','f','h']  
G['h']=['g']  

Programmer en langage python le BFS (breadth first search) avec les variables suivantes :
• Un dictionnaire P. En fin de parcours, pour tout sommet s du graphe P[s] sera le
père de s, c'est à dire le sommet à partir duquel le sommet s a été découvert lors du
parcours.
• Un dictionnaire couleur. Pour tout sommet s, couleur[s] vaut blanc si le sommet s
n'est pas passé dans la file, gris s'il est dans la file, noir lorsqu'il est sorti de la file.
• Une liste Q utilisée comme file (fifo) : on enfile un sommet lorsqu'il est découvert,
on le défile lorsqu'il est terminé (traitement prioritaire des sommets découverts au
plus tôt).

a. Déroulement attendu du programme, avec l'appel bfs(G,'b'), sur le graphe ci-


dessus :
b. Arborescence associée au parcours

L'ordre de parcours est : ligne après ligne (de la racine vers les feuilles) et de gauche à
droite pour une ligne.

c. Codage en python

def  bfs(G,s)  :  
couleur=dict()  
for  x  in  G  :  couleur[x]='blanc'  
P=dict()  
P[s]=None  
couleur[s]='gris'  
Q=[s]  
while  Q  :  
u=Q[0]  
for  v  in  G[u]  :  
if  couleur[v]=='blanc'  :  
P[v]=u  
couleur[v]='gris'  
Q.append(v)  
Q.pop(0)  
couleur[u]='noir'  
return  P  
3.2. Parcours en profondeur DFS (depth first search)

Avec la représentation d'un graphe par un dictionnaire comme précédemment, programmer


en langage python le DFS avec les variables suivantes :

• Un dictionnaire P. En _n de parcours, pour tout sommet s du graphe P[s] sera le


père de s, c'est à dire le sommet à partir duquel le sommet s a été découvert lors du
parcours.
• Un dictionnaire couleur. Pour tout sommet s, couleur[s] vaut blanc si le sommet s
n'est pas encore découvert, gris s'il est déjà découvert mais non encore fermé (c'est à
dire si l'algorithme n' a pas encore découvert tous ses voisins), noir lorsque ce
sommet est fermé.
• Une liste Q utilisée comme pile (lifo) : on empile un sommet lorsqu'il est
découvert, on le dépile lorsqu'il est terminé (traitement prioritaire des sommets
découverts au plus tard).

L’arborescence associée au parcours est donnée par la figure suivante :


II. Réseau de Neurones Artificiels : Application au XO R
Dans cette partie on se propose de construire un réseau de neurones à une couche pour
résoudre le problème du OU EXCLUSIF (XOR). Celui-ci prend 2 bits en entrée, A et B,
puis renvoie 0 si A et B sont identiques et 1 s’ils sont égaux.

Si on prend pour exemple le XOR sur 1 couche cachée à 2 neurones, qu’on se donne en
entrée 1, 0, alors avec les poids indiqués, on trouve pour la couche cachée des sorties 1 et -
1, puis en sortie finale 1. Vous pourrez tester que le réseau de neurones proposé avec ces
poids résout bien le XOR.

On va donc utiliser 2 neurones dans la couche d’entrée, 1 dans la couche de sortie et 1


couche cachée de 2 neurones.
Ceci sera fait de deux manières différentes : en partant de zéro puis en utilisant une librairie
existante (keras et tensorflow).

1. Construire le réseau de neurones à la main


a. Préparation de l’environnement
b. Définition des variables
c. Propagation (phase forward)
d. Rétropropagation du gradient (phase backpropagation)

2. Construire le perceptron avec KERAS


Dans la pratique, on utilise plutôt des librairies toutes prêtes (keras, tensorflow…).
a. Préparation de l’environnement
b. Utilisation de KERAS pour tout faire
III. Algorithmes génétiques: Application à la résolution approchée
du problème du Voyageur de Commerce
L'objectif de cette partie est de programmer un algorithme génétique pour résoudre de
façon approchée le problème du voyageur de commerce.

Rappel : Le problème du voyageur de commerce est le suivant :


• soient N villes séparées chacune d'elles par une distance D(i,j)
• trouver le chemin le plus court passant par toutes les villes et retournant à son point
de départ.
En d'autres termes, il s'agit de déterminer le plus court chemin hamiltonien sur un graphe
donné. La taille de l'espace de solutions est 1/2(N-1)!.

On prendra comme exemple une recherche sur 10 villes avec les distances entre villes
suivantes :

d [0] = [2,3,4,5,6,7,8,9,10 ] la distance de la première ville avec la 2eme , ... , 10eme


d [1] = [11,12,13,14,15,16,17,18 ] la distance de la deuxième ville avec la 3eme, ... ,10eme
d [2] = [19,20,21,22,23,24,25] #etc...
d [3] = [26,27,28,29,30,31]
d [4] = [32,33,34,35,36]
d [5] = [37,38,39 ,40]
d [6] = [41,42,43]
d [7] = [44,45]
d [8] = [46] # distance de la 9eme ville avec la 10eme ville

Vous aimerez peut-être aussi