Προς το περιεχόμενο

Χειρισμός rand() με κατάλληλο τρόπο!


epir21

Προτεινόμενες αναρτήσεις

Καλησπέρα.

 

Έχω μια εργασία σε C και πρέπει να επιστρέφονται τυχαίες τιμές αλλα κάθε τιμή εχει ποσοστά επιτυχίας στην επιλογή.

 

Τι εννοώ; (το πιο απλό παράδειγμα):

Έστω οτι θέλουμε η rand() να επιστρέφει 0 ή 1 άρα θα είναι:

int x=rand()%2;

Σε αυτό που ρωτάω όμως η rand() θα πρέπει να επιστρέφει 0 με ποσοστό 40% και 1 με ποσοστό 60%

Δηλαδή αν εκτελεστεί 100 φορές η παραπάνω γραμμή, το x θα είναι 40 φορές 0 και 60 φορές 1.

 

Έχει κανείς καμια ιδέα; Έχω ψάξει στο νετ αλλα δεν βρίσκω κάτι.

 

Ευχαριστώ εκ των προτέρων..

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Δηαλδη θες η rand να "επιστρεφει" ή κατω απο 40 στα 100 ή πανω απο 40 στα 100

δηλαδη int randSta100 = rand() % 100;

Δεν είμαι σίγουρος αν είναι αυτο ακριβώς που λες γιατί ειμαι λιγο ζαλισμένος μετά απο τόσες ώρες γράψημο.

Θα προσπαθήσω να το πω αλλιώς μήπως και καταλάβεις καλύτερα μιας και θες να βοηθήσεις.

 

Θέλω στις 100 φορες (πχ) που θα εκτελεστεί η rand(), τις 40 να βγάλει 0 και τις 60 να βγάλει 1.

 

Ή ενα άλλο ερώτημα λέει.

Να επιστρέφει 5 με 10% ποσοστό, 6 με 20% ποσοστό, 7 με 30% ποσοστό και 8 με 40% ποσοστό.

(Δεν λέει αυτό ακριβώς η άσκηση αλλα αυτό εννοεί)

Δηλαδή:

int x= rand() %(8-5+1)+5    

Έτσι όμως επιστρέφονται τυχαία 5-6-7-8.

Εγω θέλω να "περιορίσω" αυτό το τυχαίο κατα κάποιον τρόπο :P

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Αυτο σου λεω μανα μου.... το rand()%100 θα σου δωσει 40 φορες κατι κατω απο 40, και 60 φορες κατι που ειναι απανω απο το 40

 

Μπορεις να πεις οτι το κατι που ειναι κατω απο 40 συμβολιζει  το 0 και το κατι που ειναι απανω απο το 40 ειναι 1

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

#include <stdio.h>

#include <time.h>

#include <stdlib.h>

int main()

{

int i;

srand (time(NULL));

for (i=0;i<100;i++)

if ((rand() % 100) < 40) {

}

return 0;

}

θεωρητικά θα μπει στην if με πιθανότητα 40% 

οποτε βαζεις και μια else αν δεν μπει για να ειναι το υπολοιπο 60%

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Όταν είδα την απαντησή σου έφτιαχνα ενα πρόχειρο για να τεστάρω αυτό που μου έγραψε ο παπι.

Και παρατήρησα ότι έβγαζε πάνω κάτω αυτό που θέλω.

Αυτό που έγραψα ήταν σχεδόν ίδιο με το δικό σου  και βγάζουν τα ίδια αποτελέσματα.

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

 

Δηλάδη άλλη φορά μπορεί να βγάλει 40(0) 60(1) άλλη 42(0) 58(1) κ.ο.κ

Αυτό είναι σωστό πιστέυεται; γιατί το πρώτο έχει ποσοστό 40% για τα μηδενικά και 60% για τους άσσους αλλα το δεύτερο έχει 42% μηδενικά και 58% άσσοι.

Άλλη φορά μου έβγαλε 30% μηδενικά και 70% άσσους.

Δεν υπάρχει τρόπος να περιορηστεί "μπαμ" εκει που θέλουμε;

 

Όπως και  να εχει σας ευχαριστώ και τους δυο, με βοηθήσατε πολύ.

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

 

#include <stdio.h>
#include <time.h>
#include <stdlib.h>
int main()
{
int i;
srand (time(NULL));
for (i=0;i<100;i++)
if ((rand() % 100) < 40) {
}
return 0;
}
θεωρητικά θα μπει στην if με πιθανότητα 40% 
οποτε βαζεις και μια else αν δεν μπει για να ειναι το υπολοιπο 60%

 

+1, αυτό θα έγραφα και εγώ...

 

Όταν είδα την απαντησή σου έφτιαχνα ενα πρόχειρο για να τεστάρω αυτό που μου έγραψε ο παπι.

Και παρατήρησα ότι έβγαζε πάνω κάτω αυτό που θέλω.

