Telechargé par Loubna Karbil

tipe brahim

publicité
Algorithme au cours
de l'histoire
Sommaire

Vue historique

Introduction et position du problème

le principe de l’algorithmique.

Le principe de machine Turing.

complexité.

Les algorithmes classes P et NP.

Conclusion.
Vue historique
Introduction

Un algorithme est une procédure de résolution de
problème, s’appliquant à une famille d’instances du
problème et produisant, en un nombre fini d’étapes
consécutives, effectives, non-ambigües et organisées, la
réponse au problème pour toute instance de cette
famille.
Position du problème.

Peut-on tout écrire sous forme d’un algorithme?

Si oui, quel serait l’approche universelle?

Dans le cas d’une réponse négative, quelle
catégorie de problèmes ne s’apprête-elle pas à
« l’algorithmisabilité »?
le principe de
l’algorithmique
Problème
1
Réflexion
Analyse
2
Solution
Algorithme
3

Identification du problème

Analyse et réflexion

Plan d'action

Exemple: Résolution à l’aide de l’algorithme d’Euclide.
Algorithme
Comment fonction une
machine de Turing.
Exemple
indiquant ainsi que 27×45=1215.
Complexité

La complexité dans le meilleur des cas:

𝒎𝒊𝒏 𝒏 = 𝒄𝒐𝒖𝒕 𝒅 /𝒅 ∈ 𝑫 𝒏


𝑨
𝑨
La complexité dans le pire des cas:
𝒎𝒂𝒙 𝒏 = 𝒄𝒐𝒖𝒕 𝒅 /𝒅 ∈ 𝑫 𝒏
𝑨
𝑨
Complexité O(1)
Complexité constante ou
temps constant
Complexité O(log(n))
Complexité logarithmique.
Complexité O(n)
Complexité linéaire
Complexité O(n log(n))
Complexité n-logarithmique
Complexité O(n^2)
Complexité quadratique
Complexité O(n^3)
Complexité cubique
Complexité O(n^p)
Complexité polynomiale
 graphique représentant les différentes
courbes des fonctions utilisées dans les
complexités usuelles dans l’intervalle [0;20]

un algorithme est dit praticable, efficace s’il est
polynomial.
Classes de complexité

Parmi les classes les plus courantes, on distingue:

Classe P (polynomial)

Classe NP (Non déterministe Polynomial)
Classes de complexité
Classe P (polynomial):
un problème de décision est dans P s'il peut être décidé par
un algorithme déterministe en un temps polynomial par
rapport à la taille de l'instance.
Classes de complexité
Classe NP (Non déterministe Polynomial) :
c'est la classe des problèmes de décision pour lesquels la
réponse oui peut être décidée par un algorithme nondéterministe en un temps polynomial par rapport à la
taille de l'instance.
La classe NP


De manière intuitive, dire qu'un problème peut
être décidé à l'aide d'un algorithme nondéterministe polynomial signifie

qu'il est facile, pour une solution donnée, de vérifier
en un temps polynomial si celle-ci répond au problème
pour une instance donnée

mais que le nombre de solutions à tester pour résoudre
le problème est exponentiel par rapport à la taille de
l'instance.
Le non-déterminisme permet de masquer la taille
exponentielle des solutions à tester tout en
permettant à l'algorithme de rester polynomial.
Classes de complexité

On a trivialement P  NP,


En revanche : NP  P ?



car un algorithme déterministe est un
algorithme non déterministe particulier.
que l'on résume généralement à P = NP ?
est l'un des problèmes ouverts les plus
fondamentaux et intéressants en informatique
théorique.
1970 : le premier qui arrivera à décider si
P et NP sont différents ou égaux recevra
le prix Clay (plus de 1.000.000 $)

P = NP ??
Pourquoi c'est difficile de
prouver ? (1 sur 2)

Le problème de fond est que les algorithmes que l'on
programme sont tous déterministes.

