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

C: Δημιουργία Πίνακα με τυχαίους αριθμούς


Arctic

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

Οκ για το 1000! .. αλλά έχω μια ένσταση για την κατανομή των πιθανοτήτων στα loops σαν αυτό

 

 

        int numberA, numberB;
	for(numberA = 0; numberA < boardSize; numberA++)
	{
  		numberB = rand() % boardSize;
  		if(numberB != numberA)
    			swap(&board[numberA], &board[numberB]);
	}

 

 

Ας πούμε έχω 3 αριθμούς δλδ 3!=6 συνδυασμούς

Το numberB μπορεί να πάρει 3 τιμές  0,1 και 2.

Σε ένα ολόκληρο loop μπορεί να πάρει μία από τις 27 "ισοπίθανες" τιμές 000, 001, 002, 010 .....   221 και 222 .

Πολλές από τις 27 αντιστοιχίσουν σε ίδιο συνδυασμό επειδή μόνο 6 υπάρχουν.  

Ναι αλλά το 27 δεν διαιρείται από 6 , άρα κάποιοι από τους 6 συνδυασμούς θα εμφανίζονται πιο συχνά από τους άλλους

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

Οκ για το 1000! .. αλλά έχω μια ένσταση για την κατανομή των πιθανοτήτων στα loops σαν αυτό

 

 

        int numberA, numberB;
	for(numberA = 0; numberA < boardSize; numberA++)
	{
  		numberB = rand() % boardSize;
  		if(numberB != numberA)
    			swap(&board[numberA], &board[numberB]);
	}

 

 

Ας πούμε έχω 3 αριθμούς δλδ 3!=6 συνδυασμούς

Το numberB μπορεί να πάρει 3 τιμές  0,1 και 2.

Σε ένα ολόκληρο loop μπορεί να πάρει μία από τις 27 "ισοπίθανες" τιμές 000, 001, 002, 010 .....   221 και 222 .

Πολλές από τις 27 αντιστοιχίσουν σε ίδιο συνδυασμό επειδή μόνο 6 υπάρχουν.  

Ναι αλλά το 27 δεν διαιρείται από 6 , άρα κάποιοι από τους 6 συνδυασμούς θα εμφανίζονται πιο συχνά από τους άλλους

Στο παραπάνω loop μόνο 6 είναι οι δυνατές τιμές (για 3 αριθμούς όπως λες) γιατί έχεις ήδη αρχικοποιήσει τον πίνακα board[] = {0,1,2} και μετά απλά κάνεις swap. Οπότε οι συνδιασμοί 001, 011, 000, κτλ (με αριθμούς που επαναλαμβάνονται) δεν πρόκειται ποτέ να εμφανιστούν...

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

001 (...011 222 ... klp ) είναι η τριάδα από τιμές που παίρνει το rand()%3  κατά τι διάρκεια του loop, όχι ο συνδυασμός.  Αντιστοιχούν όμως σε κάποιον από τους 6 συνδυασμούς

 

001 -->το ζάρι έδειξε 0 την πρώτη φορά, 0 τη δεύτερη και 1 την τρίτη 

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

Σωστός ο albNik όσον αφορά τις πιθανότητες.. Απλά πόσταρα την προηγούμενη λύση μου ως good enough, αφού δουλεύει ικανοποιητικά και για μεγάλες τιμές του BOARDSIZE :D

 

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

 

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define BOARDSIZE 4

int factorial(int);
int continueOrStop(void);
void ithPermutation(const int, int); 
/*η ithPermutation όπως λέει και το όνομα υπολογίζει την i-οστή μετάθεση των n στοιχείων*/

int main(int argc, char *argv[])
{
	int combinations = factorial(BOARDSIZE);

	srand ((unsigned)time(NULL));

	printf("Shuffling...\n");
	ithPermutation(BOARDSIZE, rand() % combinations);
	while(continueOrStop())
	{
		printf("Shuffling...\n");
		ithPermutation(BOARDSIZE, rand() % combinations);
	}
}

int continueOrStop(void)
{
	printf("Continue (y/n)?: ");

	while (1)
	{
		char c = getchar();
		if (c == 'y' || c == 'Y')
			return 1;
		else if (c == 'n' || c == 'N')
			return 0;
	}
}

void ithPermutation(const int n, int i)
{
   int j, k = 0;
   int *fact = (int *)calloc(n, sizeof(int));
   int *perm = (int *)calloc(n, sizeof(int));

   // compute factorial numbers
   fact[k] = 1;
   while (++k < n)
      fact[k] = fact[k - 1] * k;

   // compute factorial code
   for (k = 0; k < n; ++k)
   {
      perm[k] = i / fact[n - 1 - k];
      i = i % fact[n - 1 - k];
   }

   // readjust values to obtain the permutation
   // start from the end and check if preceding values are lower
   for (k = n - 1; k > 0; --k)
      for (j = k - 1; j >= 0; --j)
         if (perm[j] <= perm[k])
            perm[k]++;

   // print permutation
   for (k = 0; k < n; ++k)
      printf("%d ", perm[k]);
   printf("\n");

   free(fact);
   free(perm);
}

int factorial(int n)
{
	int fact = 1;
	if (n > 1)
		for (int k = 2; k <= n; k++)
			fact = fact * k;

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

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

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

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

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

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

Σύνδεση

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

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