Μετάβαση στο περιεχόμενο

Προβλήματα και υπολογισιμότητα

Επιλύσιμα, ανοικτά και άλυτα προβλήματα — και το πρόβλημα του τερματισμού.

40 λεπτά

Θα μάθεις να

  1. Να κατατάσσεις ένα πρόβλημα ως επιλύσιμο, ανοικτό ή άλυτο.
  2. Να ξεχωρίζεις το «δεν έχει βρεθεί λύση» από το «αποδεδειγμένα δεν υπάρχει λύση».
  3. Να περιγράφεις τα μέρη μιας μηχανής Turing και τη σημασία της θέσης Church–Turing.
  4. Να εξηγείς με το επιχείρημα της αντίφασης γιατί το πρόβλημα του τερματισμού δεν λύνεται.

Τι είναι πρόβλημα

Πρόβλημα είναι μια κατάσταση που χρειάζεται αντιμετώπιση, απαιτεί λύση, και η λύση της δεν είναι προφανής. Πριν ρωτήσουμε πώς λύνεται, η επιστήμη των υπολογιστών ρωτά κάτι πιο βασικό: λύνεται;

Τα προβλήματα κατατάσσονται με δύο τρόπους.

Κατά τη δομή τουςΠαράδειγμα
Δομημένα: η λύση ακολουθεί γνωστή, τυποποιημένη μέθοδοεπίλυση εξίσωσης δευτέρου βαθμού
Ημιδομημένα: υπάρχει μέθοδος, αλλά χρειάζεται και κρίσηεπιλογή σχολής με βάση μόρια και προτιμήσεις
Αδόμητα: δεν υπάρχει μέθοδος, η λύση βασίζεται στην εμπειρίαπρόβλεψη της μόδας της επόμενης χρονιάς
Κατά το είδος της απάντησηςΠαράδειγμα
Απόφασης: η απάντηση είναι ναι ή όχιΕίναι ο 9797 πρώτος αριθμός;
Υπολογιστικά: η απάντηση είναι μια τιμήΠόσο κάνει 2202^{20};
Βελτιστοποίησης: η απάντηση είναι η καλύτερη από πολλές λύσειςΠοια είναι η συντομότερη διαδρομή από την Αθήνα στα Ιωάννινα;

Επιλύσιμα, ανοικτά, άλυτα

Η πιο σημαντική διάκριση αφορά το αν η λύση υπάρχει.

ΚατηγορίαΤι ξέρουμεΠαραδείγματα
Επιλύσιμαη λύση είναι γνωστήη ταξινόμηση ενός πίνακα, η εξίσωση δευτέρου βαθμού
Ανοικτάη λύση δεν έχει βρεθεί ακόμα, ούτε έχει αποδειχθεί ότι δεν υπάρχειη εικασία του Goldbach, η εικασία Collatz
Άλυταέχει αποδειχθεί ότι λύση δεν υπάρχειο τετραγωνισμός του κύκλου με κανόνα και διαβήτη, το πρόβλημα του τερματισμού

Η εικασία του Goldbach (1742) λέει ότι κάθε άρτιος μεγαλύτερος του 22 γράφεται ως άθροισμα δύο πρώτων: 10=3+710 = 3 + 7, 28=11+1728 = 11 + 17. Έχει ελεγχθεί με υπολογιστή για τεράστιους αριθμούς και δεν έχει βρεθεί ούτε μία εξαίρεση. Απόδειξη όμως δεν υπάρχει, άρα το πρόβλημα μένει ανοικτό.

Ο τετραγωνισμός του κύκλου ζητά να κατασκευαστεί με κανόνα και διαβήτη τετράγωνο με εμβαδόν ίσο με ενός δοσμένου κύκλου. Το 1882 αποδείχθηκε ότι αυτό είναι αδύνατο, γιατί ο αριθμός π\pi δεν είναι ρίζα καμίας πολυωνυμικής εξίσωσης με ακέραιους συντελεστές. Το πρόβλημα είναι άλυτο: όχι επειδή κανείς δεν τα κατάφερε, αλλά επειδή αποδείχθηκε ότι κανείς δεν θα τα καταφέρει ποτέ.

