⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fuzzydlg.cpp

📁 利用人工智能的模糊算法,实现了一个模糊控制的温控系统
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	  w=fenzi/fenmu;

	  //画出求出来的这个点
	 // CClientDC dc(this);
	 // CRect   rc;   
      //GetDlgItem(IDC_EDIT1)->GetWindowRect(&rc);   
      //ScreenToClient(&rc);   
     // CDC dc;


	  //@E=k*w,这是自己定义的一个关系,实际应用中有确定的公式
	  
	  //这里还应该恢复PB PS ZO NS NB的值
	  //再写个函数吧,呵呵
	  
	  
}


//看temp对应NB[]等数组中,比temp大的赋给temp的值,比temp小的不变
void CFuzzyDlg::mWmin(int Rule,double Temp)
{
    int i;

    int rule;
	double	temp;
	rule=Rule;
	temp=Temp;

	//规则表中,对应此时的E和@E对应的为NB
    if(rule==4)  
	{
		for(i=0;i<9;i++)
		{
		   if(NB[i]>temp) NB[i]=temp;  //现在NB中存的就是m8(w)
		}
		NB_TF=true;
	}

	//规则表中,对应此时的E和@E对应的为NS
	if(rule==3)
	{
	  for(i=0;i<9;i++)
		 {
		   if(NS[i]>temp) NS[i]=temp;  //现在NB中存的就是m8(w)
		}
          NS_TF=true;
	}

   //规则表中,对应此时的E和@E对应的为ZO
    if(rule==2)
	{
	  for(i=0;i<9;i++)
		 {
		   if(ZO[i]>temp) ZO[i]=temp;  //现在NB中存的就是m8(w)
		}
            ZO_TF=true;
	}
	//规则表中,对应此时的E和@E对应的为PS
	if(rule==1)
	{
	  for(i=0;i<9;i++)
		 {
		   if(PS[i]>temp) PS[i]=temp;  //现在NB中存的就是m8(w)
		}

             PS_TF=true;
	}
	
	//规则表中,对应此时的E和@E对应的为PB
	if(rule==0)
	{
	  for(i=0;i<9;i++)
		 {
		   if(PB[i]>temp) PB[i]=temp;  //现在NB中存的就是m8(w)
		}
        PB_TF=true;
	}


}

void CFuzzyDlg::mWmax()
{
	int i;

   //double pb[9];
   //double ps[9];
   //double zo[9];
   //double ns[9];
  // double nb[9];

   //int result[9];//这是最后的那个,可以对它积分的
  // for(i=0;i<9;i++)
  // {
  //    pb[i]=pb_result[i];
  //    ps[i]=ps_result[i];
  //    zo[i]=zo_result[i];
  //    ns[i]=ns_result[i];
  //    nb[i]=nb_result[i];
  // }
   

   //参数调用的有问题!!!
   for(i=0;i<9;i++)
	   result[i]=maxi(i);
}

double CFuzzyDlg::maxi(int i)
{
  //求5个数中的最大的那个,返回去
	double a[5];
	double k;
	int j;

	//double pb[9],ps[9],zo[9],ns[9],nb[9];
	int index;
	index=i;

   //double PB_Result[9];
   //double PS_Result[9];
   //double ZO_Result[9];
   //double NS_Result[9];
   //double NB_Result[9];


//	for(j=0;j<9;j++)
   //{
   //   pb[j]=pb_result[j];
   //   ps[j]=ps_result[j];
   //   zo[j]=zo_result[j];
   //   ns[j]=ns_result[j];
   //   nb[j]=nb_result[j];
  // }

	a[0]=PB_Result[index];
	a[1]=PS_Result[index];
	a[2]=ZO_Result[index];
	a[3]=NS_Result[index];
	a[4]=NB_Result[index];
	k=a[0];

	for(j=0;j<5;j++)
	{
	   if(k<a[j])  k=a[j];
		   
	}
    return k;
}