Αυτό που έγραψα ήταν σχεδόν ίδιο με το δικό σου  και βγάζουν τα ίδια αποτελέσματα.

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

 

Δηλάδη άλλη φορά μπορεί να βγάλει 40(0) 60(1) άλλη 42(0) 58(1) κ.ο.κ

Αυτό είναι σωστό πιστέυεται; γιατί το πρώτο έχει ποσοστό 40% για τα μηδενικά και 60% για τους άσσους αλλα το δεύτερο έχει 42% μηδενικά και 58% άσσοι.

Άλλη φορά μου έβγαλε 30% μηδενικά και 70% άσσους.

Δεν υπάρχει τρόπος να περιορηστεί "μπαμ" εκει που θέλουμε;

 

Όπως και  να εχει σας ευχαριστώ και τους 2, με βοηθήσατε πολύ.

 

όχι δεν γίνεται με το ζόρυ αλλά θα μπορούσες με έλεγχο να κάνεις το εξής (δεδομένου οτι το τρέχεις 100 φορές - πολύ σημαντικό): 

 

φτιάξε δύο μετρητές... 

 

α1=πλήθος που βγαίνει 0

α2=πλήθος που βγαίνει 1

 

#include <stdio.h>
#include <time.h>
#include <stdlib.h>
int main()
{
int i;
int a1=0;
int a2=0;
bool ouput;
srand (time(NULL));
for (i=0;i<100;i++)
 
if(a1==40){
output=1
a2++;}
elseif(a2==60){
output=0
a1++;}
else{
if ((rand() % 100) < 40) {
output=0;
a1++;
}
else{
output=1;
a2++;
}
}
 
return 0;
}

 

 

δηλαδή αν σε κάποιο σημείο φτάσεις στα 40 (0) ή στα 60 (1) μην βγάζεις άλλο τυχαία πράγματα.. κάντα fixed... πάντως το σωστό είναι να βγάζεις τυχαία πλήθη και αυτό που σου περιέγραψα είναι σικέ :P

 

Επιπλέον το 

 

"Να επιστρέφει 5 με 10% ποσοστό, 6 με 20% ποσοστό, 7 με 30% ποσοστό και 8 με 40% ποσοστό. " με κάνει να πιστεύω οτι ψάχνεις τρόπο  να αναπαράξεις πείραμα του στυλ ( έχεις 100 μπάλες σε ένα κουτί, οι 10 είναι μπλε, οι 20 είναι κίτρινες κτλπ κτλπ, και θέλεις να διαλέγεις μπάλες χωρίς επανατοποθέτηση..) αντίστοιχα με την παρακάτω λογική θα μπορούσες να παράξεις και το πρώτο πείραμα με το 60-40

 

Οπότε (δεν φτιάχνω κώδικα, τη λογική θα προσπαθήσω να περιγράψω):

 

1)φτιάξε ένα κουτί ----> δηλαδή ένα πίνακα 100 θέσεων

2) βάλε μέσα τις μπάλες με τη διαφορετική συχνότητα την κάθε μία ---> εισαγωγή τιμών στον πίνακα (10 φορές το 5, 20 φορές το 6 κτλπ) (δεν έχει σημασία πως θα τις βάλεις)

3) διάλεξε τυχαία μια θέση του πίνακα ----> θέση=rand()%100

4) σημείωσε οτι πέρασες από την θέση για να μην ξαναέρθεις -----> ανάθεση με κουλό νούμερο (-1)

5) σε περίπτωση που πέσεις σε θέση με -1 ξανατράβα :P

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Σε ευχαριστώ και εσένα φαν της τεχνολογίας   :P για την απαντησή σου και ομολογώ οτι δεν κατάλαβα πολλά απο αυτο που γράφεις αλλα το έτρεξα και τρέχει όπως θέλω αλλα μόνο για 100 φορές αν το τρέξω 200 πχ μου βγάζει 40 μηδενικά 160 άσσους.

 

Ίσως το έθεσα εγω λάθος.

Δεν θέλω να γίνεται κάποια επανάληψη.

 

Για να γίνω πιο συγκεκριμένος αυτό ειναι ενα κομάτι απο ενα project στα λειτουργικά συστήματα και αυτό το κομάτι με με την rand στην ουσία θα είναι μέσα σε μια συνάρτηση και κάθε φορά που θα εκτελείτε ενας client θα επιστρέφει μια τιμή με βάση τα ποσοστά που σας είπα πριν. Όποτε η συνάρτηση μέσα δεν θα έχει επανάληψη. Εγώ σκέφτομαι την βασική σχέση να την βάλω σε if και ανάλογα με το τι βγάζει η rand() να επιστρέφω κάτι απλα όπως είπα δεν βγάζει ακριβώς αυτα που θέλω πχ αντι για 40 60 μπορει να βγάλει 27 73 (όπως και να το κάνουμε ειναι μεγάλη διαφορά)

 

