(8 ο ) ΚΛΑΣΜΑΤΙΚΗ ΑΑΓΩΓΗ - ΙI: «διάμεσος &θεσιακή επιλογή στοιχείου» Το πρόβλημα του διαμέσου στοιχείου: ένα θεμελιακό πρόβλημα Συναντήσαμε ήδη αρκετές φορές το πρόβλημα του να «κόψουμε» ένα σύνολο στοιχείων στη μέση, ένα πρόβλημα τόσο θεμελιακό που πρέπει να το λύσουμε κατά τον καλύτερο δυνατόν τρόπο: μας δίνονται στοιχεία μιας διάταξης, τα οποία θα μπορούσαμε να τα βάλουμε σε μια λ.χ. αύξουσα σειρά, και ζητείται ποιό είναι εκείνο το στοιχείο που σε μια τέτοια ταξινόμηση θα εμφανιζόταν στη «μέση» θα είχε δηλαδή τα μισά ~/2 στοιχεία μικρότερά του, και τα υπόλοιπα μισά μεγαλύτερά του. Εάν επιτρέψουμε στον εαυτό μας να ταξινομήσουμε τα στοιχεία, αυτό το στοιχείο (που θα το ονομάζουμε διάμεσο) θα βρισκόταν προφανώς στην υπ. αρ. /2 θέση. Διατυπώνουμε λοιπόν το πρόβλημά μας κατά έναν γενικότερο τρόπο: από στοιχεία μιας διάταξης ποιό είναι το υπ.αρ. θ στην διάταξή τους; Μπορούμε να το βρούμε χωρίς να προβούμε πρώτα στην ταξινόμησή τους; ΔΙΔΕΤΑΙ: ΖΗΤΕΙΤΑΙ: ΩΣΤΕ: «ΘΕΣΙΑΚΗ ΕΠΙΛΟΓΗ ΣΤΟΙΧΕΙΟΥ» (α) αριθμοί σκ (όχι κατ ανάγκην διατεταγμένοι), και (β) μια «θέση», θ. Η τιμή του στοιχείου στην θέση θ εάν αυτά ήσαν διατεταγμένα. (δηλαδή, να υπάρχουν θ μικρότερα ή ίσα από αυτό, και θ μεγαλύτερα ή ίσα) Στο παρακάτω σχήμα διευκρινίζεται η διατύπωση του προβλήματος της «επιλογής», με ένα παράδειγμα 2 στοιχείων, από τα οποία ζητείται το 4 ο. Προσέξτε ότι είναι δυνατόν κάποια από τα στοιχεία να επαναλαμβάνονται. ποιό είναι το 4 ο στοιχείο, N = 2 42 9 5 23 7 33 9 7 33 9 5 29 εάν τα ταξινομούσαμε; 5 7 9 9 9 7 23 29 33 33 42 5 θ = 4 (θ-) = 3 μικρότερα ή ίσα (-θ) = 8 μεγαλύτερα ή ίσα Έχουμε ήδη διαφημίσει ότι το πρόβλημα αυτό είναι δυνατόν να λυθεί, και μάλιστα κατά δραστικό τρόπο, με την τεχνική της κλασματικής αναγωγής. Θυμίζουμε ότι κατά την τεχνική αυτή προσπαθούμε να απορρίψουμε αρκετά δεδομένα ως «άσχετα» με την λύση, ανάγοντας έτσι το πρόβλημα σε ένα κλασματικά μικρότερο. Στο προηγούμενο παράδειγμα κλασματικής αναγωγής που εξετάσαμε η λύση του προβλήματος καθοριζόταν από μόλις ή 2 δεδομένα, επομένως ήταν προφανές ότι τα περισσότερα δεδομένα δεν συμμετείχαν στον καθορισμό της λύσης. Στο πρόβλημα που τώρα εξετάζουμε, φαίνεται εκ πρώτης όψεως, ότι όλα τα δεδομένα παίζουν καθοριστικό ρόλο. Στο προηγούμενο σχήμα λ.χ. πρέπει 3 από τα στοιχεία να βρεθούν πριν το 9, και (τα υπόλοιπα) 8 μετά από αυτό. Πρόκειται περί οπτικής απάτης και εξηγούμαστε αμέσως: Έστω ότι αναζητούμε το υπ.αρ. θ στοιχείο, και ότι θ < /2. Τότε για τον καθορισμό αυτού του στοιχείου αρκούν μονον τα /2 μικρότερα στοιχεία. Εάν συμβαίνει το αντίστροφο, δηλαδή θ > /2, τότε αρκούν τα /2 μεγαλύτερα στοιχεία: αρκεί να αναζητήσουμε σε αυτά το υπ.αρ. (θ /2)! Και στις δύο περιπτώσεις τα μισά μόνον στοιχεία είναι αρκετά για να καθορίσουν την λύση! Δείτε το επόμενο σχήμα: Πανεπιστήμιο Κρήτης Τμήμα Επιστήμης Υπολογιστών Γ.Φ. Γεωργακόπουλος ver: 30/4/202 - -
5 7 9 9 9 7 23 29 33 33 42 5 θέση θ = 4 Τα /2 = 6 μεγαλύτερα είναι περιττά... 5 7 9 9 9 7 23 29 33 33 42 5 Τα /2 = 6 μικρότερα είναι περιττά... θέση θ = (δηλ. 5 = 6) Ποιά είναι όμως τα /2 μικρότερα ή /2 μεγαλύτερα; Αν γνωρίζαμε το διάμεσο στοιχείο μ, (αυτό δηλαδή που θα ήταν στην ~ /2 θέση) θα είμασταν σε θέση να βρούμε σε γραμμικό χρόνο Θ() τα /2 μικρότερα ή μεγαλύτερα στοιχεία, εξετάζοντας - όλα τα στοιχεία και κρίνοντας για κάθε ένα από αυτά εάν είναι μικρότερο ή μεγαλύτερου του διαμέσου μ. Δεν έχουμε κάνει πρόοδο όμως: ο εντοπισμός του διαμέσου στοιχείων είναι πρόβλημα του ιδίου τύπου μεν, αλλά και του ιδίου μεγέθους... Στη σχεδίαση αλγορίθμων (όπως ίσως και αλλού) πρέπει να ξέρεις τι ζητάς αν θέλεις να το βρείς. Αυτό που μας ενδιαφέρει είναι να απορρίψουμε ένα κλάσμα των δεδομένων, και είναι αλήθεια ότι η γνώση του διαμέσου θα μας επέτρεπε να απορρίψουμε πολλά: τα μισά από αυτά. Αλλά όπως ήδη παρατηρήσαμε ακόμα και ένα μικρότερο κλάσμα α < να απορρίπταμε λ.χ. το α = /20 από τα σημεία, πάλι θα είχαμε αυτό που ζητάμε: μια κλασματική (ή «γεωμετρική», όπως συχνά λέγεται) πρόοδο: θα είμασταν και πάλι σε θέση να απορρίψουμε με παρόμοιο τρόπο το /20 των στοιχείων, και να συνεχίσουμε με «μόνο» τα ( α) = 9 /20 από αυτά. Αλγόριθμος «Θεσιακή επιλογή στοιχείου διάταξης» Επιλογή( Τ: πίνακας αριθμών, θ: θέση..) Συνάρτηση ΠερίπουΜεσαίο { ΠερίπουΜεσαίο ένα τυχαίο? από τα Τ[]...Τ[] } Διαδικασία Διαμέριση(μ) { ΠΡΙ, ΙΣΟΙ, ΜΕΤΑ 0 Για κ = έως { Τ[κ] < μ: { Τ ΠΡΙ Τ ΠΡΙ + Τ[κ], ΠΡΙ ΠΡΙ + } // ΠΡΙ α?? Τ[κ] = μ: { Τ ΙΣΟΙ Τ ΙΣΟΙ + Τ[κ], ΙΣΟΙ ΙΣΟΙ + } Τ[κ] > μ: { Τ ΜΕΤΑ Τ ΜΕΤΑ + Τ[κ], ΜΕΤΑ ΜΕΤΑ + } // ΜΕΤΑ α?? { Εάν είναι μικρό Tότε { Ταξινομούμε & επιλέγουμε το υπ.αρ. θ } Αλλιώς { μ ΠερίπουΜεσαίο Διαμέριση(μ)) { θ ΠΡΙ : Επιλογή Επιλογή(Τ ΠΡΙ,θ) // μείον ΜΕΤΑ θ > ΠΡΙ + ΙΣΟΙ : Επιλογή Επιλογή(Τ ΜΕΤΑ,θ- ΠΡΙ - ΙΣΟΙ ) } // μείον ΠΡΙ Αλλιώς { Επιλογή μ } Δεν χρειαζόμαστε λοιπόν το ακριβώς διάμεσο στοιχείο. Ακόμα και ένα που θα είχε τουλάχιστον /20 μικρότερα από αυτό, και /20 μεγαλύτερα από αυτό, θα μας ήταν αρκετό για να κάνουμε την Πανεπιστήμιο Κρήτης Τμήμα Επιστήμης Υπολογιστών Γ.Φ. Γεωργακόπουλος ver: 30/4/202-2 -
δουλειά μας. Είναι όμως πιο εύκολο να εντοπίσουμε ένα τέτοιο «κατά /20 περίπου μεσαίο» στοιχείο; Και πράγματι, μοιάζει να είναι πιο εύκολο πρόβλημα, διότι σε τελευταία ανάλυση ακόμα και στην τύχη να διαλέγαμε ένα στοιχείο, θα μας προέκυπτε ένα «περίπου μεσαίο» με πιθανότητα 90%: όλα τα 9 /0 στοιχεία από την /20 θέση έως την 9 /20 είναι «περίπου μεσαία» με την έννοια που χρησιμοποιούμε εδώ! Αν μπορούσαμε να διαλέξουμε ένα περίπου μεσαίο στοιχείο, θα είχαμε το αλγόριθμο θεσιακής επιλογής, που δίδεται μόλις προηγουμένως. Πώς μπορούμε να διαλέξουμε ένα «περίπου μεσαίο» στοιχείο; Εάν όμως ακόμα και τυχαίο στοιχείο θα είχε μεγάλη πιθανότητα να ήταν μεσαίο, γιατί να μην διαλέξουμε ένα μεγάλο δείγμα από στοιχεία, απορρίπτοντας λ.χ. 4/5 και κρατώντας /5 στοιχεία, και να εντοπίσουμε (αναδρομικά!) το ακριβώς μεσαίο στοιχείο αυτών; Και πράγματι το διάμεσο στοιχείο από /5 στοιχεία έχει οπωσδήποτε /0 μικρότερα και /0 μεγαλύτερα. Τελειώσαμε; Όχι... Ας προσέξουμε στο επόμενο σχήμα μια (όντως «χειρίστη») περίπτωση του τί θα μπορούσε να συμβεί: δείγμα μεγέθους 2 / 0 / 0 / 0 θ «2 / 0 + 9 / 0 >» μείον......και αναδρομή επί 9 / 0 στοιχείων Έστω Τ() ο χρόνος που θα δαπανά ο αλγόριθμος μας για την επιλογή του υπ.αρ. θ στοιχείου (ή του διαμέσου, για θ = /2). Σε μια (όντως ακραία) περίπτωση, θα μπορούσε τα /5 στοιχεία που έχουμε διαλέξει να είναι τα μικρότερα εξ όλων. Για τον υπολογισμό του διαμέσου εξ αυτών (αναδρομικά!) θα δαπανούσαμε χρόνο Τ(/5). Εάν λοιπόν εξαιρέσουμε τα πρώτα μισά από αυτά (/0), και το ζητούμενο στοιχείο είναι στα υπόλοιπα θα χρειαστούμε επιπροσθέτως Τ(9/0) χρόνο για να επιλέξουμε το στοιχείο που ζητούμε ανάμεσα σε αυτά (αναδρομικά!). Το άθροισμα (/5 + 9/0) δεν είναι όμως ένα κλάσμα του είναι τα /0 του, και δεν μπορούμε να ελπίσουμε πια σε μια γεωμετρική πρόοδο... Και πράγματι: έαν λύσουμε τηλεσκοπικά την σχέση Τ() Τ( /5) + Τ( 9 /0) + Θ(), δεν θα βρούμε κάτι ταχύτερο από την πλοκή της ταξινόμησης που είναι Ο(log)... Τα στοιχεία λοιπόν που θα διαλέγουμε, (στο παράδειγμά μας τα /5), θα πρέπει να μην είναι τα μικρότερα (ή τα μεγαλύτερα), θα πρέπει δηλαδή και αυτά να είναι «περίπου στη μέση», να έχουν δηλαδή «πολλά» μικρότερα στοιχεία, και «πολλά μεγαλύτερα». (Βλ. τα σκιασμένα τμήματα στο επόμενο σχήμα, όπου τα /0 «γκρί» στοιχεία έχουν 2 /0 στοιχεία μικρότερα τους (διακεκομμένα πλαίσια). δείγμα / 0 + / 0 «/ 5 + 7 / 0 <»!! 2 / 0 μείον > 2 / 0 + / 0... και αναδρομή σε < 7 / 0 στοιχεία Πανεπιστήμιο Κρήτης Τμήμα Επιστήμης Υπολογιστών Γ.Φ. Γεωργακόπουλος ver: 30/4/202-3 -
Αυτό όμως είναι πια ένα πρόβλημα που μπορούμε να λύσουμε. Σκεπτόμενοι διαισθητικά, δεν είναι δύσκολο βρούμε πολλά στοιχεία που να έχουν συλλογικά πολλά μικρότερα: αν φροντίσουμε κάθε επιλεγόμενο στοιχείο να έχει λ.χ. 2 μικρότερα (χωρίς διπλομετρήσεις...), τότε Μ εξ αυτών θα έχουν 2Μ μικρότερα στοιχεία συλλογικά (δηλ. μικρότερα από το μέγιστο εξ αυτών)! Και για να εξασφαλίσουμε αυτή την ιδιότητα και για μικρότερα και για μεγαλύτερα στοιχεία, αρκεί να πάρουμε τα στοιχεία λ.χ. σε πεντάδες: σε κάθε 5-άδα το «μεσαίο» στοιχείο της θα έχει 2 μικρότερα και 2 μεγαλύτερα. Για να βρούμε λοιπόν ένα «περίπου μεσαίο» στοιχείο, λαμβάνουμε τα στοιχεία ανά 5, επιλέγουμε τα /5 διάμεσα στοιχεία κάθε 5-άδας, και βρίσκουμε (αναδρομικά) το ακριβώς διάμεσο από αυτά, μ. Αυτό θα έχει σίγουρα ½(/5) = /0 στοιχεία μικρότερα από αυτό, και κάθε ένα από αυτά θα έχει άλλα 2 μικρότερα, δηλαδή το στοιχείο μ θα έχει 3 /0 μικρότερα! Λόγω της συμμετρίας της κατάστασης θα έχει επίσης 3 /0 στοιχεία μεγαλύτερα από αυτό θα είναι λοιπόν το «περίπου μεσαίο» όπως θέλαμε. Ο κώδικας μας λοιπόν έχει συμπληρωθεί, και δίδεται στη συνέχεια: Αλγόριθμος «Θεσιακή επιλογή στοιχείου διάταξης» Επιλογή( Τ: πίνακας αριθμών, θ: θέση..) Συνάρτηση ΠερίπουΜεσαίο { Για κ = έως /5 { Δείγμα[κ] = το διάμεσο από Τ[5κ-4] έως Τ[5κ] } ΠερίπουΜεσαίο Επιλογή( Δείγμα, /5, /0) } Διαδικασία Διαμέριση(μ) { ΠΡΙ, ΙΣΟΙ, ΜΕΤΑ 0 Για κ = έως { Τ[κ] < μ: { Τ ΠΡΙ Τ ΠΡΙ + Τ[κ], ΠΡΙ ΠΡΙ + } // ΠΡΙ 3 / 0 Τ[κ] = μ: { Τ ΙΣΟΙ Τ ΙΣΟΙ + Τ[κ], ΙΣΟΙ ΙΣΟΙ + } Τ[κ] > μ: { Τ ΜΕΤΑ Τ ΜΕΤΑ + Τ[κ], ΜΕΤΑ ΜΕΤΑ + } // ΜΕΤΑ 3 / 0 { Εάν < 50 Tότε { Ταξινομούμε & επιλέγουμε το υπ.αρ. θ } Αλλιώς { μ ΠερίπουΜεσαίο Διαμέριση(μ)) { θ ΠΡΙ : μ Επιλογή(Τ ΠΡΙ, ΠΡΙ, θ) // ΠΡΙ 7 / 0 θ > - ΜΕΤΑ : μ Επιλογή(Τ ΜΕΤΑ, ΜΕΤΑ, θ-(- ΜΕΤΑ ) } // ΜΕΤΑ 7 / 0 Επιλογή μ Τ() /5 Θ() Τ( / 5 ) Θ() Τ(50) = Θ()! Θ()+Τ( / 5 ) Θ() ή Τ( 7 / 0 ) ή Τ( 7 / 0 ) Κάτι καταφέραμε... Θα χρειαστούμε όμως μια προσεκτική ανάλυση του κόστους για σιγουριά. Ο αλγόριθμός μας ανάγει την επιλογή του στοιχείου στην υπ. αρ. θ θέση σε ένα στιγμιότυπο θεσιακής επιλογής μειωμένο κλασματικά κατά τουλάχιστον 3 /0, και ως προς αυτό έχουμε την επιθυμητή αναγωγή. Για να το κάνει όμως αυτό χρησιμοποιεί ένα στιγμιότυπο επιλογής διαμέσου (θέση = /2), επί ενός συνόλου μόλις /5 στοιχείων στιγμιότυπο επίσης κλασματικά μειωμένο. Έχουμε όμως δύο τέτοιες κλήσεις και πρέπει να προσθέσουμε τα μεγέθη τους: δίνουν αυτά αθροιστικά μια κλασματική μείωση των δεδομένων; Ευτυχώς ναί, διότι /5 + 7 /0 = 9 /0 <. Η σχέση που προκύπτει για την πλοκή του αλγορίθμου (όπως φαίνεται και στον σχετικό ψευδοκώδικα) είναι η εξής: Τ() Τ( 2 /0) + Τ( 7 /0) + Θ(). Πανεπιστήμιο Κρήτης Τμήμα Επιστήμης Υπολογιστών Γ.Φ. Γεωργακόπουλος ver: 30/4/202-4 -
Η τηλεσκοπική επίλυση αυτής της σχέσης είναι λίγο πιο περίπλοκη από αυτές που έχουμε συνηθίσει έως τώρα. Αξίζει να την λύσουμε σε μια πιο λίγο γενική μορφή: Τ() Τ(α) + Τ(β) + Θ(), όπου α+β <. Στην παρακάτω στήλη από σχέσεις (φτιαγμένες για να απαλειφούν τηλεσκοπικά) εμφανίζεται μια σειρά από πράγματα που πρέπει να προσέξουμε: = 0 Τ() Τ(α) + Τ(β) + Θ() = Τ(α) Τ(α 2 ) + Τ(αβ) + Θ(α) Τ(β) Τ(αβ) + Τ(β 2 ) + Θ(β) = 2 Τ(α 2 ) Τ(α 3 ) + Τ(α 2 β) + Θ(α 2 ) 2Τ(αβ) Τ(α 2 β) + Τ(αβ 2 ) + Θ(2αβ) Τ(β 2 ) Τ(αβ 2 ) + Τ(β 3 ) + Θ(β 2 )...... i i ( ) i 0 i T α β i ( ) i N ( ) i 0 i T α β N + Θ((α+β) ) Το δεξιό μέλος έχει δύο διαφορετικές εμφανίσεις της πλοκής Τ(-), (τις Τ(α) και Τ(β)), και άρα χρειάζεται να επαναλάβουμε δύο φορές την σχέση ώστε να τους απαλείψουμε τηλεσκοπικά. Εμφανίζονται οι «δυωνυμικών» όροι και συντελεστές: λ.χ. για = 2, εμφανίζονται οι όροι α 2 ( φορά), αβ (2 φορές), και β 2 ( φορά), κοκ. Στην γενική περίπτωση εμφανίζονται οι όροι Τ(α i β i ) τόσες φορές όσοι είναι οι συνδυασμοί «ανά i». Ως εκ τούτου, οι όροι Θ() ομαδοποιούνται (ανά, 2, 3,...,, βλ. τα σκιασμένα πλαίσια), και παίρνουν την μορφή Θ((α+β) i i ), αφού ( ) i 0 i α β α β. Αν αθροίσουμε και απαλείψουμε τους ίσους όρους «τηλεσκοπικά», θα μείνουν μόνον οι όροι που i διακρίνονται εντός πλαισίων. Οι όροι δεξιά αθριζόμενοι δίδουν 0α β Θ( N), και επειδή (α+β) < i το άθροισμα συγκλίνει, και συγκεκριμμένα όσους όρους και αν έχει, η τιμή του είναι ( α β), (στην περίπτωσή μας /( 9 /0) = 0). Επομένως το άθροισμά τους είναι Θ(). Αυτό που παραμένει «σκοτεινό» είναι τί τιμή παίρνει το άθροισμα «i i ( ) i T( α β N)», η τιμή i 0 του οποίου σχετίζεται με το σε ποιό θα σταματήσουμε την τηλεσκοπική ανάπτυξη της σχέσης για το Τ(). Έστω γ το μέγιστο από τα α και β (στη περίπτωσή μας γ = 7/0). Επειδή ο όρος n = α i β + i θα είναι μικρότερος από γ +, όπου γ <, αυτός ο όρος για αρκετά μεγάλο θα καταστεί μικρότερος από Θ(). Για μικρές όμως τιμές του n (εδώ λ.χ. n < 50) ο αλγόριθμός μας δεν πραγματοποιεί αναδρομικές κλήσεις, και το κόστος του εκφράζεται μόνον από τον σταθερό όρο Θ(-). Επομένως αυτό το άθροισμα για αρκετά μεγάλο δεν θα περιέχει κανένα μη-μηδενικό όρο Τ[-] θα έχουν όλοι τους απαλειφεί. Το όλο κόστος λοιπόν προέρχεται από τους σταθερούς όρους, που είδαμε ότι δίδουν (όσο και εάν είναι το πλήθος τους): Τ() = Θ(). Το σχέδιό μας έχει λοιπόν ολοκληρωθεί: είναι δυνατόν να επιλέξουμε το υπ. αρ. θ στοιχείο από διατάξιμα στοιχεία, σε γραμμικό χρόνο Θ() χωρίς δηλαδή να προβούμε προηγουμένως σε ταξινόμηση (η οποία κοστίζει στη χειρότερη περίπτωση Ω(log) ). Ακριβέστερα ο όρος αυτός θα είναι ο Ο(nlogn), αλλά για n < 50, αυτός είναι πάλι μικρότερος από c n = c α i β i, (λ.χ. για μια σταθερά c = log50), και η ομαδοποίηση που δίδει την έκφραση (α+β) Θ() συνεχίζει να είναι έγκυρη. Πανεπιστήμιο Κρήτης Τμήμα Επιστήμης Υπολογιστών Γ.Φ. Γεωργακόπουλος ver: 30/4/202-5 -