Экспертная диагностическая система
Файл es.cpp
//--------------------------------------------------------------------------#include <vcl.h>
#pragma hdrstop
USERES("es.res");
USEFORM("es_frm.cpp", Form1);
//--------------------------------------------------------------------------WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
try
{
Application->Initialize();
Application->CreateForm(__classid(TForm1), &Form1);
Application->Run();
}
catch (Exception &exception)
{
Application->ShowException(&exception);
}
return 0;
}
//---------------------------------------------------------------------------
Файл es_frm.cpp
//---------------------------------------------------------------------------#include <vcl.h>
#include <stdlib.h>
#pragma hdrstop
#include "es_frmex.h"
#include "es_frm.h"
//---------------------------------------------------------------------------#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------__fastcall TForm1::TForm1(TComponent *Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------void __fastcall TForm1::FormCreate(TObject *Sender)
{
int i;
Table1->DatabaseName=GetCurrentDir();
Table2->DatabaseName=GetCurrentDir();
Table3->DatabaseName=GetCurrentDir();
Table2->Open();
Table3->Open();
Table1->Open();
DataForSign[0]=NULL;
DataForSign[1]=NULL;
DataForSign[2]=NULL;
CostPrb0=NULL;
CostPrb1=NULL;
PrbSign0=NULL;
PrbSign1=NULL;
aPrbForSign=NULL;
CurMaxMinPrb[0]=NULL;
CurMaxMinPrb[1]=NULL;
MaxMinPrb[0]=NULL;
MaxMinPrb[1]=NULL;
CurLevel=1;
CurChngLvl=0;
MaxLevel=1;
Table1->First();
do
{
if(Table1Level->AsInteger>MaxLevel)
MaxLevel=Table1Level->AsInteger;
}
while(Table1->FindNext());
ChngLvl=new int[MaxLevel];
ChngLvl[CurChngLvl]=CurLevel;
Quest=new int[Table3->RecordCount];
for(i=0;i<Table3->RecordCount;i++)
Quest[i]=0;
CalculateSign();
}
//---------------------------------------------------------------------------//Просмотр признаков и флагов для данной гиптезы
//--------------------------------------------------------------------------void TForm1::GetDataSign(void)
{
TBlobStream *Stream1, *Stream2, *Stream3;
byte *Buffer;
int *iTmp;
int MemSize;
int i;
iQntDataSign=Table1Quantitysign->AsInteger;
for(i=0;i<3;i++)
{
if(DataForSign[i]!=NULL)
{
delete DataForSign[i];
DataForSign[i]=NULL;
}
}
if(iQntDataSign)
{
Stream1 = new TBlobStream(Table1Numbersign, bmRead);
try
{
if(Stream1->Size!=0)
{
MemSize = Stream1->Size;
try
{
Buffer = new byte[MemSize]; // Allocate the memory.
Stream1->Read(Buffer,Stream1->Size);
DataForSign[0]= new int[iQntDataSign];
iTmp=(int *)Buffer;
for(i=0;i<MemSize/4;i++)
{
DataForSign[0][i]= iTmp[i];
}
delete[] Buffer;
}
catch (...)
{
;
}
}
delete Stream1;
}
catch (...)
{
delete Stream1;
}
Stream2 = new TBlobStream(Table1Flagsforsign, bmRead);
try
{
if(Stream2->Size!=0)
{
MemSize = Stream2->Size;
try
{
Buffer = new byte[MemSize]; // Allocate the memory.
Stream2->Read(Buffer,Stream2->Size);
DataForSign[1]= new int[iQntDataSign];
iTmp=(int *)Buffer;
for(i=0;i<MemSize/4;i++)
{
DataForSign[1][i]= iTmp[i];
}
delete[] Buffer;
}
catch (...)
{
;
}
}
delete Stream2;
}
catch (...)
{
delete Stream2;
}
Stream3 = new TBlobStream(Table1Numberlist, bmRead);
try
{
if(Stream3->Size!=0)
{
MemSize = Stream3->Size;
try
{
Buffer = new byte[MemSize]; // Allocate the memory.
Stream3->Read(Buffer,Stream3->Size);
DataForSign[2]= new int[iQntDataSign];
iTmp=(int *)Buffer;
for(i=0;i<MemSize/4;i++)
{
DataForSign[2][i]= iTmp[i];
}
delete[] Buffer;
}
catch (...)
{
;
}
}
delete Stream3;
}
catch (...)
{
delete Stream3;
}
}
}
void TForm1::GetDataPrb(void)
{
TBlobStream *Stream1;
int MemSize;
int j;
float *fProb;
byte *ProbBuffer;
if(aPrbVal!=NULL)
{
delete [] aPrbVal;
aPrbVal=NULL;
}
iQntPrb=Table2Qvantityelements->AsInteger;
Stream1 = new TBlobStream(Table2Probability, bmRead);
try
{
if(iQntPrb!=0 && Stream1->Size!=0)
{
MemSize = Stream1->Size;
ProbBuffer = new byte[MemSize];
Stream1->Read(ProbBuffer,Stream1->Size);
delete Stream1;
fProb=(float *)ProbBuffer;
aPrbVal=new float[iQntPrb];
for(j=0;j<iQntPrb;j++)
{
aPrbVal[j]=*fProb;
fProb++;
}
delete [] ProbBuffer;
}
}
catch (...)
{
delete Stream1;
}
}
//--------------------------------------------------------------------------// Просмотр списка значений и их вероятностей для данного признака
//--------------------------------------------------------------------------void TForm1::GetProbability(void)
{
TBlobStream *Stream1, *Stream2;
int MemSize;
int i,j;
short int siLenElem, *ptrLen;
float *fProb;
byte *Buffer, *ProbBuffer, *ptrBuf;
char* strElements;
TCostProbability *TmpCostPrb;
if(aPrbForSign!=NULL)
{
delete [] aPrbForSign;
aPrbForSign=NULL;
}
iQntPrb=Table2Qvantityelements->AsInteger;
Stream1 = new TBlobStream(Table2List, bmRead);
Stream2 = new TBlobStream(Table2Probability, bmRead);
try
{
if(iQntPrb!=0 && Stream1->Size!=0)
{
MemSize = Stream1->Size;
Buffer = new byte[MemSize]; // Allocate the memory.
Stream1->Read(Buffer,Stream1->Size);
MemSize = Stream2->Size;
ProbBuffer = new byte[MemSize];
Stream2->Read(ProbBuffer,Stream2->Size);
delete Stream1;
delete Stream2;
aPrbForSign=new TArrCostProbability(iQntPrb);
fProb=(float *)ProbBuffer;
ptrBuf=Buffer;
for(j=0;j<iQntPrb;j++)
{
ptrLen=(short int*)ptrBuf;
siLenElem=*ptrLen;
ptrBuf+=2;
strElements=new char[siLenElem+1];//Для нуля в конце строки
for(i=0;i<siLenElem;i++)
{
strElements[i]=*ptrBuf;
ptrBuf++;
}
strElements[i]='\0';
TmpCostPrb=new TCostProbability(strElements,*fProb);
aPrbForSign->SetCostPrb(j,TmpCostPrb);
delete TmpCostPrb;
delete [] strElements;
fProb++;
}
delete [] ProbBuffer;
delete [] Buffer;
}
}
catch (...)
{
delete Stream1;
delete Stream2;
}
}
void TForm1::MoveToSign(int iNumber)
{
Table1->RecNo=iNumber;
}
void TForm1::MoveToProbability(int iNumber)
{
Table2->RecNo=iNumber;
}
void TForm1::MoveToQuestion(int iNumber)
{
Table3->RecNo=iNumber;
}
//////////////////////////////////////////////////////////////
void TForm1::CalculateSign(void)
{
int i, j,k;
int Index;
long MaxLenCostPrb;
int *NumCostPrb;
float tmp;
Table1->Filter="Level='"+ IntToStr(CurLevel) +"'";
Table1->Filtered=True;
MaxLenCostPrb=Table3->RecordCount;
NumCostPrb=new int[MaxLenCostPrb];
LenCostPrb=0;
iQntPrbSign=0;
if(Table1->FindFirst())
{
do
{
iQntPrbSign++;
GetDataSign();
for(i=0;i<iQntDataSign;i++)
{
if(!DataForSign[2] || !DataForSign[0]) break;
if(FindIndexValue(NumCostPrb,MaxLenCostPrb,DataForSign[0][i])==-1)
{
NumCostPrb[LenCostPrb++]=DataForSign[0][i];
}
}
}
while(Table1->FindNext());
}
else iQntPrbSign=0;
if(CostPrb0) delete [] CostPrb0;
if(CostPrb1) delete [] CostPrb1;
CostPrb0=new int[LenCostPrb];
CostPrb1=new float[LenCostPrb];
for(i=0;i<LenCostPrb;i++)
{
CostPrb0[i]=NumCostPrb[i];//Номера признаков(свидетельств)
CostPrb1[i]=0;
}
delete [] NumCostPrb;
if(PrbSign0) delete [] PrbSign0;
if(PrbSign1) delete [] PrbSign1;
if(CurMaxMinPrb[0]) delete [] CurMaxMinPrb[0];
if(CurMaxMinPrb[1]) delete [] CurMaxMinPrb[1];
if(MaxMinPrb[0]) delete [] MaxMinPrb[0];
if(MaxMinPrb[1]) delete [] MaxMinPrb[1];
PrbSign0=new int[iQntPrbSign];
PrbSign1=new float[iQntPrbSign];
CurMaxMinPrb[0]=new float[iQntPrbSign];
CurMaxMinPrb[1]=new float[iQntPrbSign];
MaxMinPrb[0]=new float[iQntPrbSign];
MaxMinPrb[1]=new float[iQntPrbSign];
k=0;
if(Table1->FindFirst())
{
do
{
PrbSign0[k]=Table1->RecNo;
PrbSign1[k]=Table1Defaultprobability->AsFloat;
MaxMinPrb[0][k]=PrbSign1[k];
MaxMinPrb[1][k]=PrbSign1[k];
k++;
}
while(Table1->FindNext());
}
if(Table1->FindFirst())
{
k=0;
do
{
GetDataSign();
for(i=0;i<iQntDataSign;i++)
{
if(!DataForSign[2] || !DataForSign[0]) break;
MoveToProbability(DataForSign[2][i]);
GetDataPrb();
if(aPrbVal)
{
Index=FindIndexValue(CostPrb0,LenCostPrb,DataForSign[0][i]);
CostPrb1[Index]+=(aPrbVal[FindMax(aPrbVal,iQntPrb)]-aPrbVal[FindMin(aPrbVal,iQntPrb)])*PrbSign1[k];//Вычисление первоначальной цена свидетельства
tmp=aPrbVal[FindMin(aPrbVal,iQntPrb)]*(1-MaxMinPrb[0][k]);
if(tmp!=0) tmp+=MaxMinPrb[0][k]*aPrbVal[FindMax(aPrbVal,iQntPrb)];//Чтобы предотваратить деление на себя самого
else tmp=1;
MaxMinPrb[0][k]=(MaxMinPrb[0][k]*aPrbVal[FindMax(aPrbVal,iQntPrb)])/(tmp);
tmp=aPrbVal[FindMax(aPrbVal,iQntPrb)]*(1-MaxMinPrb[1][k]);
if(tmp!=0) tmp+=MaxMinPrb[1][k]*aPrbVal[FindMin(aPrbVal,iQntPrb)];//Чтобы предотваратить деление на себя самого
else tmp=1;
MaxMinPrb[1][k]=(MaxMinPrb[1][k]*aPrbVal[FindMin(aPrbVal,iQntPrb)])/(tmp);
}
}
k++;
}
while(Table1->FindNext());
}
Table1->Filtered=False;
AllredyPrbCalculate();
ShowSortPrb();
MoveToMaxCostPrbQst();
}
void TForm1::MoveToMaxCostPrbQst(void)
{
int Index;
Index=FindMax(CostPrb1,LenCostPrb);
MoveToQuestion(CostPrb0[Index]);
Index=FindMax(PrbSign1,iQntDataSign);
MoveToSign(PrbSign0[Index]);
}
int TForm1::FindIndexValue(long* Array, int Len, long Value)
{
int i;
int Index=-1;
for(i=0;i<Len;i++)
{
if(Value==Array[i])
{
Index=i;
break;
}
}
return Index;
}
int TForm1::FindIndexValue(int* Array, int Len, int Value)
{
int i;
int Index=-1;
for(i=0;i<Len;i++)
{
if(Value==Array[i])
{
Index=i;
break;
}
}
return Index;
}
int TForm1::FindIndexValue(float* Array, int Len, float Value)
{
int i;
int Index=-1;
for(i=0;i<Len;i++)
{
if(Value==Array[i])
{
Index=i;
break;
}
}
return Index;
}
int TForm1::FindMax(long* Array, int Len)
{
int Index=0;
int MaxValue;
int i;
MaxValue=Array[0];
for(i=1;i<Len;i++)
{
if(MaxValue<Array[i])
{
MaxValue=Array[i];
Index=i;
}
}
return Index;
}
int TForm1::FindMax(int* Array, int Len)
{
int Index=0;
int MaxValue;
int i;
MaxValue=Array[0];
for(i=1;i<Len;i++)
{
if(MaxValue<Array[i])
{
MaxValue=Array[i];
Index=i;
}
}
return Index;
}
int TForm1::FindMax(float* Array, int Len)
{
int Index=0;
float MaxValue;
int i;
MaxValue=Array[0];
for(i=1;i<Len;i++)
{
if(MaxValue<Array[i])
{
MaxValue=Array[i];
Index=i;
}
}
return Index;
}
int TForm1::FindMin(int* Array, int Len)
{
int Index=0;
int MinValue;
int i;
MinValue=Array[0];
for(i=1;i<Len;i++)
{
if(MinValue>Array[i])
{
MinValue=Array[i];
Index=i;
}
}
return Index;
}
int TForm1::FindMin(float* Array, int Len)
{
int Index=0;
float MinValue;
int i;
MinValue=Array[0];
for(i=1;i<Len;i++)
{
if(MinValue>Array[i])
{
MinValue=Array[i];
Index=i;
}
}
return Index;
}
void TForm1::MaxSortSign(int *Num, float *Val, int Len)
{
int i,j;
int iTmp;
float fTmp;
for(i=0;i<Len-1;i++)
{
for(j=i+1;j<Len;j++)
{
if(Val[j]>Val[i])
{
iTmp=Num[j];
fTmp=Val[j];
Num[j]=Num[i];
Val[j]=Val[i];
Num[i]=iTmp;
Val[i]=fTmp;
}
}
}
}
void TForm1::AllredyPrbCalculate(void)
{
int k, Index, Yes, No,s=0;
float Expr, Chisl, Znam;
for(k=0;k<LenCostPrb;k++)
{
if(Quest[CostPrb0[k]-1])
{
CostPrb1[k]=-1;
if(Quest[CostPrb0[k]-1]==1)
{
Yes=1;
No=0;
}
else
{
Yes=0;
No=1;
}
Table1->Filter="Level='"+ IntToStr(CurLevel) +"'";
Table1->Filtered=True;
if(Table1->FindFirst())
{
do
{
GetDataSign();
Index=FindIndexValue(DataForSign[0],iQntDataSign,CostPrb0[k]);
if(Index>=0)
{
MoveToProbability(DataForSign[2][Index]);
GetDataPrb();
Chisl=aPrbVal[Yes]*PrbSign1[s];
Znam=1-PrbSign1[s];
Znam*=aPrbVal[No];
if(Znam!=0) Znam+=aPrbVal[Yes]*PrbSign1[s];
else Znam=1;//Чтобы предотваратить деление на себя самого
Expr=Chisl/Znam;
PrbSign1[s]= Expr;
}
s++;
}
while(Table1->FindNext());
}
Table1->Filtered=False;
}
}
}
void __fastcall TForm1::SpeedButton1Click(TObject *Sender)
{
int i, Index, Yes, No,s=0;
float Expr, Chisl, Znam;
Table1->Filter="Level='"+ IntToStr(CurLevel) +"'";
Table1->Filtered=True;
Index=FindMax(CostPrb1,LenCostPrb);
if(Table1->FindFirst() && CostPrb1[Index]!=-1)
{
if(ListBox1->Selected[0])
{
Yes=1;
No=0;
Quest[CostPrb0[Index]-1]=1;
}
else
{
Yes=0;
No=1;
Quest[CostPrb0[Index]-1]=2;
}
do
{
GetDataSign();
Index=FindIndexValue(DataForSign[0],iQntDataSign,CostPrb0[FindMax(CostPrb1, LenCostPrb)]);
if(Index>=0)
{
MoveToProbability(DataForSign[2][Index]);
GetDataPrb();
Chisl=aPrbVal[Yes]*PrbSign1[s];
Znam=1-PrbSign1[s];
Znam*=aPrbVal[No];
if(Znam!=0) Znam+=aPrbVal[Yes]*PrbSign1[s];
else Znam=1;//Чтобы предотваратить деление на себя самого
Expr=Chisl/Znam;
PrbSign1[s]= Expr;
}
s++;
}
while(Table1->FindNext());
Index=FindMax(CostPrb1,LenCostPrb);
CostPrb1[Index]=-1;
}
Table1->Filtered=False;
Index=FindMax(CostPrb1,LenCostPrb);
if(CostPrb1[Index]==-1)
{
Index=FindMax(PrbSign1,iQntPrbSign);
MoveToSign(PrbSign0[Index]);
if(Table1NextLevel->AsInteger)
{
CurLevel=Table1NextLevel->AsInteger;
CurChngLvl++;
ChngLvl[CurChngLvl]=CurLevel;
SpeedButton4->Enabled=true;
ShowMessage("Следующий блок");
CalculateSign();
}
else
{
ShowMessage("Это все");
}
}
else
{
if(Table1->FindFirst())
{
s=0;
for(i=0;i<LenCostPrb;i++)
{
if(CostPrb1[i]!=-1) CostPrb1[i]=0;
}
do
{
GetDataSign();
for(i=0;i<iQntDataSign;i++)
{
if(!DataForSign[2] || !DataForSign[0]) break;
MoveToProbability(DataForSign[2][i]);
GetDataPrb();
if(aPrbVal)
{
Index=FindIndexValue(CostPrb0,LenCostPrb,DataForSign[0][i]);
if(CostPrb1[Index]!=-1)
{
CostPrb1[Index]+=(aPrbVal[FindMax(aPrbVal,iQntPrb)]-aPrbVal[FindMin( aPrbVal,iQntPrb)])*PrbSign1[s];//Вычисление первоначальной цена свидетельства
}
}
}
s++;
}
while(Table1->FindNext());
}
MoveToMaxCostPrbQst();
}
ShowSortPrb();
}
//--------------------------------------------------------------------------void __fastcall TForm1::SpeedButton2Click(TObject *Sender)
{
int i;
CurLevel=1;
for(i=0;i<Table3->RecordCount;i++)
Quest[i]=0;
ShowMessage("Все заново");
CalculateSign();
}
//--------------------------------------------------------------------------void TForm1::ShowSortPrb(void)
{
int i, OldRecNo;
int *LSign;
float *LPrbSign, tmp;
AnsiString as;
LSign=new int[iQntPrbSign];
LPrbSign=new float[iQntPrbSign];
for(i=0;i<iQntPrbSign;i++)
{
LSign[i]=PrbSign0[i];
LPrbSign[i]=PrbSign1[i];
}
OldRecNo=Table3->RecNo;
if(VerifyInfer()==3) ShowMessage("Ни одна гипотеза не является истиной");
MaxSortSign(LSign, LPrbSign, iQntPrbSign);
ListBox2->Items->Clear();
for(i=0;i<iQntPrbSign;i++)
{
as="РГ. ";
MoveToSign(LSign[i]);
if(CurMaxMinPrb[1][i]>(MaxMinPrb[0][i])/4*3)
{
as="ВГ! ";
}
tmp=CurMaxMinPrb[0][i];
CurMaxMinPrb[0][i]=0;
if(CurMaxMinPrb[1][i]>CurMaxMinPrb[0][FindMax(CurMaxMinPrb[0],iQntPrbSign)])
{
CurMaxMinPrb[0][i]=tmp;
as="НВГ!!! ";
}
CurMaxMinPrb[0][i]=tmp;
ListBox2->Items->Add(as + Table1Name->AsString + " - " + FloatToStr(LPrbSign[i]));
}
delete [] LSign;
delete [] LPrbSign;
MoveToSign(LSign[0]);
Table3->RecNo=OldRecNo;
}
bool TForm1::VerifyInfer(void)
{
int i, k;
float tmp;
bool None;
for(i=0;i<iQntPrbSign;i++)
{
CurMaxMinPrb[0][i]=PrbSign1[i];
CurMaxMinPrb[1][i]=PrbSign1[i];
}
Table1->Filter="Level='"+ IntToStr(CurLevel) +"'";
Table1->Filtered=True;
k=0;
if(Table1->FindFirst())
{
do
{
GetDataSign();
for(i=0;i<iQntDataSign;i++)
{
if(!DataForSign[2] || !DataForSign[0]) break;
if(CostPrb1[FindIndexValue(CostPrb0,LenCostPrb,DataForSign[0][i])])
{
MoveToProbability(DataForSign[2][i]);
GetDataPrb();
if(aPrbVal)
{
tmp=aPrbVal[FindMin(aPrbVal,iQntPrb)]*(1-CurMaxMinPrb[0][k]);
if(tmp!=0) tmp+=CurMaxMinPrb[0][k]*aPrbVal[FindMax(aPrbVal,iQntPrb)];
else tmp=1;//Чтобы предотваратить деление на себя самого и на ноль в знаменателе
CurMaxMinPrb[0][k]=(CurMaxMinPrb[0][k]*aPrbVal[FindMax(aPrbVal,iQntPrb)])/(tmp);
tmp=aPrbVal[FindMax(aPrbVal,iQntPrb)]*(1-CurMaxMinPrb[1][k]
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.