Coût amorti Denis TRYSTRAM Notes de cours ALGO – ENSIMAG 1A – février 2013 Coût amorti Motivation. Le contexte ici est un peu différent d’auparavant. On considère une série d’opérations effectuées sur une structure de données. Certaines opérations sont plus coûteuses que d’autres, mais elles sont rares et ainsi, leur impact global reste faible. Définition. Le temps pour exécuter une séquence de n opérations sur une structure de données est moyenné sur l’ensemble de la structure : Tamorti = Pn i=1 T (i) (où i désigne l’opération courante). n Exemple. Gestion d’un pile d’objets (LIFO). Ici, on distingue les opérations standard d’empilement (pop-in), de dépilement (pop-out) et le dépilement d’un groupe de k objets d’un seul coup. Si on fait une analyse classique de coût, au pire l’opération de dépilement multiple peut coûter n s’il y a n objets sur la pile. Cette situation n’est possible que si l’on a fait avant n opérations peu coûteuses d’empilements... L’analyse amortie diffère d’une analyse en moyenne au sens où on n’utilise pas de probabilités. L’idée est d’examiner sur une moyenne d’opérations avec une analyse plus fine en pire cas sur plusieurs opérations consécutives. On distingue essentiellement deux types de méthodes : la méthode des agrégats et la méthode de comptage (avec sa variante du potentiel). • Agrégats. ∀n, une séquence de n opérations consécutives prend au pire un total de T (n) au total, le coût amorti par opération est Tamorti = T (n) n . • Analyses comptables. Contrairement aux agrégat, cette méthode s’intéresse à chaque opération locale. On peut penser à une analogie économique où l’on va réserver un crédit à chaque opération peu coûteuse pour l’utiliser plus tard pour les opérations coûteuses. On note cci le coût amorti de l’opération i et ci son coût réel. Ce crédit peut être calculé directement par une fonction adéquate ou par une fonction potentielle. Si Di est la structure de données après la i-ème opération et Φi : Di → R la fonction potentielle, le coût amorti de l’opération i est obtenu par l’expression suivante cci = ci +Φi −Φi−1 . Ainsi, P sur l’ensemble des opérations = n1 ci + Φn − Φ0 . Pn i=1 cci = Pn 1 (ci + Φi − Φi−1 ) Si le potentiel choisi vérifie Φn ≥ Φ0 alors le coût amorti global est une borne supérieure du coût réel total. Pn i=1 cci Sur l’exemple de la pile, on obtient un coût amorti en O(1) en utilisant la méthode de l’agrégat avec l’argument global qu’il y a dépilement possible que si l’on a fait auparavant un empilement. On retrouve le même résultat par la seconde méthode en prenant un potentiel Φi égal au nombre d’éléments présents sur la pile à l’étape i, ce qui correspond à un coût amorti au pire égal à 2 à chaque étape (si l’opération est un empilement), et par conséquent au pire 2n n sur l’ensemble des opérations. Exercice : Coût amorti d’un tableau dynamique The problem is to implement a table that can resize itself when an insertion arises and the table is full. A common heuristic is to allocate a new table with a size doubled. If only insertions are performed, the load factor of a table is always at least 1/2, and thus the amount of wasted space never exceeds half the total space. In the following pseudo-code, we assume that T is an object representing the table. The field table[T ] contains a pointer to the block of storage representing the table. The field num[T ] contains the number of items in the table, and the field size[T ] is the total number of slots in the table. Initially, the table is empty: num[T ] = size[T ] = 0. Algorithm 1: Table Insert Input: The table T and the element to be inserted x Result: T ← T ∪ x 1 if size[T ] = 0 then 2 allocate table[T ] of size 1 3 size[T ] ← 1 4 end 5 if num[T ] = size[T ] then 6 allocate newtable of size 2 × size[T ] 7 insert all items in table[T ] into newtable 8 free table[T ] 9 table[T ] ← newtable 10 size[T ] ← 2 × size[T ] 11 end 12 insert x into table[T ] 13 num[T ] ← num[T ] + 1 2