Class Hub
Dynamic programming·Διάλεξη 16·~42 min

L16 · Δυναμικός Προγραμματισμός III — Ευθυγράμμιση Συμβολοσειρών

Τι θα δούμε

Πόσο όμοιες είναι δύο συμβολοσειρές; Ακούγεται απλό ερώτημα — αλλά πάνω του στηρίζονται το unix diff, ο διορθωτής ορθογραφίας, η αναγνώριση φωνής, και η σύγκριση ακολουθιών DNA. Η απάντηση λέγεται απόσταση επεξεργασίας (edit distance) και είναι ένα από τα πιο κομψά DP του μαθήματος.

Και κρύβει δύο βαθιές ιδέες που αξίζουν από μόνες τους:

  1. Ο πίνακας του DP δεν είναι απλώς πίνακας — είναι γράφημα, και η βέλτιστη λύση είναι ένα συντομότερο μονοπάτι.
  2. Συνδυάζοντας DP με διαίρει-και-κυρίευε, λύνουμε το πρόβλημα σε γραμμικό χώρο — ο αλγόριθμος του Hirschberg.

Ομοιότητα συμβολοσειρών

Φαντάσου ότι πληκτρολογείς μια λέξη και ο διορθωτής σού προτείνει διόρθωση. Πώς ξέρει ποια λέξη εννοούσες; Συγκρίνει αυτό που έγραψες με κάθε λέξη του λεξικού και διαλέγει την πιο κοντινή. Αλλά τι θα πει «κοντινή» για δύο λέξεις;

Δες αυτές τις δύο:

o c u r r a n c e
o c c u r e n c e

Καταλαβαίνεις αμέσως ότι είναι «η ίδια λέξη με λάθη». Το μάτι το βλέπει — αλλά ο υπολογιστής χρειάζεται έναν αριθμό. Πώς ποσοτικοποιείς αυτή τη διαίσθηση;

Η ιδέα: μέτρα πόσες στοιχειώδεις αλλαγές χρειάζονται για να μετατρέψεις τη μία λέξη στην άλλη. Τρία είδη αλλαγής, και μόνο τρία:

  • εισαγωγή ενός χαρακτήρα,
  • διαγραφή ενός χαρακτήρα,
  • αντικατάσταση ενός χαρακτήρα με άλλον.

Όσο λιγότερες αλλαγές χρειάζονται, τόσο πιο όμοιες οι λέξεις. Αυτός ο ελάχιστος αριθμός αλλαγών — με κατάλληλο κόστος για την καθεμία — είναι η απόσταση επεξεργασίας.

Ευθυγράμμιση συμβολοσειρών

Για να μετρήσουμε τις αλλαγές χρειαζόμαστε έναν βολικό τρόπο να τις βλέπουμε. Αυτός είναι η ευθυγράμμιση.

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

X:  o c - u r r a n c e
Y:  o c c u r e - n c e

Κάθε στήλη είναι μία «κίνηση»: είτε ένα ζευγάρι γραμμάτων, είτε ένα γράμμα με ένα κενό. Το κόστος της στήλης:

  • δύο ίδια γράμματα → (τέλειο ταίριασμα)·
  • δύο διαφορετικά γράμματα → (σύγκρουση)·
  • ένα γράμμα κι ένα κενό → .

Η ευθυγράμμιση πιο πάνω έχει ένα κενό (στήλη 3), μία σύγκρουση re (στήλη 6) κι άλλο ένα κενό (στήλη 7): κόστος . Το κόστος μιας ευθυγράμμισης είναι το άθροισμα όλων των στηλών της, και στόχος μας είναι η ευθυγράμμιση ελάχιστου κόστους — αυτό ακριβώς το ελάχιστο είναι η απόσταση επεξεργασίας.

Ένας κανόνας κάνει τις ευθυγραμμίσεις «λογικές»: τα ζεύγη δεν διασταυρώνονται. Αν διαβάσεις και τις δύο λέξεις από αριστερά προς δεξιά, τα ζεύγη πρέπει να κρατούν τη σειρά τους — μια λέξη δεν «ανακατεύεται». Αυτό φαίνεται καλύτερα στο εργαλείο παρακάτω.

Δες το μόνος σου. Παρακάτω χτίζεις μια ευθυγράμμιση δύο σύντομων συμβολοσειρών DNA, κίνηση-κίνηση, και παρακολουθείς το κόστος να σχηματίζεται:

