Οδηγός Μελέτης - Εισαγωγή στον Προγραμματισμό

Α18.11 · Προβλέποντας το Μέλλον (future)

Εργασία 2 (2024-25), Άσκηση 1 · Δυσκολία ★★☆ · programming · Κεφάλαια: 18, 13, 12

Προβλέποντας το Μέλλον (future - 50 Μονάδες)

Όλες οι προβλέψεις, από τον καιρό μέχρι την επόμενη λέξη σε μια πρόταση, αξιολογούνται με ένα κοινό κριτήριο: το πόσο ακριβείς είναι. Σε αυτήν την άσκηση, θα υλοποιήσουμε έναν αλγόριθμο που χρησιμοποιείται κατεξοχήν για να κάνουμε προβλέψεις, τον κινούμενο μέσο όρο (Simple Moving Average - SMA). Ο κινούμενος μέσος όρος είναι παρεμφερής με τον κανονικό μέσο όρο, με μια διαφορά: ο κινούμενος μέσος όρος απαιτεί και ένα “παράθυρο” (window), δηλαδή τον αριθμό των τιμών (μετρώντας από το τέλος) που θέλουμε να λάβουμε υπόψη μας στον υπολογισμό του μέσου όρου. Για παράδειγμα, ας υποθέσουμε ότι έχουμε αυτές τις 10 τιμές:

9  7  7  1  4  4  4  38  8  4

Ο μέσος όρος αυτών των τιμών είναι \(\frac{9 + 7 + 7 + 1 + 4 + 4 + 4 + 38 + 8 + 4}{10} = 8.60\). Για να υπολογίσουμε τον κινούμενο μέσο, πρέπει να επιλέξουμε ένα παράθυρο, έστω 3. Τότε ο κινούμενος μέσος με παράθυρο 3 για αυτά τα στοιχεία λαμβάνει υπόψη του μόνο τα τελευταία 3:

\[9 \quad 7 \quad 7 \quad 1 \quad 4 \quad 4 \quad 4 \quad \underbrace{38 \quad 8 \quad 4}_{SMA_3}\]

και επομένως \(SMA_3 = \frac{38 + 8 + 4}{3} = 16.67\). Αντίστοιχα, μπορούν να οριστούν κινούμενοι μέσοι με μικρότερα παράθυρα (π.χ., παράθυρο 1 σημαίνει μόνο το τελευταίο στοιχείο) ή μεγαλύτερα παράθυρα (π.χ., παράθυρο 10 θα λάμβανε υπόψη του όλες τις τιμές παραπάνω).

Σε αυτήν την άσκηση λοιπόν, καλείστε να υλοποιήσετε ένα πρόγραμμα το οποίο θα υπολογίζει τον κινούμενο μέσο όρο για μια σειρά από δεδομένα και να τον εκτυπώνει ως πρόβλεψη.

Τεχνικές Προδιαγραφές

Παραδείγματα εκτέλεσης ακολουθούν:

$ ./future
Usage: ./future <filename> [--window N (default: 50)]
$ cat values.txt
9 7 7 1 4 4 4 38 8 4
$ ./future values.txt --window 10
8.60
$ echo $?
0
$ ./future values.txt --window 3
16.67
$ ./future values.txt --window 1
4.00
$ ./future values.txt --window 0
Window too small!
$ echo $?
1
$ ./future values.txt --window 0 2> out
$ cat out
Window too small!
$ ./future values.txt --window 12
Window too large!
$ echo $?
1
$ ./future values.txt --window 1000000000000
Failed to allocate window memory

Φυσικά οι ίδιοι έλεγχοι μπορούν να γίνουν με πραγματικά δεδομένα και να δείτε αν οι προβλέψεις του προγράμματός μας είναι καλές (Το αρχείο dow_jones.txt βρίσκεται στο https://github.com/progintro/data):

$ ./future dow_jones.txt
43471.71
$ ./future dow_jones.txt --window 200
40677.19
$ ./future dow_jones.txt --window 1000
35273.61
$ wc -l dow_jones.txt
8302 dow_jones.txt
$ ./future dow_jones.txt --window 8000
15447.33

Στο αρχείο README.md πρέπει να προσθέσετε οποιεσδήποτε παρατηρήσεις σας κατά την διεκπεραίωση της άσκησης. Ο κώδικας απαιτείται να είναι καλά τεκμηριωμένος με σχόλια καθώς αυτό θα είναι μέρος της βαθμολόγησης.

Bonus (Προαιρετικό)

Πιστεύετε πως μπορείτε να φτιάξετε αλγορίθμους που προβλέπουν πως θα κινηθεί ένα οικονομικό asset καλύτερα από τον κινούμενο μέσο; Αν ναι, προσθέστε ένα easter egg option στο πρόγραμμά σας ονόματι --compete και θα μπείτε αυτόματα στον διαγωνισμό μας. Η αξιολόγηση θα γίνει με πραγματικά δεδομένα από χρηματιστήρια του κόσμου. Η διεπαφή θα είναι παρόμοια με παραπάνω, απλά υπολογίζετε την καλύτερή σας πρόβλεψη για την επόμενη τιμή σε μια σειρά δεδομένων:

$ ./future dow_jones.txt --compete
43455.32

Οι τρεις καλύτερες υποβολές θα λάβουν 100%, 70% και 40% έξτρα βαθμολογία σε αυτήν την άσκηση.

Υπόδειξη

Χρειάζεστε μόνο τις τελευταίες \(N\) τιμές: ένας κυκλικός πίνακας (ring buffer) μεγέθους ίσου με το παράθυρο, δεσμευμένος με malloc, κρατά αυτές τις τιμές όσο διαβάζετε το αρχείο, χωρίς να ξέρετε από πριν πόσες είναι. Ελέγξτε την τιμή επιστροφής της malloc (δείτε το παράθυρο \(10^{12}\)) και της fopen, διαβάστε το παράθυρο ως 64-bit ακέραιο, και θυμηθείτε ότι τα μηνύματα λάθους πάνε στο stderr.

Αριθμός στον οδηγό: Α18.11 (στο κεφάλαιο) · Μόνιμο αναγνωριστικό: hw-2024-hw2-future · Σύνδεσμος: https://progintro.github.io/study/questions/homework/hw-2024-hw2-future.html · Markdown (GitHub)