Pour la bonne et simple raison que l'on ne sait pas
construire de machine non déterministe.

Ce qui fait que l'on ne peut que simuler un algorithme
non déterministe par un algorithme déterministe
Pourquoi c'est difficile de
prouver ? (2 sur 2)

Or il est démontré qu'un algorithme déterministe qui
simule un algorithme non-déterministe qui fonctionne
en temps polynomial, fonctionne en temps
exponentiel.

Ce qui fait que pour de grandes entrées on ne peut pas
résoudre le problème en pratique, quelle que soit la
puissance de la machine.
Relation entre P et NP
(supposé…)
 Si NP  P
NP
P
NP difficile

Un problème est NP difficile si ce problème est au
moins aussi dur que tous les problèmes dans NP.

(on utilise parfois la traduction incorrecte NP-dur)
Relation entre P,NP et NP
difficile (supposé…)
 Si NP  P
NP
P
NP difficile
NP complet
On dit qu'un problème est NP-complet si

il est dans NP

il est NP-difficile
NP complet
On dit qu'un problème est NP-complet si

il est dans NP (borne supérieure ..)

il est NP-difficile (borne inférieure ..)
Relation entre P,NP, NP
difficile, et NP complet
(supposé…)
 Si NP  P
NP
P
NP complet
NP difficile
NP complet
Propriétés :

Il n’y a pas un seul problème NP
complet où il existe une preuve qu'il
puisse fournir une réponse correcte en
temps polynomial

Si pour un problème NP complet on
trouve une réponse correcte en temps
polynomial, on peut trouver une
réponse correcte en temps polynomial
pour tous les problèmes en NP complet
Réduction
Formellement on définit une notion de réduction :
Soient p et q deux problèmes,
une réduction de q à p est un algorithme
transformant toute instance de q en une instance de
p.
 Ainsi, si l'on a un algorithme pour résoudre p, on sait
aussi résoudre q.
 p est donc au moins aussi difficile à résoudre que q.
 q est donc au plus aussi difficile à résoudre que p.

On écrit aussi q ≤ p ou bien q est réductible à p
Réduction polynomiale
Formellement on définit une notion de réduction
polynomiale
Soient p et q deux problèmes, avec le but d’utiliser la
solution de p pour résoudre q
une réduction de q à p est un algorithme en temps
polynomial transformant toute instance de q en une
instance de p.
 Ainsi, si l'on a un algorithme pour résoudre p, on sait
aussi résoudre q.

 p est donc au moins aussi difficile à résoudre que q
 q est au plus aussi difficile à résoudre que p.
On écrit aussi q ≤p p
Transitivité
La réduction polynomiale est en fait une relation transitive

Si q ≤p p et p ≤p o alors q ≤p o
« aussi dur »
La réduction polynomiale est en fait une relation transitive

Si q ≤p p, alors « q est au plus aussi difficile que p »

Si aussi p ≤p q, alors « p est au plus aussi difficile que q
»
 p et q sont « à peu près la même difficulté »
NP complet
On dit qu'un problème est NP-complet si

il est dans NP

il est NP-difficile
Prouver si un problème p
est NP complet
1.
On suppose p  NP, et on argumente
comment pour une solution sp donnée,
elle peut être vérifié en un temps
polynomial
2.
q  NP complet avec q ≤p p , et il
existe une fonction f qui transforme
une solution sq de q en solution f (sq) =
sp de p
3.
Expliquer pourquoi f est polynomial
EXEMPLE
TSP
TSP – Traveling Salesman Problem (Problème du
voyageur de commerce)
étant donné
- n sommets (des « villes »)
- et les distances séparant chaque sommet,
3 variantes
Variante 1 : Est-ce qu’il y a une chaîne de longueur
totale minimale inférieur à B ?
Variante 2 : Quel est la longueur totale minimale ?
Variante 3 : Quelle est la chaîne de longueur totale
minimale ?
TSP
Voici un énoncé plus formel du problème du voyageur
de commerce sous forme de problème de décision.
Données :
un graphe complet G = (V,E,φ) avec V un ensemble
de sommets, E un ensemble d'arêtes et φ une
matrice de distances;
 un entier B

