Class Hub
Dynamic programming·Διάλεξη 15·~36 min

L15 · Δυναμικός Προγραμματισμός II — Σακίδιο & Μέγιστη Κοινή Υπακολουθία

Τι θα δούμε

Δύο κλασικά DP προβλήματα — και ένα νέο δίδαγμα. Στο L14 τα υποπροβλήματα παραμετροποιήθηκαν με μία μεταβλητή ( = «τα πρώτα αιτήματα»). Εδώ θα δούμε ότι αυτό δεν αρκεί πάντα: το πρόβλημα του σακιδίου χρειάζεται δύο μεταβλητές. Μετά, η μέγιστη κοινή υπακολουθία δείχνει DP πάνω σε δύο συμβολοσειρές.

Το πρόβλημα του σακιδίου (knapsack)

Διατύπωση

Είσοδος: αντικείμενα και ένα «σακίδιο». Το αντικείμενο έχει βάρος και αξία . Το σακίδιο αντέχει το πολύ κιλά.

Στόχος: διάλεξε υποσύνολο αντικειμένων που χωράει () και μεγιστοποιεί τη συνολική αξία.

Ο άπληστος δεν αρκεί

Ο λόγος απαντά στο «πόσο καλό είναι ένα αντικείμενο μόνο του». Αγνοεί όμως ότι το σακίδιο έχει πεπερασμένο χώρο και ότι ο στόχος είναι ο καλύτερος συνδυασμός. Ο άπληστος γεμίζει το σακίδιο με μικρά αντικείμενα καλού λόγου και μετά κολλάει με ένα κενό που κανένα μεγαλύτερο αντικείμενο δεν χωράει να καλύψει. Δες το να συμβαίνει βήμα-βήμα:

Ο άπληστος «καλύτερος λόγος» στο σακίδιο
Χωρητικότητα W = 8
Αντικείμενο 1
β2 · α3 · λόγος 1.50
Αντικείμενο 2
β3 · α4 · λόγος 1.33
Αντικείμενο 3
β4 · α5 · λόγος 1.25
Αντικείμενο 4
β5 · α6 · λόγος 1.20
Το σακίδιο του άπληστουγεμάτο: 0 / 8 κιλά
άδειο
Άπληστος
0
Βέλτιστο
·
Ο πιο φυσικός άπληστος κανόνας: ταξινόμησε τα αντικείμενα κατά λόγο αξίας/βάρους και πάρε καθένα που χωράει ακόμα. Πάτα «Επόμενο» και δες πού καταλήγει.
Βήμα 0 / 5

Πρώτη απόπειρα — και γιατί αποτυγχάνει

Στο L14 κάθε DP πρόβλημα λύθηκε με μία παράμετρο. Ας δοκιμάσουμε το ίδιο: ορίζουμε = η μέγιστη αξία που πετυχαίνουμε χρησιμοποιώντας μόνο τα αντικείμενα . Όπως πάντα, κοιτάμε το τελευταίο αντικείμενο — μέσα ή έξω;

  • Το ΕΞΩ: μένει το ίδιο πρόβλημα με ένα αντικείμενο λιγότερο → .
  • Το ΜΕΣΑ: κερδίζουμε αξία … αλλά το καταναλώνει κιλά χώρου. Και εδώ η αναδρομή κολλάει: για να πούμε αν το χωράει καν, πρέπει να ξέρουμε πόσος χώρος έχει ήδη ξοδευτεί — κι αυτό η δεν μας το λέει.

Το πρόβλημα είναι βαθύτερο από «μια λεπτομέρεια που λείπει». Σκέψου τι σημαίνει ένας αριθμός : «η καλύτερη αξία με τα πρώτα αντικείμενα». Όμως το καλύτερο prefix για το μέλλον δεν είναι αυτό με τη μεγαλύτερη αξία τώρα — είναι αυτό που αφήνει αρκετό χώρο για ό,τι ακολουθεί. Δύο διαφορετικές επιλογές στα ίδια αντικείμενα μπορεί να έχουν διαφορετική αξία και διαφορετικό ελεύθερο χώρο· ένας μόνο αριθμός δεν χωράει να κρατήσει και τα δύο. Παίξε με τις δύο στήλες:

Γιατί μία μεταβλητή δεν αρκεί

Διάλεξε τα αντικείμενα 1–3 σε κάθε σενάριο. Μένει το αντικείμενο 4 (βάρος 5, αξία 6). Ερώτηση: ποιο prefix οδηγεί στην καλύτερη τελική λύση;

Σενάριο Α
1
6 ελεύθερα
Χωράει το αντικείμενο 4; (βάρος 5)
αντ. 4
Αξία τώρα3
Ελεύθερος χώρος6
Αντικείμενο 4χωράει +6
Τελική αξία9
Σενάριο Β
1
2
3 ελεύθερα
Χωράει το αντικείμενο 4; (βάρος 5)
αντ. 4
Αξία τώρα7
Ελεύθερος χώρος3
Αντικείμενο 4δεν χωράει +0
Τελική αξία7
Παγίδα! Το Σενάριο Β έχει μεγαλύτερη αξία ΤΩΡΑ (7), αλλά μικρότερη ΤΕΛΙΚΗ αξία — γέμισε το σακίδιο και δεν χώρεσε το αντικείμενο 4. Μια OPT(3) ως ένας αριθμός θα κρατούσε τη μεγαλύτερη-τώρα (7) και θα έχανε την καλύτερη λύση (9). Η αξία ενός prefix εξαρτάται από τον ελεύθερο χώρο — γι’ αυτό χρειάζεται δεύτερη μεταβλητή: OPT(i, w).

Η σωστή αναδρομή — δύο μεταβλητές

Σκεφτόμαστε ξανά το αντικείμενο :

  • Το ΕΞΩ: η καλύτερη λύση από τα με την ίδια χωρητικότητα → .
  • Το ΜΕΣΑ (μόνο αν ): «ξοδεύουμε» χώρο και κερδίζουμε αξία, και λύνουμε το υπόλοιπο με χωρητικότητα .
OPT(i−1,w−wᵢ)OPT(i−1,w)OPT(i,w)Κάθε κελί κοιτάει μόνο την προηγούμενη γραμμή:«πάνω» (i έξω) και «πάνω-αριστερά κατά wᵢ» (i μέσα).

Ο αλγόριθμος

Αλγόριθμος0/1 Σακίδιο (knapsack)
Θ(n·W)
Γέμισε έναν πίνακα n × W· κάθε κελί είναι το max ανάμεσα στο «αντικείμενο i έξω» και στο «i μέσα».
Είσοδος:
n αντικείμενα με βάρη/αξίες, και χωρητικότητα W
Έξοδος:
η μέγιστη συνολική αξία ενός υποσυνόλου που χωράει στο σακίδιο

Με λόγια. Φτιάχνουμε έναν πίνακα με γραμμές (αντικείμενα ) και στήλες (χωρητικότητες ). Η γραμμή είναι όλο μηδενικά. Κάθε επόμενη γραμμή υπολογίζεται από την προηγούμενη: αν το αντικείμενο δεν χωράει, αντιγράφουμε το κελί από πάνω· αλλιώς παίρνουμε το μεγαλύτερο ανάμεσα στο « έξω» και στο « μέσα».

Δες τον πίνακα να γεμίζει γραμμή-γραμμή. Σε κάθε γραμμή φωτίζεται το κελί και τα δύο κελιά της προηγούμενης γραμμής από τα οποία εξαρτάται:

Σακίδιο — γέμισμα του πίνακα M, γραμμή-γραμμή
Χωρητικότητα W = 8

Αντικείμενα (βάρος, αξία): 1:(2,3) · 2:(3,4) · 3:(4,5) · 4:(5,6)

i \ w
0
1
2
3
4
5
6
7
8
0 · ∅
0
0
0
0
0
0
0
0
0
1 · (2,3)
·
·
·
·
·
·
·
·
·
2 · (3,4)
·
·
·
·
·
·
·
·
·
3 · (4,5)
·
·
·
·
·
·
·
·
·
4 · (5,6)
·
·
·
·
·
·
·
·
·
Η γραμμή 0 — μηδέν αντικείμενα — είναι όλο μηδενικά. Κάθε επόμενη γραμμή προσθέτει ένα αντικείμενο. Πάτα «Επόμενο».
Γραμμή 0 / 4

