diff --git a/TD/TD5/ML-TD5.pdf b/TD/TD5/ML-TD5.pdf
new file mode 100644
index 0000000000000000000000000000000000000000..22ca7ee0e445b78e445128437bb2087c9439122d
Binary files /dev/null and b/TD/TD5/ML-TD5.pdf differ
diff --git a/TD/TD5/q_learning.py b/TD/TD5/q_learning.py
new file mode 100644
index 0000000000000000000000000000000000000000..f1f78980848222e0596f1c1d045fce4cae96399c
--- /dev/null
+++ b/TD/TD5/q_learning.py
@@ -0,0 +1,129 @@
+import numpy as np
+
+def choix_action(epsilon, s, R, Q):
+    """ Renvoie l'action sélectionnée pour l'état s. Epsilon est une valeur seuil entre 0 et 1 permettant 
+        soit de faire de l'exploration (si tirage aléatoire supérieur au seuil), soit de faire 
+        de l'exploitation (si tirage aléatoire inférieur au seuil)
+
+    Parametres
+    ----------
+    epsilon : seuil (entre 0 et 1) pour choisir entre exploration et exploitation afin de sélectionner une action
+    s : état courant
+    R : matrice des récompenses immédiates
+    Q : matrice représentant la fonction action-valeur
+
+    Retour
+    -------
+    a : action sélectionnée
+
+    """
+
+    #########################################################
+    ##### A compléter (et supprimer l'instruction pass) ##### 
+    #########################################################
+    pass
+    
+    # return a
+
+def calcule_q(s, a, alpha, gamma, R, Q):
+    """ Calcule la nouvelle valeur de la fonction action valeur pour l'état s et l'action a
+
+    Parametres
+    ----------
+    s : état courant
+    a : action choisie
+    alpha : vitesse d'apprentissage
+    gamma : facteur d'actualisation
+    R : matrice des récompenses immédiates
+    Q : matrice représentant la fonction action-valeur
+
+    Retour
+    -------
+    q : nouvelle valeur de la fonction action valeur pour l'état s et l'action a
+
+    """
+
+    #########################################################
+    ##### A compléter (et supprimer l'instruction pass) ##### 
+    #########################################################
+    pass
+
+    # return q
+
+def politique(s,Q):
+    """ Détermine la meilleure action connaissant l'état S et la fonction action valeur Q
+
+    Parametres
+    ----------
+    s : état courant
+    Q : matrice représentant la fonction action-valeur
+
+    Retour
+    -------
+    a : action sélectionnée
+
+    """    
+
+    #########################################################
+    ##### A compléter (et supprimer l'instruction pass) ##### 
+    #########################################################
+    pass
+    
+    # return a
+
+
+
+# ===================== Partie 1: Initialisation des données =====================
+alpha = 1
+gamma = 0.8
+nb_episodes = 1000
+epsilon = 0.
+
+R = [
+    [-1, -1, -1, -1, 0, -1],
+    [-1, -1, -1, 0, -1, 100],
+    [-1, -1, -1, 0, -1, -1],
+    [-1, 0, 0, -1, 0, -1],
+    [0, -1, -1, 0, -1, 100],
+    [-1, 0, -1, -1, 0, 100],
+] 
+R = np.array(R) # Matrice des récompenses immédiates
+etat_final = 5
+
+Q = np.zeros(R.shape) # Matrice représentant la fonction action-valeur
+
+nb_etats = nb_actions = R.shape[0]
+
+# ===================== Partie 2: Apprentissage de la fonction action-valeur Q =====================
+print("Apprentissage de la fonction Q")
+for i in range(nb_episodes):
+    print("Episode : ",i)
+    s = np.random.randint(0,nb_etats)
+    print("Etat initial : ",s)
+    while True:      
+        a = choix_action(epsilon, s, R, Q)
+        print("action choisie : ", a)
+
+        Q[s,a] = calcule_q(s, a, alpha, gamma, R, Q)
+
+        if s == etat_final:
+            break
+
+        s = a
+        
+print("Matrice Q_value : ", Q)
+Q = Q / np.max(Q) * 100
+print("Matrice Q_value normalisée : ", Q)
+
+# ===================== Partie 3: Exploitation de la politique d'action apprise =====================
+
+print("Exploitation")
+
+s = 2 # choix d'un état initial
+print("Etat initial : ", s)
+
+while s != etat_final :
+    a = politique(s, Q)
+
+    s = a # nouvel état
+    print("nouvel état : ",s)