Delphi

本类阅读TOP10

·分布式网络考试系统原型分析及实现
·游戏外挂设计技术探讨①
·使用HOOK随心监视Windows
·Delphi 水晶报表打包解决
·试题库开发中非文本数据的处理
·如何将几个DBGRID里的内容导入同一个EXCEL表中....的问题
·如何使用Delphi设计强大的服务器程序
·工人线程中关闭窗体的实现
·用DLL方式封装MDI子窗体。
·支持XP下托盘栏气球提示的托盘单元

分类导航
VC语言Delphi
VB语言ASP
PerlJava
Script数据库
其他语言游戏开发
文件格式网站制作
软件工程.NET开发
[Delphi]根据 高斯正态分布随机函数RandG发生的数据 绘正态分布曲线(原创)

作者:未知 来源:月光软件站 加入时间:2005-5-13 月光软件站

{*

采用RandG(0,1)来生成标准正态分布数据

1、一次生成10k个数据进行统计,速度相当快(Celeron 1.1G +256M ddr266)<1秒

2、绘出的曲线因为选择范围是8,故看起来并不是十分陡峭,可以将其改为16,那么就更加陡峭了

3、算法:映射到1..1000个数据点,大于等于+8的,正向封顶,设其为1000;小于等于 -8 的,负向封底,设其为1;如上面所说,为了使曲线看起来更加陡峭,可以在这里改为16封顶。其实,我最初是用+2-2来封及+4-4来封定封底的,效果已经不错了。

}

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, StdCtrls, Math;

type

  TfrmMain = class(TForm)
    imgAxis: TImage;
    btnRandG: TButton;
    GroupBox1: TGroupBox;
    Splitter1: TSplitter;
    grpControl: TGroupBox;
    chkLogFrequency: TCheckBox;
    chkDrawEdge: TCheckBox;
    chkDrawLines: TCheckBox;
    cboxCopyMode: TComboBox;
    procedure FormShow(Sender: TObject);
    procedure btnRandGClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
    totalCount  :Integer;
    sampleDatas :array[1..1000] of Integer;
    procedure DrawAxis;
    procedure GaussIt(const ASampleData:Extended);
    procedure ReDraw;
    procedure DrawEdge;//画边

    procedure Log(const logName:string);
  public
    { Public declarations }
  end;

var
  frmMain: TfrmMain;

implementation

{$R *.dfm}
procedure TfrmMain.DrawAxis;
begin
  imgAxis.Canvas.Pen.Color :=clLime;
  imgAxis.Canvas.Pen.Mode  :=pmXor;
  imgAxis.Canvas.MoveTo(imgAxis.Width div 2,imgAxis.Height);
  imgAxis.Canvas.LineTo(imgAxis.Width div 2,0);
  imgAxis.Canvas.MoveTo(0,imgAxis.Height -10);
  imgAxis.Canvas.LineTo(imgAxis.Width,imgAxis.Height -10);
end;
procedure TfrmMain.ReDraw;
var
  bmp :TBitmap;
  i   :Integer;
