Taglio delle aste
Nel problema del taglio delle aste si vuole cercare il massimo guadagno ottenibile dalla vendita di pezzi ricavati dal taglio di un'asta lunga , i cui prezzi dipendono dalla lunghezza venduta.
Per esempio se e conviene tagliare l'asta in pezzi da o invece che perchè si guadagna invece che .
Sottostruttura ottima
Un'asta lunga può essere tagliata o meno in ogni posizione , totalizzando tagli e quindi portando la complessità a .
Il ricavo per l'asta sarà quindi definito ricorsivamente come: dove è il ricavo della prima parte non tagliata ulteriormente e è il maggior ricavo sul resto dell'asta.
Per il problema si dice che valga la proprietà di sottostruttura ottima perchè la soluzione ottima cercata, in questo caso , è esprimibile da combinazioni di soluzione ottime di sottoproblemi.
Ricorsione
L'algoritmo che se ne ricava
cut_rod(p, n)
if n == 0
return 0
else
q = -1
for i = 1 to n
q = max(q, p[i] + cut_rod(p, n-i))
return q
avrà complessità: che diventa per induzione su :
- Caso base, per :
- Passo induttivo assumendo che :
Top-down
cut_rod(p, n)
r = {}
for i = 0 to n
r[i] = -1
return cut_rod_aux(p, n, r)
cut_rod_aux(p, j, r)
if r[j] < 0
if j == 0
r[j] = 0
else
q = -1
for i = 1 to j
q = max(q, p[i] + cut_rod_aux(p, j - i, r))
r[j] = q
return r[j]
La complessità si può ricavare come:
perchè al diminuire di j
i valori r[j-i]
sono già stati calcolati.
Bottom-up
cut_rod(p, n)
r = {}
r[0] = 0
for j = 1 to n
q = -1
for i = 1 to j
q = max(q, p[i] + r[j - i])
r[j] = q
return r[n]
La complessità sarà anche in questo caso .
Volendo si può modificare per salvare la posizione del primo taglio da fare su un'asta lunga :
cut_rod(p, n)
r = {}
r[0] = 0
for j = 1 to n
q = -1
for i = 1 to j
if p[i] + r[j - i] > q
q = p[i] + r[j - i]
s[j] = i
r[j] = q
return r, s
print_cut_rod(p, n)
r, s = cut_rod(p, n)
while n > 0
print(s[n])
n = n - s[n]