Πολυπλοκότητα — μια λεπτή παγίδα

Ο αλγόριθμος γεμίζει έναν πίνακα , ένα κελί τη φορά, άρα τρέχει σε . Δεν έχει εκθέτες, δεν έχει μοιάζει πολυωνυμικός. Δεν είναι.

Το δεν είναι «πλήθος αντικειμένων»· είναι ένας αριθμός που δίνεται στην είσοδο. Κι έναν αριθμό τιμής τον γράφεις με μόλις δυφία. Άρα το πραγματικό μέγεθος της εισόδου μεγαλώνει σαν , ενώ ο χρόνος μεγαλώνει σαν — δηλαδή σαν . Αυτό είναι εκθετικό ως προς το μέγεθος της εισόδου. Δοκίμασε να διπλασιάσεις το και μέτρα:

Ο χρόνος n·W — πολυωνυμικός ή όχι;
n = 4 αντικείμενα

Κάθε διπλασιασμός του W προσθέτει ένα δυφίο στην είσοδο — αλλά διπλασιάζει τον χρόνο n·W. Δες το χάσμα.

Τιμή W
8
Δυφία (μέγεθος)
4
Χρόνος n·W
32
WΔυφία εισόδουΧρόνος εκτέλεσης
W = 832
Είσοδος
44 δυφία (+0)
Χρόνος
3232 1)
Πάτα «×2 το W» και παρακολούθησε δύο πράγματα: τα μπλε δυφία της εισόδου και την κόκκινη μπάρα του χρόνου.
0 διπλασιασμοί
Κάρτα μνήμης0/1 Σακίδιο
Λέξεις-κλειδιά
δύο μεταβλητές: OPT(i, w)i μέσα ή έξωαν μέσα: −wᵢ χωρητικότηταπίνακας n × Wψευδοπολυωνυμικό
Τα βήματα στο μυαλό σου
1OPT(i, w) = μέγιστη αξία με αντικείμενα 1..i και χωρητικότητα w.
2Αν wᵢ > w → το i δεν χωράει: OPT(i,w) = OPT(i−1, w).
3Αλλιώς: OPT(i,w) = max{ OPT(i−1,w), vᵢ + OPT(i−1, w−wᵢ) }.
4Γέμισε τον πίνακα n × W· πέρασμα προς τα πίσω για τα ίδια τα αντικείμενα.
Πολυπλοκότητα
Θ(n·W) — ψευδοπολυωνυμικό
Κλασική παγίδα
Μία μεταβλητή (OPT(i)) ΔΕΝ αρκεί — πρέπει να θυμάσαι και την εναπομείνασα χωρητικότητα. Ο χρόνος Θ(n·W) φαίνεται πολυωνυμικός αλλά είναι εκθετικός ως προς το μέγεθος εισόδου (το W γράφεται με log W δυφία) — το πρόβλημα είναι NP-πλήρες.

Μέγιστη κοινή υπακολουθία (LCS)

Διατύπωση

Είσοδος: δύο συμβολοσειρές και .

Στόχος: το μέγιστο μήκος μιας ακολουθίας που είναι ταυτόχρονα υπακολουθία και των δύο.

Η διάκριση είναι λεπτή κι αξίζει να την «πιάσεις» πριν προχωρήσουμε — πάτησε γράμματα και δες:

Υπακολουθία ή υποσυμβολοσειρά;

Πάτησε γράμματα για να τα κρατήσεις. Δες τι μένει υπακολουθία και τι υποσυμβολοσειρά.

Επιλογή: BCAB
Υπακολουθίαδιατηρεί τη σειρά
Υποσυμβολοσειράπρέπει να είναι συνεχόμενη
Ανάμεσα στα κρατημένα υπάρχουν γράμματα που πέταξες (κόκκινα). Αυτό το «κενό» κάνει την επιλογή υπακολουθία αλλά ΟΧΙ υποσυμβολοσειρά: η υποσυμβολοσειρά πρέπει να είναι συνεχόμενη.

Η αναδρομή

