cyycoish 发表于 2016-1-22 23:47:19

关于一个随机数生成算法的研究

按照“某书”上的一道题,使用一个简单的二次函数进行反复迭代,便可生成一组随机数。
书上的公式如下:
y:=-ax^2+ax
该函数性质一目了然:对称轴 x=1/2,图像与x轴交与0,1两点。
若我们令a:=2,则:

函数y:=2x(1-x)
这时候,我们取x初值为0.2,代入等式,求得y后再将y的值保留
然后,将上述值作为x再次带入等式……一直循环往复进行迭代
那么我们观察所有y的值:

0.320000 0.435200 0.491602 0.499859 0.500000
0.500000 0.500000 0.500000 0.500000 0.500000
0.500000 0.500000 0.500000 0.500000 0.500000
0.500000 0.500000 0.500000 0.500000 0.500000
0.500000 0.500000 0.500000 0.500000 0.500000
......
最终值停在0.5上。
我们令a:=3.2,此时函数为:y:=3.2*x(1-x) 再次进行迭代求值:

0.512000 0.799539 0.512884 0.799469 0.513019
0.799458 0.513041 0.799456 0.513044 0.799456
0.513044 0.799456 0.513044 0.799456 0.513044
0.799456 0.513044 0.799456 0.513044 0.799456
0.513044 0.799456 0.513044 0.799456 0.513044
0.799456 0.513044 0.799456 0.513044 0.799456
......
然后我们发现,数字出现再次呈现规律:在0.513044 0.799456
这两个数字上不断出现循环。
然后a:=3.5时,y:=3.5*x*(x-1)

0.560000 0.862400 0.415332 0.849909 0.446472
0.864972 0.408785 0.845879 0.456286 0.868312
0.400212 0.840148 0.470047 0.871860 0.391021
0.833433 0.485880 0.874302 0.384643 0.828424
0.497481 0.874978 0.382871 0.826983 0.500788
0.874998 0.382818 0.826940 0.500887 0.874997
0.382820 0.826941 0.500884 0.874997 0.382820
0.826941 0.500884 0.874997 0.382820 0.826941
0.500884 0.874997 0.382820 0.826941 0.500884
0.874997 0.382820 0.826941 0.500884 0.874997
0.382820 0.826941 0.500884 0.874997 0.382820
0.826941 0.500884 0.874997 0.382820 0.826941
......
循环停在0.382820 0.826941 0.500884 0.874997。
当a持续增大,一组循环数字个数增加为8、16.
但是a的值超过3.57后,则再也不会出现循环现象。
我们得到了伪随机数列。
我写一下a:=3.58时的大约200个数据:

0.572800 0.876027 0.388803 0.850734 0.454609
0.887624 0.357096 0.821891 0.524062 0.892927
0.342278 0.805943 0.559909 0.882151 0.372179
0.836509 0.489606 0.894613 0.337524 0.800493
0.571740 0.876575 0.387324 0.849549 0.457580
0.888558 0.354501 0.819212 0.530211 0.891732
0.345634 0.809692 0.551645 0.885451 0.363110
0.827914 0.510050 0.894638 0.337453 0.800411
0.571918 0.876484 0.387571 0.849748 0.457082
0.888406 0.354924 0.819652 0.529205 0.891947
0.345033 0.809027 0.553118 0.884899 0.364634
0.829400 0.506555 0.894846 0.336866 0.799726
0.573388 0.875719 0.389631 0.851390 0.452959
0.887078 0.358611 0.823433 0.520500 0.893496
0.340677 0.804127 0.563875 0.880393 0.376977
0.840818 0.479158 0.893445 0.340820 0.804289
0.563521 0.880555 0.376537 0.840430 0.480105
0.893583 0.340431 0.803845 0.564487 0.880112
0.377743 0.841491 0.477515 0.893190 0.341537
0.805105 0.561742 0.881353 0.374360 0.838488
0.484824 0.894175 0.338760 0.801926 0.568649
0.878128 0.383128 0.846100 0.466168 0.890902
0.347959 0.812243 0.545965 0.887436 0.357617
0.822423 0.522835 0.893133 0.341697 0.805286
0.561345 0.881528 0.373883 0.838059 0.485865
0.894285 0.338452 0.801570 0.569419 0.877748
0.384157 0.846958 0.464040 0.890371 0.349447
0.813854 0.542353 0.888578 0.354445 0.819153
0.530346 0.891703 0.345715 0.809782 0.551445
0.885525 0.362906 0.827715 0.510519 0.894604
0.337550 0.800524 0.571673 0.876609 0.387232
0.849474 0.457766 0.888614 0.354344 0.819048
0.530585 0.891651 0.345862 0.809944 0.551085
0.885657 0.362541 0.827356 0.511359 0.894538
0.337736 0.800740 0.571208 0.876847 0.386591
0.848955 0.459064 0.889001 0.353268 0.817922
0.533154 0.891065 0.347504 0.811747 0.547073
0.887067 0.358641 0.823463 0.520430 0.893506
0.340649 0.804094 0.563947 0.880361 0.377066
0.840897 0.478966 0.893416 0.340901 0.804381

