2012-04-21 112 views
2

它是生成隨機厄米矩陣的小代碼hermitian matrixrand()不返回隨機值

我在每次調用rand()之前都調用了srand()。但輸出中仍然沒有隨機性。

我用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  

編輯調用主)函數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

在每次致電rand之前都不要致電srand。在程序啓動時調用它一次

+0

如何接受一個答案? – Aftnix 2012-04-21 12:51:57

+0

@aftnix:我認爲有一個計時器,所以你只能在問你問題10分鐘後接受答案。 – 2012-04-21 12:52:37

+1

查爾斯沃思人真的給了這些堆棧交換應用設計背後的很多想法。很酷的動態:) – Aftnix 2012-04-21 12:55:50

6

不要如果循環調用srand內。只調用一次。

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

否則種子使用相同的種子隨機數發生器(因爲它足夠快,以獲得相同的時間)

BTW,很多時候我覺得很傳統,爲程序創建一個初始化函數/序列,其中我初始化很多事情,包括隨機生成(如呼叫srand()

1

你不想每次srand()種子隨機數發生器!只需在程序開始時調用一次即可。然後撥打rand()獲取下一個隨機數。

1

不要這樣做:

rand()%RAND_RANGE + 0*I; 

,因爲它會導致如果RAND_RANGE和RAND_MAX + 1不分較低的值進行過採樣。 (其中「幾乎總是」就是這種情況)

另外:重新啓動基於時間(NULL)發電機在大多數情況下具有完全相同的值來重新啓動,因爲time_t的粒度爲1秒。

決賽:RAND_MAX將具有至少 15位(32K)的隨機值。舊的系統實際上可能只提供15位與32 K.

更新的週期:這是從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 2012-04-21 13:08:50

+1

這個想法是:如果你從範圍的頂部得到一個樣本,就在繞回發生之前:拒絕它並重繪。例如,如果RAND_MAX是10,並且您的RAND_RANGE是4:拒絕值> = 8,否則返回值%RAND_RANGE。 (否則{0,1}的值在輸出中會比{2,3}更大的可能性)我會在我的回覆中添加一個片段。 – wildplasser 2012-04-21 13:18:11

+0

謝謝你的片段。 – Aftnix 2012-04-21 13:47:24