Χτίσε μια ευθυγράμμιση, κίνηση-κίνηση
X=GCTA · Y=CTAG

Κόστος κενού δ = 1, κόστος σύγκρουσης α = 1. Στόχος: ευθυγράμμιση ελάχιστου κόστους.

Οι δύο συμβολοσειρές — ο επόμενος χαρακτήρας κάθε μιας
X
G
C
T
A
Y
C
T
A
G
Η ευθυγράμμιση — μία στήλη ανά κίνηση
(καμία κίνηση ακόμα)
Ζευγαρώματα
0
κόστος 0
Συγκρούσεις
0
× α = 0
Κενά
0
× δ = 0
Σύνολο
0
βέλτιστο: 2
Η ευθυγράμμιση είναι άδεια. Κοίτα τον επόμενο χαρακτήρα κάθε λέξης (με πορτοκαλί πλαίσιο) και διάλεξε μία από τις τρεις κινήσεις.
Ο κανόνας «δεν διασταυρώνονται»
x₁x₂y₁y₂✓ Έγκυρη — η σειρά διατηρείται
x₁x₂y₁y₂✗ Διασταύρωση — απαγορεύεται

Δύο ζεύγη xᵢ–yⱼ και xᵢ′–yⱼ′ διασταυρώνονται όταν i < i′ αλλά j > j′ — η σειρά αναποδογυρίζει. Χτίζοντας πάντα τον επόμενο χαρακτήρα, αυτό δεν μπορεί ποτέ να συμβεί.

Η αναδρομή

Τώρα ο αλγόριθμος. Όπως πάντα στον δυναμικό προγραμματισμό, ρωτάμε: ποια είναι η τελευταία απόφαση;

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

  • Ταίριασμα με : πληρώνεις αν είναι ίδιοι), συν το βέλτιστο για , .
  • Το αταίριαστο: πληρώνεις κενό , συν το βέλτιστο για , .
  • Το αταίριαστο: πληρώνεις κενό , συν το βέλτιστο για , .

Δεν ξέρουμε ποια από τις τρεις είναι η σωστή — οπότε τις δοκιμάζουμε όλες και κρατάμε τη φθηνότερη. Αυτό είναι το .

ΑλγόριθμοςΕυθυγράμμιση συμβολοσειρών
Θ(mn)
Γέμισε ένα πλέγμα m × n· κάθε κελί είναι το min τριών γειτόνων — ταίριασμα (διαγώνια), το xᵢ αταίριαστο (πάνω), το yⱼ αταίριαστο (αριστερά).
Είσοδος:
δύο συμβολοσειρές X, Y, κόστος κενού δ και κόστη σύγκρουσης α
Έξοδος:
η απόσταση επεξεργασίας — το ελάχιστο κόστος ευθυγράμμισης

Με λόγια. Φτιάχνουμε πλέγμα με γραμμές και στήλες. Η γραμμή 0 και η στήλη 0 είναι οι βασικές περιπτώσεις — ευθυγράμμιση με κενή συμβολοσειρά. Κάθε άλλο κελί είναι το ελάχιστο τριών επιλογών: ταίριασμα των (διαγώνιο κελί), το αταίριαστο (κελί από πάνω), το αταίριαστο (κελί από αριστερά).

Πολυπλοκότητα. Ο πίνακας έχει κελιά, κάθε ένα χρόνος και χώρος.

Δες το πλέγμα να γεμίζει. Σε κάθε γραμμή φωτίζεται ένα κελί με τους τρεις γείτονες από τους οποίους εξαρτάται, και στο τέλος ανακτάται η βέλτιστη ευθυγράμμιση με πέρασμα προς τα πίσω:

Ευθυγράμμιση — γέμισμα του πλέγματος, γραμμή-γραμμή
X=GCTA · Y=CTAG

Κόστος κενού δ = 1, κόστος σύγκρουσης α = 1. Κάθε κελί = min τριών γειτόνων.

C
T
A
G
0
1
2
3
4
G
1
·
·
·
·
C
2
·
·
·
·
T
3
·
·
·
·
A
4
·
·
·
·
Οι βασικές περιπτώσεις: η γραμμή 0 και η στήλη 0 είναι «ευθυγράμμιση με την κενή συμβολοσειρά» — ένα κενό (δ) ανά χαρακτήρα. Πάτα «Επόμενο».
Βήμα 0 / 5

Το DP πλέγμα είναι γράφημα