貌似已经是随机的了。
而此现象的数学原理为:非线性系统的内在随机性。
好了至此我们得到了自己的随机数发生器,
老C写了一下它的C语言描述代码:

#include <stdlib.h>
#include <time.h>
//If you need call stdlib rand functions and initialize random seed by current time
//you must include above two lines.However if not and either not calling printf.
//you just can dont include any header files.
#include <stdio.h>

#define MAGICAL_NUMBER 3.58f
float Coef = MAGICAL_NUMBER;
float fIterationSeed = 0.2f;

float RandProducer(float a, float x);
float A5Randomize(float init);
float A5Srand(float seed);
float A5Rand(void);

int main()
{
    int i, s;
    srand((int)time(NULL));
    goto Lbl_Choose;
Lbl_StdRand:
    puts("Here are 1000 random numbers form stdlib rand. Each of them is between 0 and 1.\n");
    for (i = 1; i <= 1000; i++)
    {
      printf("%f ", rand() / (float)RAND_MAX);
      if (i % 5 == 0)
            puts("\n");
    }
Lbl_Choose:
    printf("1: A5Rand 2: StdRand 0: Exit ?"); scanf("%d", &s);
    if (s == 1)
      goto Lbl_A5Rand;
    else if (s == 2)
      goto Lbl_StdRand;
    return 0;
Lbl_A5Rand:
    puts("Here are 1000 random numbers form A5Rand. Each of them is between 0 and 1.\n");
    for (i = 1; i <= 1000; i++)
    {
      printf("%f ", A5Rand());
      if (i % 5 == 0)
            puts("\n");
    }
    goto Lbl_Choose;
    return 0;
}

//Function achievements.
float A5Rand(void)
{
    return fIterationSeed = RandProducer(Coef, fIterationSeed);
}

float A5Srand(float seed)
{
    fIterationSeed = seed < 0 ? -seed : seed;
    return fIterationSeed = seed > 1 ? 1 / seed : seed;
}

float A5Randomize(float init)
{
    return Coef = init + MAGICAL_NUMBER;
}

inline float RandProducer(float a, float x)
{
    return a * x - a * x * x;
}

我们的随机数发生器函数被命名为:A5Rand。
接下来我们生成200组数据。每组5个。也就是1000个数据。
我们来测试在a值为3.58的时候生成的随机数的质量。
我们用C语言stdlib库自带的随机数发生器作为比较来看看结果:
这里为了观察随机数的质量,我们使用VisualBasic6.0
编写了一款程序。其大致原理为将每个随机数按奇偶绘出其值,观察成像。
VB6源代码如下:

VERSION 5.00
Begin VB.Form Form1
   AutoRedraw      =   -1'True
   BackColor       =   &H00FFFFFF&
   BorderStyle   =   1'Fixed Single
   Caption         =   "Visual Randoperf Grapher - (C)0xAA55.com"
   ClientHeight    =   1515
   ClientLeft      =   45
   ClientTop       =   435
   ClientWidth   =   7515
   BeginProperty Font
      Name            =   "MS Sans Serif"
      Size            =   8.25
      Charset         =   0
      Weight          =   700
      Underline       =   0   'False
      Italic          =   0   'False
      Strikethrough   =   0   'False
   EndProperty
   ForeColor       =   &H00000000&
   LinkTopic       =   "Form1"
   MaxButton       =   0   'False
   ScaleHeight   =   101
   ScaleMode       =   3'Pixel
   ScaleWidth      =   501
   StartUpPosition =   3'Windows Default