//为积分做好准备,把一个9大小的数组分割为一个400大小的数组,这个数组为积分时使用的
void CFuzzyDlg::PreIntegral(double Result[])
{
  int i;
  int j;

  double result[9];
  
  for(i=0;i<9;i++)
	  result[i]=Result[i];
  
  i=0;
  //得先把result数组分割,准备分割为450份,相当于一个对应50份
  for(i=0;i<8;i++)
  {
     if((result[i+1]==result[i])&&(result[i]==0))   //这是一条直线
	 {
	     for(j=i*50;j<(i+1)*50;j++)
		       ReSult[j]=0;
	 }
	 if((result[i+1]==result[i])&&(result[i]!=0)) //这是一条直线
	 {
	     for(j=i*50;j<(i+1)*50;j++)
		       ReSult[j]=result[i];
	 }
	 if(result[i+1]>result[i])
	 {
	     for(j=i*50;j<(i+1)*50;j++)  //是一个斜率为1的直线
			 ReSult[j]=result[i]+0.01*(j-i*50);
	 }
	 if(result[i+1]<result[i])
	 {
	    for(j=i*50;j<(i+1)*50;j++)  //是一个斜率为-1的直线
			 ReSult[j]=result[i]+(-0.01)*(j-i*50);
	 }


  }//至此,RESULT数组就好了,呵呵
 // return ReSult;
}

double CFuzzyDlg::FenmuIntegral(double *y, double begin, double end, int n)
{
  double *func;
  func=y;

  double   l_d_step=(end-begin)/n;   
  double   l_d_integral=0;   
  for(int   i=0;i<n;i++)   
  {   
  l_d_integral+=func[i];   
  }   
  l_d_integral-=(func[0]+func[n]);   
  return   l_d_integral*l_d_step;   
}


double CFuzzyDlg::FenziIntegral(double *y, double begin, double end, int n)
{
	int i;
	double func[400];
	for(i=0;i<400;i++)
		func[i]=y[i];
 // double *func;
  //func=y;
  //这边界值可能有问题
  for(i=0;i<n;i++)
	  func[i]=func[i]*(-4+0.02*i);


  

  double   l_d_step=(end-begin)/n;   
  double   l_d_integral=0;   
  for(i=0;i<n;i++)   
  {   
  l_d_integral+=func[i];   
  }   
  l_d_integral-=(func[0]+func[n]);   
  return   l_d_integral*l_d_step;   
}


void CFuzzyDlg::OnFuzzy() 
{
	int i;
	double t;
	i=0;
	t=0;
	// TODO: Add your control notification handler code here
	GetDlgItemText(IDC_EDIT2,strT);
	T=atoi((char*)(LPCTSTR)strT);

    preT=T;
	t=T;

	GetDlgItemText(IDC_EDIT3,strtargetT);
	targetT=atoi((char*)(LPCTSTR)strtargetT);

	E=T-targetT;
	Changerate_E=0;//默认值设为零,看看行不行
    
    HuaZuoBiao(t);
   //当E @E小于某个特定的小的值,就停止

	//
   while(((E>0.8)||(E<-0.8))||((Changerate_E>0.5)||(Changerate_E<-0.5)))  //直到E,@E都为0,则停止,条件不对
	//while((E<1)&&(E>0))
	{
	   comLiShuDu_E();//算好E的隶属度数组
       comLiShuDu_Changerate_E(); //算好@E的隶属度数组

	   reasoning();
	   HuiFu();//所有的公有的该恢复的恢复

       //Changerate_E大,则温度降低的快,但是循环第二次的时候无法算它的隶属度!!
	   Changerate_E=Changerate_E+0.2*w;

	   preT=T;
	   T+=Changerate_E;
	   E=T-targetT;
	   //超出edit框的话,就停止
	   if((120-T)>120)  break;


       drawline(70+2*(preT-targetT),5+i,70+2*(T-targetT),20+i);
	  // drawline(preT,50+i,T,150+i);
	   i+=10;
	   

	}



}

void CFuzzyDlg::HuaZuoBiao(double T)
{
// 我在对话框中创建了两个按扭button1,     button2       (都是默认尺寸)   
          //打算在button1上画个矩形,如下代码,但发现   
          //矩形画在了按扭的外面。为什么?         
      CWnd*  p=GetDlgItem(IDC_EDIT1);   
      CDC*  c=p->GetDC();   
      p->Invalidate();   
      p->UpdateWindow();   
      //c->SelectStockObject(BLACK_BRUSH);   
      //c->Rectangle(50,30,80,50); 
      //CRect rc;
	 // p->GetClientRect(&rc);
	 //CBrush brush;
	  //brush.CreateSolidBrush(RGB(255,255,255));
     // c->SelectObject(&brush);
    

	  //横坐标
	  c->MoveTo(5,70);
	  c->LineTo(250,70);

	  //纵坐标
	  c->MoveTo(5,0);
	  c->LineTo(5,140);
      p->ReleaseDC(c);   
    
          
}