Ίδιο μοτίβο με το L14 — αλλά τώρα έχουμε δύο ακολουθίες, άρα φυσικά δύο παραμέτρους. Ορίζουμε = το μέγιστο μήκος κοινής υπακολουθίας των προθεμάτων και . Για να σπάσουμε το πρόβλημα, κοιτάμε τους τελευταίους χαρακτήρες, και :

  • . Έχουμε δύο ίδια γράμματα στις δύο άκρες — κι ένα ζευγάρι ίδιων γραμμάτων είναι «δωρεάν» μήκος για την κοινή υπακολουθία. Δεν χάνεις ποτέ τίποτα αν τα ζευγαρώσεις: υπάρχει πάντα μια βέλτιστη λύση που τα χρησιμοποιεί ως τελευταίο της στοιχείο. Άρα κερδίζουμε , και μένει η LCS των και .
  • . Δύο διαφορετικά γράμματα δεν γίνεται να είναι και τα δύο το τελευταίο στοιχείο μιας κοινής υπακολουθίας — άρα τουλάχιστον το ένα δεν χρησιμοποιείται. Πετάμε είτε το (μένει LCS των και ) είτε το (μένει LCS των και ). Δεν ξέρουμε ποιο — τα δοκιμάζουμε και τα δύο και κρατάμε το .
OPT(i−1,j−1)OPT(i−1,j)OPT(i,j−1)OPT(i,j)πράσινο: διαγώνια, αν xᵢ = yⱼμπλε: πάνω / αριστερά, αν xᵢ ≠ yⱼ

Ο αλγόριθμος

ΑλγόριθμοςΜέγιστη κοινή υπακολουθία (LCS)
Θ(mn)
Γέμισε έναν πίνακα m × n· κάθε κελί κοιτάει διαγώνια (αν οι χαρακτήρες ταιριάζουν) ή το max από πάνω/αριστερά.
Είσοδος:
δύο συμβολοσειρές x (μήκος m) και y (μήκος n)
Έξοδος:
το μήκος της μέγιστης κοινής υπακολουθίας τους

Με λόγια. Πίνακας με γραμμές και στήλες· η γραμμή 0 και η στήλη 0 είναι μηδενικά (κενό προθέμα). Για κάθε κελί : αν , παίρνουμε το διαγώνιο κελί συν ένα· αλλιώς, το μεγαλύτερο ανάμεσα στο κελί «από πάνω» και σ' αυτό «από αριστερά».

Παράδειγμα. Δες τον πίνακα να γεμίζει γραμμή-γραμμή για και , και μετά το πέρασμα προς τα πίσω να ανακτά την ίδια την υπακολουθία:

LCS — γέμισμα του πίνακα και πέρασμα προς τα πίσω
x=ABCB · y=BDCAB

Πράσινο κελί = τα γράμματα ταιριάζουν (διαγώνιο +1)· αλλιώς, το max από «πάνω»/«αριστερά».

B
D
C
A
B
0
0
0
0
0
0
A
0
·
·
·
·
·
B
0
·
·
·
·
·
C
0
·
·
·
·
·
B
0
·
·
·
·
·
Η γραμμή 0 και η στήλη 0 είναι το «κενό προθέμα»: μήκος κοινής υπακολουθίας 0. Πάτα «Επόμενο».
Βήμα 0 / 10

Ο πίνακας έχει κελιά, κάθε ένα υπολογίζεται σε πολυπλοκότητα . Το κάτω-δεξιά κελί δίνει το μήκος· το πέρασμα προς τα πίσω από εκεί δίνει μια συγκεκριμένη μέγιστη κοινή υπακολουθία (εδώ, το BCB).

Κάρτα μνήμηςΜέγιστη κοινή υπακολουθία (LCS)
Λέξεις-κλειδιά
DP σε δύο συμβολοσειρέςOPT(i, j) στα προθέματαxᵢ = yⱼ → διαγώνια + 1xᵢ ≠ yⱼ → max πάνω/αριστεράΘ(mn)
Τα βήματα στο μυαλό σου
1OPT(i, j) = μήκος LCS των προθεμάτων x₁..xᵢ και y₁..yⱼ.
2Αν xᵢ = yⱼ: ζευγάρωσέ τους → 1 + OPT(i−1, j−1) (διαγώνια).
3Αν xᵢ ≠ yⱼ: ένας περισσεύει → max{ OPT(i−1, j), OPT(i, j−1) }.
4Γέμισε τον πίνακα m × n· το OPT(m, n) είναι η απάντηση.
Πολυπλοκότητα
Θ(mn)
Κλασική παγίδα
Υπακολουθία ≠ υποσυμβολοσειρά — δεν χρειάζεται να είναι συνεχόμενη. Όταν xᵢ ≠ yⱼ ΔΕΝ παίρνεις το διαγώνιο κελί· παίρνεις το max από «πάνω» και «αριστερά».

