Pas aan — welke items neem je mee?
Leerdoel: je breidt knapsack uit zodat hij niet alleen de beste totaalwaarde teruggeeft, maar ook welke items je daarvoor meeneemt, door de tabel terug te lopen zoals je bij vul de tabel in met de hand deed.
Wat we willen
Tot nu toe weet je: de beste waarde is 40. Maar welke items zijn dat?
Antwoord: een lijst van indexen die je meeneemt. Voor het voorbeeld
van de les → [2, 3] (Python-indexen voor item 3 en 4).
Het idee — backtrack door de tabel
Bij vul de tabel in leerde je: begin in cel (n, W) en loop naar boven.
Voor elke rij i:
- Als
tabel[i][w] == tabel[i-1][w]→ itemiwas niet nodig (skip wint). Ga naar(i-1, w). - Anders → item
iwas wel meegenomen. Ga naar(i-1, w - gewicht_i).
In Python is dat één for-loop van groot naar klein.
Specificatie
- Input:
items,capaciteit. - Output: een lijst van Python-indexen van de meegenomen items.
Opdracht
Code-omgeving wordt voorbereid…
Tip
Achteruit lopen doe je met range(n, 0, -1): dat geeft n, n-1, …, 1.
Drie dingen om op te letten:
iis de rij in de tabel (vanaf 1),i - 1de index initems.- Vergelijk
tabel[i][w]met de cel erboven,tabel[i - 1][w]. - Vergeet
w -= ...niet als het item is meegenomen — anders blijf je in dezelfde kolom hangen en raakt de backtrack van slag.
Antwoord
def knapsack_items(items, capaciteit):
n = len(items)
tabel = knapsack_tabel(items, capaciteit)
keuze = []
w = capaciteit
for i in range(n, 0, -1): # van n omlaag naar 1
if tabel[i][w] != tabel[i - 1][w]: # item i was meegenomen
keuze.append(i - 1) # 0-gebaseerde index
w -= items[i - 1][1] # capaciteit verminderen
return keuze
Print de keuze
Code-omgeving wordt voorbereid…
Verwachte uitvoer
Indexen (Python): [2, 3]
Items (mens-nummering): [3, 4]
Totale waarde: 40
Totaal gewicht: 11 (van 11 toegestaan)
Details per item:
item 3: waarde=18, gewicht=5
item 4: waarde=22, gewicht=6
Dezelfde items als met de hand. De backtrack in Python doet precies wat jij op papier deed.
Door naar bouw zelf →.