注册 | 登录
收藏 | 帮助
热门文章
编辑推荐
相关文章  
从Melissa到Zotob:Windows蠕虫1
病毒常识: DLL 木马揭秘
应对DoS/DDoS攻击的十条军规
从后台得到webshell技巧大汇总
DNS 系统设定例--7.[Fwd] 特殊网
DNS 系统设定例--11.[Fwd] 特殊网
DNS 系统设定例--12.[Fwd;正解] 
DNS 系统设定例--13.[Fwd] NCTU 
DNS 系统设定例--16.[Fwd] 特殊网
DNS 系统设定例--17.[Rev-CIDRD]
您现在的位置: 顶尖设计 >> IT学院 >> 编程开发 >> Delphi >> 文章正文
[Delphi]根据 高斯正态分布随机函数RandG发生的数据 绘正态分布曲线(原创)
作者:dawnsong  来源:csdn  点击:  更新:2006-12-19
简介:
 

{*

采用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.

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

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

下面是Unit1.dfm

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

object frmMain: TfrmMain
  Left = 0
  Top = 0
  Width = 1012
  Height = 455
  Caption = 'frmMain'
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'Tahoma'
  Font.Style = []
  OldCreateOrder = False
  OnCreate = FormCreate
  OnShow = FormShow
  PixelsPerInch = 96
  TextHeight = 13
  object Splitter1: TSplitter
    Left = 0
    Top = 369
    Width = 1004
    Height = 4
    Cursor = crVSplit
    Align = alBottom
  end
  object GroupBox1: TGroupBox
    Left = 0
    Top = 0
    Wid

[1] [2] 下一页






  • 上一篇文章:
  • 下一篇文章:
  • 分享此文:该页面添加到 Mister Wong 添加到雅虎Yahoo!收藏 Add to:Del.icio.us Post to Furl Digg this 添加到Google书签 reddit spurl blogmarks 365Key 评论  收藏  分享  打印
     我来说两句
    姓名:       验证码:   
    主页: 
    评分: 1分 2分 3分 4分 5分
    本频道近期热评文章:
      关于我们 | 联系我们 | 站点地图 | 广告投放 | 友情链接 | 在线留言 | 版权申明
    版权所有 © 2004-2007 顶尖设计(bobd.cn)
    未经授权禁止转载,摘编,复制本站内容或建立镜像. 沪ICP备07504942号 
    网络110
    报警服务