Η παρουσίαση φορτώνεται. Παρακαλείστε να περιμένετε

Η παρουσίαση φορτώνεται. Παρακαλείστε να περιμένετε

Εισαγωγή στον Προγ/μό Υπολογιστών

Παρόμοιες παρουσιάσεις


Παρουσίαση με θέμα: "Εισαγωγή στον Προγ/μό Υπολογιστών"— Μεταγράφημα παρουσίασης:

1 Εισαγωγή στον Προγ/μό Υπολογιστών
Ενότητα 11: Αναζήτηση, Ταξινόμηση και Αξιολόγηση Αλγοριθμικής Απόδοσης Διδάσκων: Μιχάλης Τίτσιας

2 Αναζήτηση και Ταξινόμηση
Παρακάτω θα εξετάσουμε δύο βασικές πράξεις σε πίνακες (αναζήτηση και ταξινόμηση). Εκ των οποίων και οι δύο αποδεικνύεται πως είναι σημαντικές σε ένα ευρύ φάσμα πρακτικών εφαρμογών. Η απλούστερη από τις δύο είναι η αναζήτηση, η οποία είναι η διαδικασία της εύρεσης ενός συγκεκριμένου στοιχείου σ'έναν πίνακα ή άλλου είδους ακολουθία (ήδη κάτι τέτοιο το συναντήσαμε στα Strings!). Τυπικά, μια μέθοδος που υλοποιεί αναζήτηση θα επιστρέψει την θέση του πίνακα στην οποία ένα συγκεκριμένο στοιχείο εμφανίζεται, ή -1 αν αυτό δεν υπάρχει στον πίνακα. Το στοιχείο το οποίο αναζητούμε αποκαλείται κλειδί. Διαφορετικοί αλγόριθμοι υπάρχουν για την αναζήτηση (και ταξινόμηση). Η επιλογή όμως, του κατάλληλου αλγορίθμου για μια συγκεκριμένη εφαρμογή μπορεί να επηρεάσει σημαντικά το πόσο αποτελεσματικά τρέχει αυτή. Οπότε στην ενότητα αυτή θα μιλήσουμε και για αλγοριθμική αποδοτικότητα.