//(x1,t1)  (x2,t2)
/*void CGuoxu1Dlg::drawline(float t1,int x1, float t2,int x2)
{
CClientDC dc(this);
CPen pen(PS_SOLID,1,RGB(0,0,255));
CPen * pOldPen=dc.SelectObject(&pen);
dc.MoveTo(x1,(int)t1);
dc.LineTo(x2,(int)t2);
dc.SelectObject(pOldPen);
} */

void CFuzzyDlg::HuiFu()
{
	int i;

   	PB[0]=0;                        //-4
	PB[1]=0;						//-3
	PB[2]=0;						//-2
	PB[3]=0;						//-1
	PB[4]=0;						//0
	PB[5]=0;						//1
	PB[6]=0;						//2
	PB[7]=0.5;						//3
	PB[8]=1;						//4
	//PS
	PS[0]=0;                        //-4
	PS[1]=0;						//-3
	PS[2]=0;						//-2
	PS[3]=0;						//-1
	PS[4]=0;						//0
	PS[5]=0.5;						//1
	PS[6]=1;						//2
	PS[7]=0.5;						//3
	PS[8]=0;						//4
	//ZO
	ZO[0]=0;                        //-4
	ZO[1]=0;						//-3
	ZO[2]=0;						//-2
	ZO[3]=0.5;						//-1
	ZO[4]=1;						//0
	ZO[5]=0.5;						//1
	ZO[6]=0;						//2
	ZO[7]=0;						//3
	ZO[8]=0;						//4
	//NS
	NS[0]=0;                        //-4
	NS[1]=0.5;						//-3
	NS[2]=1;						//-2
	NS[3]=0.5;						//-1
	NS[4]=0;						//0
	NS[5]=0;						//1
	NS[6]=0;						//2
	NS[7]=0;						//3
	NS[8]=0;						//4
	//NB
	NB[0]=1;                        //-4
	NB[1]=0.5;						//-3
	NB[2]=0;						//-2
	NB[3]=0;						//-1
	NB[4]=0;						//0
	NB[5]=0;						//1
	NB[6]=0;						//2
	NB[7]=0;						//3
	NB[8]=0;						//4

	for(i=0;i<9;i++)
	{
	   PB_Result[i]=0;
	   PS_Result[i]=0;
	   ZO_Result[i]=0;
	   NS_Result[i]=0;
	   NB_Result[i]=0;
	}

    PB_TF=false;
	PS_TF=false;
	ZO_TF=false; 
	NS_TF=false;
	NB_TF=false;

	//初始化为0 
	//E @E对 PB PS ZO NS NB的隶属度
	LiShuDu_E[0]=0;
	LiShuDu_E[1]=0;
	LiShuDu_E[2]=0;
	LiShuDu_E[3]=0;
	LiShuDu_E[4]=0;
	LiShuDu_Changerate_E[0]=0;
	LiShuDu_Changerate_E[1]=0;
	LiShuDu_Changerate_E[2]=0;
	LiShuDu_Changerate_E[3]=0;
	LiShuDu_Changerate_E[4]=0;

	
	 for(i=0;i<9;i++)
	  {
	     result[i]=0;
	  }

	
	  RESULT=NULL;

}

void CFuzzyDlg::drawline(float t1,int x1, float t2,int x2)
{
      CWnd*  p=GetDlgItem(IDC_EDIT1);   
      CDC*  c=p->GetDC();   
      //p->Invalidate();   
     // p->UpdateWindow();     

    //CClientDC dc(this);
    CPen pen(0,1,RGB(0,0,255));//0:PS_SOLID
    CPen * pOldPen=c->SelectObject(&pen);
    c->MoveTo(x1,(int)t1);
    c->LineTo(x2,(int)t2);
    c->SelectObject(pOldPen);
	pen.DeleteObject();

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -