En aquesta secció, treballarem en diversos exercicis pràctics per aplicar les tècniques d'optimització d'algorismes que hem après fins ara. Aquests exercicis estan dissenyats per ajudar-te a identificar colls d'ampolla en el codi, millorar l'eficiència temporal i espacial, i aplicar tècniques de paral·lelització quan sigui possible.
Exercici 1: Optimització de Codi
Descripció
Tens un algorisme que calcula la suma de tots els nombres parells en una llista. Actualment, el codi és el següent:
def suma_parells(llista): suma = 0 for i in range(len(llista)): if llista[i] % 2 == 0: suma += llista[i] return suma
Tasques
- Identifica les possibles millores en termes de claredat i eficiència.
- Reescriu el codi per fer-lo més eficient.
Solució
-
Identificació de Millores:
- Utilitzar un bucle
for
directe sobre els elements de la llista en lloc d'indexar ambrange(len(llista))
. - Utilitzar una comprensió de llistes per fer el codi més concís i possiblement més ràpid.
- Utilitzar un bucle
-
Codi Optimitzat:
def suma_parells(llista): return sum([x for x in llista if x % 2 == 0])
Explicació
- La comprensió de llistes
[x for x in llista if x % 2 == 0]
crea una nova llista només amb els elements parells. - La funció
sum()
suma tots els elements de la llista resultant.
Exercici 2: Ús Eficient de Memòria
Descripció
Tens una funció que genera una llista de nombres quadrats fins a un nombre n
. El codi actual és el següent:
Tasques
- Identifica les possibles millores en termes d'ús de memòria.
- Reescriu el codi per fer-lo més eficient en termes de memòria.
Solució
-
Identificació de Millores:
- Utilitzar un generador en lloc d'una llista per reduir l'ús de memòria.
-
Codi Optimitzat:
def quadrats(n): return (i * i for i in range(n))
Explicació
- Utilitzar un generador
(i * i for i in range(n))
en lloc d'una llista permet generar els quadrats sobre la marxa, reduint l'ús de memòria.
Exercici 3: Paral·lelització d'Algorismes
Descripció
Tens una funció que calcula la suma de les potències de 2 fins a un nombre n
. El codi actual és el següent:
Tasques
- Identifica les possibles millores en termes de paral·lelització.
- Reescriu el codi per fer-lo més eficient utilitzant paral·lelització.
Solució
-
Identificació de Millores:
- Utilitzar la biblioteca
multiprocessing
per paral·lelitzar el càlcul de les potències.
- Utilitzar la biblioteca
-
Codi Optimitzat:
from multiprocessing import Pool def potencies(i): return 2 ** i def suma_potencies(n): with Pool() as pool: result = pool.map(potencies, range(n)) return sum(result)
Explicació
- La funció
potencies(i)
calcula la potència de 2 per a un valori
. - Utilitzem
Pool
de la bibliotecamultiprocessing
per paral·lelitzar el càlcul de les potències. pool.map(potencies, range(n))
distribueix el càlcul de les potències entre múltiples processos.- Finalment, sumem els resultats amb
sum(result)
.
Resum
En aquesta secció, hem treballat en diversos exercicis per optimitzar el codi en termes de claredat, eficiència temporal i espacial, i paral·lelització. Hem après a identificar colls d'ampolla i aplicar tècniques d'optimització per millorar el rendiment del nostre codi. Aquests exercicis són fonamentals per desenvolupar habilitats en l'anàlisi i disseny d'algorismes eficients.
Curs d'Anàlisi i Disseny d'Algorismes
Mòdul 1: Introducció als Algorismes
Mòdul 2: Anàlisi d'Algorismes
- Anàlisi de Complexitat Temporal
- Anàlisi de Complexitat Espacial
- Cases de Complexitat: Millor, Pitjor i Promig
Mòdul 3: Estratègies de Disseny d'Algorismes
Mòdul 4: Algorismes Clàssics
- Cerca Binària
- Ordenació per Inserció
- Ordenació per Mescla (Merge Sort)
- Ordenació Ràpida (Quick Sort)
- Algorisme de Dijkstra
- Algorisme de Floyd-Warshall