2012-04-21 177 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