EDIT: Τώρα ειδα πιο προσεκτηκα αυτό που μου έγραψες. Πολύ έξυπνο ομολογώ :P

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Σε ευχαριστώ και εσένα φαν της τεχνολογίας   :P για την απαντησή σου και ομολογώ οτι δεν κατάλαβα πολλά απο αυτο που γράφεις αλλα το έτρεξα και τρέχει όπως θέλω αλλα μόνο για 100 φορές αν το τρέξω 200 πχ μου βγάζει 40 μηδενικά 160 άσσους.

 

Ίσως το έθεσα εγω λάθος.

Δεν θέλω να γίνεται κάποια επανάληψη.

 

Για να γίνω πιο συγκεκριμένος αυτό ειναι ενα κομάτι απο ενα project στα λειτουργικά συστήματα και αυτό το κομάτι με με την rand στην ουσία θα είναι μέσα σε μια συνάρτηση και κάθε φορά που θα εκτελείτε ενας client θα επιστρέφει μια τιμή με βάση τα ποσοστά που σας είπα πριν. Όποτε η συνάρτηση μέσα δεν θα έχει επανάληψη. Εγώ σκέφτομαι την βασική σχέση να την βάλω σε if και ανάλογα με το τι βγάζει η rand() να επιστρέφω κάτι απλα όπως είπα δεν βγάζει ακριβώς αυτα που θέλω πχ αντι για 40 60 μπορει να βγάλει 27 73 (όπως και να το κάνουμε ειναι μεγάλη διαφορά)

 

EDIT: Τώρα ειδα πιο προσεκτηκα αυτό που μου έγραψες. Πολύ έξυπνο ομολογώ :P

Όμορφο πρόβλημα....  

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Υπάρχει πολύ πιο απλή λύση...

 

Η rand υποτίθεται ότι είναι με κανονική κατανομή στο [0,1] (ή [0, 1), δεν θυμάμαι.. anyways....).

 

Άρα, κάθε ένας αριθμός από τους 0.1, 0.2, 0.3,...0.9 και 1 θα έχει ίση πιθανότητα. 

 

Άρα, εάν κάθε τι που είναι μέχρι και 0.4 το κάνουμε 0.4, το 0.4 θα έχει πιθανότητα εμφάνισης 4/10. Εάν κάθε τι που είναι μεγαλύτερο από 0.4 το κάνουμε στο 0.6, τότε τo 0.6 θα έχει πιθανότητα εμφάνισης 6/10.

 

Έτσι, μία πολύ πιο απλή λύση είναι:

int i, result;
for(i = 0; i < 100; i++)
{
  result = (rand() > 0.4)?(1):(0);
}

 

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Υπάρχει πολύ πιο απλή λύση...

 

Η rand υποτίθεται ότι είναι με κανονική κατανομή στο [0,1] (ή [0, 1), δεν θυμάμαι.. anyways....).

 

Άρα, κάθε ένας αριθμός από τους 0.1, 0.2, 0.3,...0.9 και 1 θα έχει ίση πιθανότητα. 

 

Άρα, εάν κάθε τι που είναι μέχρι και 0.4 το κάνουμε 0.4, το 0.4 θα έχει πιθανότητα εμφάνισης 4/10. Εάν κάθε τι που είναι μεγαλύτερο από 0.4 το κάνουμε στο 0.6, τότε τo 0.6 θα έχει πιθανότητα εμφάνισης 6/10.

 

Έτσι, μία πολύ πιο απλή λύση είναι:

int i, result;
for(i = 0; i < 100; i++)
{
  result = (rand() > 0.4)?(1):(0);
}

 

Ίσως το σκέφτομαι λάθος αλλά χωρίς κάποιο μετασχηματισμό όλα τα αποτελέσματα της rand δεν θα είναι μεγαλύτερα από 0.4 ?

  • Like 1
Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Ίσως το σκέφτομαι λάθος αλλά χωρίς κάποιο μετασχηματισμό όλα τα αποτελέσματα της rand δεν θα είναι μεγαλύτερα από 0.4 ?

 

Θα είναι, έχεις δίκιο. Βλακεία μου... λείπει μία κανονικοποίηση των αποτελεσμάτων της rand στο διάστημα [0, 1] (ίσως κάποια διαίρεση με  RAND_MAX)

 

Από εκεί και πέρα, το point μου είναι ότι όλα τα παραπάνω των άλλων poster σε αυτό το thread μπορούν να γίνουν πιο σύντομα. 

 

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

result = (rand()%1 > 0.4)?(1):(0);

 

 

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

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε

Πρέπει να είστε μέλος για να αφήσετε σχόλιο

Δημιουργία λογαριασμού

Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!

Δημιουργία νέου λογαριασμού

Σύνδεση

Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.

Συνδεθείτε τώρα
  • Δημιουργία νέου...