Αναδρομικός αλγόριθμος Ένας αναδρομικός αλγόριθμος επιλύει ένα πρόβλημα για κάποιες τιμές δεδομένων λύνοντας το ίδιο πρόβλημα για άλλες (σχετιζόμενες) τιμές δεδομένων Είναι απαραίτητο βέβαια να λύνεται το πρόβλημα απευθείας για κάποιες συγκεκριμένες τιμές
Αναδρομικός αλγόριθμος Ένας αναδρομικός αλγόριθμος επιλύει ένα πρόβλημα για κάποιες τιμές δεδομένων λύνοντας το ίδιο πρόβλημα για άλλες (σχετιζόμενες) τιμές δεδομένων Είναι απαραίτητο βέβαια να λύνεται το πρόβλημα απευθείας για κάποιες συγκεκριμένες τιμές είναι συχνά πιο αποδοτικός (εύκολος, γρήγορος, απλός) από τον ισοδύναμο μη αναδρομικό
Αναδρομικός αλγόριθμος Ένας αναδρομικός αλγόριθμος επιλύει ένα πρόβλημα για κάποιες τιμές δεδομένων λύνοντας το ίδιο πρόβλημα για άλλες (σχετιζόμενες) τιμές δεδομένων Είναι απαραίτητο βέβαια να λύνεται το πρόβλημα απευθείας για κάποιες συγκεκριμένες τιμές είναι συχνά πιο αποδοτικός (εύκολος, γρήγορος, απλός) από τον ισοδύναμο μη αναδρομικό υλοποιείται με υποπρόγραμμα που πρέπει να καλεί τον εαυτό του
Αναδρομικός αλγόριθμος Ένας αναδρομικός αλγόριθμος επιλύει ένα πρόβλημα για κάποιες τιμές δεδομένων λύνοντας το ίδιο πρόβλημα για άλλες (σχετιζόμενες) τιμές δεδομένων Είναι απαραίτητο βέβαια να λύνεται το πρόβλημα απευθείας για κάποιες συγκεκριμένες τιμές είναι συχνά πιο αποδοτικός (εύκολος, γρήγορος, απλός) από τον ισοδύναμο μη αναδρομικό υλοποιείται με υποπρόγραμμα που πρέπει να καλεί τον εαυτό του Στη Fortran 95 τα υποπρογράμματα έχουν τη δυνατότητα να καλούν τον εαυτό τους, αν τροποποιηθούν κατάλληλα
Παράδειγμα: παραγοντικό Δύο ισοδύναμοι ορισμοί για το παραγοντικό ακέραιου μη αρνητικού αριθμού: Μη αναδρομικός n! = { 1 2 (n 1) n, n > 0, 1, n = 0 Aναδρομικός n! = { (n 1)! n, n > 0, 1, n = 0
Αναδρομική συνάρτηση παραγοντικού Όχι απόλυτα σωστός κώδικας Στις εντολές γράφουμε ακριβώς ό,τι μας λέει ο μαθηματικός ορισμός:
Αναδρομική συνάρτηση παραγοντικού Όχι απόλυτα σωστός κώδικας Στις εντολές γράφουμε ακριβώς ό,τι μας λέει ο μαθηματικός ορισμός: Ο παραπάνω κώδικας δεν είναι ΑΠΟΛΥΤΑ ΣΩΣΤΟΣ Χρειάζεται τροποποίηση Ας δούμε πρώτα πώς λειτουργεί
Αναδρομική συνάρτηση παραγοντικού (2/2) Πώς λειτουργεί Αν γράψουμε ο compiler εκτελεί την par με
Αναδρομική συνάρτηση παραγοντικού (2/2) Πώς λειτουργεί Αν γράψουμε ο compiler εκτελεί την par με Το αποτέλεσμα της είναι Δεν μπορεί να το επιστρέψει: καλείται μια συνάρτηση (η par για )
Αναδρομική συνάρτηση παραγοντικού (2/2) Πώς λειτουργεί Αν γράψουμε ο compiler εκτελεί την par με Το αποτέλεσμα της είναι Δεν μπορεί να το επιστρέψει: καλείται μια συνάρτηση (η par για ) Το αποτέλεσμα της είναι Δεν μπορεί να το επιστρέψει: καλείται μια συνάρτηση (η par για )
Αναδρομική συνάρτηση παραγοντικού (2/2) Πώς λειτουργεί Αν γράψουμε ο compiler εκτελεί την par με Το αποτέλεσμα της είναι Δεν μπορεί να το επιστρέψει: καλείται μια συνάρτηση (η par για ) Το αποτέλεσμα της είναι Δεν μπορεί να το επιστρέψει: καλείται μια συνάρτηση (η par για ) Το αποτέλεσμα της είναι Αυτό επιστρέφεται
Αναδρομική συνάρτηση παραγοντικού (2/2) Πώς λειτουργεί Αν γράψουμε ο compiler εκτελεί την par με Άρα Το αποτέλεσμα της είναι Δεν μπορεί να το επιστρέψει: καλείται μια συνάρτηση (η par για ) Το αποτέλεσμα της είναι Δεν μπορεί να το επιστρέψει: καλείται μια συνάρτηση (η par για ) Το αποτέλεσμα της είναι Αυτό επιστρέφεται par(2) par(1)*2 (par(0)*1)*2 (1*1)*2 = 2!
Γενικός ορισμός αναδρομικής συνάρτησης Στον ορισμό (και τη δήλωση) της συνάρτησης πρέπει δηλώσουμε ότι είναι αναδρομική και να διαχωρίσουμε το όνομα με το οποίο γίνεται η κλήση της συνάρτησης από τη μεταβλητή του ονόματος της συνάρτησης: όνομα(παράμετροςα, παράμετροςβ, ) & (όνομα2) τύπος_παραμέτρου_α, (xxx) :: παράμετροςα τύπος_παραμέτρου_β, (yyy) :: παράμετροςβ τύπος_επιστρεφόμενης_ποσότητας :: όνομα2 τύπος_α :: τοπική_μεταβλητή_α, τύπος_β :: τοπική_μεταβλητή_β,! κώδικας όνομα2 = όνομα
Αναδρομική συνάρτηση παραγοντικού Τροποποίηση του ορισμού Ο παραπάνω κώδικας είναι ΣΩΣΤΟΣ
Γενικός ορισμός αναδρομικής υπορουτίνας Σε υπορουτίνα που καλεί τον εαυτό της χρειάζεται μόνο η προσθήκη της λέξης πριν το : όνομα(παράμετροςα, παράμετροςβ, ) τύπος_παραμέτρου_α, (xxx) :: παράμετροςα τύπος_παραμέτρου_β, (yyy) :: παράμετροςβ τύπος_α :: τοπική_μεταβλητή_α, τύπος_β :: τοπική_μεταβλητή_β,! κώδικας όνομα
Παράδειγμα: πολυώνυμα Hermite (1/2) Στη Μαθηματική Φυσική χρησιμοποιείται η οικογένεια πολυωνύμων Hermite: H 0 (x) = 1, H 1 (x) = 2x, H 2 (x) = 4x 2 2, H 3 (x) = 8x 3 12x, H 4 (x) = 16x 4 48x 2 + 12, Τα πολυώνυμα H n (x) ικανοποιούν την αναδρομική σχέση: H n (x) = 2xH n 1 (x) 2(n 1)H n 2 (x), n 2
Παράδειγμα: πολυώνυμα Hermite (2/2) Αναδρομική συνάρτηση που υπολογίζει τα H n (x):
Υποπρογράμματα κατά στοιχείο (ELEMENTAL) Στις ενσωματωμένες συναρτήσεις το όρισμα μπορεί να είναι μία τιμή αλλά επιτρέπεται να είναι και διάνυσμα: Επιθυμούμε το ίδιο να μπορεί να γίνει και σε δικά μας υποπρογράμματα που δέχονται απλές μεταβλητές Γι αυτό συμπληρώνουμε τη δήλωση με το πριν τη λέξη ή
Παράδειγμα υπορουτίνας ELEMENTAL (1/2) Ορισμός
Παράδειγμα υπορουτίνας ELEMENTAL (2/2) Δήλωση και κλήση
Υπορουτίνα παραγωγής τυχαίων αριθμών (1/2) Η υπορουτίνα δέχεται μια πραγματική μεταβλητή Κάθε φορά που καλείται αποδίδει στο όρισμα τυχαία τιμή στο διάστημα [0, 1) Η υπορουτίνα είναι άρα δέχεται και διάνυσμα πραγματικών στους οποίους αποδίδει τυχαίες τιμές
Υπορουτίνα παραγωγής τυχαίων αριθμών (1/2) Η υπορουτίνα δέχεται μια πραγματική μεταβλητή Κάθε φορά που καλείται αποδίδει στο όρισμα τυχαία τιμή στο διάστημα [0, 1) Η υπορουτίνα είναι άρα δέχεται και διάνυσμα πραγματικών στους οποίους αποδίδει τυχαίες τιμές Παράδειγμα
Υπορουτίνα παραγωγής τυχαίων αριθμών (2/2) Αλλαγή διαστήματος Αν r είναι τυχαίος πραγματικός αριθμός στο [0, 1), τότε κάνουμε τη μετατροπή x = κr + λ και επιλέγουμε τους συντελεστές κ, λ ώστε η ποσότητα x να βρίσκεται εντός των επιθυμητών ορίων Εύκολα επαληθεύεται ότι ο x = (b a)r + a ικανοποιεί τις σχέσεις a x < b, άρα ο x είναι τυχαίος πραγματικός στο διάστημα [a, b)