Ψευδοτυχαίοι αριθμοί. Δημιουργία ψευδοτυχαίων ακολουθιών Ορισμός ορίων εύρους για rand()

Έχουμε μια ακολουθία αριθμών που αποτελείται από πρακτικά ανεξάρτητα στοιχεία που υπακούουν σε μια δεδομένη κατανομή. Κατά κανόνα, ομοιόμορφη κατανομή.

Μπορείτε να δημιουργήσετε τυχαίους αριθμούς στο Excel με διαφορετικούς τρόπους και τρόπους. Ας εξετάσουμε μόνο τα καλύτερα από αυτά.

Συνάρτηση τυχαίου αριθμού στο Excel

  1. Η συνάρτηση RAND επιστρέφει έναν τυχαίο, ομοιόμορφα κατανεμημένο πραγματικό αριθμό. Θα είναι μικρότερο από 1, μεγαλύτερο ή ίσο με 0.
  2. Η συνάρτηση RANDBETWEEN επιστρέφει έναν τυχαίο ακέραιο.

Ας δούμε τη χρήση τους με παραδείγματα.

Δειγματοληψία τυχαίων αριθμών με χρήση RAND

Αυτή η συνάρτηση δεν απαιτεί ορίσματα (RAND()).

Για να δημιουργήσετε έναν τυχαίο πραγματικό αριθμό στην περιοχή από το 1 έως το 5, για παράδειγμα, χρησιμοποιήστε τον ακόλουθο τύπο: =RAND()*(5-1)+1.

Ο επιστρεφόμενος τυχαίος αριθμός κατανέμεται ομοιόμορφα στο διάστημα.

Κάθε φορά που υπολογίζεται το φύλλο εργασίας ή αλλάζει η τιμή σε οποιοδήποτε κελί του φύλλου εργασίας, επιστρέφεται ένας νέος τυχαίος αριθμός. Εάν θέλετε να αποθηκεύσετε τον πληθυσμό που δημιουργήθηκε, μπορείτε να αντικαταστήσετε τον τύπο με την τιμή του.

  1. Κάντε κλικ στο κελί με έναν τυχαίο αριθμό.
  2. Στη γραμμή τύπων, επιλέξτε τον τύπο.
  3. Πατήστε F9. ΚΑΙ ΕΙΣΑΓΕΤΕ.

Ας ελέγξουμε την ομοιομορφία της κατανομής των τυχαίων αριθμών από το πρώτο δείγμα χρησιμοποιώντας ένα ιστόγραμμα κατανομής.


Το εύρος των κατακόρυφων τιμών είναι η συχνότητα. Οριζόντια - "τσέπες".



Λειτουργία RANDBETWEEN

Η σύνταξη για τη συνάρτηση RANDBETWEEN είναι (κάτω όριο, άνω όριο). Το πρώτο όρισμα πρέπει να είναι μικρότερο από το δεύτερο. Διαφορετικά, η συνάρτηση θα προκαλέσει σφάλμα. Τα όρια θεωρούνται ακέραιοι. Ο τύπος απορρίπτει το κλασματικό μέρος.

Παράδειγμα χρήσης της συνάρτησης:

Τυχαίοι αριθμοί με ακρίβεια 0,1 και 0,01:

Πώς να φτιάξετε μια γεννήτρια τυχαίων αριθμών στο Excel

Ας φτιάξουμε μια γεννήτρια τυχαίων αριθμών που δημιουργεί μια τιμή από ένα συγκεκριμένο εύρος. Χρησιμοποιούμε έναν τύπο όπως: =INDEX(A1:A10,INTEGER(RAND()*10)+1).

Ας φτιάξουμε μια γεννήτρια τυχαίων αριθμών στην περιοχή από 0 έως 100 σε βήματα του 10.

Από τη λίστα με τις τιμές κειμένου πρέπει να επιλέξετε 2 τυχαίες. Χρησιμοποιώντας τη συνάρτηση RAND, συγκρίνουμε τιμές κειμένου στην περιοχή A1:A7 με τυχαίους αριθμούς.

Ας χρησιμοποιήσουμε τη συνάρτηση INDEX για να επιλέξουμε δύο τυχαίες τιμές κειμένου από την αρχική λίστα.

Για να επιλέξετε μία τυχαία τιμή από τη λίστα, χρησιμοποιήστε τον ακόλουθο τύπο: =INDEX(A1:A7,RANDBETWEEN(1,COUNT(A1:A7))).

Γεννήτρια τυχαίων αριθμών κανονικής κατανομής

Οι συναρτήσεις RAND και RANDBETWEEN παράγουν τυχαίους αριθμούς με ομοιόμορφη κατανομή. Οποιαδήποτε τιμή με την ίδια πιθανότητα μπορεί να πέσει στο κατώτερο όριο του ζητούμενου εύρους και στο ανώτερο. Αυτό έχει ως αποτέλεσμα μια τεράστια διαφορά από την τιμή στόχο.

