C
creation-zy
Unregistered / Unconfirmed
GUEST, unregistred user!
我已经找到了产生[red]真正的[/red]随机数(种子)的方法了——该方案每次可以产生好几个数字,
根据我的统计分析,这些数字Mod [blue]1000000[/blue]之后的分布比较均匀。
原理——多任务系统中线程运行的不可再现性——即人们无法确定多个无关线程的进度关系,
要完全重现,必须达到自开机以来鼠标、键盘事件的完全一致,磁头调度的位置、时间的完全一致、
中断事件发生的完全一致、系统中线程运行的切换完全一致(注意,完全一致是指事件发生的
CPU所在周期、状态完全一致——可能吗?? 哈哈哈哈哈哈哈哈!!!)。
附源代码:
unit Thread;
interface
uses
Classes, Windows;
type
PInt=^Integer;
TGo = class(TThread)
private
PtrInt;
WaitPtrInt;
protected
procedure Execute;
override;
public
procedure Init(PtrInt,WaitPIInt);
end;
implementation
procedure TGo.Execute;
begin
while WaitPtr^=0do
Sleep(1);
while not Terminateddo
Inc(Ptr^);
//此处可以改进,让线程之间相互累加。。。
end;
procedure TGo.Init(PtrInt,WaitPI: PInt);
begin
Ptr:=PtrInt;
WaitPtr:=WaitPI;
end;
end.
unit Main;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ExtCtrls, Spin;
type
TForm1 = class(TForm)
Button1: TButton;
Image1: TImage;
Button2: TButton;
SpinEdit1: TSpinEdit;
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
procedure DrawGraph;
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
uses
Thread;
const
ThreadNumber=6;
DivNumber=200;
ModNumber=1000000;
//产生的数字 MOD 10^6 之后的分布比较均匀
var
RecordInt:array[1..ThreadNumber]of Integer;
RandRecord:array[0..DivNumber-1]of Integer;
procedure TForm1.Button1Click(Sender: TObject);
var
Thds:array[1..ThreadNumber]of TGo;
i,Start:Integer;
Str:String;
begin
Button1.Enabled:=false;
Start:=0;
for i:=1 to ThreadNumberdo
begin
Thds:=TGo.Create(true);
RecordInt:=0;
Thds.Init(@RecordInt,@Start);
Thds.Priority:=tpTimeCritical;
//这一句有必要,否则...
end;
for i:=1 to ThreadNumberdo
Thds.Resume;
Start:=1;
Sleep(20);
//实际上的等待时间超过4秒,Why??
for i:=1 to ThreadNumberdo
Thds.Terminate;
Str:='';
for i:=1 to ThreadNumberdo
begin
Inc(RandRecord[RecordInt mod ModNumber div (ModNumber div DivNumber)]);
Str:=Str+IntToStr(RecordInt)+' ';
end;
Caption:=Str;
Button1.Enabled:=true;
Button1.SetFocus;
DrawGraph;
end;
procedure TForm1.DrawGraph;
//显示产生的数字是否均匀(此处分了200个区间,效果还可以)
var
i,h,w,x1,x2,y,max:Integer;
begin
h:=Image1.Height;
w:=Image1.Width;
max:=0;
for i:=0 to DivNumber-1do
if max<RandRecord then
max:=RandRecord;
with Image1.Canvasdo
begin
Brush.Color:=clBlack;
FillRect(Rect(0,0,w,h));
if max=0 then
exit;
Brush.Color:=clLime;
for i:=0 to DivNumber-1do
begin
x1:=w*i div DivNumber;
x2:=w*(i+1) div DivNumber;
y:=h*RandRecord div max;
FillRect(Rect(x1,h,x2,h-y));
end;
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
var
i:Integer;
begin
for i:=0 to DivNumber-1do
RandRecord:=0;
end;
procedure TForm1.Button2Click(Sender: TObject);
var
Count:Integer;
begin
if Button2.Tag=1 then
begin
Button2.Tag:=0;
exit;
end;
Button2.Tag:=1;
Button2.Caption:='Stop';
Count:=0;
while (Button2.Tag<>0) and (Count<SpinEdit1.Value)do
begin
Button1.Click;
Application.ProcessMessages;
Inc(Count);
end;
Button2.Tag:=0;
Button2.Caption:='Start';
end;
end.
注:运行环境为:PIII800,Win NT4
每次产生6个均匀分布于 0-999999 的数字,完全重复的概率为[red]十的负三十六次方[/red]。OK?
[][][^][^]
欢迎大家提出改进意见!谢谢!
另:若分类不妥,还有劳版主,将其放到适当的分类中去,谢谢了!
根据我的统计分析,这些数字Mod [blue]1000000[/blue]之后的分布比较均匀。
原理——多任务系统中线程运行的不可再现性——即人们无法确定多个无关线程的进度关系,
要完全重现,必须达到自开机以来鼠标、键盘事件的完全一致,磁头调度的位置、时间的完全一致、
中断事件发生的完全一致、系统中线程运行的切换完全一致(注意,完全一致是指事件发生的
CPU所在周期、状态完全一致——可能吗?? 哈哈哈哈哈哈哈哈!!!)。
附源代码:
unit Thread;
interface
uses
Classes, Windows;
type
PInt=^Integer;
TGo = class(TThread)
private
PtrInt;
WaitPtrInt;
protected
procedure Execute;
override;
public
procedure Init(PtrInt,WaitPIInt);
end;
implementation
procedure TGo.Execute;
begin
while WaitPtr^=0do
Sleep(1);
while not Terminateddo
Inc(Ptr^);
//此处可以改进,让线程之间相互累加。。。
end;
procedure TGo.Init(PtrInt,WaitPI: PInt);
begin
Ptr:=PtrInt;
WaitPtr:=WaitPI;
end;
end.
unit Main;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ExtCtrls, Spin;
type
TForm1 = class(TForm)
Button1: TButton;
Image1: TImage;
Button2: TButton;
SpinEdit1: TSpinEdit;
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
procedure DrawGraph;
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
uses
Thread;
const
ThreadNumber=6;
DivNumber=200;
ModNumber=1000000;
//产生的数字 MOD 10^6 之后的分布比较均匀
var
RecordInt:array[1..ThreadNumber]of Integer;
RandRecord:array[0..DivNumber-1]of Integer;
procedure TForm1.Button1Click(Sender: TObject);
var
Thds:array[1..ThreadNumber]of TGo;
i,Start:Integer;
Str:String;
begin
Button1.Enabled:=false;
Start:=0;
for i:=1 to ThreadNumberdo
begin
Thds:=TGo.Create(true);
RecordInt:=0;
Thds.Init(@RecordInt,@Start);
Thds.Priority:=tpTimeCritical;
//这一句有必要,否则...
end;
for i:=1 to ThreadNumberdo
Thds.Resume;
Start:=1;
Sleep(20);
//实际上的等待时间超过4秒,Why??
for i:=1 to ThreadNumberdo
Thds.Terminate;
Str:='';
for i:=1 to ThreadNumberdo
begin
Inc(RandRecord[RecordInt mod ModNumber div (ModNumber div DivNumber)]);
Str:=Str+IntToStr(RecordInt)+' ';
end;
Caption:=Str;
Button1.Enabled:=true;
Button1.SetFocus;
DrawGraph;
end;
procedure TForm1.DrawGraph;
//显示产生的数字是否均匀(此处分了200个区间,效果还可以)
var
i,h,w,x1,x2,y,max:Integer;
begin
h:=Image1.Height;
w:=Image1.Width;
max:=0;
for i:=0 to DivNumber-1do
if max<RandRecord then
max:=RandRecord;
with Image1.Canvasdo
begin
Brush.Color:=clBlack;
FillRect(Rect(0,0,w,h));
if max=0 then
exit;
Brush.Color:=clLime;
for i:=0 to DivNumber-1do
begin
x1:=w*i div DivNumber;
x2:=w*(i+1) div DivNumber;
y:=h*RandRecord div max;
FillRect(Rect(x1,h,x2,h-y));
end;
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
var
i:Integer;
begin
for i:=0 to DivNumber-1do
RandRecord:=0;
end;
procedure TForm1.Button2Click(Sender: TObject);
var
Count:Integer;
begin
if Button2.Tag=1 then
begin
Button2.Tag:=0;
exit;
end;
Button2.Tag:=1;
Button2.Caption:='Stop';
Count:=0;
while (Button2.Tag<>0) and (Count<SpinEdit1.Value)do
begin
Button1.Click;
Application.ProcessMessages;
Inc(Count);
end;
Button2.Tag:=0;
Button2.Caption:='Start';
end;
end.
注:运行环境为:PIII800,Win NT4
每次产生6个均匀分布于 0-999999 的数字,完全重复的概率为[red]十的负三十六次方[/red]。OK?
[][][^][^]
欢迎大家提出改进意见!谢谢!
另:若分类不妥,还有劳版主,将其放到适当的分类中去,谢谢了!