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

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

Δημοσ.

Οκ για το 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;
}

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

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

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

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

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

Σύνδεση

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

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