Μια κανονική κατανομή σημαίνει ότι οι περισσότεροι από τους αριθμούς που δημιουργούνται είναι κοντά στον αριθμό στόχο. Ας προσαρμόσουμε τον τύπο RANDBETWEEN και ας δημιουργήσουμε έναν πίνακα δεδομένων με κανονική κατανομή.

Το κόστος του προϊόντος Χ είναι 100 ρούβλια. Ολόκληρη η παρτίδα που παράγεται ακολουθεί κανονική κατανομή. Μια τυχαία μεταβλητή ακολουθεί επίσης μια κανονική κατανομή πιθανοτήτων.

Υπό αυτές τις συνθήκες, η μέση τιμή του εύρους είναι 100 ρούβλια. Ας δημιουργήσουμε έναν πίνακα και ας δημιουργήσουμε ένα γράφημα με κανονική κατανομή με τυπική απόκλιση 1,5 ρούβλια.

Χρησιμοποιούμε τη συνάρτηση: =NORMINV(RAND();100;1.5).

Το Excel υπολόγισε ποιες τιμές ήταν εντός του εύρους πιθανότητας. Δεδομένου ότι η πιθανότητα παραγωγής ενός προϊόντος με κόστος 100 ρούβλια είναι μέγιστη, ο τύπος δείχνει τιμές κοντά στο 100 πιο συχνά από άλλους.

Ας προχωρήσουμε στη σχεδίαση του γραφήματος. Πρώτα πρέπει να δημιουργήσετε έναν πίνακα με κατηγορίες. Για να γίνει αυτό, χωρίζουμε τον πίνακα σε περιόδους:

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

Ανέστειλε το AdBlock σε αυτόν τον ιστότοπο.

Μερικές φορές μπορεί να είναι απαραίτητο να δημιουργηθούν τυχαίοι αριθμοί. Ένα απλό παράδειγμα.

Παράδειγμα: Καθορισμός του νικητή σε διαγωνισμό αναδημοσίευσης.

Υπάρχει μια λίστα με 53 άτομα. Είναι απαραίτητο να επιλέξετε έναν νικητή από αυτούς. Εάν το επιλέξετε μόνοι σας, μπορεί να κατηγορηθείτε για προκατάληψη. Αποφασίζεις λοιπόν να γράψεις ένα πρόγραμμα. Θα λειτουργήσει ως εξής. Εισαγάγετε τον αριθμό των συμμετεχόντων N, μετά τον οποίο το πρόγραμμα εμφανίζει έναν αριθμό - τον αριθμό του νικητή.

Ξέρετε ήδη πώς να πάρετε έναν αριθμό από έναν παίκτη. Πώς όμως μπορείς να αναγκάσεις έναν υπολογιστή να σκεφτεί έναν τυχαίο αριθμό; Σε αυτό το μάθημα θα μάθετε πώς να το κάνετε αυτό.

συνάρτηση rand().

Αυτή η συνάρτηση επιστρέφει έναν τυχαίο ακέραιο στην περιοχή από μηδέν έως RAND_MAX. Το RAND_MAX είναι μια ειδική σταθερά C που διατηρεί τη μέγιστη ακέραια τιμή που μπορεί να επιστραφεί από τη συνάρτηση rand().

Η συνάρτηση rand() ορίζεται στο αρχείο κεφαλίδας stdlib.h. Επομένως, εάν θέλετε να χρησιμοποιήσετε το rand στο πρόγραμμά σας, μην ξεχάσετε να συμπεριλάβετε αυτό το αρχείο κεφαλίδας. Η σταθερά RAND_MAX ορίζεται επίσης σε αυτό το αρχείο. Μπορείτε να βρείτε αυτό το αρχείο στον υπολογιστή σας και να δείτε τη σημασία του.

Ας δούμε αυτό το χαρακτηριστικό σε δράση. Ας τρέξουμε τον παρακάτω κώδικα:

Λίστα 1.

#περιλαμβάνω // για να χρησιμοποιήσετε τη συνάρτηση printf #include // για να χρησιμοποιήσετε τη συνάρτηση rand int main(void) ( /* δημιουργία πέντε τυχαίων ακεραίων */ printf("%d\n", rand()); printf("%d\n", rand()); printf ("%d\n", rand());

Θα πρέπει να μοιάζει κάπως έτσι.

Εικ.1 Πέντε τυχαίοι αριθμοί που δημιουργούνται από τη συνάρτηση rand

Αλλά θα θέλαμε να πάρουμε αριθμούς από το 1 έως το 53, και όχι τα πάντα στη σειρά. Ακολουθούν μερικά κόλπα που θα σας βοηθήσουν να περιορίσετε τη συνάρτηση rand().