Εδώ έρχεται η πρώτη βαθιά ιδέα — και είναι μια αλλαγή οπτικής, όχι νέος αλγόριθμος.

Μέχρι τώρα λέγαμε «γεμίζουμε έναν πίνακα». Αλλά κοίτα ξανά τι κάναμε: κάθε κελί πήρε την τιμή του από τρία άλλα κελιά, προσθέτοντας ένα κόστος. «Παίρνω την τιμή μου από γείτονες, συν ένα κόστος» — αυτό είναι ο ορισμός ενός γραφήματος με βάρη.

Φτιάχνουμε λοιπόν ένα γράφημα απόστασης επεξεργασίας: μια κορυφή για κάθε ζεύγος , με τρεις ακμές που αντιστοιχούν στις τρεις περιπτώσεις της αναδρομής:

  • κάτω — κόστος : αφήνει το αταίριαστο,
  • δεξιά — κόστος : αφήνει το αταίριαστο,
  • διαγώνια — κόστος : ταιριάζει το με το .

Στο εργαλείο παρακάτω, ο αριθμός μέσα σε κάθε κορυφή είναι το της — και βλέπεις ότι είναι όντως η συντομότερη απόσταση από το . Περπάτησε το βέλτιστο μονοπάτι και δες κάθε ακμή του να γίνεται μία στήλη της ευθυγράμμισης:

Το πλέγμα ως γράφημα — η ευθυγράμμιση είναι συντομότερο μονοπάτι
Κόστος: 0

Το ίδιο πλέγμα που γέμισες — αλλά τώρα κάθε κελί είναι κορυφή και κάθε επιλογή της αναδρομής είναι μια ακμή με κόστος.

CTAGGCTA0123411233212343212343212
κάτω = κενό στο X (xᵢ αταίριαστο), δδεξιά = κενό στο Y (yⱼ αταίριαστο), δδιαγώνια = ταίριασμα xᵢ–yⱼ, α
Κάθε κελί είναι μια κορυφή· ο αριθμός μέσα του είναι το OPT(i, j) — και αυτό ισούται ακριβώς με το μήκος του συντομότερου μονοπατιού από την κορυφή (0, 0). Πάτα «Επόμενο» για να περπατήσεις το βέλτιστο μονοπάτι.
Βήμα 0 / 5

Ευθυγράμμιση σε γραμμικό χώρο — Hirschberg

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

Πρώτη παρατήρηση — η τιμή σε γραμμικό χώρο

Πρώτη παρατήρηση, και σώζει πολλά: για να υπολογίσεις μια γραμμή του πίνακα, χρειάζεσαι μόνο την αμέσως προηγούμενη, — η αναδρομή κοιτάει πάντα ένα κελί από πάνω, ένα διαγώνια, κι ένα αριστερά στην ίδια γραμμή. Όλες οι παλιότερες γραμμές είναι πια άχρηστες.

Άρα κράτα μόνο δύο γραμμές κάθε φορά. Η τιμή υπολογίζεται έτσι σε χώρο και χρόνο.

Δες ακριβώς τι κρατιέται και τι πετιέται — και γιατί αυτό αρκεί για την τιμή αλλά όχι για την ευθυγράμμιση:

Γραμμικός χώρος — κράτα μόνο δύο γραμμές
Στη μνήμη: 5 κελιά

Κάθε γραμμή εξαρτάται μόνο από την προηγούμενη — άρα δύο γραμμές αρκούν.

Δύο γραμμές
5 κελιά · O(m+n)
Ολόκληρος ο πίνακας
25 κελιά · O(mn)
C
T
A
G
0
1
2
3
4
G
·
·
·
·
·
C
·
·
·
·
·
T
·
·
·
·
·
A
·
·
·
·
·
Ξεκινάμε με τη γραμμή 0 (την «κενή» βάση). Σε κάθε βήμα θα γεμίζει μία νέα γραμμή — και θα κρατάμε μόνο όσες χρειάζονται.
Βήμα 0 / 5

Η ιδέα του Hirschberg (1975) — διαίρει-και-κυρίευε + DP

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

  • = συντομότερο μονοπάτι από την αρχή στο — δηλαδή ακριβώς το ·
  • = συντομότερο μονοπάτι από το στο τέλος — το ίδιο πράγμα «ανάποδα», με τις ακμές αντεστραμμένες.

Το μετρά «πόσο κοστίζει να φτάσω εδώ»· το μετρά «πόσο κοστίζει να τελειώσω από εδώ».

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

