Φίλη μαθήτρια, φίλε μαθητή Στο ένθετο αυτό παρουσιάζεται μία επιπλέον ενότητα, η οποία συμπληρώνει την εξεταστέα ύλη των πανελλαδικών εξετάσεων για το σχολικό έτος 2015 2016. Η φιλοσοφία παρουσίασης της θεωρίας της ενότητας αυτής εξακολουθεί να είναι με τη μορφή ερωτήσεων και απαντήσεων, όπως άλλωστε και στο βιβλίο. Με κεντρικό άξονα την εξεταστέα ύλη οφείλουμε να σου επισημάνουμε τις παρακάτω παρατηρήσεις, οι οποίες αφορούν την άρτια προετοιμασία σου: Δεν αποτελούν εξεταστέα ύλη τα παρακάτω: η ενότητα 1 «Ανάλυση προβλήματος» (σελ. 7 σελ. 19), οι ερωτήσεις 2.4 και 2.5 (σελ. 22), η εντολή Επίλεξε (σελ. 65 σελ. 66), οι ερωτήσεις 5.1 και 5.2 (σελ. 213), η ενότητα 6 «Τεχνικές Σχεδίασης Αλγορίθμων» (σελ. 337 σελ. 339), ο αντικειμενοστραφής και ο παράλληλος προγραμματισμός (δηλαδή οι ερωτήσεις 7.40 7.42 στη σελ. 353). Οι ενότητες 3, 4 και 5 να μελετηθούν παράλληλα και κατ αντιστοιχία με τις ενότητες 8, 9 και 10. Οι αλγόριθμοι θα πρέπει να γράφονται στο προγραμματιστικό περιβάλλον της γλώσσας προγραμματισμού ΓΛΩΣΣΑ. Οι παράγραφοι των δυναμικών δομών δεδομένων, καθώς και της επίδοσης αποδοτικότητας αλγορίθμων, οι οποίες παρουσιάζονται στο ένθετο, θα πρέπει να μελετηθούν θεωρητικά. Οι αλγόριθμοι αναζήτησης και ταξινόμησης, καθώς και τα λυμένα θέματα στη στοίβα και την ουρά πρέπει να μελετηθούν διεξοδικά. Οι συγγραφείς
12 ΔΥΝΑΜΙΚΕΣ ΔΟΜΕΣ ΔΕΔΟΜΕΝΩΝ ΑΝΑΛΥΣΗ ΑΛΓΟΡΙΘΜΩΝ ΑΛΓΟΡΙΘΜΟΙ ΣΤΟΙΒΑΣ ΚΑΙ ΟΥΡΑΣ 12.1 Ποιο είναι το τμήμα προγράμματος το οποίο υλοποιεί τη στοίβα σε ένα μονοδιάστατο πίνακα Α[Ν]; Το τμήμα προγράμματος το οποίο υλοποιεί τη στοίβα σε ένα μονοδιάστατο πίνακα Α[Ν] είναι: TOP <- 0 ΓΡΑΨΕ 'Δώστε επιλογή' ΔΙΑΒΑΣΕ Choice ΜΕΧΡΙΣ_ΟΤΟΥ Choice = 'Ω' Ή Choice = 'Α' Ή Choice = 'Ε' ΟΣΟ Choice <> 'Ε' ΕΠΑΝΑΛΑΒΕ ΑΝ Choice = 'Ω' ΤΟΤΕ ΑΝ TOP = Ν ΤΟΤΕ ΓΡΑΨΕ 'Η στοίβα είναι γεμάτη' TOP <- TOP + 1 ΓΡΑΨΕ 'Δώστε αριθμό' ΔΙΑΒΑΣΕ Α[ΤΟP] ΑΝ TOP = 0 ΤΟΤΕ ΓΡΑΨΕ 'Η στοίβα είναι άδεια' ΓΡΑΨΕ 'Απώθηση του αριθμού', Α[TOP] Α[TOP] <- 0 TOP <- TOP 1 ΓΡΑΨΕ 'Δώστε επιλογή' ΔΙΑΒΑΣΕ Choice ΜΕΧΡΙΣ_ΟΤΟΥ Choice = 'Ω' Ή Choice = 'Α' Ή Choice = 'Ε' 12.2 Ποιο είναι το τμήμα προγράμματος το οποίο υλοποιεί την ουρά σε ένα μονοδιάστατο πίνακα Α[Ν]; 3
Το τμήμα προγράμματος το οποίο υλοποιεί την ουρά σε ένα μονοδιάστατο πίνακα Α[Ν] είναι: FRONT <- 0 REAR <- 0 ΓΡΑΨΕ 'Δώστε επιλογή' ΔΙΑΒΑΣΕ Choice ΜΕΧΡΙΣ_ΟΤΟΥ Choice = 'EN' Ή Choice = 'DE' Ή Choice = 'EXIT' ΟΣΟ Choice <> 'EXIT' ΕΠΑΝΑΛΑΒΕ ΑΝ Choice = 'EN' ΤΟΤΕ ΑΝ REAR = Ν ΤΟΤΕ ΓΡΑΨΕ 'Η ουρά είναι γεμάτη' REAR <- REAR + 1 ΓΡΑΨΕ 'Δώστε αριθμό' ΔΙΑΒΑΣΕ Α[REAR] ΑΝ FRONT = 0 Ή FRONT > REAR ΤΟΤΕ ΓΡΑΨΕ 'Η ουρά είναι άδεια' ΓΡΑΨΕ 'Εξαγωγή του αριθμού', Α[FRONT] Α[FRONT] <- 0 FRONT <- FRONT + 1 ΓΡΑΨΕ 'Δώστε επιλογή' ΔΙΑΒΑΣΕ Choice ΜΕΧΡΙΣ_ΟΤΟΥ Choice = 'EN' Ή Choice = 'DE' Ή Choice = 'EXIT' ΑΛΓΟΡΙΘΜΟΣ ΔΥΑΔΙΚΗΣ ΑΝΑΖΗΤΗΣΗΣ 12.3 Ποιο είναι το τμήμα προγράμματος το οποίο υλοποιεί τον αλγόριθμο της δυαδικής αναζήτησης σε ένα μονοδιάστατο ταξινομημένο πίνακα Α[Ν]; Το τμήμα προγράμματος το οποίο υλοποιεί τη δυαδική αναζήτηση σε ένα μονοδιάστατο ταξινομημένο πίνακα Α[Ν] είναι: ΔΙΑΒΑΣΕ key Left <- 1 Right <- Ν pos <- 0 Found <- ΨΕΥΔΗΣ ΟΣΟ (Left <= Right) ΚΑΙ (Found = ΨΕΥΔΗΣ) ΕΠΑΝΑΛΑΒΕ Μid <- (Left + Right) DIV 2 ΑN A[Μid] = key ΤΟΤΕ pos <- Μid 4
Found <- ΑΛΗΘΗΣ ΑN A[Μid] < key ΤΟΤΕ Left <- Μid + 1 Right <- Μid 1 ΑN Found = ΑΛΗΘΗΣ ΤΟΤΕ ΓΡΑΨΕ 'Βρέθηκε στη θέση', pos ΓΡΑΨΕ 'Δεν βρέθηκε' ΑΛΓΟΡΙΘΜΟΙ ΤΑΞΙΝΟΜΗΣΗΣ 12.4 Ποιο είναι το τμήμα προγράμματος το οποίο υλοποιεί την ταξινόμηση με εισαγωγή σε ένα μονοδιάστατο πίνακα Α[Ν]; Αρχικά αντιγράφουμε τα Ν στοιχεία του πίνακα Α στις θέσεις 2 έως Ν + 1 ενός πίνακα Β. Το τμήμα προγράμματος το οποίο υλοποιεί την ταξινόμηση ευθείας εισαγωγής στο μονοδιάστατο πίνακα Β[Ν + 1] είναι: ΓIA Ι ΑΠΟ 3 ΜΕΧΡΙ Ν + 1 TMP <- Β[Ι] J <- I 1 Β[1] <- TMP ΟΣΟ TMP < Β[J] ΕΠΑΝΑΛΑΒΕ Β[J + 1] <- Β[J] J <- J 1 Β[J + 1] <- TMP Το παραπάνω τμήμα προγράμματος είναι ιδανικό για περιπτώσεις δεδομένων που είναι ταξινομημένα σε κάποιο βαθμό και χρησιμοποιείται σε πολλά υβριδικά σχήματα. Επίσης πρέπει να θεωρηθεί ότι ο πίνακας Β έχει Ν + 1 θέσεις, με πρώτη θέση τη θέση Β[1], που χρησιμοποιείται για την προσωρινή αποθήκευση του στοιχείου της α- κολουθίας πηγής που πρόκειται να εισαχθεί στην ακολουθία προορισμού. Έτσι, τα στοιχεία διακρίνονται σχηματικά σε μία ακολουθία προορισμού (destination sequence) Β[2], Β[3],..., Β[I 1] και σε μία ακολουθία πηγής (source sequence) Β[I],..., Β[Ν + 1]. Αρχικά η ακολουθία προορισμού αποτελείται από το δεύτερο στοιχείο και σταδιακά αυξάνεται κατά ένα στοιχείο, το οποίο επιτυγχάνεται παρεμβάλλοντάς το στοιχείο Β[I] στην κατάλληλη θέση μεταξύ των στοιχείων της ακολουθίας προορισμού, εκτελώντας διαδοχικές συγκρίσεις από τα δεξιά προς τα αριστερά με τα στοιχεία της ακολουθίας προορισμού. Τελικά αντιγράφουμε τα στοιχεία του πίνακα Β από τις θέσεις 2 έως Ν + 1 κατ αντιστοιχία στις θέσεις 1 έως Ν του πίνακα Α. Έτσι, τα στοιχεία του πίνακα Α έχουν πλέον ταξινομηθεί. 12.5 Ποιο είναι το τμήμα προγράμματος το οποίο υλοποιεί την ταξινόμηση με επιλογή σε ένα μονοδιάστατο πίνακα Α[Ν]; Το τμήμα προγράμματος που υλοποιεί την ταξινόμηση ευθείας επιλογής σε ένα μονοδιάστατο πίνακα Α[Ν] είναι: ΓIA I ΑΠΟ 1 ΜΕΧΡΙ Ν 1 J <- I ΓIA K ΑΠΟ I + 1 ΜΕΧΡΙ Ν 5
ΑN Α[K] < Α[J] TOTE J <- K TMP <- A[J] A[J] <- A[I] A[I] <- TMP Η παραπάνω μέθοδος καλείται ταξινόμηση ευθείας επιλογής (straight selection sort). H ευθεία επιλογή εξετάζει κατά σειρά τα στοιχεία της ακολουθίας πηγής, ώστε να ανιχνεύσει το στοιχείο με το ελάχιστο κλειδί και να το τοποθετήσει ως το επόμενο στοιχείο της ακολουθίας προορισμού. Αντίθετα, η ευθεία εισαγωγή συγκρίνει σε κάθε βήμα το επόμενο στοιχείο της ακολουθίας πηγής με όλα τα στοιχεία της ακολουθίας προορισμού για να εντοπίσει το κατάλληλο σημείο εισαγωγής του. ΔΥΝΑΜΙΚΕΣ ΔΟΜΕΣ ΔΕΔΟΜΕΝΩΝ 12.6 Ποιες δομές δεδομένων καλούνται δυναμικές δομές δεδομένων; Οι δομές δεδομένων που χρησιμοποιούν δείκτες αποκαλούνται δυναμικές (dynamic), γιατί η υλοποίησή τους γίνεται έτσι, ώστε να μην απαιτείται εκ των προτέρων καθορισμός του μέγιστου αριθμού κόμβων. Είναι φανερό ότι οι δομές αυτές είναι πιο ευέλικτες από τη στατική δομή του πίνακα, επειδή επεκτείνονται και συρρικνώνονται κατά τη διάρκεια εκτέλεσης του προγράμματος. Οι στατικές δομές δεδομένων και οι λίστες λέγονται γραμμικές, ενώ τα δένδρα και οι γράφοι μη γραμμικές βάσεις δεδομένων. 12.7 Τι γνωρίζετε για τη λίστα; Στις λίστες το κύριο χαρακτηριστικό είναι ότι οι κόμβοι τους συνήθως βρίσκονται σε απομακρυσμένες θέσεις μνήμης και η σύνδεσή τους γίνεται με δείκτες. Οι δείκτες (pointer index) προσφέρονται από τις περισσότερες σύγχρονες γλώσσες προγραμματισμού και παραπέμπουν σε θέσεις μνήμης και πίνακα αντίστοιχα. Ο δείκτης (pointer) δεν λαμβάνει αριθμητικές τιμές όπως ακέραιες, πραγματικές κ.ά., αλλά οι τιμές του είναι διευθύνσεις στην κύρια μνήμη και χρησιμοποιείται ακριβώς για τη σύνδεση των διαφόρων στοιχείων μιας δομής, που είναι αποθηκευμένα σε μη συνεχόμενες θέσεις μνήμης. Στο σχήμα παρουσιάζεται η δομή του κόμβου μιας λίστας, όπου υποτίθεται ότι το πρώτο πεδίο, που ονομάζεται Δεδομένα, είναι κάποια αλφαριθμητική πληροφορία, ενώ το δεύτερο πεδίο, που ονομάζεται Δείκτης, είναι ο δείκτης που δείχνει στον επόμενο κόμβο της λίστας. Στο σχήμα παρουσιάζεται μια λίστα με τέσσερις κόμβους, όπου οι δείκτες έχουν τη μορφή βέλους, προκειμένου να φαίνεται ο κόμβος στον οποίο παραπέμπουν. Με τη χρήση δεικτών διευκολύνονται οι λειτουργίες της εισαγωγής και της διαγραφής δεδομένων σε μια λίστα. Στο σχήμα φαίνεται η εισαγωγή ενός νέου κόμβου μεταξύ του δεύτερου και τρίτου 6
κόμβου της προηγούμενης λίστας. Όπως φαίνεται και στο σχήμα, οι απαιτούμενες ενέργειες για την εισαγωγή (παρεμβολή) του νέου κόμβου είναι ο δείκτης του δεύτερου κόμβου να δείχνει το νέο κόμβο και ο δείκτης του νέου κόμβου να δείχνει τον τρίτο κόμβο (δηλαδή να πάρει την τιμή που είχε πριν την εισαγωγή ο δείκτης του δεύτερου κόμβου). Έτσι οι κόμβοι της λίστας διατηρούν τη λογική τους σειρά, αλλά οι φυσικές θέσεις στη μνήμη μπορεί να είναι τελείως διαφορετικές. Αντίστοιχα για τη διαγραφή ενός κόμβου αρκεί να αλλάξει τιμή ο δείκτης του προηγούμενου κόμβου και να δείχνει πλέον τον επόμενο αυτού που διαγράφεται, όπως φαίνεται στο σχήμα. Ο κόμβος που διαγράφηκε (ο τρίτος) αποτελεί «άχρηστο δεδομένο» και ο χώρος μνήμης που καταλάμβανε παραχωρείται για άλλη χρήση. 12.8 Τι γνωρίζετε για τα δένδρα; Τα δένδρα (trees) είναι δομές που στις σύγχρονες γλώσσες προγραμματισμού υλοποιούνται με τη βοήθεια των δεικτών, ενώ αποτελούν μη γραμμικές δυναμικές βάσεις δεδομένων. Δένδρο είναι ένα σύνολο κόμβων που συνδέονται με ακμές. Υπάρχει ένας μόνο κόμβος που ονομάζεται ρίζα (root) και στον οποίο δεν καταλήγουν, αλλά μόνο ξεκινούν ακμές. Από κάθε κόμβο μπορούν να ξεκινούν καμία, μία ή περισσότερες ακμές. Σε κάθε κόμβο (εκτός της ρίζας) καταλήγει μία μόνο ακμή. Βέβαια, μπορούν να υλοποιηθούν και με στατικές δομές (με πίνακες). Το κύριο χαρακτηριστικό των δένδρων είναι ότι από έναν κόμβο δεν υπάρχει μόνο ο επόμενος κόμβος, αλλά περισσότεροι. Υπάρχει ένας μόνο κόμβος, που λέγεται ρίζα, από τον οποίο ξεκινούν όλοι οι άλλοι κόμβοι. Στο σχήμα παρατηρούμε ότι από τη ρίζα ξεκινούν δύο κόμβοι. Οι κόμβοι αυτοί λέγονται παιδιά της ρίζας. Με την ίδια λογική, από κάθε παιδί της ρίζας ξεκινούν άλλα παιδιά κ.ο.κ. Για παράδειγμα, υπάρχει μια ιδιαίτερη δενδρική δομή, ο σωρός (heap), ο οποίος μπορεί να εφαρμοστεί για τη γρήγορη εύρεση του στοιχείου με τη μικρότερη τιμή. Επίσης μια χρήσιμη κατηγορία δένδρων είναι τα δυαδικά δένδρα αναζήτησης. 12.9 Τι γνωρίζετε για τους γράφους; Ένας γράφος (graph) αποτελείται από ένα σύνολο κόμβων (ή σημείων ή κορυφών) και ένα σύνολο γραμμών (ή ακμών ή τόξων) που ενώνουν μερικούς ή όλους τους κόμβους. Ο γράφος αποτελεί την πιο γενική δομή δεδομένων, με την έννοια ότι όλες οι προηγούμενες δομές που παρουσιάστηκαν μπορούν να θεωρηθούν περιπτώσεις γράφων. Πολλά προβλήματα και καταστάσεις της καθημερινής μας ζωής μπορούν να περιγραφούν με τη βοήθεια γράφων. Για παράδειγμα, τα σημεία ενός γράφου μπορούν να παριστούν πόλεις και οι γραμμές τις οδικές συνδέσεις μεταξύ τους. Λόγω της μεγάλης πληθώρας και ποικιλίας των προβλημάτων που σχετίζονται με γράφους, έχει αναπτυχθεί ομώνυμη θεωρία, η Θεωρία Γράφων. 7
ΕΠΙΔΟΣΗ ΑΠΟΔΟΤΙΚΟΤΗΤΑ ΑΛΓΟΡΙΘΜΩΝ 12.10 Ποια ερωτήματα προκύπτουν για την κατανόηση της επίδοσης ενός αλγορίθμου; Για την κατανόηση της επίδοσης ενός αλγορίθμου χρειάζεται να απαντηθεί ένα σύνολο ερωτημάτων. Τα πρωταρχικά ερωτήματα που προκύπτουν είναι: πώς υπολογίζεται ο χρόνος εκτέλεσης ενός αλγορίθμου; πώς μπορούν να συγκριθούν μεταξύ τους οι διάφοροι αλγόριθμοι; πώς μπορεί να γνωρίζει κανείς αν ένας αλγόριθμος είναι «βέλτιστος»; Οι πληροφορίες αυτές αφορούν κυρίως στην αναγνώριση της χειρότερης περίπτωσης του αλγορίθμου και στην αποτύπωση του μεγέθους του προβλήματος με βάση το πλήθος των δεδομένων. 12.11 Τι αφορά η χειρότερη περίπτωση ενός αλγορίθμου; Η χειρότερη περίπτωση (worst case scenario) ενός αλγορίθμου αφορά στο μέγιστο κόστος εκτέλεσης του αλγορίθμου, κόστος που αποτιμάται σε υπολογιστικούς πόρους. Το κόστος αυτό πολλές φορές κρίνει την επιλογή και το σχεδιασμό ενός αλγορίθμου. Για να εκφραστεί αυτή η χειρότερη περίπτωση, χρειάζεται κάποιο μέγεθος σύγκρισης και αναφοράς που να χαρακτηρίζει τον αλγόριθμο. Η πλέον συνηθισμένη πρακτική είναι η μέτρηση του αριθμού των βασικών πράξεων που θα πρέπει να εκτελέσει ο αλγόριθμος στη χειρότερη περίπτωση. Για παράδειγμα, μία βασική πράξη μπορεί να είναι: η εντολή ανάθεση τιμής, η σύγκριση μεταξύ δύο μεταβλητών ή οποιαδήποτε αριθμητική πράξη μεταξύ δύο μεταβλητών. Η χειρότερη περίπτωση αντιπροσωπεύει τις τιμές εκείνες που, όταν δίνονται ως είσοδος στον αλγόριθμο, οδηγούν στην εκτέλεση του μέγιστου αριθμού βασικών πράξεων. Αν, για παράδειγμα, θέλουμε να αποτιμήσουμε τη χειρότερη περίπτωση του διπλανού αλγορίθμου, τότε είναι προφανές ότι η χειρότερη περίπτωση προκύπτει όταν γίνουν 10 επαναλήψεις (δηλαδή μέχρι n = 0). Το μέγεθος του αλγορίθμου μπορεί να εκφραστεί από τη μεταβλητή n, που στην ουσία εκφράζει το πλήθος των επαναλήψεων του βασικού βρόχου του αλγορίθμου. Γενικά, τα δεδομένα συνιστούν το μέγεθος της εισόδου ενός αλγορίθμου. 12.12 Ποιο το μέγεθος και η βασική πράξη των παρακάτω αλγορίθμων; Αλγόριθμος Παράδειγμα1 n 10 Αρχή_επανάληψης Διάβασε m n n 1 Μέχρις_ότου (m = 0) Ή (n = 0) Εκτύπωσε m Τέλος Παράδειγμα1 Μέγεθος εισόδου και βασική πράξη αλγορίθμων Αλγόριθμος Μέγεθος εισόδου αλγορίθμου (n) Βασική Πράξη Ταξινόμηση το πλήθος των αντικειμένων που θα ταξινομηθούν σύγκριση Πολλαπλασιασμός το πλήθος των ψηφίων των αριθμών που θα πολλαπλασιασθούν αριθμητικές πράξεις Αναζήτηση το πλήθος των στοιχείων του πίνακα σύγκριση 8
12.13 Ποια είναι η επίδοση και ο χρόνος εκτέλεσης του παρακάτω αλγορίθμου; Αλγόριθμος Παράδειγμα2 x 123 y 234 Για i από 0 μέχρι 4 Εκτύπωσε i z x * y Τέλος_επανάληψης Εκτύπωσε x Εκτύπωσε y Εκτύπωσε z Τέλος Παράδειγμα2 Η επίδοση του παραπάνω αλγορίθμου θα υπολογιστεί με βάση τον αριθμό των πράξεων που θα εκτελεστούν. Με δεδομένο ότι ο βρόχος του προγράμματος θα εκτελεστεί 5 φορές, προκύπτει η παρακάτω ανάλυση: Εντολή αλγορίθμου Αριθμός πράξεων ανάθεση τιμών στα x και y 2 βρόχος επανάληψης αρχική τιμή i 1 έλεγχος i 6 αύξηση i 5 εκτύπωση i 5 υπολογισμός z (2x5) 10 εκτύπωση x, y, z 3 ΣΥΝΟΛΟ 32 Οι βρόχοι επανάληψης αποτελούν το κρίσιμο σημείο για το χαρακτηρισμό της επίδοσης ενός αλγορίθμου. Έτσι, αν ο αλγόριθμος αυτός γενικευθεί ώστε ο βρόχος να εκτελεστεί n φορές, ο χρόνος εκτέλεσης θα εξαρτάται από το μέγεθος του n. Ο παρακάτω πίνακας παρουσιάζει τους χρόνους εκτέλεσης του αλγορίθμου αυτού για διαφορετικά μεγέθη του n: Χρόνοι εκτέλεσης αλγορίθμου ανάλογα με το μέγεθος μέγεθος n Χρόνος εκτέλεσης 5 42 μικρο-δευτερόλεπτα 10 77 μικρο-δευτερόλεπτα 100 707 μικρο-δευτερόλεπτα 1.000.000 7 δευτερόλεπτα (περίπου) 12.14 Πώς αντιλαμβάνεστε την αποδοτικότητα ενός αλγορίθμου; Αν η επίλυση ενός προβλήματος επιτυγχάνεται με τη χρήση δύο ή περισσότερων αλγορίθμων, χρειάζεται να γίνει η επιλογή του καταλληλότερου με βάση την αποδοτικότητά τους. Έτσι, αν ο αλγόριθμος Β έχει το ίδιο αποτέλεσμα με τον αλγόριθμο Α αλλά δίνει τα αποτελέσματα σε λιγότερο χρόνο, τότε είναι αποδοτικότερος του Α. Με παρόμοιο τρόπο, όταν ο αλγόριθμος Β έχει το ίδιο αποτέλεσμα με έναν αλγόριθμο Α αλλά έχει τα αποτελέσματα με χρήση λιγότερης μνήμης, τότε 9
είναι αποδοτικότερος του Α. Βέβαια, όταν συγκρίνονται δύο αλγόριθμοι, θα πρέπει να συγκρίνονται με χρήση των ίδιων δεδομένων και κάτω από τις ίδιες συνθήκες. 12.15 Ποιοι παράγοντες καθορίζουν το χρόνο εκτέλεσης ενός αλγορίθμου; Οι παράγοντες που καθορίζουν το χρόνο εκτέλεσης ενός αλγορίθμου είναι: ο τύπος του ηλεκτρονικού υπολογιστή που θα εκτελέσει το πρόγραμμα του αλγορίθμου, η γλώσσα προγραμματισμού που θα χρησιμοποιηθεί, η δομή του προγράμματος και οι δομές δεδομένων που χρησιμοποιούνται, ο χρόνος που απαιτείται για την πρόσβαση στο δίσκο και για τις ενέργειες εισόδου-εξόδου, το είδος του συστήματος, ενός χρήστη ή πολλών χρηστών. 12.16 Ποιοι παράγοντες πρέπει να ικανοποιούνται κατά τη σύγκριση δύο προγραμμάτων; Κατά τη σύγκριση δύο προγραμμάτων θα πρέπει: και τα δύο προγράμματα να έχουν συνταχθεί στην ίδια γλώσσα προγραμματισμού, να έχει χρησιμοποιηθεί ο ίδιος μεταφραστής της γλώσσας προγραμματισμού, να χρησιμοποιείται η ίδια υπολογιστική πλατφόρμα, ακριβώς τα ίδια δεδομένα να αποτελούν είσοδο κατά τον έλεγχο των δύο αλγορίθμων. ΠΟΛΥΠΛΟΚΟΤΗΤΑ ΑΛΓΟΡΙΘΜΩΝ 12.17 Με ποιους τρόπους επιτυγχάνεται η μέτρηση της επίδοσης ενός αλγορίθμου; Ο απλούστερος τρόπος μέτρησης της επίδοσης ενός αλγορίθμου είναι ο εμπειρικός (empirical) ή, αλλιώς, ο λεγόμενος εκ των υστέρων (a posteriori). Δηλαδή, ο αλγόριθμος υλοποιείται και εφαρμόζεται σε ένα σύνολο δεδομένων, ώστε να υπολογισθεί ο απαιτούμενος χρόνος επεξεργασίας (processing time) και η χωρητικότητα μνήμης (memory space). Ο τρόπος όμως αυτός παρουσιάζει δύο κύρια μειονεκτήματα. Αφενός είναι δύσκολο να προβλεφθεί η συμπεριφορά του αλγορίθμου για κάποιο άλλο σύνολο δεδομένων, αφετέρου ο χρόνος επεξεργασίας εξαρτάται από το υλικό, τη γλώσσα προγραμματισμού και το μεταφραστή και προπάντων από τη δεινότητα του προγραμματιστή. Έτσι μπορεί να συναχθούν λανθασμένες εκτιμήσεις για την επίδοση του αλγορίθμου. Ο δεύτερος τρόπος εκτίμησης της επίδοσης ενός αλγορίθμου είναι ο θεωρητικός (theoretical) ή, αλλιώς, ο λεγόμενος εκ των προτέρων (a priori). Για το σκοπό αυτό εισάγεται μία μεταβλητή n, που εκφράζει το μέγεθος (size) του προβλήματος, ώστε η μέτρηση της αποδοτικότητας του αλγορίθμου να ισχύει για οποιοδήποτε σύνολο δεδομένων και ανεξάρτητα από υποκειμενικούς παράγοντες, ό- πως αυτοί που αναφέρθηκαν. Η σημασία της μεταβλητής αυτής εξαρτάται από το πρόβλημα που πρόκειται να επιλυθεί. Για παράδειγμα, αν το πρόβλημα είναι η ταξινόμηση k στοιχείων, τότε n = k. Στη συνέχεια ο χρόνος επεξεργασίας και ο απαιτούμενος χώρος μνήμης εκτιμώνται με τη βοήθεια μιας συνάρτησης f(n), που εκφράζει τη χρονική πολυπλοκότητα (time complexity) ή την πολυπλοκότητα χώρου (space complexity). 12.18 Τι καλείται τάξη ενός αλγορίθμου; Ορισμός Αν η πολυπλοκότητα ενός αλγορίθμου είναι f (n), τότε λέγεται ότι είναι τάξης O(g(n)), αν υπάρχουν δύο θετικοί ακέραιοι c και n 0, έτσι ώστε για κάθε n n0 να ισχύει: f (n) c g(n) 10
3 2 Έστω ότι η πολυπλοκότητα ενός αλγορίθμου δίνεται από το πολυώνυμο f(n) 2n 5n 4n 3. Ο πιο σημαντικός όρος του πολυωνύμου είναι η τρίτη δύναμη, ενώ η σημασία των υπόλοιπων όρων σταδιακά μειώνεται επιπλέον, αγνοείται ο συντελεστής 2 της τρίτης δύναμης. Έτσι προκύπτει ότι 3 3 g(n) n και η πολυπλοκότητα του αλγορίθμου είναι O(n ). Η έκφραση αυτή εκφράζει την ποιοτική και όχι την ποσοτική συμπεριφορά του αλγορίθμου. Κατά τον ίδιο τρόπο, αν δοθεί η έκφραση n 2 n f(n) 5 2 4n 4logn, τότε προκύπτει ότι g(n) 2, καθώς αγνοούνται οι μη σημαντικοί όροι του f (n) και ο συντελεστής 5 του όρου n 2. 12.19 Ποιες είναι οι κατηγορίες χρονικής πολυπλοκότητας ενός αλγορίθμου; Οι κατηγορίες χρονικής πολυπλοκότητας ενός αλγορίθμου είναι: O(1) : Κάθε εντολή του προγράμματος εκτελείται μία φορά ή, το πολύ, μερικές μόνο φορές. Στην περίπτωση αυτή λέγεται ότι ο αλγόριθμος είναι σταθερής πολυπλοκότητας. O(log n) : Ο αλγόριθμος είναι λογαριθμικής πολυπλοκότητας. Ας σημειωθεί ότι με «log» θα συμβολίζεται ο δυαδικός λογάριθμος, ενώ με «ln» θα συμβολίζεται ο φυσικός λογάριθμος. Συνήθως, οι λογάριθμοι που χρησιμοποιούνται στο βιβλίο αυτό είναι δυαδικοί. O(n) : Η πολυπλοκότητα λέγεται γραμμική. Αυτή είναι η καλύτερη επίδοση για έναν αλγόριθμο που πρέπει να εξετάσει ή να δώσει στην έξοδο n στοιχεία. O(n log n) : Διαβάζεται όπως ακριβώς γράφεται, n log n, δηλαδή χωρίς να χρησιμοποιείται κάποιο επίθετο (όπως, για παράδειγμα, γραμμολογαριθμική). Στην κατηγορία αυτή ανήκει μία πολύ σπουδαία οικογένεια αλγορίθμων ταξινόμησης. 2 O(n ) : Τετραγωνική πολυπλοκότητα. Πρέπει να χρησιμοποιείται μόνο για προβλήματα μικρού μεγέθους. 3 O(n ) : Κυβική πολυπλοκότητα. Και αυτοί οι αλγόριθμοι πρέπει να χρησιμοποιούνται μόνο για προβλήματα μικρού μεγέθους. n O(2 ) : Σπάνια στην πράξη χρησιμοποιούνται αλγόριθμοι εκθετικής πολυπλοκότητας. Χρόνοι εκτέλεσης αλγορίθμων ανάλογα με την πολυπλοκότητα και το μέγεθος Πολυπλοκότητα αλγορίθμου Μέγεθος προβλήματος n = 20 n = 40 n = 60 O(n) 0.00002 δεύτερα 0.00004 δεύτερα 0.00006 δεύτερα 2 O(n ) 0.0004 δεύτερα 0.0016 δεύτερα 0.0036 δεύτερα 3 O(n ) 0.008 δεύτερα 0.064 δεύτερα 216 δεύτερα O(2n) 1.0 δεύτερo 2.7 ημέρες 366 αιώνες O(n!) 771 αιώνες 3 1032 αιώνες 3 1066 αιώνες 11
12.20 Ποια είναι η πολυπλοκότητα του αλγορίθμου ταξινόμησης ευθείας ανταλλαγής; Το πιο βασικό κριτήριο της επίδοσης μιας μεθόδου ταξινόμησης είναι ο αριθμός C, που μετρά τις απαιτούμενες συγκρίσεις κλειδιών (key comparisons) που εκτελούνται μέχρι να τελειώσει η ταξινόμηση. Ένα άλλο κριτήριο είναι ο αριθμός Μ, που μετρά τις μετακινήσεις (moves) των στοιχείων. Οι αριθμοί C και M είναι συναρτήσεις του αριθμού n των στοιχείων που πρέπει να ταξινομηθούν. Με βάση τον αλγόριθμο όπως περιγράφεται στην παράγραφο, εύκολα προκύπτει ότι ο αριθμός των συγκρίσεων στην καλύτερη, τη μέση και τη χειρότερη περίπτωση είναι ο ίδιος. Ο αριθμός αυτός είναι: C 1 2... (n 1). Με βάση τις ιδιότητες της αριθμητικής προόδου προκύπτει ότι n(n 1) C, που τελικά σημαίνει ότι η πολυπλοκότητα της ταξινόμησης αυτής είναι 2 2 O(n ). 12.21 Ποια είναι η πολυπλοκότητα του αλγορίθμου γραμμικής αναζήτησης; Έχουμε ήδη μελετήσει την απλούστερη μέθοδο αναζήτησης, τη γραμμική ή σειριακή μέθοδο. Όταν αναζητούμε ένα κλειδί που πράγματι υπάρχει στον πίνακα, τότε λέμε ότι η αναζήτηση είναι επιτυχής (successful). Στην αντίθετη περίπτωση, λέμε ότι η αναζήτηση είναι ανεπιτυχής (unsuccessful). Το κόστος της αναζήτησης μετράται με τον αριθμό των συγκρίσεων κλειδιών. Έτσι το κόστος αυτό για την επιτυχή αναζήτηση συμβολίζεται με Ε, ενώ για την ανεπιτυχή αναζήτηση συμβολίζεται με Α. Ας εξετάσουμε αρχικά πώς προκύπτει η πολυπλοκότητα της επιτυχούς αναζήτησης σε μη ταξινομημένο πίνακα που αποτελείται από n στοιχεία. Αν αναζητάμε το πρώτο στοιχείο, τότε η επιτυχής αναζήτηση θα κοστίσει μία σύγκριση, ενώ αν αναζητάμε το δεύτερο στοιχείο, τότε το κόστος είναι δύο συγκρίσεις. Με την ίδια λογική, αν αναζητάμε το n-οστό στοιχείο, τότε θα εκτελεσθούν n συγκρίσεις κλειδιών μέχρι την περάτωση του αλγορίθμου. Έτσι, κατά μέσο όρο, ο απαιτούμενος αριθμός συγκρίσεων κλειδιών για την επιτυχή αναζήτηση είναι: 1 2... n n(n 1) n 1 E n 2n 2 Από τη σχέση αυτή εύκολα καταλήγουμε στο συμπέρασμα ότι η επιτυχής αναζήτηση έχει πολυπλοκότητα της τάξης O(n), με την απαραίτητη προϋπόθεση ότι τα κλειδιά που αναζητάμε είναι ισοπίθανα. Η πολυπλοκότητα της ανεπιτυχούς αναζήτησης είναι επίσης τάξης O(n). Αυτό προκύπτει με βάση την απλή σκέψη ότι, όταν το αναζητούμενο κλειδί δεν υπάρχει στον πίνακα, τότε η αναζήτηση καταλήγει να εξετάσει ένα προς ένα όλα τα κλειδιά μέχρι το τέλος του πίνακα. Αν ο πίνακας είναι ταξινομημένος, τότε η διαδικασία της επιτυχούς και της ανεπιτυχούς αναζήτησης μπορεί να βελτιωθεί, ωστόσο και πάλι η πολυπλοκότητα θα είναι γραμμικής τάξης. Πολυπλοκότητες μερικών αλγορίθμων Αλγόριθμος Ώθηση απώθηση σε στοίβα Εισαγωγή εξαγωγή σε ουρά Fibonacci επαναληπτική Πολυπλοκότητα O(1) O(1) O(n) Ταξινόμηση ευθείας ανταλλαγής 2 O(n ) Σειριακή αναζήτηση O(n) Δυαδική αναζήτηση O(log n) 12
ΘΕΜΑΤΑ ΜΕ ΑΠΑΝΤΗΣΗ 12.22 Έστω ότι σε μία στοίβα εισάγονται τρία στοιχεία με τη σειρά: πρώτα το Κ, μετά το Λ και τέλος το Μ, τα οποία αργότερα εξάγονται. Όμως, οι εξαγωγές αυτές μπορούν να συμβούν οποτεδήποτε μεταξύ ή μετά τις εισαγωγές. Να γράψετε όλες τις δυνατές διατάξεις των παραπάνω στοιχείων. Θα συμβεί το ίδιο όταν χρησιμοποιηθεί αντί για στοίβα ουρά; Λύση Το πλήθος των διαφορετικών διατάξεων 3 στοιχείων είναι 3! = 1*2*3 = 6. Οι δυνατές όμως διατάξεις χρησιμοποιώντας στοίβα είναι οι εξής 5: α. ΚΛΜ: ώθηση Κ απώθηση Κ, ώθηση Λ απώθηση Λ, ώθηση Μ απώθηση Μ β. ΚΜΛ: ώθηση Κ απώθηση Κ, ώθηση Λ, ώθηση Μ απώθηση Μ, απώθηση Λ γ. ΛΜΚ: ώθηση Κ, ώθηση Λ απώθηση Λ, ώθηση Μ απώθηση Μ, απώθηση Κ δ. ΛΚΜ: ώθηση Κ, ώθηση Λ απώθηση Λ, απώθηση Κ, ώθηση Μ απώθηση Μ ε. ΜΛΚ: ώθηση Κ, ώθηση Λ, ώθηση Μ απώθηση Μ, απώθηση Λ, απώθηση Κ Προφανώς, χρησιμοποιώντας ουρά για τα τρία αυτά στοιχεία και με προϋπόθεση ότι η σειρά εισαγωγής των στοιχείων είναι Κ, Λ, Μ, η μοναδική διάταξη που προκύπτει είναι η ΚΛΜ. Αυτό είναι το αποτέλεσμα της λειτουργίας FIFO της ουράς. 12.23 Μια γαλακτοβιομηχανία παστεριώνει τα γάλατα που συλλέγει από τους παραγωγούς ανάλογα με την ημερομηνία παραγωγής του γάλακτος. Έτσι συλλέγει αρχικά το γάλα σε διαφορετικά δοχεία και το παστεριώνει με σειρά προτεραιότητας. Θα πρέπει δηλαδή το γάλα το οποίο παρήχθη πρώτο να παστεριωθεί πρώτο. Να γραφεί πρόγραμμα σε ΓΛΩΣΣΑ το οποίο: α. Να εισάγει αρχικά την τιμή 0 σε όλες τις θέσεις του πίνακα Α[10] και τον κενό χαρακτήρα στον πίνακα Κ[10] αντίστοιχα. β. Να εισάγει στον πίνακα Α[10] τις ημέρες που έχουν παρέλθει από την παραγωγή του κάθε διαφορετικού δοχείου γάλακτος και στον παράλληλο πίνακα Κ[10] τον αντίστοιχο κωδικό του δοχείου, χρησιμοποιώντας τη λειτουργία της εισαγωγής σε ουρά. Κατά τη διαδικασία αυτή θα πρέπει οι ημέρες παραγωγής που εισάγονται στον πίνακα Α να είναι λιγότερες από τις προηγούμενες. γ. Να εμφανίζει κατά σειρά τους κωδικούς των δοχείων τα οποία πρέπει να παστεριωθούν, χρησιμοποιώντας τη λειτουργία της εξαγωγής. δ. Η παραπάνω διαδικασία να ελέγχεται από αντίστοιχο μενού επιλογής. Λύση ΠΡΟΓΡΑΜΜΑ queue ΜΕΤΑΒΛΗΤΕΣ ΑΚΕΡΑΙΕΣ: Ι, Π, REAR, FRONT, Α[10], Η ΧΑΡΑΚΤΗΡΕΣ: Κ[10], Choice ΑΡΧΗ ΓΙΑ Ι ΑΠΟ 1 ΜΕΧΡΙ 10 Α[Ι] <- 0 Κ[Ι] <- ' ' ΓΡΑΨΕ 'Δώστε επιλογή' ΔΙΑΒΑΣΕ Choice 13
ΜΕΧΡΙΣ_ΟΤΟΥ Choice = 'εισαγωγή' Ή Choice = 'εξαγωγή' Ή Choice = 'έξοδος' Π <- 0 REAR <- 0 FRONT <- 0 ΟΣΟ Choice <> 'έξοδος' ΕΠΑΝΑΛΑΒΕ ΑΝ Choice = 'εισαγωγή' ΤΟΤΕ ΑΝ REAR = 10 ΤΟΤΕ ΓΡΑΨΕ 'Τα δοχεία είναι γεμάτα' REAR <- REAR + 1 Π <- Π + 1 ΑΝ Π = 1 ΤΟΤΕ ΔΙΑΒΑΣΕ Α[REAR], Κ[REAR] Η <- Α[REAR] FRONT <- 1 ΓΡΑΨΕ 'Δώστε ημέρες παραγωγής' ΔΙΑΒΑΣΕ Α[REAR] ΜΕΧΡΙΣ_ΟΤΟΥ Α[REAR] > Η Η <- Α[REAR] ΓΡΑΨΕ 'Δώστε κωδικό δοχείου' ΔΙΑΒΑΣΕ Κ[REAR] ΑΝ FRONT = 0 Ή FRONT > REAR ΤΟΤΕ ΓΡΑΨΕ 'Τα δοχεία είναι άδεια' ΓΡΑΨΕ 'Παστερίωση δοχείου', Κ[FRONT] Α[FRONT] <- 0 Κ[FRONT] <- ' ' FRONT <- FRONT + 1 ΓΡΑΨΕ 'Δώστε επιλογή' ΔΙΑΒΑΣΕ Choice ΜΕΧΡΙΣ_ΟΤΟΥ Choice = 'εισαγωγή' Ή Choice = 'εξαγωγή' Ή Choice = 'έξοδος' ΤΕΛΟΣ_ΠΡΟΓΡΑΜΜΑΤΟΣ 12.24 Στη χώρα της Αραρουνίας ο πληθωρισμός τρέχει με μηνιαίο ρυθμό 5%. Η εταιρία κατασκευής και εμπορίας φωτοτυπικού χαρτιού KAR2, θέλοντας αφενός να κυριαρχήσει στην αγορά, αφετέρου να μεγιστοποιήσει τα κέρδη της, αποθηκεύει πρώτη ύλη σε μεγάλα ρολά στις αποθήκες της, χρησιμοποιώντας στη συνέχεια την πιο πρόσφατα αποθηκευμένη πρώτη ύλη. Το περιθώριο κέρδους της εταιρίας είναι 10% στην τιμή αγοράς ανά ρολό και η κάθε μηνιαία παραγγελία πρώτης 14
ύλης αποτελείται από 20 ρολά. Η αποθήκη της εταιρίας έχει δυνατότητα αποθήκευσης έως και 240 ρολά πρώτης ύλης. Να γραφεί πρόγραμμα σε ΓΛΩΣΣΑ το οποίο: α. Να εισάγει αρχικά την τιμή 0 σε όλες τις θέσεις του πίνακα Α[12] και τον κενό χαρακτήρα στον πίνακα Κ[12] αντίστοιχα. β. Να εισάγει στον πίνακα Α[12] την τιμή αγοράς της κάθε παραγγελίας και στον παράλληλο πίνακα Κ[12] τον αντίστοιχο κωδικό της, υλοποιώντας τη λειτουργία της ώθησης σε στοίβα. Κατά τη διαδικασία αυτή να γίνεται έλεγχος ώστε η κάθε παραγγελία να έχει τιμή αγοράς υψηλότερη κατά 5% από την αμέσως προηγούμενη. Η λειτουργία της ώθησης να ολοκληρώνεται όταν γεμίσει η αποθήκη. γ. Να διαβάζει την ποσότητα της πρώτης ύλης που πρέπει να χρησιμοποιηθεί για την κατασκευή φωτοτυπικού χαρτιού ελέγχοντας ώστε αυτή να είναι πολλαπλάσια του 20 και να μην υπερβαίνει την αποθηκευμένη πρώτη ύλη. Στη συνέχεια να εμφανίζει τον κωδικό και την τιμή αγοράς της χρησιμοποιούμενης πρώτης ύλης υλοποιώντας τη λειτουργία της απώθησης από τη στοίβα, ελέγχοντας παράλληλα την υποχείλισή της. Η ώθηση και η απώθηση να ε- λέγχονται από αντίστοιχο μενού με επιλογές Ω (ώθηση), Α (απώθηση), Ε (έξοδος). δ. Να εμφανίζει μετά από την έξοδο τα κέρδη της εταιρίας. Λύση ΠΡΟΓΡΑΜΜΑ stack ΜΕΤΑΒΛΗΤΕΣ ΑΚΕΡΑΙΕΣ: Ι, J, K, Π, TOP, ΠΟΣΟΤΗΤΑ ΠΡΑΓΜΑΤΙΚΕΣ: Α[12], ΚΕΡΔΗ, ΤΙΜΗ ΧΑΡΑΚΤΗΡΕΣ: Κ[12], Choice ΑΡΧΗ ΓΙΑ Ι ΑΠΟ 1 ΜΕΧΡΙ 12 Α[Ι] <- 0 Κ[Ι] <- ' ' ΓΡΑΨΕ 'Δώστε επιλογή' ΔΙΑΒΑΣΕ Choice ΜΕΧΡΙΣ_ΟΤΟΥ Choice = 'Ω' Ή Choice = 'Α' Ή Choice = 'Ε' ΚΕΡΔΗ <- 0 Π <- 0 TOP <- 0 ΠΟΣΟΤΗΤΑ <- 0 ΟΣΟ Choice <> 'Ε' ΕΠΑΝΑΛΑΒΕ ΑΝ Choice = 'Ω' ΤΟΤΕ ΑΝ TOP = 12 ΤΟΤΕ ΓΡΑΨΕ 'Η αποθήκη είναι γεμάτη' Π <- Π + 1 TOP <- TOP + 1 ΑΝ Π = 1 ΤΟΤΕ ΔΙΑΒΑΣΕ Α[ΤΟP], Κ[ΤΟP] ΤΙΜΗ <- Α[ΤΟP] 15
ΓΡΑΨΕ 'Δώστε τιμή αγοράς' ΔΙΑΒΑΣΕ Α[ΤΟP] ΜΕΧΡΙΣ_ΟΤΟΥ Α[ΤΟP] > 1.05 * ΤΙΜΗ ΤΙΜΗ <- Α[ΤΟP] ΓΡΑΨΕ 'Δώστε κωδικό παραγγελίας' ΔΙΑΒΑΣΕ Κ[ΤΟP] ΠΟΣΟΤΗΤΑ <- ΠΟΣΟΤΗΤΑ + 20 ΑΝ TOP = 0 ΤΟΤΕ ΓΡΑΨΕ 'Η αποθήκη είναι άδεια' ΓΡΑΨΕ 'Δώσε ποσότητα πρώτης ύλης' ΔΙΑΒΑΣΕ ΠΟΣ ΜΕΧΡΙΣ_ΟΤΟΥ ΠΟΣ < = ΠΟΣΟΤΗΤΑ ΚΑΙ ΠΟΣ DIV 20 = 0 Κ <- ΠΟΣ DIV 20 J <- 0 ΓΙΑ Ι ΑΠΟ TOP ΜΕΧΡΙ TOP + 1 K ME_BHMA 1 J <- J + 5 ΚΕΡΔΗ <- ΚΕΡΔΗ + Α[I] * (J + 10) / 100 ΠΟΣΟΤΗΤΑ <- ΠΟΣΟΤΗΤΑ 20 Α[I] <- 0 Κ[I] <- ' ' ΓΡΑΨΕ 'Δώστε επιλογή' ΔΙΑΒΑΣΕ Choice ΜΕΧΡΙΣ_ΟΤΟΥ Choice = 'Ω' Ή Choice = 'Α' Ή Choice = 'Ε' ΓΡΑΨΕ ΚΕΡΔΗ ΤΕΛΟΣ_ΠΡΟΓΡΑΜΜΑΤΟΣ 16