Περιορίστε τους τυχαίους αριθμούς από πάνω.

Όποιος περίμενε στο σχολείο τη στιγμή που θα βοηθούσαν τα μαθηματικά, ετοιμαστείτε. Η στιγμή έφτασε. Για να περιορίσετε τους τυχαίους αριθμούς από πάνω, μπορείτε να χρησιμοποιήσετε τη λειτουργία λήψης του υπολοίπου της διαίρεσης, την οποία μάθατε στο τελευταίο μάθημα. Ίσως γνωρίζετε ότι το υπόλοιπο της διαίρεσης με τους αριθμούς K είναι πάντα μικρότερο από τον αριθμό K. Για παράδειγμα, η διαίρεση με το 4 μπορεί να οδηγήσει σε υπολείμματα 0, 1, 2 και 3. Επομένως, εάν θέλετε να περιορίσετε τους τυχαίους αριθμούς από πάνω στον αριθμό K, τότε απλώς πάρτε το υπόλοιπο της διαίρεσης με το K. Σαν αυτό:

Λίστα 2.

#περιλαμβάνω #περιλαμβάνω int main(void) ( /* δημιουργούν πέντε τυχαίους ακέραιους λιγότερους από 100 */ printf("%d\n", rand()%100); printf("%d\n", rand()%100); printf ("%d\n", rand()%100);


Εικ.2 Πέντε τυχαίοι αριθμοί μικρότεροι του 100

Περιορίστε τους παρακάτω αριθμούς.

Η συνάρτηση rand επιστρέφει τυχαίους αριθμούς από το διάστημα. Τι γίνεται αν χρειαζόμαστε μόνο αριθμούς μεγαλύτερους από το M (για παράδειγμα, 1000); Τι πρέπει να κάνω; Είναι απλό. Ας προσθέσουμε απλώς την τιμή M σε αυτό που επέστρεψε η συνάρτηση rand. Στη συνέχεια, εάν η συνάρτηση επιστρέψει 0, η τελική απάντηση θα είναι M, εάν 2394, τότε η τελική απάντηση θα είναι M + 2394. Με αυτή την ενέργεια φαίνεται να μετατοπίζουμε όλους τους αριθμούς προς τα εμπρός κατά M μονάδες.

Ορίστε τα άνω και κάτω όρια της συνάρτησης rand.

Για παράδειγμα, πάρτε αριθμούς από το 80 έως το 100. Φαίνεται ότι χρειάζεται απλώς να συνδυάσετε τις δύο παραπάνω μεθόδους. Θα πάρουμε κάτι σαν αυτό:

Λίστα 3.

#περιλαμβάνω #περιλαμβάνω int main(void) ( /* δημιουργούν πέντε τυχαίους ακέραιους αριθμούς μεγαλύτερους από 80 και λιγότερους από 100 */ printf("%d\n", 80 + rand()%100); printf("%d\n", 80 + rand ()% 100), 80 + rand()% 100); 100);

Δοκιμάστε να εκτελέσετε αυτό το πρόγραμμα. Εκπληκτος;

Ναι, αυτή η μέθοδος δεν θα λειτουργήσει. Ας τρέξουμε αυτό το πρόγραμμα με το χέρι για να δούμε αν κάναμε λάθος. Ας υποθέσουμε ότι η rand() επέστρεψε τον αριθμό 143. Το υπόλοιπο όταν διαιρείται με το 100 είναι 43. Τότε 80 + 43 = 123. Άρα αυτή η μέθοδος δεν λειτουργεί. Αυτό το σχέδιο θα παράγει αριθμούς από 80 έως 179.

Ας αναλύσουμε την έκφρασή μας βήμα βήμα. Το rand()%100 μπορεί να επιστρέψει αριθμούς από το 0 έως το 99. Εκείνοι. από το τμήμα.
Η λειτουργία + 80 μετατοπίζει το τμήμα μας κατά 80 μονάδες προς τα δεξιά. Παίρνουμε.
Όπως μπορείτε να δείτε, το πρόβλημά μας βρίσκεται στο δεξί περίγραμμα του τμήματος μετατοπίζεται προς τα δεξιά κατά 79 μονάδες. Αυτός είναι ο αρχικός μας αριθμός 80 μείον 1. Ας καθαρίσουμε τα πράγματα και ας μετακινήσουμε το δεξί περίγραμμα πίσω: 80 + rand()%(100 - 80 + 1) . Τότε όλα πρέπει να λειτουργούν όπως θα έπρεπε.

Γενικά, αν πρέπει να πάρουμε αριθμούς από το τμήμα, τότε πρέπει να χρησιμοποιήσουμε την ακόλουθη κατασκευή:
A + rand()%(B-A+1) .

