Dans mon cours d'introduction à la programmation, nous apprenons la méthode d'initialisation-maintenance-terminaison pour prouver qu'un algorithme fait ce que nous attendons de lui. Mais nous n'avons eu qu'à prouver qu'un algorithme déjà connu pour être correct est correct. On ne nous a jamais demandé de montrer qu'un algorithme n'est pas correct.
Existe-t-il des exemples classiques d'algorithmes qui semblent corrects, mais qui ne le sont pas? Je recherche des cas où l'approche Initialisation-Maintenance-Arrêt intercepte quelque chose que l'intuition à première vue ne fait pas.
ds.algorithms
proofs
Marin
la source
la source
Réponses:
Maximum local 2D
entrée: tableau bidimensionnel An × n UNE
sortie: un maximum local - une paire telle que A [ i , j ] n'a pas de cellule voisine dans le tableau qui contient une valeur strictement supérieure.( i , j ) A [ i , j ]
(Les cellules voisines sont celles parmi qui sont présentes dans le tableau.) Ainsi, par exemple, si A estA [ i , j + 1 ] , A [ i , j - 1 ] , A [ i - 1 , j ] , A [ i + 1 , j ] UNE
alors chaque cellule en gras est un maximum local. Chaque tableau non vide a au moins un maximum local.
Algorithme. Il existe un algorithme : il suffit de vérifier chaque cellule. Voici une idée pour un algorithme récursif plus rapide.O ( n2)
Étant donné , définissez la croix X pour qu'elle se compose des cellules de la colonne du milieu et des cellules de la ligne du milieu. Tout d' abord vérifier chaque cellule X pour voir si la cellule est un maximum local dans A . Si oui, renvoyez une telle cellule. Sinon, soit ( i , j ) une cellule de X avec une valeur maximale. Puisque ( i , j ) n'est pas un maximum local, il doit avoir une cellule voisine ( i ' , j ' ) de plus grande valeur.UNE X X UNE ( i , j ) X ( i , j ) ( je′, j′)
Partitionnez (le tableau A , moins les cellules de X ) en quatre quadrants - les quadrants supérieur gauche, supérieur droit, inférieur gauche et inférieur droit - de manière naturelle. La cellule voisine ( i ′ , j ′ ) de plus grande valeur doit être dans l'un de ces quadrants. Appelez ce quadrant A ′ .A ∖ X UNE X ( je′, j′) UNE′
Lemme. Quadrant contient un maximum local de A .UNE′ UNE
Preuve. Pensez à commencer par la cellule . S'il ne s'agit pas d'un maximum local, déplacez-vous vers un voisin avec une valeur plus élevée. Cela peut être répété jusqu'à arriver à une cellule qui est un maximum local. Cette cellule finale doit être en A ' , car A ' est délimité de tous côtés par des cellules dont les valeurs sont inférieures à la valeur de la cellule ( i ' , j ' ) . Cela prouve le lemme. ⋄( je′, j′) UNE′ UNE′ ( je′, j′) ⋄
L'algorithme s'appelle récursivement sur le sous-tableauA'pour y trouver un maximum local(i,j), puis renvoie cette cellule.n2× n2 UNE′ ( i , j )
Le temps d'exécution pour une matrice n × n satisfait T ( n ) = T ( n / 2 ) + O ( n ) , donc T ( n ) = O ( n ) .T( n ) n × n T( n ) = T( n / 2 ) + O ( n ) T( n ) = O ( n )
Ainsi, nous avons prouvé le théorème suivant:
Théorème. Il existe un algorithme pour trouver un maximum local dans un tableau n × n .O ( n ) n × n
Ou avons-nous?
la source