2012-04-21 1 views
2

Его небольшой код для генерации случайной эрмитовой матрицы hermitian matrix.rand() не возвращает случайные значения

Я вызвал srand() перед каждым вызовом rand(). но все равно никакой случайности в выходе.

Я использовал сложный тип данных c99 для создания эрмитовой матрицы. Я не уверен, где я ошибаюсь :(

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

#define MATSIZE 5 
#define RAND_RANGE 100 

double complex mat[MATSIZE][MATSIZE]; 

void gen_mat() 
{ 
    int i =0,j; 
    int real; 
    int img; 
    for(;i < MATSIZE; i++) 
    { 
    srand(time(NULL)); 
    real = rand()%RAND_RANGE + 1; 
    srand(time(NULL)); 
    img = rand()%RAND_RANGE + 1; 
    for(j = MATSIZE; j != i ; j--) 
    { 
     mat[i][j] = real + img * I; 
     mat[j][i] = conj(mat[i][j]); 
    } 
    srand(time(NULL)); 
    if(i == j) 
     mat[i][i] = rand()%RAND_RANGE + 0*I; 
    } 
} 

void print_mat() 
{ 
    int i,j; 
    for(i = 0; i < MATSIZE; i++) 
    { 
    for(j = 0; j < MATSIZE; j++) 
    { 
     printf("%f + %f *i", creal(mat[i][j]), cimag(mat[i][j])); 
     printf(" "); 
    } 
    puts("\n"); 
    } 
} 

int main() 
{ 
    gen_mat(); 
    print_mat(); 
    return 0; 
} 

выход образец

[[email protected] physics-numaric]$ ./a.out 
66.000000 + 0.000000 *i 67.000000 + 67.000000 *i 67.000000 + 67.000000 *i    67.000000 + 67.000000 *i 67.000000 + 67.000000 *i  

67.000000 + -67.000000 *i 66.000000 + 0.000000 *i 67.000000 + 67.000000 *i  67.000000 + 67.000000 *i 67.000000 + 67.000000 *i  

67.000000 + 67.000000 *i 67.000000 + -67.000000 *i 66.000000 + 0.000000 *i 67.000000 + 67.000000 *i 67.000000 + 67.000000 *i  

67.000000 + 67.000000 *i 67.000000 + -67.000000 *i 67.000000 + -67.000000 *i 66.000000 + 0.000000 *i 67.000000 + 67.000000 *i  

67.000000 + 67.000000 *i 67.000000 + -67.000000 *i 67.000000 + -67.000000 *i  67.000000 + -67.000000 *i 66.000000 + 0.000000 *i  

EDIT вызова srand в основной() на самом деле решить эту проблему. Спасибо вам, ребята.

[[email protected] physics-numaric]$ ./a.out 
31.000000 + 0.000000 *i 81.000000 + 75.000000 *i 81.000000 + 75.000000 *i  81.000000 + 75.000000 *i 81.000000 + 75.000000 *i  

81.000000 + -75.000000 *i 53.000000 + 0.000000 *i 69.000000 + 57.000000 *i 69.000000 + 57.000000 *i 69.000000 + 57.000000 *i  

69.000000 + 57.000000 *i 69.000000 + -57.000000 *i 27.000000 + 0.000000 *i 93.000000 + 11.000000 *i 93.000000 + 11.000000 *i  

93.000000 + 11.000000 *i 69.000000 + -57.000000 *i 93.000000 + -11.000000 *i 58.000000 + 0.000000 *i 76.000000 + 78.000000 *i  

76.000000 + 78.000000 *i 69.000000 + -57.000000 *i 93.000000 + -11.000000 *i 76.000000 + -78.000000 *i 67.000000 + 0.000000 *i  

ответ

8

Не звоните srand перед каждым звонком до rand. Вызывайте его один раз, когда запускается ваша программа.

+0

Как принять ответ? – Aftnix

+0

@aftnix: Я думаю, что есть таймер, поэтому вы можете принять ответ через 10 минут после того, как задали вопрос. –

+1

Люди из Charlseworth действительно много думали об этом дизайне приложения для обмена столами. крутая динамика :) – Aftnix

6

Не звоните srand внутри, если петля. Назовите его только один раз.

srand(time(NULL)); 
for(;i < MATSIZE; i++) 
{ 
    // ... calls to rand() 
} 

В противном случае вы семя генератора случайных чисел с тем же семени (как это достаточно быстро, чтобы получить то же самое время)

Кстати, много раз я нахожу это весьма условно, чтобы создать функцию инициализации для программы/sequence, где я инициализирую многие вещи, в том числе случайное генерирование (например, вызов srand())

1

Вы не хотите, чтобы каждый раз сгенерировал генератор случайных чисел srand()! Просто назовите его один раз в начале вашей программы. Затем вызовите rand(), чтобы получить следующее случайное число.

1

Не делайте этого:

rand()%RAND_RANGE + 0*I; 

, так как это приведет к более низкие значения должны быть передискретизация, если RAND_RANGE и RAND_MAX + 1 не делят. (что «почти всегда» имеет место)

Также: перезапуск генератора в зависимости от времени (NULL) в большинстве случаев перезапускается с точно таким же значением, поскольку зернистость time_t составляет одну секунду.

Финал: rand_max будет иметь не менее 15 бит (32K) стоит случайного. Старые системы могут фактически поставлять только 15 бит с циклом 32 К.

ОБНОВЛЕНИЕ: это фрагмент от wakkerbot. Функция urnd() пытается вернуть объективное значение между 0 и диапазоном. Тест, вероятно, может быть выполнен более элегантно.

typedef unsigned long long BigThing; 

unsigned int urnd(unsigned int range) 
{ 
    static bool flag = FALSE; 

    if (flag == FALSE) { 
#if defined(__mac_os) || defined(DOS) 
     srand(time(NULL)); 
#else 
     srand48(time(NULL)); 
#endif 
    } 
    flag = TRUE; 
#if defined(__mac_os) || defined(DOS) 
    return rand()%range; 
#else 

if (range <= 1) return 0; 

while(1)  { 
    BigThing val, box; 
#if WANT_RDTSC_RANDOM 
    val = rdtsc_rand(); 
#else 
    val = lrand48(); 
#endif 
/* we need this to avoid oversampling of the lower values. 
* Oversampling the lower values becomes more of a problem if (UNSIGNED_MAX/range) gets smaller 
*/ 
    box = val/range; 
    if ((1+box) *range < range) continue; 
    return val % range; 
     } 
#endif 
} 
+0

Так что вы предлагаете? как я должен принимать случайное значение, а также поддерживать правильный диапазон? – Aftnix

+1

Идея: если вы получите образец из верхней части диапазона, перед тем, как произойдет обход: отклоните его и перерисуйте. Например, если RAND_MAX равно 10, а ваш RAND_RANGE равен 4: отклонять значения> = 8, в противном случае возвращать значение% RAND_RANGE. (в противном случае значения {0,1} имели бы больше шансов на результат в результатах, чем {2,3}). Я добавлю фрагмент ответа. – wildplasser

+0

Благодарим вас за фрагмент. – Aftnix