Σύμφωνα με αυτόν τον τύπο, θα ξαναγράψουμε το τελευταίο μας πρόγραμμα:

Λίστα 4.

#περιλαμβάνω #περιλαμβάνω int main(void) ( /* δημιουργούν πέντε τυχαίους ακέραιους αριθμούς από το τμήμα */ printf("%d\n", 80 + rand()%(100 - 80 + 1)); printf("%d\n", 80 + rand()%(100 - 79)); "%d\n", 80 + rand()%21 )

Αποτέλεσμα:


Εικ.3 Τυχαίοι αριθμοί από μια περιοχή

Λοιπόν, τώρα μπορείτε να λύσετε το αρχικό πρόβλημα του μαθήματος. Δημιουργήστε έναν αριθμό από ένα τμήμα. Ή δεν μπορείς;

Αλλά πρώτα, μερικές πιο χρήσιμες πληροφορίες. Εκτελέστε το τελευταίο πρόγραμμα τρεις φορές στη σειρά και σημειώστε τους τυχαίους αριθμούς που δημιουργεί. Παρατήρησες;

συνάρτηση srand().

Ναι, κάθε φορά εμφανίζονται οι ίδιοι ίδιοι αριθμοί. «Τόσο γεννήτρια!» - λες. Και δεν θα έχεις απόλυτο δίκιο. Πράγματι, οι ίδιοι αριθμοί παράγονται όλη την ώρα. Αλλά μπορούμε να το επηρεάσουμε αυτό χρησιμοποιώντας τη συνάρτηση srand(), η οποία ορίζεται επίσης στο αρχείο κεφαλίδας stdlib.h. Αρχικοποιεί τη γεννήτρια τυχαίων αριθμών με έναν αριθμό σποράς.

Μεταγλωττίστε και εκτελέστε αυτό το πρόγραμμα πολλές φορές:

Λίστα 5.

#περιλαμβάνω #περιλαμβάνω int main(void) ( srand(2); /* δημιουργούν πέντε τυχαίους ακέραιους αριθμούς από το τμήμα */ printf("%d\n", 80 + rand()%(100 - 80 + 1)); printf("% d\n", 80 + rand()%(100 - 79)); printf("%d\n", 80 + rand()%21); printf("%d\n", 80 + rand() %21); printf("%d\n", 80 + rand()%21);

Τώρα αλλάξτε το όρισμα της συνάρτησης srand() σε έναν άλλο αριθμό (ελπίζω να μην έχετε ξεχάσει τι είναι το όρισμα συνάρτησης;) και μεταγλωττίστε και εκτελέστε ξανά το πρόγραμμα. Η σειρά των αριθμών πρέπει να αλλάξει. Μόλις αλλάξουμε το όρισμα στη συνάρτηση srand, αλλάζει και η ακολουθία. Όχι πολύ πρακτικό, έτσι; Για να αλλάξετε τη σειρά, πρέπει να κάνετε εκ νέου μεταγλώττιση του προγράμματος. Εάν μόνο αυτός ο αριθμός θα εισαχθεί αυτόματα εκεί.

Και μπορεί να γίνει. Για παράδειγμα, ας χρησιμοποιήσουμε τη συνάρτηση time(), η οποία ορίζεται στο αρχείο κεφαλίδας time.h. Αυτή η συνάρτηση, εάν το NULL μεταβιβαστεί ως όρισμα, επιστρέφει τον αριθμό των δευτερολέπτων που έχουν περάσει από την 1η Ιανουαρίου 1970. Εδώ είναι μια ματιά στο πώς γίνεται.

Λίστα 6.

#περιλαμβάνω #περιλαμβάνω #περιλαμβάνω // για να χρησιμοποιήσετε τη συνάρτηση time() int main(void) ( srand(time(NULL)); /* δημιουργεί πέντε τυχαίους ακέραιους αριθμούς από το τμήμα */ printf("%d\n", 80 + rand()%( 100 - 80 + 1)); \n", 80 + rand()%21); printf("%d\n", 80 + rand()%21); )

Μπορείτε να ρωτήσετε, τι είναι το NULL; Λογική ερώτηση. Εν τω μεταξύ, θα σας πω ποια είναι αυτή η ειδική δεσμευμένη λέξη. Μπορώ επίσης να πω τι σημαίνει μηδενικός δείκτης, αλλά... Αυτό δεν σας παρέχει καμία πληροφορία, γι' αυτό σας συνιστώ να μην το σκέφτεστε αυτήν τη στιγμή. Και απλά να το θυμάστε ως κάποιο είδος έξυπνου κόλπου. Σε επόμενα μαθήματα θα εξετάσουμε αυτό το πράγμα με περισσότερες λεπτομέρειες.

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

Η τυπική συνάρτηση βιβλιοθήκης της γλώσσας C (όχι C++) rand() μας βοηθάει.

