unit ReliabilityMain; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, TeEngine, Series, ExtCtrls, TeeProcs, Chart, Math; const STOP_TIME = 1000000000; T1 = 1000.0; nu = 1.0; m = 1000.0; sigma = 2000.0; mu = 0.002; type TForm1 = class(TForm) Chart1: TChart; Series1: TBarSeries; Series2: TBarSeries; procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); private { Private declarations } public { Public declarations } end; TDevice = record OK, WasOK: Boolean; BlockOK: array [1..3] of Boolean; BlockNextSwitchTime: array [1..3] of Double; TotalOKTime: Double; NumCrashes: Integer; end; var Form1: TForm1; Device: TDevice; t, tOld, tOut: Double; implementation {$R *.DFM} function Weibull(T1, nu: Double): Double; begin Weibull := Power(-T1 * ln(Random), 1 / nu); end; function Expon(mu: Double): Double; begin Expon := -(1 / mu) * ln(Random); end; function Norm(m, sigma: Double): Double; var S: Double; i: Integer; begin repeat S := 0; for i := 1 to 12 do S := S + Random; Result := m + sigma * (S - 6); until Result > 0; end; procedure CheckOK(var D: TDevice); begin D.WasOK := D.OK; D.OK := (D.BlockOK[1] and D.BlockOK[2]) or (D.BlockOK[1] and D.BlockOK[3]) or (D.BlockOK[2] and D.BlockOK[3]); if D.OK then D.TotalOKTime := D.TotalOKTime + (t - tOld); if (not D.OK) and D.WasOK then Inc(D.NumCrashes); end; procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); var i, j: Integer; begin // initialization Randomize; t := 0; tOld := 0; tOut := 10; with Device do begin OK := TRUE; WasOK := TRUE; NumCrashes := 0; for j := 1 to 3 do BlockOK[j] := TRUE; BlockNextSwitchTime[1] := Weibull(T1, nu); BlockNextSwitchTime[2] := Weibull(T1, nu); BlockNextSwitchTime[3] := Norm(m, sigma); end;// with // main loop repeat with Device do begin // check device blocks for j := 1 to 3 do begin if BlockOK[j] and (t > BlockNextSwitchTime[j]) then // simulate block crash begin BlockOK[j] := FALSE; BlockNextSwitchTime[j] := BlockNextSwitchTime[j] + Expon(mu); // recovery time end;// if if (not BlockOK[j]) and (t > BlockNextSwitchTime[j]) then // simulate block recovery begin BlockOK[j] := TRUE; if j = 3 then BlockNextSwitchTime[j] := BlockNextSwitchTime[j] + Norm(m, sigma) // operation time else BlockNextSwitchTime[j] := BlockNextSwitchTime[j] + Weibull(T1, nu); // operation time end;// if end;// for j... end;// with // check whole device CheckOK(Device); if t = tOut then begin if Device.NumCrashes > 0 then begin Series1.AddXY(log10(t), Device.TotalOKTime / Device.NumCrashes); Series2.AddXY(log10(t), (t - Device.TotalOKTime) / Device.NumCrashes); end; tOut := tOut * 10; end; tOld := t; t := t + 10; until t > STOP_TIME; Caption := Caption + ' - Коэффициент готовности: ' + FloatToStr(Device.TotalOKTime / STOP_TIME); end; end.