begin//根据数组里面的数和totalCount重新画图
  bmp :=TBitmap.Create;
  try
    bmp.Width :=imgAxis.Width;
    bmp.Height:=imgAxis.Height;
    bmp.Canvas.Brush.Color :=clBlack;
    bmp.Canvas.FillRect(bmp.Canvas.ClipRect);
    bmp.Canvas.Pen.Color :=clRed;
    bmp.Canvas.Pen.Width :=1;
    //根据Image高度和1->1000发生的频数设置画线的高度
    //应该计算出图像所能反映的最小分辨率,应能体现到频数有1的变化
    for i:=1 to 1000 do
    begin
      sampleDatas[i] :=(sampleDatas[i]*(bmp.Height-10))  *250 div totalCount;//频数->频率->实际图像高度值
      sampleDatas[i] :=bmp.Height-10 -sampleDatas[i];//高度转换为实际坐标
      bmp.Canvas.MoveTo(i,bmp.Height-10);
      if chkDrawLines.Checked then
        bmp.Canvas.LineTo(i,sampleDatas[i]);
    end;
    //Log('height.txt');
    if cboxCopyMode.Items[cboxCopyMode.ItemIndex]='cmBlackness' then
      imgAxis.Canvas.CopyMode :=cmBlackness
    else if cboxCopyMode.Items[cboxCopyMode.ItemIndex]='cmDstInvert' then
      imgAxis.Canvas.CopyMode :=cmDstInvert
    else if cboxCopyMode.Items[cboxCopyMode.ItemIndex]='cmMergeCopy' then
      imgAxis.Canvas.CopyMode :=cmMergeCopy
    else if cboxCopyMode.Items[cboxCopyMode.ItemIndex]='cmMergePaint' then
      imgAxis.Canvas.CopyMode :=cmMergePaint
    else if cboxCopyMode.Items[cboxCopyMode.ItemIndex]='cmNotSrcCopy' then
      imgAxis.Canvas.CopyMode :=cmNotSrcCopy
    else if cboxCopyMode.Items[cboxCopyMode.ItemIndex]='cmNotSrcErase' then
      imgAxis.Canvas.CopyMode :=cmNotSrcErase
    else if cboxCopyMode.Items[cboxCopyMode.ItemIndex]='cmPatCopy' then
      imgAxis.Canvas.CopyMode :=cmPatCopy
    else if cboxCopyMode.Items[cboxCopyMode.ItemIndex]='cmPatInvert' then
      imgAxis.Canvas.CopyMode :=cmPatInvert
    else if cboxCopyMode.Items[cboxCopyMode.ItemIndex]='cmPatPaint' then
      imgAxis.Canvas.CopyMode :=cmPatPaint
    else if cboxCopyMode.Items[cboxCopyMode.ItemIndex]='cmSrcAnd' then
      imgAxis.Canvas.CopyMode :=cmSrcAnd
    else if cboxCopyMode.Items[cboxCopyMode.ItemIndex]='cmSrcCopy' then
      imgAxis.Canvas.CopyMode :=cmSrcCopy
    else if cboxCopyMode.Items[cboxCopyMode.ItemIndex]='cmSrcErase' then
      imgAxis.Canvas.CopyMode :=cmSrcErase
    else if cboxCopyMode.Items[cboxCopyMode.ItemIndex]='cmSrcInvert' then
      imgAxis.Canvas.CopyMode :=cmSrcInvert
    else if cboxCopyMode.Items[cboxCopyMode.ItemIndex]='cmSrcPaint' then
      imgAxis.Canvas.CopyMode :=cmSrcPaint
    else if cboxCopyMode.Items[cboxCopyMode.ItemIndex]='cmWhiteness' then
      imgAxis.Canvas.CopyMode :=cmWhiteness;

    imgAxis.Canvas.CopyRect(imgAxis.Canvas.ClipRect,bmp.Canvas,bmp.Canvas.ClipRect);
    //imgAxis.Canvas.Draw(0,0,bmp);//这个不能控制CopyMode
  finally
    bmp.Destroy;
  end;
end;
procedure TfrmMain.GaussIt(const ASampleData:Extended);
var
  x :Integer;
begin
  Inc(totalCount);
  //ShowMessage(FloatToStr(ASampleData));
  //将这个随机数映射到1..1000,正数:500->1000,负数500->1
  //ASampleData>=8  ---1000
  //           =0   ---500
  //           <=-8 ---1
  x :=Round(ASampleData *1000);
  //确定范围
  if x>=4000 then x:=4000
  else if x<=-4000 then x:=-4000;
 
  x := (x +4001) shr 3;
  Inc(sampleDatas[x]);//记录发生的频数,除以总次数就是频率了
  //ShowMessage(IntToStr(x));
  //ShowMessage(IntToStr(sampleDatas[x]));
end;
procedure TfrmMain.FormCreate(Sender: TObject);
begin
  DoubleBuffered :=true;
  DrawAxis;
end;

procedure TfrmMain.btnRandGClick(Sender: TObject);
var
  i:Integer;
begin
  totalCount :=0;
  for i:=1 to 1000 do
    sampleDatas[i]:=0;
  for i:=1 to 100000 do//总计10000次
    GaussIt(RandG(0,1));//标准正态分布

  if chkLogFrequency.Checked then
    Log('afterBtn.txt');

  ReDraw;
  if chkDrawEdge.Checked then
    DrawEdge;
  DrawAxis;
end;

procedure TfrmMain.FormShow(Sender: TObject);
begin
  Left :=0;
  btnRandG.Click;
end;

procedure TfrmMain.Log(const logName:string);
var
  i:Integer;
  log:TStringList;
  str:string;
begin
  log :=TStringList.Create;
  try
    for i:=1 to 1000 do
    begin
      str :=Format('%.4d : %d(频数)',[i,sampleDatas[i]]);
      log.Add(str);
    end;
    str :=Format('总数:%d',[totalCount]);
    log.Add(str);

    totalCount :=0;
    for i:=1 to 1000 do
      inc(totalCount,sampleDatas[i]);
    str :=Format('实际总数:%d',[totalCount]);
    log.Add(str);

    log.SaveToFile(logName);
  finally
    log.Destroy;
  end;
end;

procedure TfrmMain.DrawEdge;//画边
var
  i:Integer;
  points :array[1..1000] of TPoint;
begin
  for i:=1 to 1000 do
  begin
    points[i].x :=i;
    points[i].y :=sampleDatas[i];
  end;
  imgAxis.Canvas.Polyline(points);
end;

end.

--------------------------------------------------------------------------------------------




相关文章

相关软件