Και τώρα διαίρει-και-κυρίευε: η ευθυγράμμιση πάνω-αριστερά του κι αυτή κάτω-δεξιά είναι ανεξάρτητα, μικρότερα αντίγραφα του ίδιου προβλήματος. Αναδρομή στο καθένα.

Hirschberg — η βέλτιστη κορυφή, μετά αναδρομή
X=GTTACG · Y=GATTACAG

DP για να βρεθεί η μεσαία κορυφή· διαίρει-και-κυρίευε για να σπάσει το πρόβλημα γύρω της.

G
A
T
T
A
C
A
G
G
T
T
A
C
G
Η βέλτιστη ευθυγράμμιση είναι ένα μονοπάτι (0,0) → (m,n) μέσα σ’ αυτό το πλέγμα m×n. Θα το βρούμε ΧΩΡΙΣ ποτέ να κρατήσουμε όλο το πλέγμα στη μνήμη.
Βήμα 0 / 8
ΑλγόριθμοςHirschberg — ευθυγράμμιση σε γραμμικό χώρο
O(m+n) χώρος, O(mn) χρόνος
Βρες με DP τη μεσαία κορυφή της βέλτιστης ευθυγράμμισης, και σπάσε το πρόβλημα γύρω της — διαίρει-και-κυρίευε.
Είσοδος:
δύο συμβολοσειρές X, Y
Έξοδος:
η βέλτιστη ευθυγράμμιση — σε γραμμικό χώρο

Με λόγια. Διαίρει: υπολόγισε με DP σε γραμμικό χώρο τη στήλη (εμπρός) και τη στήλη (πίσω). Βρες τη γραμμή που ελαχιστοποιεί το — η βέλτιστη ευθυγράμμιση περνά από το . Κυρίευε: λύσε αναδρομικά τα δύο μισά ορθογώνια — το πάνω-αριστερά και το κάτω-δεξιά .

Πολυπλοκότητα. χώρος — κάθε DP κρατά μόνο δύο γραμμές. Ο χρόνος μένει επειδή κάθε επίπεδο της αναδρομής δουλεύει σε ορθογώνια συνολικού εμβαδού που υποδιπλασιάζεται: .

Κάρτα μνήμηςΑπόσταση επεξεργασίας (ευθυγράμμιση)
Λέξεις-κλειδιά
OPT(i, j) στα προθέματατρεις περιπτώσεις: ταίριασμα / κενό X / κενό Ymin, όχι maxπλέγμα = γράφημαΘ(mn)
Τα βήματα στο μυαλό σου
1OPT(i, j) = ελάχιστο κόστος ευθυγράμμισης των προθεμάτων x₁..xᵢ και y₁..yⱼ.
2Βάση: ευθυγράμμιση με κενή συμβολοσειρά → ένα κενό δ ανά χαρακτήρα.
3Αναδρομή: min{ α + διαγώνιο, δ + πάνω, δ + αριστερά }.
4Γέμισε τον πίνακα m × n· πέρασμα προς τα πίσω για την ίδια την ευθυγράμμιση.
Πολυπλοκότητα
Θ(mn) χρόνος και χώρος
Κλασική παγίδα
Τρεις περιπτώσεις, όχι δύο — και τα δύο άκρα μπορεί να μείνουν αταίριαστα. Και είναι min (ελάχιστο κόστος), όχι max όπως στο knapsack ή στο LCS.
Κάρτα μνήμηςHirschberg — γραμμικός χώρος
Λέξεις-κλειδιά
DP + διαίρει-και-κυρίευεf εμπρός, g πίσωμεσαία στήλη n/2q ελαχιστοποιεί f + gO(m+n) χώρος
Τα βήματα στο μυαλό σου
1Υπολόγισε f(·, n/2) εμπρός και g(·, n/2) πίσω — δύο γραμμές κάθε φορά.
2Βρες τη γραμμή q που ελαχιστοποιεί f(q, n/2) + g(q, n/2).
3Η βέλτιστη ευθυγράμμιση περνά από το (q, n/2) — ευθυγράμμισέ το.
4Αναδρομή στα δύο μισά ορθογώνια γύρω από το (q, n/2).
Πολυπλοκότητα
O(m+n) χώρος, O(mn) χρόνος
Κλασική παγίδα
Η ΤΙΜΗ OPT(m,n) βγαίνει εύκολα σε γραμμικό χώρο (δύο γραμμές) — αλλά η ΙΔΙΑ Η ευθυγράμμιση όχι· γι' αυτό χρειάζεται το κόλπο f + g. Ο χρόνος μένει O(mn) γιατί το εμβαδόν υποδιπλασιάζεται.

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