Ένα ανοικτό πρόβλημα μπορεί να καταλήξει σε οποιαδήποτε από τις δύο άλλες κατηγορίες. Το «τελευταίο θεώρημα του Fermat» ήταν ανοικτό για πάνω από τρεισήμισι αιώνες, ώσπου το 1994 ο Andrew Wiles το απέδειξε. Ο τετραγωνισμός του κύκλου ήταν ανοικτός για δύο χιλιετίες, ώσπου αποδείχθηκε αδύνατος.

Η μηχανή Turing

Για να αποδείξεις ότι κανένα πρόγραμμα δεν λύνει ένα πρόβλημα, πρέπει πρώτα να ορίσεις με ακρίβεια τι είναι «πρόγραμμα». Αυτό έκανε ο Alan Turing το 1936. Η μηχανή του έχει τρία μέρη:

  • μια ταινία χωρισμένη σε κελιά, απεριόριστη σε μήκος, όπου σε κάθε κελί γράφεται ένα σύμβολο
  • μια κεφαλή που διαβάζει και γράφει ένα κελί τη φορά και μετακινείται ένα κελί αριστερά ή δεξιά
  • έναν πίνακα κανόνων: «αν είσαι στην κατάσταση Α και διαβάζεις 1, γράψε 0, πήγαινε δεξιά και πέρνα στην κατάσταση Β»

Αυτό είναι όλο. Φαίνεται υπερβολικά απλό για να κάνει κάτι χρήσιμο, κι όμως μπορεί να εκτελέσει οποιονδήποτε αλγόριθμο εκτελεί ο πιο σύγχρονος υπολογιστής. Πιο αργά, αλλά οποιονδήποτε.

Το πρόβλημα του τερματισμού

Κάθε προγραμματιστής έχει γράψει κάποτε μια ατέρμονη επανάληψη. Θα ήταν πολύτιμο ένα εργαλείο που διαβάζει οποιοδήποτε πρόγραμμα με τα δεδομένα του και απαντά σωστά «θα σταματήσει» ή «θα τρέχει για πάντα».

Το 1936 ο Turing απέδειξε ότι ένα τέτοιο εργαλείο δεν μπορεί να υπάρξει. Η απόδειξη είναι απαγωγή σε άτοπο: υποθέτουμε ότι υπάρχει και καταλήγουμε σε αντίφαση.

Ας υποθέσουμε ότι κάποιος έγραψε τη συνάρτηση stops(program, data), που επιστρέφει True αν το program σταματά όταν τρέξει με είσοδο data, και False αλλιώς. Τότε μπορούμε να γράψουμε το εξής πρόγραμμα:

def stops(program, data):
    # Η υποθετική συνάρτηση. Η απόδειξη δείχνει ότι κανείς δεν μπορεί να τη γράψει.
    raise NotImplementedError("δεν υπάρχει τέτοια συνάρτηση")


def paradox(program):
    if stops(program, program):
        while True:  # αν «σταματά», κάνε ατέρμονη επανάληψη
            pass
    else:
        return "σταμάτησα"  # αν «δεν σταματά», σταμάτα αμέσως

Το paradox κάνει πάντα το αντίθετο από ό,τι προβλέπει το stops. Τώρα το ερώτημα-παγίδα: τι γίνεται με το paradox(paradox);

Αν το stops(paradox, paradox) απαντήσει……τότε το paradox(paradox)Άρα το stops
True («σταματά»)μπαίνει σε ατέρμονη επανάληψηέκανε λάθος
False («δεν σταματά»)επιστρέφει αμέσωςέκανε λάθος

Και οι δύο απαντήσεις είναι λάθος. Αφού όμως υποθέσαμε ότι το stops απαντά πάντα σωστά, η υπόθεση ήταν ψευδής: η συνάρτηση stops δεν μπορεί να γραφτεί, από κανέναν, σε καμία γλώσσα, σε κανέναν υπολογιστή.

Το επιχείρημα θυμίζει το αρχαίο παράδοξο του ψεύτη, «αυτή η πρόταση είναι ψευδής»: ένα αντικείμενο που μιλά για τον εαυτό του και αντιστρέφει ό,τι λέγεται γι' αυτό.