End
Attribute VB_Name = "Form1"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = True
Attribute VB_Exposed = False
Option Explicit
Dim idxLocate As Integer
Dim szTemp As String
Dim fso, f As Object

Private Sub Form_DblClick()
    On Error GoTo Lbl_ErrH:
    Dim Max As Single, Min As Single
    Dim DataArray() As String
    Dim szFileName As String
    Dim Sum As Double
    Dim i As Integer
    szTemp = ""
    Sum = 0#
    Max = 0#
    Min = 1#
    szFileName = App.Path & "\data" & CStr(idxLocate) & ".txt"
    Set f = fso.OpenTextFile(szFileName, 1, False)
    DataArray = Split(Replace(Replace(f.ReadAll, vbCr, ""), vbLf, ""), " ")
    Me.Cls
    Me.ForeColor = &H0&
    Me.Line (0, 0)-(500, 100), vbBlack, B
    For i = 0 To 499 Step 2
      Me.Line (i + 1, 100)-(i, 100 - Val(DataArray(i + 1)) * 100), vbBlue
      Me.Line (i, 100)-(i, 100 - Val(DataArray(i)) * 100), vbRed
      Sum = Sum + Val(DataArray(i + 1)) + Val(DataArray(i))
      Max = IIf(Val(DataArray(i + 1)) > Max, Val(DataArray(i + 1)), Max)
      Max = IIf(Val(DataArray(i)) > Max, Val(DataArray(i)), Max)
      Min = IIf(Val(DataArray(i + 1)) < Min, Val(DataArray(i + 1)), Min)
      Min = IIf(Val(DataArray(i)) < Min, Val(DataArray(i)), Min)
    Next
    Me.CurrentY = 0
    Me.CurrentX = Me.ScaleWidth = Me.TextWidth(szFileName)
    Me.Print "Fn:" & szFileName
    Me.CurrentX = 0
   
    szTemp = Format(Sum, "0.000000") & " " & _
             Format(Sum / 1000#, "0.000000") & " " & _
             Format(Max, "0.000000") & " " & _
             Format(Min, "0.000000")
    Print "SUM:" & vbTab & Format(Sum, "0.000000")
    Print "AVG:" & vbTab & Format(Sum / 1000#, "0.000000")
    Print "MAX:" & vbTab & Format(Max, "0.000000")
    Print "MIN:" & vbTab & Format(Min, "0.000000")
    Exit Sub
Lbl_ErrH:
    MsgBox Err.Number & ":" & Err.Description, 16, "Error!"
End Sub

Private Sub Form_KeyUp(KeyCode As Integer, Shift As Integer)
    On Error GoTo Lbl_ErrH:
    Select Case KeyCode
    Case 189
      If idxLocate > 0 Then idxLocate = idxLocate - 1
      If Not fso.FileExists(App.Path & "\data" & CStr(idxLocate) & ".txt") Then
            idxLocate = idxLocate + 1
            ShowMessage ("File Not Found." & idxLocate & " Press <F5> to reload.")
      Else
            Form_DblClick
      End If
    Case 187
      idxLocate = idxLocate + 1
      If Not fso.FileExists(App.Path & "\data" & CStr(idxLocate) & ".txt") Then
            idxLocate = idxLocate - 1
            ShowMessage ("File Not Found." & idxLocate & " Press <F5> to reload.")
      Else
            Form_DblClick
      End If
    Case 191
      MsgBox "STRAT:" & vbTab & "F5" & vbCrLf & _
               "SAVE:" & vbTab & "F3" & vbCrLf & _
               "SWITCH:" & vbTab & "<-|+>" & vbCrLf & _
               "BATCH" & vbTab & "F7" & vbCrLf & _
               "HELP" & vbTab & "/|?" & vbCrLf & _
               "(C) 2016 CYY @ 0xAA55.com" _
               , 0, "Help"
    Case 116
      Form_DblClick
    Case 114
      SavePicture Me.Image, App.Path & "\data" & CStr(idxLocate) & ".bmp"
      MsgBox "File saved!", 48, "Done"
    Case 118
      BatchFiles
    End Select
    Exit Sub
Lbl_ErrH:
    MsgBox Err.Number & ":" & Err.Description, 16, "Error!"
End Sub

Private Sub Form_Load()
    Dim szDisplay As String
    Set fso = CreateObject("Scripting.FileSystemObject")
    szDisplay = "START: Double-Click/F5; BATCH: F7; SWITCH:<-|+>; HELP: ?/"
    Me.Line (0, 0)-(Me.ScaleWidth, Me.ScaleHeight), vbBlack, BF
    Me.CurrentX = Me.ScaleWidth / 2 - Me.TextWidth(szDisplay) / 2
    Me.CurrentY = Me.ScaleHeight / 2 - Me.TextHeight(szDisplay) / 2
    Me.ForeColor = &HFFFFFF
    Me.Print szDisplay
    idxLocate = 0
End Sub

Sub ShowMessage(szDisplay As String, Optional ColorFore As Long = &HFFFFFF)
    Me.Line (0, 0)-(Me.ScaleWidth, Me.ScaleHeight), vbBlack, BF
    Me.CurrentX = Me.ScaleWidth / 2 - Me.TextWidth(szDisplay) / 2
    Me.CurrentY = Me.ScaleHeight / 2 - Me.TextHeight(szDisplay) / 2
    Me.ForeColor = ColorFore
    Me.Print szDisplay
End Sub

Sub BatchFiles()
    On Error Resume Next
    Static szFileContent As String
    Dim iErrorCtr As Integer
    Dim iFileCtr As Integer
    szFileContent = vbNullString
    While fso.FileExists(App.Path & "\data" & CStr(idxLocate) & ".txt")
      Form_DblClick
      szFileContent = szFileContent & szTemp & vbCrLf
      SavePicture Me.Image, App.Path & "\data" & CStr(idxLocate) & ".bmp"
      If Err <> 0 Then
            iErrorCtr = iErrorCtr + 1
            Err.Clear
      End If
      iFileCtr = iFileCtr + 1
      idxLocate = idxLocate + 1
    Wend
    idxLocate = idxLocate - 1
    ShowMessage "HANDLED:" & iFileCtr & "," & _
                "ERROR:" & iErrorCtr & "," & _
                "SUCCESSED:" & iFileCtr - iErrorCtr, _
                IIf(iFileCtr - iErrorCtr <= 0, vbRed, vbYellow)
    Err.Clear
    Set f = fso.OpenTextFile(App.Path & "\dtreport.txt", 2, True)
    f.Write szFileContent
    If Err <> 0 Then MsgBox Err.Number & ":" & Err.Description, 16, "Error!"
End Sub


程序运行效果:

这个程序读入自身目录下的data0.txt文件(文件格式与C语言输出格式一致)
的1000个数据并分析制图,制图结果按下F3键会按照txt文件名保存至当前目录。
我们先来看stdlib rand的结果:

我们再来看A5Rand的结果:


效果已经显现,stdlib rand非常不错,A5Rand虽然数据随机,但是分布过于均匀。
1月21号我对A5Rand(a值等于3.58)和stdlib rand进行了“暴力测试”。
这次样本容量相当大。我对stdlib rand与A5Rand 分别生成10组矩阵,每组1000个随机数。
效果报告太大,顾节选部分。(rar压缩包就4M多)
这次我对10个矩阵分别进行了 数值和,平均数,最大,最小数的统计
A5Rand统计结果如下:

SUM      AVG      MAX      MIN
323.919580 0.323920 0.894984 0.336477
323.862921 0.323863 0.894985 0.336473
323.846480 0.323846 0.894999 0.336433
323.815000 0.323815 0.894999 0.336434
323.826478 0.323826 0.894999 0.336434
323.815000 0.323815 0.894999 0.336434
323.826478 0.323826 0.894999 0.336434
323.815000 0.323815 0.894999 0.336434
323.826478 0.323826 0.894999 0.336434
323.815000 0.323815 0.894999 0.336434

而这是stdlib rand的统计结果:

SUM      AVG      MAX      MIN
249.412740 0.249413 0.998529 0.000136
247.160952 0.247161 0.999388 0.001050
251.454442 0.251454 0.999395 0.003241
244.582801 0.244583 0.996929 0.000884
248.742623 0.248743 0.999873 0.002175
250.106113 0.250106 0.997334 0.000467
261.062332 0.261062 0.998823 0.000000
263.112599 0.263113 0.999694 0.006322
259.486934 0.259487 0.999951 0.001819
241.423291 0.241423 0.998722 0.000324

接着我又无聊地对2w个数据分别作出现频率统计。
ps:我用的是n年前自己写的字/词频分析。
然后因该软件实现技术,算法上的重大缺陷。跑1w个数据耗时10分钟。
光是打开文件就花费1分多钟。(渣渣)


好在效果出来了,在此分享一下节选片段:
A5Rand(大量重复!):

7.词句: 0.894908 出现次数为: 19 出现频率为: 0.0019
8.词句: 0.894985 出现次数为: 19 出现频率为: 0.0019
9.词句: 0.894999 出现次数为: 19 出现频率为: 0.0019
10. 词句: 0.337423 出现次数为: 18 出现频率为: 0.0018
11. 词句: 0.800376 出现次数为: 18 出现频率为: 0.0018
12. 词句: 0.571993 出现次数为: 18 出现频率为: 0.0018
13. 词句: 0.876445 出现次数为: 18 出现频率为: 0.0018
14. 词句: 0.387675 出现次数为: 18 出现频率为: 0.0018
15. 词句: 0.849832 出现次数为: 18 出现频率为: 0.0018
16. 词句: 0.456872 出现次数为: 18 出现频率为: 0.0018
17. 词句: 0.888341 出现次数为: 18 出现频率为: 0.0018
18. 词句: 0.355105 出现次数为: 18 出现频率为: 0.0018
19. 词句: 0.819839 出现次数为: 18 出现频率为: 0.0018
20. 词句: 0.528776 出现次数为: 18 出现频率为: 0.0018
21. 词句: 0.892035 出现次数为: 18 出现频率为: 0.0018
22. 词句: 0.344783 出现次数为: 18 出现频率为: 0.0018
23. 词句: 0.808750 出现次数为: 18 出现频率为: 0.0018

stdlib rand:

23. 词句: 0.743599 出现次数为: 2 出现频率为: 0.0002
24. 词句: 0.568461 出现次数为: 2 出现频率为: 0.0002
25. 词句: 0.087062 出现次数为: 2 出现频率为: 0.0002
26. 词句: 0.874452 出现次数为: 2 出现频率为: 0.0002
27. 词句: 0.977495 出现次数为: 2 出现频率为: 0.0002
28. 词句: 0.177088 出现次数为: 2 出现频率为: 0.0002
29. 词句: 0.505303 出现次数为: 2 出现频率为: 0.0002
30. 词句: 0.769167 出现次数为: 2 出现频率为: 0.0002
31. 词句: 0.856239 出现次数为: 2 出现频率为: 0.0002
32. 词句: 0.725977 出现次数为: 2 出现频率为: 0.0002
33. 词句: 0.376608 出现次数为: 2 出现频率为: 0.0002
34. 词句: 0.861518 出现次数为: 2 出现频率为: 0.0002
35. 词句: 0.107373 出现次数为: 2 出现频率为: 0.0002
36. 词句: 0.929944 出现次数为: 2 出现频率为: 0.0002
37. 词句: 0.374588 出现次数为: 2 出现频率为: 0.0002
38. 词句: 0.607417 出现次数为: 2 出现频率为: 0.0002
39. 词句: 0.179999 出现次数为: 2 出现频率为: 0.0002
40. 词句: 0.744827 出现次数为: 2 出现频率为: 0.0002
41. 词句: 0.623363 出现次数为: 2 出现频率为: 0.0002
42. 词句: 0.998426 出现次数为: 2 出现频率为: 0.0002
43. 词句: 0.210764 出现次数为: 2 出现频率为: 0.0002
44. 词句: 0.584360 出现次数为: 2 出现频率为: 0.0002
45. 词句: 0.126537 出现次数为: 2 出现频率为: 0.0002
46. 词句: 0.295641 出现次数为: 2 出现频率为: 0.0002
47. 词句: 0.093876 出现次数为: 2 出现频率为: 0.0002
48. 词句: 0.401310 出现次数为: 2 出现频率为: 0.0002
49. 词句: 0.729049 出现次数为: 2 出现频率为: 0.0002
50. 词句: 0.412082 出现次数为: 2 出现频率为: 0.0002
51. 词句: 0.233230 出现次数为: 2 出现频率为: 0.0002
52. 词句: 0.520887 出现次数为: 2 出现频率为: 0.0002
53. 词句: 0.932117 出现次数为: 2 出现频率为: 0.0002
54. 词句: 0.439312 出现次数为: 2 出现频率为: 0.0002
55. 词句: 0.384457 出现次数为: 2 出现频率为: 0.0002
56. 词句: 0.838543 出现次数为: 2 出现频率为: 0.0002
57. 词句: 0.386779 出现次数为: 2 出现频率为: 0.0002
58. 词句: 0.969157 出现次数为: 2 出现频率为: 0.0002
59. 词句: 0.407021 出现次数为: 2 出现频率为: 0.0002
60. 词句: 0.914250 出现次数为: 2 出现频率为: 0.0002
61. 词句: 0.571047 出现次数为: 2 出现频率为: 0.0002
62. 词句: 0.789341 出现次数为: 2 出现频率为: 0.0002
63. 词句: 0.003714 出现次数为: 2 出现频率为: 0.0002
64. 词句: 0.932136 出现次数为: 2 出现频率为: 0.0002
65. 词句: 0.076419 出现次数为: 2 出现频率为: 0.0002
66. 词句: 0.101964 出现次数为: 2 出现频率为: 0.0002
67. 词句: 0.915684 出现次数为: 2 出现频率为: 0.0002
68. 词句: 0.575908 出现次数为: 2 出现频率为: 0.0002
69. 词句: 0.471095 出现次数为: 2 出现频率为: 0.0002
70. 词句: 0.219661 出现次数为: 2 出现频率为: 0.0002
71. 词句: 0.097873 出现次数为: 2 出现频率为: 0.0002
72. 词句: 0.917924 出现次数为: 2 出现频率为: 0.0002
73. 词句: 0.221586 出现次数为: 2 出现频率为: 0.0002
74. 词句: 0.711277 出现次数为: 1 出现频率为: 0.0001
75. 词句: 0.437822 出现次数为: 1 出现频率为: 0.0001
76. 词句: 0.472661 出现次数为: 1 出现频率为: 0.0001
77. 词句: 0.016471 出现次数为: 1 出现频率为: 0.0001
78. 词句: 0.825967 出现次数为: 1 出现频率为: 0.0001
79. 词句: 0.028305 出现次数为: 1 出现频率为: 0.0001
80. 词句: 0.714593 出现次数为: 1 出现频率为: 0.0001
81. 词句: 0.169405 出现次数为: 1 出现频率为: 0.0001
82. 词句: 0.193566 出现次数为: 1 出现频率为: 0.0001
83. 词句: 0.271427 出现次数为: 1 出现频率为: 0.0001
84. 词句: 0.874044 出现次数为: 1 出现频率为: 0.0001
85. 词句: 0.058684 出现次数为: 1 出现频率为: 0.0001
86. 词句: 0.299395 出现次数为: 1 出现频率为: 0.0001

可以说A5Rand在a值为3.58时生成的随机数相当不理想!
接下来,我将a值增加值4.0
那么在C代码中将 MAGICAL_NUMBER 魔数宏改至4.0
#define MAGICAL_NUMBER 4.0f
也就是说迭代式为 4*x*(1-x)

事实上,4是我们用该迭代公式求0~1的随机数的极值了。
再大抛物线顶端y值将超过1.
效果好得难以置信啊!

这是A5Rand函数,a值等于4.0,迭代初始值(随机数种子)等于2.0 时候的图象。
这里发现了一个问题。因为a值取4.0,加之函数图象交于x轴 (0,0)点和 (1,0)点,
所以0和1的出现频率陡增。
我们将魔数a改为3.99试试:
函数: y:=3.99*x(1-x)

效果简直不能再赞!拔群!拔群啊!
我们放一张stdlib rand的图进行对比!

至此我们应该得到了一个并不是最高效的http://www.0xaa55.com/thread-785-1-1.html、
实用的伪随机数生成算法!

好了,最后我们应该选用一个无限接近4,而又不能等于4的值(看我怎样实现!)

#include <stdio.h>

static float fIterationSeed = 0.2f;

float RandProducer(float x)
{
    float a;
    *(int*)&a = 0x407FFFFF; //What'd Fucking number is this? I wont tell you.
    return a * x - a * x * x;
}
float A5Srand(float seed)
{
    fIterationSeed = seed < 0 ? -seed : seed;
    return fIterationSeed = seed > 1 ? 1 / seed : seed;
}

float A5Rand(void)
{
    return fIterationSeed = RandProducer(fIterationSeed);
}

//All code we need to use A5Rand machine is above this comment.

//Also we can drop the following code.
//Main function? hehe! it doesn't metter.
#include <stdlib.h>
#include <time.h>

int main()
{
    int i, s;
    srand((int)time(NULL));
    goto Lbl_Choose;
Lbl_StdRand:
    puts("Here are 1000 random numbers form stdlib rand. Each of them is between 0 and 1.\n");
    for (i = 1; i <= 1000; i++)
    {
      printf("%f ", rand() / (float)RAND_MAX);
      if (i % 5 == 0)
            puts("\n");
    }
Lbl_Choose:
    printf("1: A5Rand 2: StdRand 0: Exit ?"); scanf("%d", &s);
    if (s == 1)
      goto Lbl_A5Rand;
    else if (s == 2)
      goto Lbl_StdRand;
    return 0;
Lbl_A5Rand:
    puts("Here are 1000 random numbers form A5Rand. Each of them is between 0 and 1.\n");
    for (i = 1; i <= 1000; i++)
    {
      printf("%f ", A5Rand());
      if (i % 5 == 0)
            puts("\n");
    }
    goto Lbl_Choose;
    return 0;
}

ps:我会往后新开一帖讲述the fucking number。敬请期待。
然后后面老C没有时间做大量测试了。
估计也没有人像老C一样闲的蛋疼做这些测试。
就这样吧。完。01 22 2015 cyycoish

0xAA55 发表于 2016-1-23 14:37:18

……效果没那么好啊,数字也不是十分随机。
跑完随机数生成一个“样本数组”以后,用快速傅里叶变换(FFT)统计频率试试。我估计0.9以上的数字基本很少。

略游 发表于 2016-2-2 15:30:42

用公式生成的随机数怎么是随机的呢

cyycoish 发表于 2016-3-23 13:28:09

略游 发表于 2016-2-2 15:30
用公式生成的随机数怎么是随机的呢

那要怎么生成随机数呢?给每台计算机安装射线管,或者放射性元素?
A5亲自测试过VS的随机数生成算法,我的帖子里边链接你都没看。
所以说这些都是Psuedo随机数,真正的随机数还是自己统计每天降雨量为好。

(⊙o⊙) 发表于 2017-11-8 08:46:44

计算机的随机,叫做 偶然 数。不是真正的随机。

大能猫 发表于 2019-6-2 03:08:58

回楼上:公式生成本来就不是真随机,所以才叫伪随机数啊,pseudo random number
然后话说我觉得测试的时候加个方差什么的会不会好一点呢,毕竟方差或者标准差本身就是用来检验数据分布情况的,还有伪随机数要求对于解空间中一共n个元素,每个元素的出现概率统计上要等于1/n,不知道这点满不满足

Cer 发表于 2020-3-20 12:00:42

复杂啊。

imr2013 发表于 2022-11-23 22:12:23

生成伪随机数就非常不容易了
页: [1]
查看完整版本: 关于一个随机数生成算法的研究