Κλείδωσε τη γνώση

Βάλε στη σειρά τα βήματα του DP για το σακίδιο:

Βάλε τα βήματα στη σειρά
Ο αλγόριθμος DP για το πρόβλημα του σακιδίου, από την πρώτη ενέργεια στην τελευταία.
Σύρε τις γραμμές για αναδιάταξη — ή χρησιμοποίησε τα βελάκια.
1.Για κάθε αντικείμενο i και χωρητικότητα w, αν το i δεν χωράει (wᵢ > w), αντέγραψε το κελί από πάνω.
2.Γέμισε τη γραμμή 0 με μηδενικά — κανένα αντικείμενο, καμία αξία.
3.Όρισε OPT(i, w) = μέγιστη αξία με αντικείμενα 1..i και χωρητικότητα w.
4.Η βέλτιστη αξία είναι το κελί M[n, W].
5.Κάνε πέρασμα προς τα πίσω για να βρεις ποια αντικείμενα επιλέχθηκαν.
6.Αλλιώς, πάρε το max ανάμεσα στο «i έξω» και στο «i μέσα».

Και συμπλήρωσε τα κενά:

Συμπλήρωσε τα κενά
Σακίδιο και LCS σε τέσσερις λέξεις-κλειδιά.
Στο πρόβλημα του σακιδίου, μία μεταβλητή δεν αρκεί για να περιγράψει ένα υποπρόβλημα — χρειάζεται και η εναπομείνασα . Έτσι ο πίνακας γίνεται , μεγέθους n × W, και ο χρόνος Θ(n·W) λέγεται . Στη μέγιστη κοινή υπακολουθία, όταν xᵢ = yⱼ παίρνουμε το κελί συν ένα.

Μοτίβο σκέψης

Τι μάθαμε

