unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ComCtrls, Spin, StdCtrls, ExtCtrls, TeeProcs, TeEngine, Chart, Series, Math, Menus, GanttCh, TabNotBk; const // Типизированные константы параметров законов распределения // Работоспособность элементов nyu_otk:real=0.8; // Вейбул t_otk:real=1000; // Вейбул myu_otk:real=1000; // Нормальный закон sigma_otk:real=100; // Нормальный закон lambda_otk:real=0.001; // Экспоненциальный закон // Востановление элементов lambda_vost:real=0.01; // Экспоненциальный myu_vost:real=100; // Нормальный - мат. ожидание sigma_vost:real=10; // Нормальный - СКО nyu_vost:real=0.8; // Вейбула t_vost:real=1000; // Вейбула Tm:real=100000; // Время моделирования (час) ne:integer=3; // Количество элементов в расчетной схеме надежности fw101:string='e1+e2+e3'; // Логическая функция ИУ2-101 fw102:string='(e01*e02)+(e03*e04)+(e05*e06)'; // Логическая функция ИУ2-102 fw103:string='(e01+e02)*(e01+e03)*(e02+e03)'; // Логическая функция ИУ2-103 type StructElement=record tk:real; // Время конца текущего участка моделирования otk_e:boolean; // Признак работоспособности элемента end; TForm1 = class(TForm) RadioGroup1: TRadioGroup; RadioGroup2: TRadioGroup; GroupBox1: TGroupBox; Label1: TLabel; Edit1: TEdit; Label2: TLabel; Edit2: TEdit; Label3: TLabel; Edit3: TEdit; Label4: TLabel; Edit4: TEdit; Label5: TLabel; Edit5: TEdit; Label6: TLabel; Edit6: TEdit; Label7: TLabel; Edit7: TEdit; Label8: TLabel; Edit8: TEdit; Button1: TButton; Button2: TButton; Label10: TLabel; Edit9: TEdit; StatusBar1: TStatusBar; GroupBox2: TGroupBox; Label11: TLabel; Edit10: TEdit; Label12: TLabel; Edit11: TEdit; Label13: TLabel; Edit12: TEdit; Edit14: TEdit; Button4: TButton; Button5: TButton; Timer1: TTimer; RadioGroup3: TRadioGroup; GroupBox3: TGroupBox; Button3: TButton; Button6: TButton; Label14: TLabel; Label16: TLabel; Edit16: TEdit; Label9: TLabel; Edit15: TEdit; Edit13: TEdit; Label15: TLabel; MainMenu1: TMainMenu; RadioGroup4: TRadioGroup; TabbedNotebook1: TTabbedNotebook; Chart1: TChart; Series1: TBarSeries; Series2: TBarSeries; Series3: TBarSeries; Chart2: TChart; Series4: TGanttSeries; Edit17: TEdit; Chart3: TChart; Series5: TGanttSeries; Memo1: TMemo; Label17: TLabel; Label18: TLabel; Chart4: TChart; Series6: TBarSeries; Chart5: TChart; Series7: TBarSeries; Panel1: TPanel; N1: TMenuItem; N2: TMenuItem; Image1: TImage; Label19: TLabel; procedure FormPaint(Sender: TObject); // Инициализация начальных значений параметров procedure Edit9KeyPress(Sender: TObject; var Key: Char); // Контроль ввода числовой формы procedure Edit1KeyPress(Sender: TObject; var Key: Char); procedure Button1Click(Sender: TObject); // Установка новых значений коэффициентов procedure Button2Click(Sender: TObject); // Возврат коэффициентов по умолчанию procedure Button3Click(Sender: TObject); // Генераторы отказов procedure Timer1Timer(Sender: TObject); // Проверка генераторов случайных чисел procedure Button6Click(Sender: TObject); // Генераторы востановлений procedure RadioGroup4Click(Sender: TObject); // Выбор отображаемых диаграмм procedure Button5Click(Sender: TObject); // Начало счета procedure TabbedNotebook1Click(Sender: TObject); // Выбор страницы диаграммы непосредственно procedure N1Click(Sender: TObject); // Меню - ВЫХОД procedure N2Click(Sender: TObject); // Меню - О ПРОГРАММЕ private { Private declarations } public { Public declarations } EA:array[1..10] of StructElement; // Массив времен отказа/востановления элементов STO:array[1..20000] of StructElement; // Массив времен отказов/востановления системы function RandExp(f,l:real):real; // Экспоненциальное распределение function RandVeyb(f,t,n:real):real; // Распределение Вейбула function DetectMinimumElement:integer; // Определение элемента с минимальным временем function DetectEndModeling:boolean; // Определение конца откезка времени моделирования function DetectOtkaz102:boolean; // Функция работоспособности ИУ2-102 function DetectOtkaz101:boolean; // Функция работоспособности ИУ2-101 function DetectOtkaz103:boolean; // Функция работоспособности ИУ2-103 Procedure ShowTimeDiagram(tt:integer; var jj:integer); // Отображение резльтатов на диаграммах end; var Form1: TForm1; implementation uses Unit2; {$R *.dfm} Procedure TForm1.ShowTimeDiagram(tt:integer; var jj:integer); var aa,bb:integer; begin bb:=0; Memo1.Lines.Add('********************'); for aa:=1 to tt do if not STO[aa].otk_e then Begin bb:=bb+1; Memo1.Lines.Add('Отказ №'+IntToStr(bb)+' T= '+FloatToStrF(STO[aa].tk,ffFixed,8,2)); end; Memo1.Lines.Add('===================='); Memo1.Lines.Add('Всего отказов '+IntToStr(bb)); Edit17.Text:='Отказов '+IntToStr(bb); jj:=bb; for aa:=1 to tt-1 do Begin if aa=1 then Series5.AddGanttColor(0,STO[1].tk,1,'Система',clGreen) else if not STO[aa].otk_e then Begin if aa=tt-1 then Series5.AddGanttColor(STO[aa].tk,Tm,1,'Система',clRed) else Series5.AddGanttColor(STO[aa].tk,STO[aa+1].tk,1,'Система',clRed); end else Begin if aa=tt-1 then Series5.AddGanttColor(STO[aa].tk,Tm,1,'Система',clGreen) else Series5.AddGanttColor(STO[aa].tk,STO[aa+1].tk,1,'Система',clGreen); end; end; end; function TForm1.DetectOtkaz101:boolean; var ee:array[1..3] of boolean; aa:integer; Begin for aa:=1 to ne do ee[aa]:=EA[aa].otk_e; DetectOtkaz101:=(ee[1] or ee[2] or ee[3]); end; function TForm1.DetectOtkaz102:boolean; var ee:array[1..6] of boolean; aa:integer; begin for aa:=1 to ne do ee[aa]:=EA[aa].otk_e; DetectOtkaz102:=(ee[1] and ee[2]) or (ee[3] and ee[4]) or (ee[5] and ee[6]); end; function TForm1.DetectOtkaz103:boolean; var ee:array[1..6] of boolean; aa:integer; begin for aa:=1 to ne do ee[aa]:=EA[aa].otk_e; DetectOtkaz103:=(ee[1] or ee[2]) and (ee[1] or ee[3]) and (ee[2] or ee[3]) and (ee[1] or ee[2] or ee[3]); end; function TForm1.DetectEndModeling:boolean; var aa:integer; bb:boolean; begin bb:=false; for aa:=1 to ne do if EA[aa].tk>=Tm then Begin bb:=true; break; end; DetectEndModeling:=bb; end; function TForm1.DetectMinimumElement:integer; var aa,bb:integer; cc:real; Begin cc:=10e10; for aa:=1 to ne do if EA[aa].tk0 then convert:=copy(s,1,ps-1)+'.'+copy(s,ps+1,length(s)-ps) else convert:=s; end; begin // Установка начальных значений параметров randomize; // Запуститить генератор Edit1.Text:=Convert(FloatToStr(nyu_otk)); Edit2.Text:=Convert(FloatToStr(t_otk)); Edit3.Text:=Convert(FloatToStr(myu_otk)); Edit4.Text:=Convert(FloatToStr(sigma_otk)); Edit5.Text:=Convert(FloatToStr(lambda_otk)); Edit6.Text:=Convert(FloatToStr(lambda_vost)); Edit7.Text:=Convert(FloatToStr(myu_vost)); Edit8.Text:=Convert(FloatToStr(sigma_vost)); Edit15.Text:=Convert(FloatToStr(nyu_vost)); Edit16.Text:=Convert(FloatToStr(t_vost)); case RadioGroup3.ItemIndex of // Выбор режима работы 0:Begin Edit9.Text:=fw101; ne:=3; RadioGroup1.Enabled:=true; RadioGroup2.Enabled:=true end; 1:Begin Edit9.Text:=fw102; ne:=6; RadioGroup1.Enabled:=true; RadioGroup2.Enabled:=true; end; 2:Begin Edit9.Text:=fw103; ne:=3; RadioGroup1.Enabled:=false; RadioGroup2.Enabled:=false end; end; Edit13.Text:=Convert(FloatToStr(tm)); end; procedure TForm1.Edit9KeyPress(Sender: TObject; var Key: Char); begin // Вводить только разрешенные символы if not (key in [#8,#42,#43,#48..#57]) then key:=#0; end; procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char); begin // Вводить только разрешенные символы Edit14.Text:=IntToStr(ord(key)); if not (key in [#8,#46,#48..#57]) then key:=#0; end; procedure TForm1.Button1Click(Sender: TObject); var ec:integer; // Ошибки ввода значений begin val(Edit1.Text,nyu_otk,ec); if ec<>0 then MessageDlg('Ошибка ввода вещественного значения!',mtError,[mbOk],0); val(Edit2.Text,t_otk,ec); if ec<>0 then MessageDlg('Ошибка ввода вещественного значения!',mtError,[mbOk],0); val(Edit3.Text,myu_otk,ec); if ec<>0 then MessageDlg('Ошибка ввода вещественного значения!',mtError,[mbOk],0); val(Edit4.Text,sigma_otk,ec); if ec<>0 then MessageDlg('Ошибка ввода вещественного значения!',mtError,[mbOk],0); val(Edit5.Text,lambda_otk,ec); if ec<>0then MessageDlg('Ошибка ввода вещественного значения!',mtError,[mbOk],0); val(Edit6.Text,lambda_vost,ec); if ec<>0 then MessageDlg('Ошибка ввода вещественного значения!',mtError,[mbOk],0); val(Edit7.Text,myu_vost,ec); if ec<>0 then MessageDlg('Ошибка ввода вещественного значения!',mtError,[mbOk],0); val(Edit8.Text,sigma_vost,ec); if ec<>0 then MessageDlg('Ошибка ввода вещественного значения!',mtError,[mbOk],0); val(Edit13.Text,tm,ec); if ec<>0 then MessageDlg('Ошибка ввода вещественного значения!',mtError,[mbOk],0); if tm>10000000 then tm:=10000000; val(Edit15.Text,nyu_vost,ec); if ec<>0 then MessageDlg('Ошибка ввода вещественного значения!',mtError,[mbOk],0); val(Edit16.Text,t_vost,ec); if ec<>0 then MessageDlg('Ошибка ввода вещественного значения!',mtError,[mbOk],0); end; procedure TForm1.Button2Click(Sender: TObject); begin // Дефолтовые значения (т.е. по умолчанию) nyu_otk:=0.8; t_otk:=1000; myu_otk:=1000; sigma_otk:=100; lambda_otk:=0.001; lambda_vost:=0.01; myu_vost:=100; sigma_vost:=10; nyu_vost:=0.8; t_vost:=1000; Tm:=100000; Form1.FormPaint(sender); end; procedure TForm1.Button3Click(Sender: TObject); begin // Проверка генераторов времени безотказной работы button5.Enabled:=not button5.Enabled; timer1.Enabled:=not timer1.Enabled; if Timer1.Enabled then Button3.Caption:='СТОП' else Button3.Caption:='ТЕСТ БЕЗОТК.'; if timer1.Enabled then Begin Button6.Enabled:=false; RadioGroup4.ItemIndex:=0 end else Button6.Enabled:=true; Chart1.Series[0].Clear; Chart1.Series[1].Clear; Chart1.Series[2].Clear; end; procedure TForm1.Timer1Timer(Sender: TObject); var i:integer; begin // Проверка генераторов Chart1.Series[0].Clear; Chart1.Series[1].Clear; Chart1.Series[2].Clear; if Button3.Enabled then Begin case RadioGroup1.ItemIndex of 0:Chart1.LeftAxis.Maximum:=1.25*t_otk; 1:Chart1.LeftAxis.Maximum:=myu_otk+4*sigma_otk; 2:Chart1.LeftAxis.Maximum:=6/lambda_otk; end; for i:=1 to 25 do case RadioGroup1.ItemIndex of 0:Chart1.Series[0].AddXY(i,RandVeyb(random,t_otk,nyu_otk)); 1:Chart1.Series[1].AddXY(i,RandG(myu_otk,sigma_otk)); 2:Chart1.Series[2].AddXY(i,RandExp(random,lambda_otk)); end; end else Begin case RadioGroup2.ItemIndex of 0:Chart1.LeftAxis.Maximum:=6/lambda_vost; 1:Chart1.LeftAxis.Maximum:=myu_vost+4*sigma_vost; 2:Chart1.LeftAxis.Maximum:=1.25*t_vost; end; for i:=1 to 25 do case RadioGroup2.ItemIndex of 0:Chart1.Series[0].AddXY(i,RandExp(random,lambda_vost)); 1:Chart1.Series[1].AddXY(i,RandG(myu_vost,sigma_vost)); 2:Chart1.Series[2].AddXY(i,RandVeyb(random,t_vost,nyu_vost)); end; end; end; procedure TForm1.Button6Click(Sender: TObject); begin // Проверка генераторов времени востановления button5.Enabled:=not button5.Enabled; timer1.Enabled:=not timer1.Enabled; if Timer1.Enabled then Button6.Caption:='СТОП' else Button6.Caption:='ТЕСТ ВОСТАН.'; if timer1.Enabled then Begin Button3.Enabled:=false; RadioGroup4.ItemIndex:=0; end else Button3.Enabled:=true; Chart1.Series[0].Clear; Chart1.Series[1].Clear; Chart1.Series[2].Clear; end; procedure TForm1.RadioGroup4Click(Sender: TObject); begin // Переключение режимов отображения TabbedNotebook1.PageIndex:=RadioGroup4.ItemIndex; end; procedure TForm1.Button5Click(Sender: TObject); label restart; var i,j,k,m,l:integer; // Индексы массивов ovf:integer; // Счетчик переполнения tmp,so,sb,sro,srb:real; // Среднее время наработки и востановления tot,tvo,mo,mb:array[1..1000] of real; begin RadioGroup4Click(sender); ovf:=1; restart: if ovf>1000 then exit; Series4.Clear; // Стереть диаграммы Series5.Clear; Series6.Clear; Series7.Clear; Memo1.Lines.Clear; // Стереть текстовое окно отказов case RadioGroup3.ItemIndex of // Выбор варианта решения 0:BEGIN // Для группы ИУ2-101 for i:=1 to ne do Begin EA[i].otk_e:=true; case RadioGroup1.ItemIndex of 0:EA[i].tk:=RandVeyb(random,t_otk,nyu_otk); 1:EA[i].tk:=RandG(myu_otk,sigma_otk); 2:EA[i].tk:=RandExp(random,lambda_otk); end; Series4.AddGanttColor(0,EA[i].tk,i,IntToStr(i),clGreen); end; k:=0; repeat j:=DetectMinimumElement; // Определение элемента с минимальным временем EA[j].otk_e:=not EA[j].otk_e; // Переброска флага работает/востанавливается k:=k+1; // Шаг решения STO[k].otk_e:=DetectOtkaz101; // Определение состояния системы - логическая функция работоспособности STO[k].tk:=EA[j].tk; // Отвметка времени для системы if not EA[j].otk_e then // Если элемент отказал case RadioGroup2.ItemIndex of // Востановление элемента 0:tmp:=RandExp(random,lambda_vost); 1:tmp:=RandG(myu_vost,sigma_vost); 2:tmp:=RandVeyb(random,t_vost,nyu_vost); end else case RadioGroup1.ItemIndex of // Работа элемента до отказа 0:tmp:=RandVeyb(random,t_otk,nyu_otk); 1:tmp:=RandG(myu_otk,sigma_otk); 2:tmp:=RandExp(random,lambda_otk); end; EA[j].tk:=EA[j].tk+tmp; // Приращение времени элемента if Tm<100001 then // Во избежание переполнения вывода диаграммы Begin // Вывод диаграмм работы/востановления элементов if EA[j].otk_e then Series4.AddGanttColor(EA[j].tk-tmp,EA[j].tk,j,IntToStr(j),clGreen) else Series4.AddGanttColor(EA[j].tk-tmp,EA[j].tk,j,IntToStr(j),clRed); end; until DetectEndModeling; // Определение конца моделирования Edit14.Text:=IntToStr(k); // Вывод кол-ва тактов решения ShowTimeDiagram(k,l); // Вывод диаграмм работы/востановления ситемы if l<2 then Begin ovf:=ovf+1; goto restart; // Если убрать - возникает иногда деление на ноль (случайно) end; l:=1; m:=1; i:=1; for i:=1 to k-1 do // Определение моментов отказа/востановления системы if not (STO[i].otk_e=STO[i+1].otk_e) then if STO[i+1].otk_e then Begin MB[l]:=STO[i+1].tk; // Моменты востановления l:=l+1; end else Begin MO[m]:=STO[i+1].tk; // Моменты отказов m:=m+1; end; so:=0; sb:=0; for i:=1 to m-2 do // Определение средних времен Begin tot[i]:=mo[i+1]-mb[i]; // Время наработки до отказа - для гистограммы so:=so+tot[i]; // Для среднего времени до отказа tvo[i]:=mb[i]-mo[i]; // Время востановления - гистогармма времен востановления sb:=sb+tvo[i]; // Для среднего времени востановления end; sro:=so/(m-1); // Среднее время наработки до отказа srb:=sb/(l-1); // Среднее время востановления системы Edit10.Text:=FloatToStrF(sro,ffFixed,5,2); // Вывод ср. наработки Edit11.Text:=FloatToStrF(srb,ffFixed,5,2); // Вывод ср. востановления if sro+srb<>0 then // Определение коэффициента готовности Edit12.Text:=FloatToStrF(sro/(sro+srb),ffFixed,5,3); for i:=1 to m-1 do Series6.AddXY(i,tot[i]); // Вывод гистограммы отказов for i:=1 to l-1 do Series7.AddXY(i,tvo[i]); // Вывод гистограммы востановления END; 1:BEGIN // Для группы ИУ2-102 (описание см. выше) for i:=1 to ne do Begin EA[i].otk_e:=true; case RadioGroup1.ItemIndex of 0:EA[i].tk:=RandVeyb(random,t_otk,nyu_otk); 1:EA[i].tk:=RandG(myu_otk,sigma_otk); 2:EA[i].tk:=RandExp(random,lambda_otk); end; Series4.AddGanttColor(0,EA[i].tk,i,IntToStr(i),clGreen); end; k:=0; repeat j:=DetectMinimumElement; EA[j].otk_e:=not EA[j].otk_e; k:=k+1; STO[k].otk_e:=DetectOtkaz102; STO[k].tk:=EA[j].tk; if not EA[j].otk_e then case RadioGroup2.ItemIndex of 0:tmp:=RandExp(random,lambda_vost); 1:tmp:=RandG(myu_vost,sigma_vost); 2:tmp:=RandVeyb(random,t_vost,nyu_vost); end else case RadioGroup1.ItemIndex of 0:tmp:=RandVeyb(random,t_otk,nyu_otk); 1:tmp:=RandG(myu_otk,sigma_otk); 2:tmp:=RandExp(random,lambda_otk); end; EA[j].tk:=EA[j].tk+tmp; if Tm<100001 then Begin if EA[j].otk_e then Series4.AddGanttColor(EA[j].tk-tmp,EA[j].tk,j,IntToStr(j),clGreen) else Series4.AddGanttColor(EA[j].tk-tmp,EA[j].tk,j,IntToStr(j),clRed); end; until DetectEndModeling; Edit14.Text:=IntToStr(k); ShowTimeDiagram(k,l); if l<2 then Begin ovf:=ovf+1; goto restart; end; l:=1; m:=1; i:=1; for i:=1 to k-1 do if not (STO[i].otk_e=STO[i+1].otk_e) then if STO[i+1].otk_e then Begin MB[l]:=STO[i+1].tk; l:=l+1; end else Begin MO[m]:=STO[i+1].tk; m:=m+1; end; so:=0; sb:=0; for i:=1 to m-2 do Begin tot[i]:=mo[i+1]-mb[i]; so:=so+tot[i]; tvo[i]:=mb[i]-mo[i]; sb:=sb+tvo[i]; end; sro:=so/(m-1); srb:=sb/(l-1); Edit10.Text:=FloatToStrF(sro,ffFixed,5,2); Edit11.Text:=FloatToStrF(srb,ffFixed,5,2); if sro+srb<>0 then Edit12.Text:=FloatToStrF(sro/(sro+srb),ffFixed,5,3); for i:=1 to m-1 do Series6.AddXY(i,tot[i]); for i:=1 to l-1 do Series7.AddXY(i,tvo[i]); END; 2:BEGIN // Для группы ИУ2-103 (описание см. выше) for i:=1 to ne do Begin EA[i].otk_e:=true; case i of 1,2:EA[i].tk:=RandVeyb(random,t_otk,nyu_otk); 3:EA[i].tk:=RandG(myu_otk,sigma_otk); end; Series4.AddGanttColor(0,EA[i].tk,i,IntToStr(i),clGreen); end; k:=0; repeat j:=DetectMinimumElement; EA[j].otk_e:=not EA[j].otk_e; k:=k+1; STO[k].otk_e:=DetectOtkaz103; STO[k].tk:=EA[j].tk; if not EA[j].otk_e then tmp:=RandExp(random,lambda_vost) else case j of 1,2:tmp:=RandVeyb(random,t_otk,nyu_otk); 3:tmp:=RandG(myu_otk,sigma_otk); end; EA[j].tk:=EA[j].tk+tmp; if Tm<100001 then Begin if EA[j].otk_e then Series4.AddGanttColor(EA[j].tk-tmp,EA[j].tk,j,IntToStr(j),clGreen) else Series4.AddGanttColor(EA[j].tk-tmp,EA[j].tk,j,IntToStr(j),clRed); end; until DetectEndModeling; Edit14.Text:=IntToStr(k); ShowTimeDiagram(k,l); if l<2 then Begin ovf:=ovf+1; goto restart; end; l:=1; m:=1; i:=1; for i:=1 to k-1 do if not (STO[i].otk_e=STO[i+1].otk_e) then if STO[i+1].otk_e then Begin MB[l]:=STO[i+1].tk; l:=l+1; end else Begin MO[m]:=STO[i+1].tk; m:=m+1; end; so:=0; sb:=0; for i:=1 to m-2 do Begin tot[i]:=mo[i+1]-mb[i]; so:=so+tot[i]; tvo[i]:=mb[i]-mo[i]; sb:=sb+tvo[i]; end; sro:=so/(m-1); srb:=sb/(l-1); Edit10.Text:=FloatToStrF(sro,ffFixed,5,2); Edit11.Text:=FloatToStrF(srb,ffFixed,5,2); if sro+srb<>0 then Edit12.Text:=FloatToStrF(sro/(sro+srb),ffFixed,5,3); for i:=1 to m-1 do Series6.AddXY(i,tot[i]); for i:=1 to l-1 do Series7.AddXY(i,tvo[i]); END; end; end; procedure TForm1.TabbedNotebook1Click(Sender: TObject); begin // Выбор страницы диаграмм RadioGroup4.ItemIndex:=TabbedNotebook1.PageIndex; end; procedure TForm1.N1Click(Sender: TObject); begin // Выход из программы - меню Form2.close; end; procedure TForm1.N2Click(Sender: TObject); begin // Вывод окна "О программе" - меню Form1.Enabled:=false; Form2.Visible:=true; Form2.SetFocus; end; end.