Βάλε στη σειρά τα βήματα του DP για την ευθυγράμμιση:

Βάλε τα βήματα στη σειρά
Ο αλγόριθμος ευθυγράμμισης συμβολοσειρών, από την πρώτη ενέργεια στην τελευταία.
Σύρε τις γραμμές για αναδιάταξη — ή χρησιμοποίησε τα βελάκια.
1.Όρισε OPT(i, j) = ελάχιστο κόστος ευθυγράμμισης των προθεμάτων x₁..xᵢ και y₁..yⱼ.
2.Κάνε πέρασμα προς τα πίσω από το (m, n) για την ίδια την ευθυγράμμιση.
3.Υπολόγισε τα δύο κόστη κενού = δ + το πάνω κελί, και δ + το αριστερό κελί.
4.Γέμισε τη γραμμή 0 και τη στήλη 0 με τα πολλαπλάσια του κόστους κενού δ.
5.Για κάθε κελί (i, j), υπολόγισε το κόστος ταιριάσματος = α + το διαγώνιο κελί.
6.Θέσε M[i, j] = το ελάχιστο από τις τρεις τιμές.

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

Συμπλήρωσε τα κενά
Η ευθυγράμμιση και ο γραμμικός χώρος σε τέσσερις λέξεις-κλειδιά.
Η απόσταση επεξεργασίας υπολογίζεται με DP πάνω σε ένα πλέγμα m × n· κάθε κελί είναι το τριών γειτόνων. Το πλέγμα είναι στην πραγματικότητα , και η βέλτιστη ευθυγράμμιση είναι ένα συντομότερο . Ο αλγόριθμος του Hirschberg πετυχαίνει χώρο συνδυάζοντας DP με διαίρει-και-κυρίευε.

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

Τι μάθαμε

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

  1. Απόσταση επεξεργασίας — ελάχιστο κόστος μετατροπής μιας συμβολοσειράς σε άλλη, με κόστος κενού και κόστος σύγκρουσης .
  2. Ευθυγράμμιση = μη-διασταυρούμενα ζεύγη χαρακτήρων. Αναδρομή με τρεις περιπτώσεις: ταίριασμα (διαγώνια), το αταίριαστο (πάνω), το αταίριαστο (αριστερά). Χρόνος & χώρος .
  3. Το DP πλέγμα είναι γράφημα: = συντομότερο μονοπάτι .
  4. Hirschberg — συνδυασμός DP + διαίρει-και-κυρίευε. Με (εμπρός) και (πίσω), βρες την κορυφή της μεσαίας στήλης που ελαχιστοποιεί , και αναδρομή. χώρος, χρόνος.
Επόμενο
L17 · DP IV — DP σε γραφήματα

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

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

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

Από φροντιστήριοΦροντιστήριο 2023–24Άσκηση 2Δυναμικός προγραμματισμόςΜέτριο

Φροντιστηριακό Σετ #8 · Άσκηση 2 — Βέλτιστη ευθυγράμμιση αλληλουχιών DNA

Έχουμε δύο αλληλουχίες DNA — δηλαδή δύο συμβολοσειρές πάνω σε ένα τετραγράμματο αλφάβητο — και θέλουμε να τις ευθυγραμμίσουμε με τον καλύτερο δυνατό τρόπο. «Ευθυγράμμιση» όπως στη L16: βάζουμε τη μία κάτω από την άλλη σε στήλες· κάθε στήλη είτε ζευγαρώνει δύο γράμματα, είτε ζευγαρώνει ένα γράμμα με ένα κενό (παύλα). Αυτή τη φορά, ωστόσο, αντί για το ελάχιστο κόστος, ψάχνουμε το μέγιστο σκορ:

  • ταύτιση (ίδια βάση): — επιβράβευση
  • μη-ταύτιση (διαφορετική βάση): — μικρή ποινή
  • κενό: — μεγαλύτερη ποινή

Δίνονται (μήκος 6) και (μήκος 7). Βρες τη βέλτιστη βαθμολογία ευθυγράμμισης και ανάκτησε τουλάχιστον μία βέλτιστη ευθυγράμμιση.

Φόρτωση σχολίων…
L16 · Δυναμικός Προγραμματισμός III — Ευθυγράμμιση Συμβολοσειρών · Algorithms Class Hub