int rand(void);

Δημιουργεί έναν ψευδοτυχαίο ακέραιο στην περιοχή τιμών από 0 έως RAND_MAX. Η τελευταία είναι μια σταθερά που ποικίλλει ανάλογα με την εφαρμογή της γλώσσας, αλλά στις περισσότερες περιπτώσεις είναι 32767.
Τι γίνεται αν χρειαζόμαστε τυχαίους αριθμούς από το 0 έως το 9; Μια τυπική διέξοδος από αυτήν την κατάσταση είναι να χρησιμοποιήσετε τη λειτουργία διαίρεσης modulo.

Αν χρειαζόμαστε αριθμούς από το 1 (όχι το 0) έως το 9, τότε μπορούμε να προσθέσουμε έναν...

Η ιδέα είναι η εξής: δημιουργούμε έναν τυχαίο αριθμό από το 0 έως το 8 και αφού προσθέσουμε το 1 μετατρέπεται σε τυχαίο αριθμό από το 1 έως το 9.

Και τέλος, το πιο λυπηρό.
Δυστυχώς, η συνάρτηση rand() δημιουργεί ψευδοτυχαίους αριθμούς, π.χ. αριθμοί που φαίνονται τυχαίοι, αλλά στην πραγματικότητα είναι μια ακολουθία τιμών που υπολογίζονται χρησιμοποιώντας έναν έξυπνο αλγόριθμο που παίρνει ως παράμετρο τον λεγόμενο κόκκο. Εκείνοι. Οι αριθμοί που δημιουργούνται από τη συνάρτηση rand() θα εξαρτηθούν από την τιμή που έχει ο κόκκος τη στιγμή που καλείται. Και ο κόκκος ορίζεται πάντα από τον μεταγλωττιστή στην τιμή 1. Με άλλα λόγια, η ακολουθία των αριθμών θα είναι ψευδοτυχαία, αλλά πάντα η ίδια.
Και δεν είναι αυτό που χρειαζόμαστε.

Η συνάρτηση srand() βοηθά στη διόρθωση της κατάστασης.

void srand(unsigned int seed);

Ορίζει τον κόκκο ίσο με την τιμή της παραμέτρου με την οποία κλήθηκε. Και η σειρά των αριθμών θα είναι επίσης διαφορετική.

Όμως το πρόβλημα παραμένει. Πώς να κάνετε τον κόκκο τυχαίο, επειδή όλα εξαρτώνται από αυτό;
Μια τυπική διέξοδος από αυτήν την κατάσταση είναι να χρησιμοποιήσετε τη συνάρτηση time().

time_t time(time_t* timer);

Επίσης, κληρονομείται από τη γλώσσα C και, όταν καλείται με μηδενικό δείκτη ως παράμετρο, επιστρέφει τον αριθμό των δευτερολέπτων που έχουν περάσει από την 1η Ιανουαρίου 1970. Όχι, αυτό δεν είναι αστείο.

Τώρα μπορούμε να περάσουμε την τιμή αυτής της συνάρτησης στη συνάρτηση srand() (η οποία κάνει ένα σιωπηρό cast) και θα έχουμε έναν υπέροχο τυχαίο κόκκο.
Και οι αριθμοί θα είναι υπέροχοι και μη επαναλαμβανόμενοι.

Για να χρησιμοποιήσετε τις συναρτήσεις rand() και srand() πρέπει να συμπεριλάβετε ένα αρχείο κεφαλίδας , και για να χρησιμοποιήσετε time() - αρχείο .

Εδώ είναι ένα πλήρες παράδειγμα.

#περιλαμβάνω
#περιλαμβάνω
#περιλαμβάνω

χρησιμοποιώντας namespace std?

int main()
{
cout<< "10 random numbers (1..100): " << endl;
srand(time(NULL));
for(int i=0;i<10;i++) cout << rand() % 100 + 1 << " ";
cin.get();
επιστροφή 0;
}

Η συνάρτηση που δημιουργεί ψευδοτυχαίους αριθμούς έχει ένα πρωτότυπο στο αρχείο βιβλιοθήκης stdlib.h:

1
2
3
4
5
6

ανυπόγραφο long int next = 1;
int rand (κενό)
{
επόμενο = επόμενο * 1103515245;
επιστροφή ((unsigned int )(next / 65536) * 2768);
}


Η συνάρτηση rand() δεν δέχεται ορίσματα, αλλά λειτουργεί στην επόμενη μεταβλητή με καθολικό εύρος.

Εάν χρειάζεται να δημιουργήσετε μια ακολουθία στο εύρος , τότε χρησιμοποιείται ο τύπος:

Αριθμός = rand()%(M2-M1+1) + M1;

