L16 · Δυναμικός Προγραμματισμός III — Ευθυγράμμιση Συμβολοσειρών
Τι θα δούμε
Πόσο όμοιες είναι δύο συμβολοσειρές; Ακούγεται απλό ερώτημα — αλλά πάνω του στηρίζονται το unix diff, ο διορθωτής ορθογραφίας, η αναγνώριση φωνής, και η σύγκριση ακολουθιών DNA. Η απάντηση λέγεται απόσταση επεξεργασίας (edit distance) και είναι ένα από τα πιο κομψά DP του μαθήματος.
Και κρύβει δύο βαθιές ιδέες που αξίζουν από μόνες τους:
- Ο πίνακας του DP δεν είναι απλώς πίνακας — είναι γράφημα, και η βέλτιστη λύση είναι ένα συντομότερο μονοπάτι.
- Συνδυάζοντας 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), μία σύγκρουση r–e (στήλη 6) κι άλλο ένα κενό (στήλη 7): κόστος . Το κόστος μιας ευθυγράμμισης είναι το άθροισμα όλων των στηλών της, και στόχος μας είναι η ευθυγράμμιση ελάχιστου κόστους — αυτό ακριβώς το ελάχιστο είναι η απόσταση επεξεργασίας.
Ένας κανόνας κάνει τις ευθυγραμμίσεις «λογικές»: τα ζεύγη δεν διασταυρώνονται. Αν διαβάσεις και τις δύο λέξεις από αριστερά προς δεξιά, τα ζεύγη πρέπει να κρατούν τη σειρά τους — μια λέξη δεν «ανακατεύεται». Αυτό φαίνεται καλύτερα στο εργαλείο παρακάτω.
Δες το μόνος σου. Παρακάτω χτίζεις μια ευθυγράμμιση δύο σύντομων συμβολοσειρών DNA, κίνηση-κίνηση, και παρακολουθείς το κόστος να σχηματίζεται:
Κόστος κενού δ = 1, κόστος σύγκρουσης α = 1. Στόχος: ευθυγράμμιση ελάχιστου κόστους.
Δύο ζεύγη xᵢ–yⱼ και xᵢ′–yⱼ′ διασταυρώνονται όταν i < i′ αλλά j > j′ — η σειρά αναποδογυρίζει. Χτίζοντας πάντα τον επόμενο χαρακτήρα, αυτό δεν μπορεί ποτέ να συμβεί.
Η αναδρομή
Τώρα ο αλγόριθμος. Όπως πάντα στον δυναμικό προγραμματισμό, ρωτάμε: ποια είναι η τελευταία απόφαση;
Ορίζουμε = ελάχιστο κόστος ευθυγράμμισης των προθεμάτων και . Κοίτα την τελευταία στήλη μιας βέλτιστης ευθυγράμμισης — τι μπορεί να περιέχει; Ακριβώς τις τρεις κινήσεις που μόλις δοκίμασες:
- Ταίριασμα με : πληρώνεις (ή αν είναι ίδιοι), συν το βέλτιστο για , .
- Το αταίριαστο: πληρώνεις κενό , συν το βέλτιστο για , .
- Το αταίριαστο: πληρώνεις κενό , συν το βέλτιστο για , .
Δεν ξέρουμε ποια από τις τρεις είναι η σωστή — οπότε τις δοκιμάζουμε όλες και κρατάμε τη φθηνότερη. Αυτό είναι το .
- Είσοδος:
- δύο συμβολοσειρές X, Y, κόστος κενού δ και κόστη σύγκρουσης α
- Έξοδος:
- η απόσταση επεξεργασίας — το ελάχιστο κόστος ευθυγράμμισης
Με λόγια. Φτιάχνουμε πλέγμα με γραμμές και στήλες. Η γραμμή 0 και η στήλη 0 είναι οι βασικές περιπτώσεις — ευθυγράμμιση με κενή συμβολοσειρά. Κάθε άλλο κελί είναι το ελάχιστο τριών επιλογών: ταίριασμα των (διαγώνιο κελί), το αταίριαστο (κελί από πάνω), το αταίριαστο (κελί από αριστερά).
Πολυπλοκότητα. Ο πίνακας έχει κελιά, κάθε ένα → χρόνος και χώρος.
Δες το πλέγμα να γεμίζει. Σε κάθε γραμμή φωτίζεται ένα κελί με τους τρεις γείτονες από τους οποίους εξαρτάται, και στο τέλος ανακτάται η βέλτιστη ευθυγράμμιση με πέρασμα προς τα πίσω:
Κόστος κενού δ = 1, κόστος σύγκρουσης α = 1. Κάθε κελί = min τριών γειτόνων.
Το DP πλέγμα είναι γράφημα
Εδώ έρχεται η πρώτη βαθιά ιδέα — και είναι μια αλλαγή οπτικής, όχι νέος αλγόριθμος.
Μέχρι τώρα λέγαμε «γεμίζουμε έναν πίνακα». Αλλά κοίτα ξανά τι κάναμε: κάθε κελί πήρε την τιμή του από τρία άλλα κελιά, προσθέτοντας ένα κόστος. «Παίρνω την τιμή μου από γείτονες, συν ένα κόστος» — αυτό είναι ο ορισμός ενός γραφήματος με βάρη.
Φτιάχνουμε λοιπόν ένα γράφημα απόστασης επεξεργασίας: μια κορυφή για κάθε ζεύγος , με τρεις ακμές που αντιστοιχούν στις τρεις περιπτώσεις της αναδρομής:
- κάτω — κόστος : αφήνει το αταίριαστο,
- δεξιά — κόστος : αφήνει το αταίριαστο,
- διαγώνια — κόστος : ταιριάζει το με το .
Στο εργαλείο παρακάτω, ο αριθμός μέσα σε κάθε κορυφή είναι το της — και βλέπεις ότι είναι όντως η συντομότερη απόσταση από το . Περπάτησε το βέλτιστο μονοπάτι και δες κάθε ακμή του να γίνεται μία στήλη της ευθυγράμμισης:
Το ίδιο πλέγμα που γέμισες — αλλά τώρα κάθε κελί είναι κορυφή και κάθε επιλογή της αναδρομής είναι μια ακμή με κόστος.
Ευθυγράμμιση σε γραμμικό χώρο — Hirschberg
Ο πίνακας είναι το πρόβλημα. Στην υπολογιστική βιολογία ευθυγραμμίζονται ακολουθίες DNA με — ένας πίνακας κελιών δεν χωράει σε καμία μνήμη.
Πρώτη παρατήρηση — η τιμή σε γραμμικό χώρο
Πρώτη παρατήρηση, και σώζει πολλά: για να υπολογίσεις μια γραμμή του πίνακα, χρειάζεσαι μόνο την αμέσως προηγούμενη, — η αναδρομή κοιτάει πάντα ένα κελί από πάνω, ένα διαγώνια, κι ένα αριστερά στην ίδια γραμμή. Όλες οι παλιότερες γραμμές είναι πια άχρηστες.
Άρα κράτα μόνο δύο γραμμές κάθε φορά. Η τιμή υπολογίζεται έτσι σε χώρο και χρόνο.
Δες ακριβώς τι κρατιέται και τι πετιέται — και γιατί αυτό αρκεί για την τιμή αλλά όχι για την ευθυγράμμιση:
Κάθε γραμμή εξαρτάται μόνο από την προηγούμενη — άρα δύο γραμμές αρκούν.
Η ιδέα του Hirschberg (1975) — διαίρει-και-κυρίευε + DP
Δουλεύουμε στο γράφημα απόστασης που μόλις είδαμε. Ορίζουμε δύο ποσότητες — και οι δύο υπολογίζονται με το κόλπο των δύο γραμμών, σε γραμμικό χώρο:
- = συντομότερο μονοπάτι από την αρχή στο — δηλαδή ακριβώς το ·
- = συντομότερο μονοπάτι από το στο τέλος — το ίδιο πράγμα «ανάποδα», με τις ακμές αντεστραμμένες.
Το μετρά «πόσο κοστίζει να φτάσω εδώ»· το μετρά «πόσο κοστίζει να τελειώσω από εδώ».
Διαλέγουμε τώρα τη μεσαία στήλη . Για κάθε κελί της, το λέει πόσο θα κόστιζε η καλύτερη ευθυγράμμιση αν ήταν αναγκασμένη να περάσει από εκεί. Πάρε τη γραμμή με το ελάχιστο : τότε υπάρχει βέλτιστη ευθυγράμμιση που όντως περνά από την κορυφή . Βρήκαμε ένα σίγουρο κελί της απάντησης — και μόνο με γραμμικό χώρο.
Και τώρα διαίρει-και-κυρίευε: η ευθυγράμμιση πάνω-αριστερά του κι αυτή κάτω-δεξιά είναι ανεξάρτητα, μικρότερα αντίγραφα του ίδιου προβλήματος. Αναδρομή στο καθένα.
DP για να βρεθεί η μεσαία κορυφή· διαίρει-και-κυρίευε για να σπάσει το πρόβλημα γύρω της.
- Είσοδος:
- δύο συμβολοσειρές X, Y
- Έξοδος:
- η βέλτιστη ευθυγράμμιση — σε γραμμικό χώρο
Με λόγια. Διαίρει: υπολόγισε με DP σε γραμμικό χώρο τη στήλη (εμπρός) και τη στήλη (πίσω). Βρες τη γραμμή που ελαχιστοποιεί το — η βέλτιστη ευθυγράμμιση περνά από το . Κυρίευε: λύσε αναδρομικά τα δύο μισά ορθογώνια — το πάνω-αριστερά – και το κάτω-δεξιά –.
Πολυπλοκότητα. χώρος — κάθε DP κρατά μόνο δύο γραμμές. Ο χρόνος μένει επειδή κάθε επίπεδο της αναδρομής δουλεύει σε ορθογώνια συνολικού εμβαδού που υποδιπλασιάζεται: .
Κλείδωσε τη γνώση
Βάλε στη σειρά τα βήματα του DP για την ευθυγράμμιση:
Και συμπλήρωσε τα κενά:
Μοτίβο σκέψης
Τι μάθαμε
Τι κρατάμε από αυτή τη διάλεξη
- Απόσταση επεξεργασίας — ελάχιστο κόστος μετατροπής μιας συμβολοσειράς σε άλλη, με κόστος κενού και κόστος σύγκρουσης .
- Ευθυγράμμιση = μη-διασταυρούμενα ζεύγη χαρακτήρων. Αναδρομή με τρεις περιπτώσεις: ταίριασμα (διαγώνια), το αταίριαστο (πάνω), το αταίριαστο (αριστερά). Χρόνος & χώρος .
- Το DP πλέγμα είναι γράφημα: = συντομότερο μονοπάτι .
- Hirschberg — συνδυασμός DP + διαίρει-και-κυρίευε. Με (εμπρός) και (πίσω), βρες την κορυφή της μεσαίας στήλης που ελαχιστοποιεί , και αναδρομή. χώρος, χρόνος.
Ασκήσεις από εξετάσεις
Από τη θεωρία στην εξεταστική
1 άσκηση που χρησιμοποιεί ως τελευταίο εργαλείο αυτή τη διάλεξη. Οι πρόσφατες εξεταστικές (2024/2025) φέρουν badge προτεραιότητας.
Φροντιστηριακό Σετ #8 · Άσκηση 2 — Βέλτιστη ευθυγράμμιση αλληλουχιών DNA
Έχουμε δύο αλληλουχίες DNA — δηλαδή δύο συμβολοσειρές πάνω σε ένα τετραγράμματο αλφάβητο — και θέλουμε να τις ευθυγραμμίσουμε με τον καλύτερο δυνατό τρόπο. «Ευθυγράμμιση» όπως στη L16: βάζουμε τη μία κάτω από την άλλη σε στήλες· κάθε στήλη είτε ζευγαρώνει δύο γράμματα, είτε ζευγαρώνει ένα γράμμα με ένα κενό (παύλα). Αυτή τη φορά, ωστόσο, αντί για το ελάχιστο κόστος, ψάχνουμε το μέγιστο σκορ:
- ταύτιση (ίδια βάση): — επιβράβευση
- μη-ταύτιση (διαφορετική βάση): — μικρή ποινή
- κενό: — μεγαλύτερη ποινή
Δίνονται (μήκος 6) και (μήκος 7). Βρες τη βέλτιστη βαθμολογία ευθυγράμμισης και ανάκτησε τουλάχιστον μία βέλτιστη ευθυγράμμιση.