«Γιατί να μην τρέξουμε απλώς το πρόγραμμα και να δούμε;» Αν σταματήσει, έχουμε απάντηση. Αν όμως τρέχει ακόμα μετά από μια ώρα, δεν ξέρουμε αν θα σταματήσει στο επόμενο λεπτό ή ποτέ. Η αναμονή δίνει μόνο τη μία από τις δύο απαντήσεις.

Επιλύσιμο δεν σημαίνει εύκολο

Ανάμεσα στα επιλύσιμα υπάρχει μια ακόμα διαφορά: κάποια λύνονται γρήγορα και κάποια μόνο θεωρητικά. Για να βρεις τη συντομότερη διαδρομή που περνά από 2020 πόλεις, μπορείς να δοκιμάσεις όλες τις σειρές. Είναι όμως περισσότερες από 101810^{18}, και κανένας υπολογιστής δεν θα τελείωνε σε όλη σου τη ζωή.

Για πολλά τέτοια προβλήματα δεν ξέρουμε αν υπάρχει γρήγορος αλγόριθμος. Το ερώτημα αυτό, γνωστό ως P εναντίον NP, είναι ίσως το πιο διάσημο ανοικτό πρόβλημα της πληροφορικής. Κανείς δεν έχει βρει γρήγορο αλγόριθμο, αλλά κανείς δεν έχει αποδείξει ότι δεν υπάρχει. Το πώς μετράμε το «γρήγορα» είναι το θέμα του επόμενου μαθήματος.

ΕρώτημαΚλάδοςΠαράδειγμα
Λύνεται καθόλου;υπολογισιμότητατο πρόβλημα του τερματισμού: όχι, και αυτό έχει αποδειχθεί
Λύνεται σε λογικό χρόνο;πολυπλοκότηταη συντομότερη διαδρομή από πολλές πόλεις: δεν ξέρουμε ακόμα

Λυμένα παραδείγματα

Παράδειγμα 1

Κατάταξε ως επιλύσιμο, ανοικτό ή άλυτο: (α) η ταξινόμηση 10001000 ονομάτων, (β) η εικασία του Goldbach, (γ) η τριχοτόμηση οποιασδήποτε γωνίας με κανόνα και διαβήτη.

Δοκίμασέ το πρώτα. Μετά δες τη λύση.

Παράδειγμα 2

Ένας συμμαθητής λέει: «Το πρόβλημα του τερματισμού είναι άλυτο, γιατί κανείς δεν έχει καταφέρει ακόμα να γράψει τη συνάρτηση stops». Τι λάθος κάνει;

Δοκίμασέ το πρώτα. Μετά δες τη λύση.

Παράδειγμα 3

Μια εταιρεία διαφημίζει πρόγραμμα που «εντοπίζει με βεβαιότητα κάθε ατέρμονη επανάληψη σε οποιοδήποτε πρόγραμμα». Είναι δυνατόν;

Δοκίμασέ το πρώτα. Μετά δες τη λύση.

Ασκήσεις

Πρώτα ερωτήσεις με επιλογές: διαλέγεις, πατάς «Έλεγξε» και μαθαίνεις αμέσως αν το βρήκες και γιατί. Στο τέλος, λίγες ασκήσεις χωρίς επιλογές — εκεί κρύβεται μόνο η απάντηση.

Πολλαπλή επιλογήΆσκηση 1 από 14
Ένα πρόβλημα για το οποίο δεν έχει βρεθεί λύση, αλλά ούτε έχει αποδειχθεί ότι δεν υπάρχει, λέγεται:

Τα κατάφερες;

  • Να κατατάσσεις ένα πρόβλημα ως επιλύσιμο, ανοικτό ή άλυτο.
  • Να ξεχωρίζεις το «δεν έχει βρεθεί λύση» από το «αποδεδειγμένα δεν υπάρχει λύση».
  • Να περιγράφεις τα μέρη μιας μηχανής Turing και τη σημασία της θέσης Church–Turing.
  • Να εξηγείς με το επιχείρημα της αντίφασης γιατί το πρόβλημα του τερματισμού δεν λύνεται.

Λύσε τις ασκήσεις πιο πάνω και θα δεις εδώ πού στέκεσαι.