3 Γραμμική Αναζήτηση Η πιο απλή στρατηγική για αναζήτηση είναι να ξεκινήσουμε από την αρχή του πίνακα και να κοιτάξουμε κάθε στοιχείο με τη σειρά. Ο αλγόριθμος αυτός ονομάζεται γραμμική αναζήτηση. Η γραμμική αναζήτηση είναι απλή στην υλοποίηση. Όπως απεικονίζεται στην μέθοδο που ακολουθεί, η οποία επιστρέφει την πρώτη θέση στην οποία η τιμή κλειδί εμφανίζεται στον πίνακα, ή -1 αν αυτή δεν εμφανίζεται καθόλου: private int linearSearch(int key, int[] array) { for (int i = 0; i < array.length; i++) { if (key == array[i]) return i; } return -1;

4 Προσομοιώνοντας την Γραμμική Αναζήτηση
public void run() { int[] primes = { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29 }; println("linearSearch(17) -> " + linearSearch(17, primes)); println("linearSearch(27) -> " + linearSearch(27, primes)); } 1 2 3 4 5 6 7 8 11 13 17 19 23 29 9 private int linearSearch(int key, int[] array) { for ( int i = 0 ; i < array.length ; i++ ) { if (key == array[i]) return i; return -1; 27 key array i 10 public void run() { int[] primes = { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29 }; println("linearSearch(17) -> " + linearSearch(17, primes)); println("linearSearch(27) -> " + linearSearch(27, primes)); } private int linearSearch(int key, int[] array) { for ( int i = 0 ; i < array.length ; i++ ) { if (key == array[i]) return i; } return -1; 27 key array i private int linearSearch(int key, int[] array) { for ( int i = 0 ; i < array.length ; i++ ) { if (key == array[i]) return i; } return -1; 27 key array i primes 1 2 9 3 10 4 6 5 6 7 8 4 3 1 2 5 2 3 5 7 11 13 17 19 23 29 1 2 3 4 5 6 7 8 9 LinearSearch linearSearch(17) -> 6 linearSearch(27) -> -1 Παράληψη προσομοίωσης

5 Ένα Μεγαλύτερο Παράδειγμα
Για να επιδείξουμε την αποδοτικότητα της γραμμικής αναζήτησης, είναι χρήσιμο να δουλέψουμε με ένα κάπως μεγαλύτερο παράδειγμα. Το παράδειγμα στην επόμενη διαφάνεια χρησιμοποιεί έναν πίνακα που περιέχει 286 τηλεφωνικούς κωδικούς περιοχών που έχουν ανατεθεί στις Η.Π.Α. Ο σκοπός στο παράδειγμα αυτό είναι να αναζητήσουμε στην λίστα τον κωδικό περιοχής της Silicon Valley, που είναι 650. Ο αλγόριθμος γραμμικής αναζήτησης χρειάζεται να εξετάσει κάθε στοιχείο του πίνακα ώστε να βρει την τιμή που ταιριάζει. Καθώς ο πίνακας γίνεται μεγαλύτερος, ο αριθμός των βημάτων που απαιτούνται για την γραμμική αναζήτηση μεγαλώνει ανάλογα. Καθώς παρακολουθείτε την αργή διαδικασία της αναζήτησης για το 650 στην επόμενη διαφάνεια, προσπαθήστε να βρείτε έναν πιο αποδοτικό τρόπο με τον οποίο μπορείτε να ψάξετε στον συγκεκριμένο πίνακα για έναν δοθέντα κωδικό.

6 Γραμμική Αναζήτηση (Παράδειγμα Κωδικών Περιοχών)
201 202 203 205 206 207 208 209 210 212 213 214 215 216 217 218 219 224 225 228 229 231 234 239 240 248 251 252 253 254 256 260 262 267 269 270 276 281 283 301 302 303 304 305 307 308 309 310 312 313 314 315 316 317 318 319 320 321 323 325 330 331 334 336 337 339 347 351 352 360 361 364 385 386 401 402 404 405 406 407 408 409 410 412 413 414 415 416 417 419 423 424 425 430 432 434 435 440 443 445 469 470 475 478 479 480 484 501 502 503 504 505 507 508 509 510 512 513 515 516 517 518 520 530 540 541 551 559 561 562 563 564 567 570 571 573 574 575 580 585 586 601 602 603 605 606 607 608 609 610 612 614 615 616 617 618 619 620 623 626 630 631 636 641 646 660 661 662 678 682 701 702 703 704 706 707 708 712 713 714 715 716 717 718 719 720 724 727 731 732 734 740 754 757 760 762 763 765 769 770 772 773 774 775 779 781 785 786 801 802 803 804 805 806 808 810 812 813 814 815 816 817 818 828 830 831 832 835 843 845 847 848 850 856 857 858 859 860 862 863 864 865 870 878 901 903 904 906 907 908 909 910 912 913 914 915 916 917 918 919 920 925 928 931 936 937 940 941 947 949 951 952 954 956 959 970 971 972 973 978 979 980 985 989 651 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 650

7 Η Ιδέα της Δυαδικής Αναζήτησης
Το γεγονός ότι οι κωδικοί περιοχών είναι σε αύξουσα σειρά μας δίνει την δυνατότητα να βρούμε μια τιμή πιο αποδοτικά Η βασική ιδέα είναι πως λαμβάνουμε πιο πολλή πληροφορία ξεκινώντας από το μεσαίο στοιχείο παρά από το πρώτο. Κοιτώντας το μεσαίο στοιχείο σε σχέση με την τιμή που αναζητάτε, υπάρχουν τρία ενδεχόμενα: Αν η τιμή που αναζητάτε είναι μεγαλύτερη από το μεσαίο στοιχείο, τότε μπορείτε να αποκλείσετε το πάνω μισό του πίνακα. Αν η τιμή που αναζητάτε είναι μικρότερη από το μεσαίο στοιχείο, τότε μπορείτε να αποκλείσετε το κάτω μισό του πίνακα. Αν η τιμή που αναζητάτε είναι ίση με το μεσαίο στοιχείο, τότε μπορείτε να σταματήσετε επειδή βρήκατε την τιμή που ψάχνατε. Μπορείτε να επαναλάβετε αυτή την διαδικασία στα στοιχεία που απομένουν. Διότι, ο αλγόριθμος προχωρά διαιρώντας την λίστα των στοιχείων κάθε φορά στην μέση. Ονομάζετα δυαδική αναζήτηση (binary search).

8 Δυαδική Αναζήτηση (Παράδειγμα Κωδικών Περιοχών)
Το κλειδί 650 είναι ίσο με 650, άρα η διαδικασία τελείωσε. Συνέχισε με το στοιχείο 2 , που είναι 650 στην θέση 165: Η δ.α. Χρειάζεται να δει μόνο οχτώ στοιχεία ώστε να βρει το 650. Το κλειδί 650 είναι μικρότερο από 651, άρα διώξε το δεύτερο μισό. Συνέχισε με το στοιχείο 2 , το οποίο είναι 651 στην θέση 166: Το κλειδί 650 είναι μεγαλύτερο από 630, άρα διώξε το πρώτο μισό. Το κλειδί 650 είναι μικρότερο από 662, άρα διώξε το δεύτερο μισό. Το κλειδί 650 είναι μεγαλύτερο από 646, άρα διώξε το πρώτο μισό. Συνέχισε με την θέση 2 , που είναι 805 στην θέση 214: Το κλειδί 650 είναι μεγαλύτερο από 602, άρα διώξε το πρώτο μισό. Συνέχισε με το στοιχείο 2 , που είναι 646 στην θέση 164: Το κλειδί 650 είναι μικρότερο από 805, άρα διώξε το δεύτερο μισό. Το κλειδί 650 είναι λιγότερο από 708, άρα διώξε το δεύτερο μισό. Συνέχισε με την θέση 2 , που είναι 630 στην θέση 160: Ξεκίνα με τον έλεγχο της θέσης 2 , που είναι 602 στην θέση 142: Συνέχισε με την θέση 2 , που είναι 662 στην θέση 169: Συνέχισε με την θέση 2 , που είναι 708 στην θέση 178: 201 202 203 205 206 207 208 209 210 212 213 214 215 216 217 218 219 224 225 228 229 231 234 239 240 248 251 252 253 254 256 260 262 267 269 270 276 281 283 301 302 303 304 305 307 308 309 310 312 313 314 315 316 317 318 319 320 321 323 325 330 331 334 336 337 339 347 351 352 360 361 364 385 386 401 402 404 405 406 407 408 409 410 412 413 414 415 416 417 419 423 424 425 430 432 434 435 440 443 445 469 470 475 478 479 480 484 501 502 503 504 505 507 508 509 510 512 513 515 516 517 518 520 530 540 541 551 559 561 562 563 564 567 570 571 573 574 575 580 585 586 601 602 603 605 606 607 608 609 610 612 614 615 616 617 618 619 620 623 626 630 631 636 641 646 651 660 661 662 678 682 701 702 703 704 706 707 708 712 713 714 715 716 717 718 719 720 724 727 731 732 734 740 754 757 760 762 763 765 769 770 772 773 774 775 779 781 785 786 801 802 803 804 805 806 808 810 812 813 814 815 816 817 818 828 830 831 832 835 843 845 847 848 850 856 857 858 859 860 862 863 864 865 870 878 901 903 904 906 907 908 909 910 912 913 914 915 916 917 918 919 920 925 928 931 936 937 940 941 947 949 951 952 954 956 959 970 971 972 973 978 979 980 985 989 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 650

9 Υλοποιώντας την Δυαδική Αναζήτηση
Η παρακάτω μέθοδος υλοποιεί τον αλγόριθμο δυαδικής αναζήτησης για έναν πίνακα ακεραίων. private int binarySearch(int key, int[] array) { int lh = 0; int rh = array.length - 1; while (lh <= rh) { int mid = (lh + rh) / 2; if (key == array[mid]) return mid; if (key < array[mid]) { rh = mid - 1; } else { lh = mid + 1; } return -1; Μπορούμε να γράψουμε μια παρόμοια υλοποίηση της δυαδικής αναζήτησης που λειτουργεί σε συμβολοσειρές (strings). Ο αλγόριθμος είναι ο ίδιος.

10 Αποδοτικότητα της Γραμμικής Αναζήτησης
Από το παράδειγμα φαίνεται ξεκάθα, πως ο χρόνος εκτέλεσης του αλγορίθμου γραμμικής αναζήτησης εξαρτάται από το μέγεθος του πίνακα. Η ιδέα πως ο χρόνος που απαιτείται για να ψάξεις μια λίστα τιμών εξαρτάται από το πόσες τιμές υπάρχουν είναι διόλου εκπληκτική. Ο χρόνος εκτέλεσης εξαρτάται από το μέγεθος του προβλήματος στο οποίο εφαρμόζεται για την πλειονότητα των αλγορίθμων. Σε πολλές εφαρμογές, είναι εύκολο να βρούμε μια αριθμητική τιμή που καθορίζει το μέγεθος του προβλήματος, που γενικά συμβολίζεται με N. Για τις περισσότερες εφαρμογές σε πίνακα, το μέγεθος του προβλήματος είναι αυτό του πίνακα. Στην χειρότερη περίπτωση (που συμβαίνει όταν η τιμή που αναζητούμε βρίσκεται στο τέλος του πίνακα ή δεν υπάρχει καθόλου) η γραμμική αναζήτηση απαιτεί N βήματα. Κατά μέσο όρο, χρειάζεται περίπου τον μισό χρόνο.

11 Αποδοτικότητα της Γραμμικής Αναζήτησης
Ο χρόνος εκτέλεσης της δυαδικής αναζήτησης εξαρτάται κι αυτός από το μέγεθος του πίνακα, όμως με αλλιώτικο τρόπο. Σε κάθε βήμα της διαδικασίας, ο αλγόριθμος αποκλείει τις μισές από τις πιθανές θέσεις που απομένουν. Στην χειρότερη περίπτωση, ο αριθμός βημάτων που απαιτείται είναι ίσος με τον αριθμό των τιμών που μπορεί να διαιρέσεις στην μέση το αρχικό μέγεθος του πίνακα μέχρι να απομείνει ένα στοιχείο. Δηλαδή, αυτό που πρέπει να βρούμε είναι η τιμή του k που ικανοποιεί την ακόλουθη εξίσωση: 1 = N / 2 / 2 / 2 / / 2 k times Μπορούμε να απλοποιήσουμε την φόρμουλα αυτή ως εξής: 1 = N / 2k 2k = N k = log2 N

12 Συγκρίνοντας τις Αποδοτικότητες Αναζήτησης
Η διαφορά στον αριθμό των βημάτων που απαιτούνται από τους δύο αλγορίθμους φαίνεται στον ακόλουθο πίνακα, που συγκρίνει τις τιμές N και τον κοντινότερο ακεραίο στο log2 N: 3 log2 N N 7 10 20 30 100 1000 1,000,000 1,000,000,000 Για μεγάλες τιμές του N, η διαφορά στον αριθμό των βημάτων που απαιτούνται είναι τεράστια. Αν έπρεπε να ψάξετε σε μια λίστα εκατομμυρίων στοιχείων η δυαδική αναζήτηση θα έτρεχε 50,000 φορές γρηγορότερα από την γραμμική αναζήτηση. Αν υπήρχαν ένα δισσεκατομύριο στοιχεία, ο παράγοντας αυτός θα γινόταν 33,000,000.

13 Ταξινόμηση Η δυαδική αναζήτηση δουλεύει μόνο σε πίνακες των οποίων τα στοιχεία είναι διατεταγμένα σε σειρά. Η διαδικασία της τοποθέτησης των στοιχείων σε σειρά ονομάζεται ταξινόμηση. Υπάρχουν πολλοί αλγόριθμοι ικανοί για ταξινόμηση πίνακα. Όπως με την αναζήτηση, οι αλγόριθμοι αυτοί μπορεί να ποικίλουν ουσιαστικά στην αποδοτικότητα, ειδικά όσο ο πίνακας γίνεται μεγαλύτερος. Από όλους τους βασικούς αλγορίθμους στην Επιστήμη των Υπολογιστών, η ταξινόμηση είναι μακράν ο πιο σημαντικός σε σχέση με τις πρακτικές εφαρμογές της. Η αλφαβητική οργάνωση ενός τηλεφωνικού καταλόγου, η οργάνωση των αρχείων μιας βιβλιοθήκης ανά αριθμό καταλόγου, και η οργάνωση ομαδικής αλληλογραφίας με βάση τον ταχυδρομικό κώδικα είναι όλα παραδείγματα ταξινόμησης που ασχολούνται με πολύ μεγάλες συλλογές δεδομένων.

14 Ο Αλγόριθμος Ταξινόμησης Επιλογής
Από τους πολλούς αλγορίθμους ταξινόμησης, ο ευκολότερος προς περιγραφή είναι η ταξινόμηση επιλογής, που υλοποιείται από τον παρακάτω κώδικα: private void sort(int[] array) { for (int lh = 0; lh < array.length; lh++) { int rh = findSmallest(array, lh, array.length); swapElements(array, lh, rh); } Οι μεταβλητές lh και rh κρατούν τις θέσεις του αριστερού και δεξιού χεριού εάν επρόκειτο να πραγματοποιηθεί αυτή η διαδικασία με το χέρι. Η μέθοδος findSmallest(array, p1, p2) επιστρέφει την θέση της μικρότερης τιμής του πίνακα από την θέση p1 μέχρι και πριν το p2. Η μέθοδος swapElements(array, p1, p2) ανταλλάσει τα στοιχεία των θέσεων που δόθηκαν ως ορίσματα.

15 Προσομοιώνοντας την Ταξινόμηση Επιλογής
public void run() { int[] test = { 809, 503, 946, 367, 987, 838, 259, 236, 659, 361 }; sort(test); } private void sort(int[] array) { for ( int lh = 0 ; lh < array.length ; lh++ ) { int rh = findSmallest(array, lh, array.length); swapElements(array, lh, rh); rh array lh 1 2 3 4 5 6 7 8 9 809 503 946 367 987 838 259 236 659 361 public void run() { int[] test = { 809, 503, 946, 367, 987, 838, 259, 236, 659, 361 }; sort(test); } private void sort(int[] array) { for ( int lh = 0 ; lh < array.length ; lh++ ) { int rh = findSmallest(array, lh, array.length); swapElements(array, lh, rh); } rh array lh private int findSmallest(int[] array, int p1, int p2) { int smallestIndex = p1; for ( int i = p1 + 1 ; i < p2 ; i++ ) { if (array[i] < array[smallestIndex]) smallestIndex = i; } return smallestIndex; 10 p2 array p1 i smallestIndex test 7 8 6 10 9 3 1 2 5 4 9 8 6 3 7 3 1 6 7 1 2 3 4 6 8 7 10 9 5 809 503 946 367 987 838 259 236 659 361 1 2 3 4 5 6 7 8 9 Παράλειψη προσομοίωσης

16 Αποδοτικότητα της Ταξινόμησης Επιλογής
Όπως και στους αλγορίθμους αναζήτησης και εδώ είναι χρήσιμη η κατανόηση του πως ο χρόνος εκτέλεσης της ταξινόμησης εξαρτάται από το μέγεθος του πίνακα. Μια στρατηγική είναι να μετρήσουμε τον χρόνο που απαιτεί η εκτέλεση για πίνακες διαφορετικού μεγέθους. Στην Java, μπορούμε να μετρήσουμε τον χρόνο που παρήλθε καλώντας την System.currentTimeMillis πριν και μετά από την ταξινόμηση. Η στατηγική αυτή όμως απαιτεί πολύ προσοχή: Αν ένας αλγόριθμος εκτελείται πολύ γρήγορα, το ρολόι του συστήματος δεν θα μας δώσει ακριβής μέτρηση. Στις περιπτώσεις αυτές, θα πρέπει να επαναλάβουμε την διαδικασία πολλές φορές και να διαιρέσουμε με τον αριθμό των επαναλήψεων. Οι περισσότεροι αλγόριθμοι έχουν διασπορά που εξαρτάται από τα δεδομένα. Για να την αποφύγουμε, παραμορφώνουμε τα δεδομένα, έχει νόημα να τρέξουμε αρκετές ανεξάρτητες δοκιμές με διαφορετικά δεδομένα και να υπολογίσουμε τον μέσο όρο των αποτελεσμάτων. Είναι σημαντικό να λαμβάνουμε υπόψην πως η Java μερικές φορές θα χρειάζεται να κάνει και άλλες δραστηριότητες (σημαντικότερη η συλλογή απορριμάτων) που μπορεί να χρειάζονται αρκετό χρόνο αλλά δεν έχουν σχέση στην πραγματικότητα με τον αλγόριθμο.

17 Μετρώντας τους Χρόνους Ταξινόμησης
.0021 .0025 .0022 .0026 .0020 .0030 .0023 .006 .007 .008 .011 .014 .015 .028 .024 .025 .026 .023 .027 .039 .037 .036 .041 .042 .140 .034 .038 .187 .152 .168 .176 .146 .165 .178 .154 3.94 3.63 4.06 3.76 4.11 3.51 3.48 3.64 3.31 3.45 13.40 12.90 13.80 17.60 14.10 12.70 81.60 16.00 15.50 322.5 355.9 391.7 321.6 388.3 321.3 398.7 322.1 1319. 1388. 1327. 1318. 1331. 1336. 1335. 1325. N = 10 20 30 40 50 100 500 1000 5000 10000 Trial 1 Trial 2 Trial 3 Trial 4 Trial 5 Trial 6 Trial 7 Trial 8 Trial 9 Trial 10 .0024 .049 .162 3.69 21.05 346.4 1332. m .00029 .00139 .00013 .0014 .0323 .0151 0.272 21.33 33.83 20.96 s .039 14.32 1326. .00036 .0025 1.69 7.50 .011 .140 81.60 1388.

18 Χρόνοι Εκτέλεσης της Ταξινόμησης Επιλογής
Ο αλγόριθμος γραμμικής αναζήτησης έχει την ιδιότητα πως ο χρόνος εκτέλεσης του είναι ανάλογος του μεγέθους του πίνακα. Αν δεκαπλασιάσουμε το μέγεθος του πίνακα, τότε αναμένουμε ο αλγόριθμος να πάρει δεκαπλάσιο χρόνο. 10 100 1000 10000 .0024 0.162 14.32 1332. N time Όπως ξεκαθαρίζουν οι χρόνοι εκτέλεσης στην προηγούμενη διαφάνεια, η κατάσταση για την ταξινόμηση επιλογής είναι πολύ διαφορετική. Ο πίνακας δεξιά δείχνει τον μέσο χρόνο εκτέλεσης όταν η ταξινόμηση επιλογής εκτελεστεί σε 10, 100, 1000, και τιμές. Με μια χονδρική εκτίμηση (ειδικά όταν δουλεύουμε με μεγαλύτερες τιμές του N) φαίνεται ότι όσο δεκαπλασιάζουμε το μέγεθος του πίνακα ο αλγόριθμος ταξινόμησης επιλογής απαιτεί 100 φορές περισσότερο χρόνο.

19 Μετρώντας Πράξεις Ένας άλλος τρόπος για να εκτιμήσουμε τον χρόνο εκτέλεσης είναι να μετρήσουμε πόσες πράξεις απαιτούνται για να ταξινομίσουμε πίνακα μεγέθους N. Στην υλοποίηση της ταξινόμησης επιλογής, το τμήμα κώδικα που εκτελείται πιο συχνά (και γι’ αυτό συνεισφέρει τον περισσότερο χρόνο εκτέλεσης) είναι ο κώδικας της μέθοδος findSmallest. Ο αριθμός των πράξεων που απαιτεί κάθε κλήση της findSmallest αλλάζει όσο τρέχει ο αλγόριθμος: N τιμές ελέγχονται στην πρώτη κλήση της findSmallest. N - 1 τιμές ελέγχονται στην δεύτερη κλήση. N - 2 τιμές ελέγχονται στην τρίτη κλήση, και ούτω καθεξής. Με μαθηματικούς συμβολισμούς, ο αριθμός των τιμών που ελέγχονται στην findSmallest μπορεί να εκφραστεί ως ένα άθροισμα, που στην συνέχεια μπορεί να αντικατασταθεί από μια απλή φόρμουλα: i = 1 N i (N - 1) + N = = N x (N + 1) 2

20 Γεωμετρική Προβολή Μπορείτε να πείσετε τον ευατό σας ότι
N x (N + 1) (N - 2) + (N - 1) + N = 2 αν σκεφτείτε το πρόβλημα γεωμετρικά. Οι όροι στην αριστερή μεριά μπορούν να οργανωθούν σε ένα τρίγωνο, όπως φαίνεται παρακάτω για N = 6. Αν αντιγράψετε το τρίγωνο και το περιστρέψετε κατά 180˚, παίρνετε ένα ορθογώνιο που περιέχει 6 x 7 dots, και σε κάθε τρίγωνο ανήκουν οι μισές.

21 Τετραγωνική Ανάπτυξη Ο λόγος πίσω από την μεγάλη ανάπτυξη του χρόνου εκτέλεσης γίνεται ξεκάθαρος αν δημιουργήσουμε έναν πίνακα που να δείχνει την τιμή της παράστασης για διάφορες τιμές του N: N x (N + 1) 2 N x (N + 1) 2 N 10 55 100 5050 1000 500,500 10000 50,005,000 Η ανάπτυξη της δεξιάς στήλης μοιάζει με αυτή του χρόνου εκτέλεσης του αλγορίθμου επιλογής. Όσο x η τιμή N x (N + 1) 2 του N δεκαπλασιάζεται, η τιμή της παράστασηςxx εκαντονταπλασιάζεται, δηλαδή πολλαπλασιάζεται με το Οι αλγόριθμοι των οποίων ο χρόνος εκτέλεσης αυξάνεται ανάλογα με το τετράγωνο του μεγέθους του προβλήματος ονομάζονται τετραγωνικοί (quadratic).

22 Μια Πιο Αποδοτική Στρατηγική
Για μικρού μεγέθους πίνακες η ταξινόμηση επιλογής είναι μια τέλεια στρατηγική. Ακόμα και για 10,000 στοιχεία ο μέσος χρόνος εκτέλεσης, ξεπερνά ελάχιστα το 1 second. Η τετραγωνική συμπεριφορά της Τ.Ε., παρ’ όλα αυτά, την κάνει απαγορευτική για μεγάλες – εμπορικές εφαρμογές. Αν υποθέσουμε ότι η τετραγωνική ανάπτυξη συνεχίζεται και μετά τους χρόνους του πίνακα, η ταξινόμηση 100,000 τιμών θα απαιτούσε χρόνο 2 λεπτών, και η ταξινόμηση 1,000,000 τιμών θα απαιτούσε πάνω από 3 ώρες. Υπάρχουν στρατηγικές ταξινόμησης για μεγάλους πίνακες πολύ αποδοτικότερες από τη ταξινόμηση επιλογής. Οι περισσότεροι από αυτούς τους αλγορίθμους, δυστυχώς, χρησιμοποιούν τεχνικές που είναι πέρα από τους σκοπούς του μαθήματος μας. Στις επόμενες διαφάνειες, όμως, θα αναστήσουμε έναν αλγόριθμο ταξινόμησης που ήταν δημοφιλής στις πρώιμες μέρες των υπολογιστών ώστε να δείξουμε ότι βελτιώσεις στην απόδοση είναι εφικτές.

23 Ταξινομώντας Διάτρητες Κάρτες
Από την απογραφή του 1880 και έπειτα, οι πληροφορίες συχνά αποθηκεύονταν σε διάτρητες κάρτες όπως αυτή στα δεξιά, όπου έχει τρυπηθεί ο αριθμός 236 στις πρώτες τρεις στήλες. 1 2 3 4 5 6 7 8 9 . . . 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 78 79 80 The IBM 083 Sorter Οι εταιρίες υπολογιστών έφτιαχναν μηχανές που ταξινομούσαν στοίβες από διάτρητες κάρτες, όπως η IBM 083 sorter στα αριστερά. Η στοίβα με τις κάρτες φορτωνόταν σε μια θήκη στο δεξί κομμάτι της μηχανής, και ύστερα οι κάρτες κατανέμονταν σε διάφορους κάδους (bins) στο μπροστινό μέρος ανάλογα με τι τιμή είχε τρυπηθεί σε μία συγκεκριμένη στήλη.

24 Ο Αλγόριθμος Ταξινόμησης Βάσης
Η IBM 083 sorter είχε μεγάλη εμπορική επιτυχία επειδή έδινε την δυνατότητα ταξινόμησης μεγάλων συνόλων διάτρητων καρτών γρήγορα και αποδοτικά. Ο αλγόριθμος που χρησιμοποιούσε η IBM 083 ονομάζεται (ταξινόμηση βάσης) radix sort και έχει τα εξής βήματα: Ρύθμισε την μηχανή να ταξινομεί το τελευταίο ψηφίο. 1. Βάλε την στοίβα με τις κάρτες στην πλαϊνή θήκη. 2. Βάλε την μηχανή να κατανήμει τις κάρτες στους κάδους. 3. Βάλε τις κάρτες από τους κάδους πίσω στην πλαϊνή θήκη. Οι κάρτες από τον κάδο 0 να είναι στον πάτο, ενώ οι κάρτες από τον κάδο 1 να είναι πάνω, και ούτω καθεξής. 4. Ρύθμισε την μηχανή ώστε να ταξινομεί στο προηγούμενο ψηφίο. 5. Επανάλαβε τα βήματα 3 έως 5 μέχρι να τελειώσουν τα ψηφία. 6. Η επόμενη διαφάνεια απεικονίζει αυτή την διαδικασία για ένα σύνολο αριθμών με τρία ψηφία.

25 Προσομοιώση της Ταξινόμηση Βάσης
1 2 3 4 5 6 7 8 9 1 2 3 4 5 6 7 8 9 987 946 838 809 659 503 367 361 259 236 838 367 987 946 236 503 361 367 987 946 236 503 361 809 259 659 838 367 987 946 236 503 361 946 838 236 809 503 259 659 946 838 236 809 503 946 236 503 361 838 236 809 503 987 367 361 259 659 946 838 236 809 987 367 361 259 659 946 838 236 809 503 809 503 809 259 659 838 367 987 946 236 503 361 503 361 809 259 659 838 367 987 946 236 809 259 809 367 361 259 659 946 838 236 809 503 987 367 361 259 659 946 838 236 809 503 809 259 659 809 259 659 838 987 367 361 259 659 946 838 236 809 259 659 838 367 987 946 809 259 659 838 367 987 809 259 659 838 367 809 259 659 838 367 987 946 236 503 361 809 503 946 367 987 838 259 236 659 987 946 838 809 659 503 367 361 259 236 809 503 946 367 809 503 946 367 987 809 503 987 367 361 259 659 946 838 838 809 659 503 367 361 259 236 809 503 946 367 987 838 259 659 503 367 361 259 236 809 503 946 367 987 838 259 236 809 503 946 809 809 503 946 367 987 838 259 236 659 361 987 367 361 259 987 367 361 259 659 987 367 361 259 659 946 259 236 987 367 361 987 503 367 361 259 236 987 367 367 361 259 236 809 503 946 367 987 838 Step 1a. Ταξινόμησε τις κάρτες ως προς το τελευταίο ψηφίο. Step 1b. Ξαναγέμισε την πλαϊνή θήκη (έναν έναν κάδο). Η λίστα έχει ταξινομηθεί ως προς το τελευταίο ψηφίο Step 2a. Ταξινόμησε ως προς το μεσαίο (επόμενο) στοιχείο. Step 2b. Ξαναγέμισε την πλαϊνή θήκη (έναν έναν κάδο). Η λίστα είναι ταξινομημένη ως προς δύο ψηφία. Step 3a. Ταξινόμησε ως προς το πρώτο (επόμενο) στοιχείο. Step 3b. Ξαναγέμισε την θήκη (για τελευταία φορα). Πλέον η λίστα είναι πλήρως ταξινομημένη. 809 503 361 259 236 838 361 503 367 236 946 259 659 503 367 659 946 361 236 987 367 809 838 838 987 987 946 259 659 809 946 659 259 838 361 367 236 987 503 987 367 946 503 838 259 361 659 236 809 361 659 259 809 503 809 838 236 367 946 987 Παράληψη προσομοίωσης

26 Αποδοτικότητα της Ταξινόμησης Βάσης
Το πλεονέκτημα της βάσης εναντίον της επιλογής είναι ότι ο χρόνος που απαιτείται για να ταξινομήσουμε μια στοίβα από κάρτες δεν μεγαλώνει πλέον ανάλογα με το τετράγωνο του αριθμού των καρτών. Αντίθετα ο χρόνος εκτέλεσης είναι ανάλογος του γινομένου N x D όπου N ο αριθμός των καρτών και D ο μέγιστος αριθμός των ψηφίων των αριθμών που ταξινομούμε. Για να ληφθεί υπόψην το γεγονός ότι τα μεγαλύτερα σύνολα δεδομένων τείνουν να χρησιμοποιούν πιο μεγάλους αριθμούς, οι αναλύσεις αλγορίθμων ταξινόμησης υποθέτουν ότι το εύρος των τιμών που ταξινομούνται είναι ανάλογο του αριθμού των τιμών. Επειδή ο αριθμός των ψηφίων ενός αριθμού N είναι ανάλογος του λογαρίθμου του N, οι επιστήμονες της πληροφορικής θεωρούν την απόδοση της ταξινόμησης βάσης ανάλογη του γινομένου N log N

27 Αξιολόγηση της Αλγοριθμικής Απόδοσης
Η συζήτηση περί της αποδοτικότητας των διάφορων αλγορίθμων αναζήτησης και ταξινόμησης απεικονίζει μια θεμελιώδη τεχνική της επιστήμης των υπολογιστών που ονομάζεται αλγοριθμική ανάλυση (algorithmic analysis). Ο πρωταρχικός σκοπός της αλγοριθμικής ανάλυσης ειναι να κάνει ποιοτικές εκτιμήσεις σχετικά με την αποδοτικότητα ενός αλγορίθμου παρά να προσφέρει ακριβείς ποσοτικές προβλέψεις για τον χρόνο εκτέλεσης. Ο χρόνος εκτέλεσης ενός προγράμματος εξαρτάται, για παράδειγμα, από την ταχύτητα του hardware και την έκταση στην οποία ο μεταγλωτιστής (compiler) βελτιστοποιεί τον κώδικα. Η ποιοτική απόδοση του ίδιου του αλγορίθμου είναι εντελώς ανεξάρτητη από τέτοιους παράγοντες. Ένα από τα πιο σημαντικά προβλήματα στην αλγοριθμική ανάλυση είναι η εύρεση της υπολογιστικής πολυπλοκότητας (computational complexity) ενός αλγορίθμου. Αυτή είναι η σχέση μεταξύ του μεγέθους του προβλήματος και του αναμενόμενου χρόνου εκτέλεσης.

28 O ( N ) O ( N log N ) Ο συμβολισμός Big-O
Ο πιο κοινός τρόπος για να εκφραστεί η υπολογιστική πολυπλοκότητα είναι να χρησιμοποιήσουμε τον συμβολισμό big-O, που παρουσιάστηκε από τον Γερμανό μαθηματικό Paul Bachmann to1892. O συμβολισμός big-O αποτελείται από το γράμμα O ακολουθούμενο από μια φόρμουλα που προσφέρει μια ποιοτική αξιολόγηση του χρόνου εκτέλεσης συναρτήσει του μεγέθους του προβλήματος, που παραδοσιακά συμβολίζεται με N. Για παράδειγμα η πολυπλοκότητα της γραμμικής αναζήτησης είναι O ( N ) και η πολυπλοκότητα της αλλαγής βάσης είναι O ( N log N ) Το προφέρουμε ως “big-O of N (Όμικρον του Ν) ” και “big-O of N log N (Όμικρον του Ν logN) ” αντίστοιχα.

29 Συχνές απλοποιήσεις του Big-O
Διώχνουμε κάθε όρο του οποίου η συνεισφορά στον χρόνο εκτέλεσης σταματά να είναι σημαντική όσο μεγαλώνει N. 1. Εξαλείφουμε τους σταθερούς παράγοντες. 2. Ως εκ τούτου η πολυπλοκότητα της ταξινόμησης επιλογής είναι O ( N 2 ) N x (N + 1) 2 O ( ) και όχι

30 Εξαγωγή της Πολυπλοκότητας από τον Κώδικα
Εξαγωγή της Πολυπλοκότητας από τον Κώδικα Σε πολλές περιπτώσεις, μπορούμε να εξάγουμε την πολυπλοκότητα ενός προγράμματος άμεσα από την δομή του κώδικα. Ο συνηθισμένος τρόπος για να κάνουμε αυτή την ανάλυση ξεκινά κοιτώντας για ποιο μέρος του κώδικα εκτελείται πιο συχνά από άλλα μέρη του. Όσο οι πράξεις (ενέργειες) που συμβαίνουν στον αλγόριθμο παίρνουν χοντρικά τον ίδιο χρόνο, οι ενέργειες που εκτελούνται συχνότερα θα κυριαρχούν στον συνολικό χρόνο εκτέλεσης. Για παράδειγμα, στην υλοποίηση της ταξινόμησης επιλογής, η πιο συχνή ενέργεια είναι η πρόταση if μέσα στην μέθοδο findSmallest. Η πρόταση αυτή είναι μέρος δύο βρόχων for, ένας στην findSmallest και ένας στην sort. Ο συνολικός αριθμός εκτελέσεων είναι (N - 1) + N το οποίο είναι O(N 2).

31 Άσκηση: Υπολογιστική Πολυπλοκότητα
Υποθέτοντας ότι κανένα από τα βήματα στο σώμα των βρόχων for που ακολουθούν δεν εξαρτάται από το μέγεθος του προβλήματος που είναι αποθηκευμένο στην μεταβλητή n ποια είναι η πολυπλοκότητα για κάθε ένα από τα παραδείγματα: for (int i = 0; i < n; i++) { for (int j = 0; j < i; j++) { . . . loop body . . . } a) O ( N 2 ) Ο βρόχος αυτός ακολουθεί ίδιο πρότυπο με αυτό της ταξινόμησης επιλογής. for (int k = 1; k <= n; k *= 2) { . . . loop body . . . } b) O ( log N ) Ο βρόχος αυτός ακολουθεί ίδιο πρότυπο με αυτό της δυαδικής αναζήτησης. c) for (int i = 0; i < 100; i++) { for (int j = 0; j < i; j++) { . . . loop body . . . } O ( 1 ) Ο βρόχος αυτός δεν εξαρτάται καθόλου από την τιμή του n.

32 Διάβασμα για το σπίτι Κεφάλαιο 12 ως και την ενότητα 12.3 (ως την σελίδα 584) από «Η Τέχνη και Επιστήμη της JAVA: Μια εισαγωγή στην Επιστήμη των Υπολογιστών», E. Roberts


Κατέβασμα ppt "Εισαγωγή στον Προγ/μό Υπολογιστών"

Παρόμοιες παρουσιάσεις


Διαφημίσεις Google