Οπου Αριθμός– παραγόμενος αριθμός. Μ2-Μ1+1– πλήρες εύρος αναπαράστασης αριθμών. Μ1– μετατόπιση του καθορισμένου εύρους σε σχέση με 0. % - υπόλοιπο της διαίρεσης.

Για παράδειγμα, εάν πρέπει να δημιουργήσετε μια ακολουθία στην περιοχή [-10;10], τότε η κλήση συνάρτησης θα μοιάζει με

Αριθμός = rand()%(10+10+1)-10

Αριθμός = rand()%(21)-10

Ως αποτέλεσμα της λήψης του υπολοίπου από τη διαίρεση με το 21, έχουμε έναν αριθμό από το 0 έως το 20. Αφαιρώντας το 10 από τον αριθμό που προκύπτει, παίρνουμε έναν αριθμό στο επιθυμητό εύρος [-10;10].

Ωστόσο, η ακολουθία που δημιουργείται από τη συνάρτηση rand() θα φαίνεται η ίδια κάθε φορά που εκτελείται το πρόγραμμα.

Για να δημιουργήσετε διαφορετικές ακολουθίες κάθε φορά που εκκινείται το πρόγραμμα, είναι απαραίτητο να αρχικοποιήσετε την καθολική μεταβλητή στη συνέχεια με τιμή διαφορετική από 1. Για το σκοπό αυτό, χρησιμοποιήστε τη συνάρτηση
void srand (unsigned int seed)
(επόμενο = σπόρος;)

Για να διασφαλιστεί ότι η αρχικοποίηση του επόμενου είναι διαφορετική κάθε φορά που εκκινείται το πρόγραμμα, η τρέχουσα ώρα χρησιμοποιείται συχνότερα ως όρισμα εκκίνησης.

Παράδειγμα Συμπληρώστε έναν πίνακα 20 στοιχείων με τυχαίους αριθμούς στην περιοχή από 0 έως 99.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