Τι κρατάμε από αυτή τη διάλεξη

  1. Σακίδιο (0/1 knapsack) — μέγιστη αξία αντικειμένων που χωράνε σε χωρητικότητα . Ο άπληστος (λόγος ) αποτυγχάνει.
  2. Η μονοδιάστατη παραμετροποίηση δεν αρκεί — χρειάζεται δεύτερη μεταβλητή: .
  3. Αναδρομή: . Χρόνος ψευδοπολυωνυμικός· το πρόβλημα απόφασης είναι NP-πλήρες.
  4. Μέγιστη κοινή υπακολουθία (LCS) — μέγιστο μήκος κοινής (όχι κατ' ανάγκη συνεχόμενης) υπακολουθίας δύο συμβολοσειρών.
  5. Αναδρομή: αν → διαγώνια · αλλιώς → από «πάνω» και «αριστερά». Χρόνος .
Επόμενο
L16 · DP III — LCS, edit distance

Ασκήσεις από εξετάσεις

Από τη θεωρία στην εξεταστική

4 άσκησεις που χρησιμοποιούν ως τελευταίο εργαλείο αυτή τη διάλεξη. Οι πρόσφατες εξεταστικές (2024/2025) φέρουν badge προτεραιότητας.

Παλαιό θέμαΣεπτέμβριος 2025Θέμα Εξετάσεων 2025Θέμα 1.83%Δυναμικός προγραμματισμόςΜέτριο

Σεπτέμβριος 2025 · Θέμα 1.8 — Φράγματα πολυπλοκότητας της LCS

Ποια από τα παρακάτω αποτελούν ορθά φράγματα στην πολυπλοκότητα της εύρεσης της μέγιστης κοινής υπακολουθίας δύο συμβολοσειρών με και χαρακτήρες;

(i) · (ii) · (iii) · (iv) .

Παλαιό θέμαΣεπτέμβριος 2025Θέμα Εξετάσεων 2025Θέμα 320%Δυναμικός προγραμματισμόςΔύσκολο

Σεπτέμβριος 2025 · Θέμα 3 — Όνομα σκύλου (συντομότερη κοινή υπερακολουθία)

Ένα ζευγάρι με ονόματα και θέλει να ονομάσει τον σκύλο του με ένα όνομα που να περιέχει και τα δύο ονόματά τους ως υπακολουθίες, και να είναι το συντομότερο δυνατό. Π.χ. για ΓΑΒ και ΜΙΑΟΥ, το ΜΙΓΑΒΟΥ ή το ΓΜΙΑΟΥΒ είναι έγκυρα, αλλά όχι το ΓΑΒΜΙΑΟΥ (πολύ μακρύ). Σχεδίασε αλγόριθμο Δυναμικού Προγραμματισμού που βρίσκει το βέλτιστο μήκος για συμβολοσειρές μηκών .

Ορίζουμε = το μήκος της συντομότερης συμβολοσειράς που περιέχει ως υπακολουθίες τα πρώτα στοιχεία της και τα πρώτα στοιχεία της .

(i) Το βέλτιστο μήκος δίνεται από την τιμή . (ii) Γράψε την αναδρομική σχέση. (iii) Ποια η χρονική πολυπλοκότητα και γιατί;

Παλαιό θέμαΣεπτέμβριος 2024Θέμα Εξετάσεων 2024Θέμα 440%Δυναμικός προγραμματισμόςΔύσκολο

Σεπτέμβριος 2024 · Θέμα 4 — Διαφημίσεις χορηγών (Σακίδιο)

Στην πρώτη μέρα ενός φεστιβάλ παρουσιάζονται δύο συγκροτήματα. Από το τέλος της συναυλίας του πρώτου μέχρι την έναρξη του δεύτερου μεσολαβεί χρόνος . Σε αυτό το διάστημα η διοργανώτρια εταιρεία θα προβάλει διαφημίσεις χορηγών (χωρίς επαναλήψεις). Έχουν καταθέσει προτάσεις εταιρείες· η διαφήμιση έχει διάρκεια και αποφέρει κέρδος (όλα θετικοί ακέραιοι). Ορίζουμε = το μέγιστο κέρδος από τις διαφημίσεις με συνολική διάρκεια το πολύ .

(α) Ποια τιμή δίνει το μέγιστο κέρδος; (β) Γράψε τον αναδρομικό τύπο του . (γ) Χρονική πολυπλοκότητα του υπολογισμού όλων των υποπροβλημάτων — αιτιολόγησε. (δ) Πολυπλοκότητα για τον εντοπισμό των διαφημίσεων που δίνουν το μέγιστο κέρδος. (ε) Σε ποιο γνωστό πρόβλημα αντιστοιχεί αν επιπλέον κάθε διαφήμιση πρέπει να προβληθεί σε σταθερό διάστημα εντός του ;

Παλαιό θέμαΙούνιος 2022Θέμα 335%Δυναμικός προγραμματισμόςΔύσκολο

Ιούνιος 2022 · Θέμα 3 — 0/1 σακίδιο: άπληστος vs δυναμικός

Θεωρήστε το 0-1 πρόβλημα του σακιδίου: μεγιστοποίησε υπό τον περιορισμό , με , όπου τα είναι ακέραιοι.

i. Περιγράψτε σε φυσική γλώσσα έναν άπληστο αλγόριθμο που επιστρέφει μια εφικτή λύση. ii. Υπολογίστε την πολυπλοκότητά του. iii. Για το στιγμιότυπο , , , εφαρμόστε τον αλγόριθμο. iv. Μπορεί ο αλγόριθμος να επιστρέφει πάντα τη βέλτιστη λύση και να είναι πολυωνυμικός; v. Με δυναμικό προγραμματισμό, πόσα υποπροβλήματα χρειάζονται; Δώστε την αναδρομική σχέση.

Φόρτωση σχολίων…
L15 · Δυναμικός Προγραμματισμός II — Σακίδιο & Μέγιστη Κοινή Υπακολουθία · Algorithms Class Hub