# Cour 5 -- Algorithme
###### tags `cour` `M1 S1` `Algorithme`
[Somaire](/ueYXUIJIQ6C6hcYzKYeojA#)\
[precedent](/IKMxLzyLRZ--ApSIHlh1YQ)
> [time= 5 oct 202O]
[TOC]
## Karatsuba (rapelle)
On avait:
$$
T(N) = 3T\left(\frac{N}{2}\right) + N\\
T(1) = T(0) = 1
$$
- on a **3 appelle récursif** sur une instance de taille $\frac{N}{2}$
- et **N addition**
```graphviz
Digraph G{
p0 -> {p11, p12, p13}
p11 -> {p21, p22, p23}
p21 -> pi [style=dotted, arrowhead=none]
pi -> p1 [style=dotted, arrowhead=none]
{
rank=same
p0 [label="N"]
}
{
rank=same
p11 [label="N/2"]
p12 [label="N/2"]
p13 [label="N/2"]
}
{
rank =same
p21 [label="N/2"]
p22 [label="N/2"]
p23 [label="N/2"]
}
{
rank = same
pi [label="N/2^i"]
}
{
rank = same
p1 [label="1"]
}
}
```
A chaque niveau on a $3^i$ noeud
Rapelle:
$$
\log_b(a) = \frac{\log_c(a)}{\log_c(b)}\\
2^{log_2(N)} = N\\
3^{log_2(N)} = N^{log_2(3)}
$$
On a donc:
$$
\begin{align}
T(N)&= \sum_{i=1}^{\log_2(N)} 3^i \times \left(\frac{N}{2}\right)^i \\
&= N \times \sum_{i=1}^{\log_2(N)}\left(\frac{3}{2}\right)^i\\
&= N^{log_2(3)}\\
&= N^{1,58}
\end{align}
$$
## Résolution de récurences
On a souvent lorsqu'on analyse des algos de type diviser pour régner des formules de compléxité de la forme:
$$
T(N) = \textbf{a} T\left(\frac{N}{\textbf{b}}\right) + f(N)
$$
avec
- $\textbf{a}$ etant le nombre d'apelle récurisf
- $T\left(\frac{N}{\textbf{b}}\right)$ taille des sous-instances
- $f(N)$ travail réaliser sans compter les apelles récursifs
>> ajouter graph général
Si on somme par hauteur:
$$
T(N) = \sum_{i=0}^{\log_b(N)} a^i \times f\left(\frac{N}{b^i}\right) \\
$$
On suppose aussi:
$$
T(1) = T(0) = 1
$$
:::info
Ex:
- **Tri fusion:** $T(N) = 2T\left(\frac{N}{2}\right) + N$
- *a* = 2; *b* = 2; *f(N)* = N
- **Karatsuba:** $T(N) = 3T\left(\frac{N}{2}\right) + N$
- *a* = 3; *b* = 2; *f(N)* = N
:::
### Calculons pour $f(N) = N$
Calculons pour a, b des entier quelconques et $f(N) = N$
$$
T(N) = \sum_{i=0}^{\log_b(N)} a^i \times f\left(\frac{N}{b^i}\right) \\
$$
On condière 3 sous cas:
#### cas 2: $a = b$
$$
\begin{align}
T(N) &= N \sum_{i=0}^{\log_b(N)} \left(\frac{a}{b}\right)^i \\
&= N \sum_{i=0}^{\log_b(N)} 1\\
&= N \times (\log_b(N) + 1)\\
&= O(N log(N))
\end{align}
$$
#### cas 1 et 3: $a \neq b$
$$
\begin{align}
T(N) &= N \sum_{i=0}^{\log_b(N)} \left(\frac{a}{b}\right)^i \\
&= \frac{N}{1 - \frac{a}{b}} \left(1 - \left(\frac{a}{b}\right)^{\log_b(N)}\right) \\
&= \frac{N}{1 - \frac{a}{b}} \left(1 - a^{\log_b(N)}\right) \\
&= \frac{1}{1 - \frac{a}{b}} \left(N - Na^{\log_b(N)}\right) \\
&= \frac{1}{1 - \frac{a}{b}} \left(N - N^{\log_b(a)}\right) \\
\end{align}
$$
#### cas 1: a < b
$$
\begin{align}
T(N) &= \underbrace{\frac{1}{1 - \frac{a}{b}}}_{\geq 0} \times N
- \underbrace{\frac{1}{1 - \frac{a}{b}} \times N^{\log_b(a)}}_{<<N}\\
\textbf{on conclut T(N)} & \textbf{= $O\left(N\right)$}
\end{align}
$$
#### cas 3: a > b
$$
\begin{align}
T(N) &= \underbrace{\frac{1}{1 - \frac{a}{b}} \times N}_{\approx 0}
- \underbrace{\frac{1}{1 - \frac{a}{b}} \times N^{\log_b(a)}}_{>0}\\
\textbf{on conclut T(N)} & \textbf{= $O\left(N^{\log_b(a)}\right)$}
\end{align}
$$
### Attaquons le cas plus général de f(N) quelconque
$$
\text{Soit la relation de compléxité: } \\
\begin{align}
T(N) &= a T\left(\frac{N}{b}\right) + f(N) \text{ et:}\\
cas 1: \quad & a f(\frac{N}{b}) = c f(N),
\: c < 1\\
cas 2: \quad & a f(\frac{N}{b}) = \: f(N),
\: c = 1\\
cas 3: \quad & a f(\frac{N}{b}) = c f(N),
\: c > 1\\
\end{align}
$$
- **c < 1**: le travaille décroit
- **c = 1**: le travaille est équilibré a chaque niveau
- **c > 1**: on travaille augment a chaque niveau
#### proposition:
$$
\begin{align}
\forall{a,b,c}
&\text{ Si } af\left(\frac{N}{b}\right) = cf(N)\\
&\text{ Alors } a^i f\left(\frac{N}{b^i}\right) = c^{i}f(N)
\end{align}
$$
- $a^i$ etant le nombre de noeud au niveau *i*
- $\frac{N}{b^i}$ etant le travail réliser sur chaque noeud au niveau *n*
### Preuve
Laissée au lecteur:
On a que:
$$
\begin{align}
T(N) &= \sum_{i=0}^{log_b(N)} a^i f\left(\frac{N}{b^i}\right)\\
&= \sum_{i=0}^{log_b(N)} c^i f\left(N\right) \\
&= f(N) \sum_{i=0}^{log_b(N)} c^i
\end{align}
$$
#### cas 2: c = 1
$$
\begin{align}
T(N) &= f(N)\times (\log_b(N) + 1)\\
&= \theta(f(N)\log_b(N))
\end{align}
$$
#### cas 1: c < 1
$$
\begin{align}
T(N) &= f(N) \underbrace{\sum_{i=0}^{log_b(N)} c^i}_{\text{la série converge}}\\
&= \theta(f(N))
\end{align}
$$
#### cas 3: c > 1
la série ici va divergé, dans ce cas on a que le therme qui correspond a: $i = log_b(N)$ qui domine.
\begin{align}
T(N) &= \sum_{i=0}^{log_b(N)} a^i f\left(\frac{N}{b^i}\right)\\
&= \theta\left(
a^{\log_b(N)} \times
\underbrace{f\left(\frac{N}{b^{log_b(N)}}\right)}_{f(1) = 1}
\right)\\
&= \theta\left(a^{\log_b(N)}\right)\\
&= \theta\left(N^{\log_b(a)}\right)
\end{align}
### On a montré:
#### Master théorem (version Erickson)
$$
\begin{align}
\text{Si } T(N) &= a T\left(\frac{N}{b}\right) + f(N) \text{ et:}\\
(1) \quad & \text{Si } a f\left(\frac{N}{b}\right) = c f(N), \: c < 1\\
&\text{Alors } T(N) = \Theta(f(N))\\
\\
(2) \quad & \text{Si } a f\left(\frac{N}{b}\right) = c f(N), \: c = 1\\
&\text{Alors } T(N) = \Theta(f(N) \times \log_b(N))\\
\\
(3) \quad & \text{Si } a f\left(\frac{N}{b}\right) = c f(N), \: c > 1\\
&\text{Alors } T(N) = \Theta(N^{\log_b(a)})\\
\end{align}
$$
:::info
**Tri fusion:**\
$T(N) = 2 T\left(\frac{N}{2}\right) + N$
- a = 2
- b = 2
- f(N) = N
Donc:
$T(N) = \theta(N log(N))$
**BFPRT:**\
$T(N) = T\left(\frac{N}{5}\right) + T\left(\frac{7N}{10}\right) + N$\
On peut pas appliquer le master théorem.
**Karatsuba**:\
$T(N) = 3T\left(\frac{N}{2}\right) + N$\
$a f(\frac{N}{b})= 3 \frac{N}{2} = \frac{3}{2} N$
- a = 3
- b = 2
- f(N) = N
- c > 1
Donc:
$T(N) = \theta(N^{\log_2(3)}) = N^{1,58}$
:::
## Problème réputés difficiles
Il y a des problèmes utiles pour lesquels les meilleurs algos ont une compléxité exponentiels.
## Ensemble indépendant maximum
Aussi appelé probleme du **stable maximum**.
**En Entré:**\
Un graphe G non-orienté
**En Sortie:**\
La taille du sous ensemble maximum de sommets tel que aucune paire de sommet de l'ensemble n'est arrète du graphe
```graphviz
Digraph g{
node [shape=circle]
{
rank = same;
a [label=""]
}
{
rank = same;
b [label="" style=filled]
c [label="" style=filled]
e [label=""]
}
{
rank = same;
d [label=""]
}
a -> {b, c} [arrowhead=none]
b -> {d, c} [arrowhead=none]
c -> {e} [arrowhead=none]
d -> {c} [arrowhead=none]
}
```
**pas de stable**
```graphviz
Digraph g{
node [shape=circle]
{
rank = same;
a [label="" style=filled]
}
{
rank = same;
b [label="" ]
c [label=""]
e [label=""]
}
{
rank = same;
d [label="" style=filled]
}
a -> {b, c} [arrowhead=none]
b -> {d, c} [arrowhead=none]
c -> {e} [arrowhead=none]
d -> {c} [arrowhead=none]
}
```
**stable mais pas max**
```graphviz
Digraph g{
node [shape=circle]
{
rank = same;
a [label="" style=filled]
}
{
rank = same;
b [label="" ]
c [label=""]
e [label="" style=filled]
}
{
rank = same;
d [label="" style=filled]
}
a -> {b, c} [arrowhead=none]
b -> {d, c} [arrowhead=none]
c -> {e} [arrowhead=none]
d -> {c} [arrowhead=none]
}
```
**stable de taille max**
### Algo 1
Essayer tout les sous-ensemble de sommets.\
Si G a n sommets, on va essayer 2^n^ sous-ensembles; pour chaque sous ensemble vérifier s'il forme un stable.\
Compléxité:
$O(2^n \times n^2)$
- $2^n$ sous ensemble
- $n^2$ vérifiéer si c'est un stable
### Algo 2
```python=
def EIM2(G):
if G.empty():
return 0
#prendre un sommet v
v = G.un_sommet()
# on enleve les voisins de v et ses voisin
# (stable contient v)
avec = 1 + EIM2(G.sans_voisinage(v))
# on enleve v du graph
# (v n'est pas dans le stable)
sans = EIM2(G.sans(v))
return max(avec, sans)
```
##### Compléxité
$$
T(N) \leq
\begin{cases}
0 & \text{si } N = 0\\
T(N - 1) + T(N - 1) + O(N^2)
\end{cases}
$$
- $T(N - 1)$ temps *avec v*
- $T(N - 1)$ temps *sans v*
- $O(N^2)$ temps de construction du graph
$$
\begin{align}
T(N) &\approx 2T(N-1) + N^2 \\
&\leq O\left(2^N N^2\right)
\end{align}
$$
[next](/Cy2DGQBnSUuO1akqrawPpg)