Question :

Existe-t-il un cycle passant une et une seule fois
par chaque sommet tel que la somme des coûts des
arcs utilisés soit inférieure à B
TSP : Calcul de compléxité
Nombre de chemins candidats en fonction du nombre de villes

TSP est NP complet
Nombre de villes n
Nombre de chemins candidats
3
1
4
3
5
12
6
60
7
360
8
2 520
9
20 160
10
181 440
15
43 589 145 600
20
6,082 × 1016
71
5,989 × 1099
TSP : Algorithme
Une approche de résolution naïve, mais qui donne un résultat exact, est l'énumération de tous les chemins possibles par recherche
(𝑛−1)!
,
exhaustive. La complexité en temps de cet algorithme est en 𝑂(𝑛!) (plus exactement
ce qui devient vite impraticable
2
même pour de petites instances. Par exemple, si le calcul d'un chemin prend une microseconde, alors le calcul de tous les chemins
pour 10 points est de 181 440 microsecondes soit 0,18 seconde, mais pour 15 points, cela représente déjà
43 589 145 600 microsecondes soit un peu plus de 12 heures et pour 20 points de 6 × 10 microsecondes soit presque deux
millénaires (1 901 années). Pour 25 villes, le temps de calcul dépasse l'âge de l'Univers.
16
Held et Karp ont montré que la programmation dynamique permettait de résoudre le problème en 𝑂(𝑛2 2𝑛 )
Les méthodes d'optimisation linéaire sont à ce jour parmi les plus efficaces pour la résolution du problème de voyageur de
commerce et désormais de résoudre des problèmes de grande taille (à l'échelle d'un pays), moyennant éventuellement un temps de
calcul important.
TSP : Réflexion
%matplotlib inline
Populating the interactive namespace from numpy and
matplotlib
import random
n = 30
x = [ random.random() for _ in range(n) ]
y = [ random.random() for _ in range(n) ]
import matplotlib.pyplot as plt
plt.plot(x,y,"o")
TSP : Réflexion
plt.plot(x + [ x[0] ], y + [ y[0] ], "o-")
def longueur (x,y, ordre):
i = ordre[-1]
x0,y0 = x[i], y[i]
d = 0
for o in ordre:
x1,y1 = x[o], y[o]
d += (x0-x1)**2 + (y0-y1)**2
x0,y0 = x1,y1
return d
ordre = list(range(len(x)))
print("longueur initiale",
longueur(x,y,ordre))
def permutation(x,y,ordre):
d = longueur(x,y,ordre)
d0 = d+1
it = 1
while d < d0 :
it += 1
print("iteration",it, "d=",d)
d0 = d
for i in range(0,len(ordre)-1) :
for j in
range(i+2,len(ordre)):
r = ordre[i:j].copy()
r.reverse()
ordre2 = ordre[:i] + r +
ordre[j:]
t = longueur(x,y,ordre2)
if t < d :
d = t
ordre = ordre2
return ordre
ordre = permutation
(x,y,list(range(len(x))))
print("longueur min", longueur(x,y,ordre))
xo = [ x[o] for o in ordre + [ordre[0]]]
yo = [ y[o] for o in ordre + [ordre[0]]]
plt.plot(xo,yo, "o-")
longueur initiale 9.088214152577255
iteration 2 d= 9.088214152577255
iteration 3 d= 1.8810860903995525
iteration 4 d= 1.4267273563131075
iteration 5 d= 1.294543808915691
iteration 6 d= 0.9886582784000091
def longueur (x,y, ordre):
# on change cette fonction
d = 0
for i in range(1,len(ordre)):
n = ordre[i-1]
o = ordre[i]
x0,y0 = x[n], y[n]
x1,y1 = x[o], y[o]
d += (x0-x1)**2 + (y0-y1)**2
return d
ordre = list(range(len(x)))
print("longueur initiale", longueur(x,y,ordre))
ordre = permutation (x,y,list(range(len(x))))
print("longueur min", longueur(x,y,ordre))
xo = [ x[o] for o in ordre]
yo = [ y[o] for o in ordre]
plt.plot(xo,yo, "o-")
longueur initiale 8.224935150348868
iteration 2 d= 8.224935150348868
iteration 3 d= 1.4864813285014096
iteration 4 d= 0.8977401460581786
iteration 5 d= 0.8363214570582255
iteration 6 d= 0.8112951461233574
longueur min 0.8112951461233574
def longueur (x,y, ordre):
i = ordre[-1]
x0,y0 = x[i], y[i]
d = 0
for o in ordre:
x1,y1 = x[o], y[o]
d += (x0-x1)**2 + (y0-y1)**2
x0,y0 = x1,y1
return d
ordre = list(range(len(x)))
print("longueur initiale", longueur(x,y,ordre))
def permutation(x,y,ordre):
d = longueur(x,y,ordre)
d0 = d+1
it = 1
while d < d0 :
it += 1
print("iteration",it, "d=",d, "ordre[0]", ordre[0])
d0 = d
for i in range(1,len(ordre)-1) : # on part de 1 et plus de 0, on est sûr que le premier noeud ne bouge pas
for j in range(i+2,len(ordre)):
r = ordre[i:j].copy()
r.reverse()
ordre2 = ordre[:i] + r + ordre[j:]
t = longueur(x,y,ordre2)
if t < d :
d = t
ordre = ordre2
return ordre
ordre = permutation (x,y,list(range(len(x))))
print("longueur min", longueur(x,y,ordre))
xo = [ x[o] for o in ordre + [ordre[0]]]
yo = [ y[o] for o in ordre + [ordre[0]]]
plt.plot(xo,yo, "o-")
plt.text(xo[0],yo[0],"0",color="r",weight="bold",size="x-large")
plt.text(xo[-2],yo[-2],"N-1",color="r",weight="bold",size="x-large")
longueur initiale 9.088214152577255
iteration 2 d= 9.088214152577255 ordre[0] 0
iteration 3 d= 2.5487629282495905 ordre[0] 0
iteration 4 d= 2.0525351013235587 ordre[0] 0
iteration 5 d= 1.9682052771032004 ordre[0] 0
iteration 6 d= 1.9626694831332183 ordre[0] 0
ordre = list(range(len(x)))
print("longueur initiale", longueur(x,y,ordre))
def permutation(x,y,ordre):
d = longueur(x,y,ordre)
d0 = d+1
it = 1
while d < d0 :
it += 1
print("iteration",it, "d=",d, "ordre[0]", ordre[0])
d0 = d
for i in range(1,len(ordre)-1) : # on part de 1 et plus de 0, on est sûr que le premier noeud ne bouge pas
for j in range(i+2,len(ordre)+ 1): # correction !
r = ordre[i:j].copy()
r.reverse()
ordre2 = ordre[:i] + r + ordre[j:]
t = longueur(x,y,ordre2)
if t < d :
d = t
ordre = ordre2
return ordre
ordre = permutation (x,y,list(range(len(x))))
print("longueur min", longueur(x,y,ordre))
xo = [ x[o] for o in ordre + [ordre[0]]]
yo = [ y[o] for o in ordre + [ordre[0]]]
plt.plot(xo,yo, "o-")
plt.text(xo[0],yo[0],"0",color="r",weight="bold",size="x-large")
plt.text(xo[-2],yo[-2],"N-1",color="r",weight="bold",size="x-large")
longueur initiale 9.088214152577255
iteration 2 d= 9.088214152577255 ordre[0] 0
iteration 3 d= 2.15274032488533 ordre[0] 0
iteration 4 d= 1.5871321718676845 ordre[0] 0
iteration 5 d= 1.4761768065688674 ordre[0] 0
iteration 6 d= 1.305681395064649 ordre[0] 0
iteration 7 d= 1.1729692207112679 ordre[0] 0
iteration 8 d= 1.1696656744721234 ordre[0] 0
iteration 9 d= 1.0944778856037314 ordre[0] 0
longueur min 1.094477885603731
ordre = list(range(len(x)))
print("longueur initiale", longueur(x,y,ordre))
def permutation_rnd(x,y,ordre):
d = longueur(x,y,ordre)
d0 = d+1
it = 1
while d < d0 :
it += 1
print("iteration",it, "d=",d, "ordre[0]", ordre[0])
d0 = d
for i in range(1,len(ordre)-1) :
for j in range(i+2,len(ordre)+ 1):
k = random.randint(1,len(ordre)-1)
l = random.randint(k+1,len(ordre))
r = ordre[k:l].copy()
r.reverse()
ordre2 = ordre[:k] + r + ordre[l:]
t = longueur(x,y,ordre2)
if t < d :
d = t
ordre = ordre2
return ordre
ordre = permutation_rnd (x,y,list(range(len(x))))
print("longueur min", longueur(x,y,ordre))
xo = [ x[o] for o in ordre + [ordre[0]]]
yo = [ y[o] for o in ordre + [ordre[0]]]
plt.plot(xo,yo, "o-")
plt.text(xo[0],yo[0],"0",color="r",weight="bold",size="x-large")
plt.text(xo[-2],yo[-2],"N-1",color="r",weight="bold",size="x-large")
longueur initiale 9.088214152577255
iteration 2 d= 9.088214152577255 ordre[0] 0
iteration 3 d= 2.0752331652833953 ordre[0] 0
iteration 4 d= 1.5498126598925794 ordre[0] 0
iteration 5 d= 1.0632204732444923 ordre[0] 0
iteration 6 d= 0.9586894082016447 ordre[0] 0
longueur min 0.9586894082016447
<matplotlib.text.Text at 0x95ce3b0>
ordre = permutation_rnd (x,y,list(range(len(x))))
print("longueur min", longueur(x,y,ordre))
xo = [ x[o] for o in ordre + [ordre[0]]]
yo = [ y[o] for o in ordre + [ordre[0]]]
plt.plot(xo,yo, "o-")
plt.text(xo[0],yo[0],"0",color="r",weight="bold",size="x-large")
plt.text(xo[-2],yo[-2],"N-1",color="r",weight="bold",size="x-large")
iteration 2 d= 9.088214152577255 ordre[0] 0
iteration 3 d= 2.2142449917653977 ordre[0] 0
iteration 4 d= 1.5041710703267277 ordre[0] 0
iteration 5 d= 1.3132407450526207 ordre[0] 0
iteration 6 d= 1.172238044178559 ordre[0] 0
iteration 7 d= 1.1522114915981128 ordre[0] 0
longueur min 1.1522114915981128
<matplotlib.text.Text at 0x9b054b0>
ordre = list(range(len(x)))
print("longueur initiale", longueur(x,y,ordre))
def permutation_rnd(x,y,ordre,miniter):
d = longueur(x,y,ordre)
d0 = d+1
it = 1
while d < d0 or it < miniter :
it += 1
d0 = d
for i in range(1,len(ordre)-1) :
for j in range(i+2,len(ordre)+ 1):
k = random.randint(1,len(ordre)-1)
l = random.randint(k+1,len(ordre))
r = ordre[k:l].copy()
r.reverse()
ordre2 = ordre[:k] + r + ordre[l:]
t = longueur(x,y,ordre2)
if t < d :
d = t
ordre = ordre2
return ordre
def n_permutation(x,y, miniter):
ordre = list(range(len(x)))
bordre = ordre.copy()
d0 = longueur(x,y,ordre)
for i in range(0,20):
print("iteration",i, "d=",d0)
random.shuffle(ordre)
ordre = permutation_rnd (x,y,ordre, 20)
d = longueur(x,y,ordre)
if d < d0 :
d0 = d
bordre = ordre.copy()
return bordre
ordre = n_permutation (x,y, 20)
print("longueur min", longueur(x,y,ordre))
xo = [ x[o] for o in ordre + [ordre[0]]]
yo = [ y[o] for o in ordre + [ordre[0]]]
plt.plot(xo,yo, "o-")
plt.text(xo[0],yo[0],"0",color="r",weight="bold",size=
"x-large")
plt.text(xo[-2],yo[-2],"N1",color="r",weight="bold",size="x-large")
longueur initiale 9.088214152577255
iteration 0 d= 9.088214152577255
iteration 1 d= 0.9257857251290083
iteration 2 d= 0.9257857251290083
iteration 3 d= 0.9257857251290083
iteration 4 d= 0.9257857251290083
iteration 5 d= 0.9257857251290083
iteration 6 d= 0.9257857251290083
iteration 7 d= 0.9257857251290083
iteration 9 d= 0.9257857251290083
iteration 10 d= 0.9257857251290083
iteration 11 d= 0.9257857251290083
iteration 12 d= 0.9257857251290083
iteration 13 d= 0.9257857251290083
iteration 14 d= 0.9257857251290083
iteration 15 d= 0.890296113557742
iteration 16 d= 0.890296113557742
iteration 17 d= 0.890296113557742
iteration 18 d= 0.890296113557742
iteration 19 d= 0.890296113557742
longueur min 0.890296113557742
Réflexion

Un algorithme pour résoudre en temps polynomial le
problème du voyageur de commerce peut en faire de
même pour tout problème dans NP.

L’équivalent médical serait une maladie universelle : si
vous savez la traiter, alors vous savez aussi soigner
toutes les autres maladies !

Le problème TSP est-il le seul NP-complet ? Pas
vraiment. On en connaît des milliers.
Conclusion

Concluons sur une note psychologique cette
introduction au mystère de P et NP. Les spécialistes
misent sur leur inégalité. Pourquoi ? Il y a beaucoup de
raisons, dont aucune n’est très convaincante.
L’argument anthropomorphique rejette
l’égalité P=NP comme un affront à notre humanité. Si
prouver n’est pas plus difficile que vérifier, alors créer
une œuvre d’art n’est pas plus difficile que de
l’apprécier.
Références

[1] Muhtar, F. (2014). Abu Abdullah Ibn Musa Al-Khawarizmi (Pelopor Matematika Dalam
Islam). Beta: Jurnal Tadris Matematika, 7(2), 82-97.

[2] Karimi, A. H., Barthe, G., Schölkopf, B., & Valera, I. (2020). A survey of algorithmic
recourse: definitions, formulations, solutions, and prospects. arXiv preprint
arXiv:2010.04050.

[3] Berry G., Penser, modéliser, et maîtriser le calcul informatique, Collège de
France / Fayard, coll. « Leçons inaugurales », no 208, 2009.

[4] Knuth, D. E. (1973). The Art of Computer Programming, Volume I : Fundamental
Algorithms (2e éd.). Addison-Wesley

[5] Copeland, B. J., & Sylvan, R. (1999). Beyond the universal Turing
machine. Australasian Journal of Philosophy, 77(1), 46-66.

[6] Copeland, B. J. (1997). The church-turing thesis.

[7] https://www.inria.fr/fr/quest-ce-quun-algorithme

[8] Arora S. et Barak B., Computational Complexity: A Modern Approach, Cambridge
University Press, 2009.

[9] Deutsch, D. (1985). Quantum theory, the Church–Turing principle and the universal
quantum computer. Proceedings of the Royal Society of London. A. Mathematical and
Physical Sciences, 400(1818), 97-117.
Merci pour votre attention
Téléchargement