#περιλαμβάνω
#περιλαμβάνω
#περιλαμβάνω
#define SIZE 20
int main() (
int a?
srand(time(NULL));
για (int i = 0; i {
a[i] = rand() % 100;
printf("%d " , a[i]);
}
getchar();
επιστροφή 0;
}


Αποτέλεσμα εκτέλεσης

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

Εφαρμογή στο Γ

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

#περιλαμβάνω
#περιλαμβάνω
#περιλαμβάνω
#define SIZE 20
int main() (
int a?
srand(time(NULL));

για (int i = 0; i< SIZE; i++)
{
a[i] = i + 1;
printf("%2d " , a[i]);
}
για (int i = 0; i< SIZE; i++)
{
// Δημιουργήστε τυχαία δύο ευρετήρια στοιχείων
int ind1 = rand() % 20;
int ind2 = rand() % 20;
// και ανταλλάξτε στοιχεία με αυτούς τους δείκτες
int temp = a;
a = a;
a = θερμοκρασία;
}
printf("\n" );

για (int i = 0; i< SIZE; i++)
printf("%2d " , a[i]);
getchar();
επιστροφή 0;
}


Αποτέλεσμα εκτέλεσης


Συχνά προκύπτει το καθήκον της τυχαίας επιλογής προκαθορισμένων στοιχείων πίνακα. Επιπλέον, είναι απαραίτητο να διασφαλιστεί η απουσία επανάληψης στην επιλογή αυτών των στοιχείων.
Ο αλγόριθμος για αυτή την επιλογή είναι ο εξής:

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

Υλοποιήσεις στο Γ
Ως αποτέλεσμα, λαμβάνουμε έναν νέο πίνακα b, που σχηματίζεται από μια τυχαία επιλογή στοιχείων του πίνακα a.

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

#περιλαμβάνω
#περιλαμβάνω
#περιλαμβάνω
#define SIZE 20
int main() (
int a?
int b; // πίνακας που προκύπτει
srand(time(NULL));
// Συμπληρώστε τον πίνακα με διαδοχικές τιμές από 1 έως 20
για (int i = 0; i< SIZE; i++)
{
a[i] = i + 1;
printf("%2d " , a[i]);
}

για (int i = 0; i< SIZE; i++)
{
int ind = rand() % 20; // επιλέξτε ένα αυθαίρετο ευρετήριο
ενώ (a == -1) // ενώ το στοιχείο είναι "επιλεγμένο"
{
ind++; // μετακίνηση προς τα δεξιά
ind %= 20; // αν φτάσουμε στο σωστό περίγραμμα, επιστρέψτε στην αρχή
}
b[i] = a; // γράψτε το επόμενο στοιχείο του πίνακα β
a = -1; // επισημάνετε το στοιχείο του πίνακα a ως "επιλεγμένο"
}
printf("\n" );
// Εξαγωγή του πίνακα που προκύπτει
για (int i = 0; i< SIZE; i++)
printf("%2d " , b[i]);
getchar();
επιστροφή 0;
}


Αποτέλεσμα εκτέλεσης

Ετικέτες: Γ τυχαίοι, Γ τυχαίοι αριθμοί, δημιουργία τυχαίων αριθμών, RNG, ψευδοτυχαίοι αριθμοί, μέθοδος Μόντε Κάρλο

Ψευδοτυχαίοι αριθμοί

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

Παραδείγματα χρήσης τυχαίων αριθμών συναντάς παντού. Οι ψευδοτυχαίοι αριθμοί χρησιμοποιούνται στο σχεδιασμό και τα γραφικά, για τη δημιουργία επιπέδων σε παιχνίδια υπολογιστή και για την προσομοίωση της τεχνητής νοημοσύνης. Σε μαθηματικούς αλγόριθμους χρησιμοποιούνται σύνολα τυχαίων αριθμών (βλ. μεθόδους Monte Carlo).

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

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

Ας δούμε μια τυπική γεννήτρια.

#περιλαμβάνω #περιλαμβάνω #περιλαμβάνω int main() ( int i, r; srand(42); for (i = 0; i< 10; i++) { r = rand(); printf("%d\n", r); } _getch(); return 0; }

Αρχικά, πρέπει να αρχικοποιήσετε τη γεννήτρια τυχαίων αριθμών (RNG, ή RNG - γεννήτρια τυχαίων αριθμών), να ορίσετε τη βάση, βάσει της οποίας θα πραγματοποιηθεί η δημιουργία στο μέλλον. Είναι σημαντικό ότι για την ίδια αρχική τιμή η γεννήτρια θα επιστρέψει τους ίδιους αριθμούς.

Srand(42);

Εκχωρήστε στη μεταβλητή r μια τυχαία τιμή

R = rand();

Η τιμή θα είναι στην περιοχή από 0 έως RAND_MAX.

Για να λάβετε ένα νέο σύνολο αριθμών την επόμενη φορά που θα ξεκινήσετε, πρέπει να αρχικοποιείτε τη γεννήτρια με διαφορετικές τιμές κάθε φορά. Για παράδειγμα, μπορείτε να χρησιμοποιήσετε την ώρα συστήματος:

Srand(time(NULL));

Srand(_getpid());

Η συνάρτηση getpid της βιβλιοθήκης process.h επιστρέφει το αναγνωριστικό διεργασίας (μπορείτε επίσης να χρησιμοποιήσετε το getpid, την έκδοση της συνάρτησης που δεν είναι POSIX).

Κεντρικό οριακό θεώρημα

Είναι πολύ σημαντικό να υπενθυμίσουμε ή να εισαγάγουμε αμέσως το κεντρικό οριακό θεώρημα. Άτυπος ορισμός: η κατανομή ενός αθροίσματος ασθενώς εξαρτώμενων τυχαίων μεταβλητών τείνει στο κανονικό. Εξήγηση σε σχήμα δακτύλου: αν προσθέσετε πολλές τυχαίες μεταβλητές, ανεξάρτητα από την κατανομή τους, η κατανομή του αθροίσματος θα είναι κανονική. Μπορείτε συχνά να δείτε κώδικα σαν αυτόν

#περιλαμβάνω #περιλαμβάνω #περιλαμβάνω int main() ( int i, r, r1, r2, r3; srand(time(NULL)); r1 = rand(); r2 = rand(); r3 = rand(); r = (r1 + r2 + r3 ) / 3; printf("%d", r);

Δημιουργία τυχαίων αριθμών σε ένα δεδομένο διάστημα

Αρχικά, παίρνουμε έναν τυχαίο αριθμό από το μηδέν έως το ένα:

Const float RAND_MAX_F = RAND_MAX; float get_rand() ( return rand() / RAND_MAX_F; )

Για να πάρετε έναν αριθμό στο διάστημα από το μηδέν έως το Ν, πολλαπλασιάστε το N με έναν τυχαίο αριθμό από το μηδέν στο ένα. Για να λάβουμε έναν τυχαίο αριθμό από το M στο N, μετατοπίζουμε τον αριθμό που προκύπτει κατά M.

Float get_rand_range(const float min, const float max) ( return get_rand() * (max - min) + min; )

Για να λάβουμε έναν ακέραιο, θα πάρουμε το υπόλοιπο της διαίρεσης με το μήκος του διαστήματος. Αλλά το υπόλοιπο της διαίρεσης θα επιστρέψει έναν αριθμό μικρότερο από το μεσοδιάστημά μας, οπότε το αυξάνουμε κατά ένα:

Int get_rand_range_int(const int min, const int max) ( return rand() % (max - min + 1) + min; )

Ένα παράδειγμα χρήσης τυχαίων αριθμών για τον υπολογισμό ενός ολοκληρώματος. Ας έχουμε κάποια ομαλή συνάρτηση μιας μεταβλητής. Ας το περιορίσουμε σε ένα τετράγωνο από το a στο b, και από το 0 σε κάποιο σημείο, το οποίο είναι προφανώς μεγαλύτερο από τη συνάρτησή μας.

Θα ρίξουμε τυχαία κουκκίδες στο τετράγωνό μας. Εάν βρίσκονται πάνω από τη συνάρτηση (που φαίνονται ως πράσινοι σταυροί στο σχήμα), τότε θα τα αντιστοιχίσουμε στην πρώτη ομάδα Α, εάν κάτω από τη συνάρτηση (κόκκινο στο σχήμα), τότε θα τα αντιστοιχίσουμε στη δεύτερη ομάδα Β. Η θέση των σημείων είναι τυχαία και κατανέμεται ομοιόμορφα (καθώς το πρότυπο η γεννήτρια δίνει ομοιόμορφη κατανομή. Αυτό το απλό παράδειγμα, παρεμπιπτόντως, δείχνει ήδη πόσο σημαντικό είναι να γνωρίζουμε τις ιδιότητες του RNG). Τότε η αναλογία των κόκκινων κουκκίδων προς τον συνολικό αριθμό των κουκκίδων θα είναι ίση με την αναλογία της περιοχής κάτω από το γράφημα προς τη συνολική επιφάνεια. Και το συνολικό εμβαδόν είναι το τετράγωνο (b-a) επί q.

Src="/images/c_random_integral.png" alt=" Ό,τι πέφτει τυχαία πάνω από τη συνάρτησή μας είναι πράσινο, ό,τι κάτω είναι κόκκινο.
Η αναλογία πράσινου προς κόκκινο θα είναι ίση με την αναλογία της περιοχής πάνω από το γράφημα προς την περιοχή κάτω από το γράφημα."> Всё, что случайно попадает выше нашей функции - зелёное, всё что ниже - красное. !}
Η αναλογία πράσινου προς κόκκινο θα είναι ίση με την αναλογία της περιοχής πάνω από το γράφημα προς την περιοχή κάτω από το γράφημα.

Ας εφαρμόσουμε τους υπολογισμούς μας - βρείτε το ολοκλήρωμα της συνάρτησης x^2 στο διάστημα από το 0 έως το δύο με δύο τρόπους.

#περιλαμβάνω #περιλαμβάνω #περιλαμβάνω #περιλαμβάνω #περιλαμβάνω const float RAND_MAX_F = RAND_MAX; float get_rand() ( return rand() / RAND_MAX_F; ) float get_rand_range(const float min, const float max) ( return get_rand() * (max - min) + min; ) #define ROUNDS 1000 float fun(float x) ( επιστροφή x * x ) float square_square(float a, float b, float q) ( float h = (b - a) / (float) ROUNDS; float sum = 0; for (; a)< b; a += h) { sum += fun(a) * h; } return sum; } float rand_square(float a, float b, float q) { float res; float x, y; int i; int lower = 0; float ratio; float square; srand(time(NULL)); for (i = 0; i < ROUNDS; i++) { x = get_rand_range(a, b); y = get_rand_range(0, q); res = fun(x); if (res >y) ( χαμηλότερο++; ) ) αναλογία = (float)lower / (float)ROUNDS; τετράγωνο = (b - a) * q * λόγος; τετράγωνο επιστροφής? ) int main() ( float abs_ans = 2.66667f; float sr = rand_square(0, 2, 4); float ss = square_square(0, 2, 4); printf("Rounds = %d\n", ROUNDS); printf("Sa = %.5f\n", abs_ans ("Sr = %.5f\n", sr); ", fabs(sr - abs_ans)); printf("ds = %.5f\n", fabs(ss - abs_ans)); _getch(); return 0; )

Παίξτε με την τιμή ROUNDS, αλλάξτε την και δείτε πώς αλλάζει η ακρίβεια υπολογισμού.

Δημιουργία πραγματικών τυχαίων αριθμών

Για τη δημιουργία πραγματικών τυχαίων αριθμών, χρησιμοποιούνται γεννήτριες που βασίζονται σε ορισμένες τυχαίες φυσικές διεργασίες. Για παράδειγμα, στον θερμικό θόρυβο, στην καταμέτρηση του αριθμού των σχάσεων μιας ραδιενεργής ουσίας, στον ατμοσφαιρικό θόρυβο κ.λπ. Το μειονέκτημα τέτοιων γεννητριών είναι η χαμηλή ταχύτητα λειτουργίας τους (ο αριθμός των παραγόμενων αριθμών ανά δευτερόλεπτο). Φυσικά, τέτοιες γεννήτριες είναι συνήθως μια ξεχωριστή συσκευή.