📄 temperature.h
字号:
/* 本程序是人工智能的作业,模拟一个用模糊原理控制的温控系统
作者:杨建国(20401598)
时间:2004.10.28
*/
#ifndef _TEMPERATURE_H
#define _TEMPERATURE_H
#include <stdio.h>
#include "mymath.h"
#define NB 0 //负的大
#define NS 1 //负的小
#define ZO 2 //零
#define PS 3 //正的小
#define PB 4 //正的大
float NextUN0(float * a,int start,int len) //返回浮点数组中下一个不为0的数
{
int i;
for(i=start+1;i<len;i++)
{
if(a[i]<=-0.0001f&&a[i]>=0.0001f)
return a[i];
}
return 0.0f;
}
float GetWup(float * b,float a,float * alpha,int alphaLen)
{
int i=0;
float x1,x2,x3,x4; //梯形斜线与直线的交点
//int end=0,start=0,end1=0;
float *end=new float[alphaLen]; //两个状态相交的点
float nstart;
float s;
float pl,pr;
float bi;
for(i=0;i<alphaLen-1;i++)
{
if(alpha[i]>=-0.0001f&&alpha[i]<=0.0001f)
{
end[i]=b[i%(alphaLen/2)];
}
else if(alpha[i+1]>=-0.0001f&&alpha[i+1]<=0.0001f)
{
end[i]=b[i%(alphaLen/2)+1];
}
else
{
x1=a+b[i%(alphaLen/2)]-a*alpha[i];
x2=a*alpha[i+1]+b[(i+1)%(alphaLen/2)]-a;
x3=a+b[i%(alphaLen/2)]-a*alpha[i+1];
x4=a*alpha[i]+b[(i+1)%(alphaLen/2)]-a;
if((x2<=((b[i%(alphaLen/2)]+b[(i+1)%(alphaLen/2)])/2))&&(x1>=((b[i%(alphaLen/2)]+b[(i+1)%(alphaLen/2)])/2))) end[i]=(b[i%(alphaLen/2)]+b[(i+1)%(alphaLen/2)])/2;
else end[i]=alpha[i]>alpha[i+1]?x3:x4;
}
}
for(i=0,s=0;i<alphaLen-1;i++)
{
if(i==0||i==5) nstart=b[0];
else nstart=end[i-1];
bi=b[i%(alphaLen/2)];
pl=a*alpha[i]-a+bi;
pr=a+bi-a*alpha[i];
if(alpha[i]!=0)
{
if(pl>nstart)
{
s+=(bi*bi-pl*pl)*alpha[i]/2;
s+=pl*pl*pl/3/a+(1-bi/a)*pl*pl/2-(nstart*nstart*nstart/3/a+(1-bi/a)*nstart*nstart/2);
}
else
{
s+=(bi*bi-nstart*nstart)*alpha[i]/2;
}
if(pr<end[i])
{
s+=(pr*pr-bi*bi)*alpha[i]/2;
s+=(1+bi/a)*end[i]*end[i]/2-end[i]*end[i]*end[i]/a/3-((1+bi/a)*pr*pr/2-pr*pr*pr/a/3);
}
else
{
s+=(end[i]*end[i]-bi*bi)*alpha[i]/2;
}
}
}
delete []end;
return s;
}
float GetWdown(float * b,float a,float * alpha,int alphaLen)
{
int i=0;
float x1,x2,x3,x4; //梯形斜线与直线的交点
//int end=0,start=0,end1=0;
float *end=new float[alphaLen]; //两个状态相交的点
float nstart;
float s;
float pl,pr;
float bi;
for(i=0;i<alphaLen-1;i++)
{
if(alpha[i]>=-0.0001f&&alpha[i]<=0.0001f)
{
end[i]=b[i%(alphaLen/2)];
}
else if(alpha[i+1]>=-0.0001f&&alpha[i+1]<=0.0001f)
{
end[i]=b[i%(alphaLen/2)+1];
}
else
{
x1=a+b[i%(alphaLen/2)]-a*alpha[i];
x2=a*alpha[i+1]+b[(i+1)%(alphaLen/2)]-a;
x3=a+b[i%(alphaLen/2)]-a*alpha[i+1];
x4=a*alpha[i]+b[(i+1)%(alphaLen/2)]-a;
if((x2<=((b[i%(alphaLen/2)]+b[(i+1)%(alphaLen/2)])/2))&&(x1>=((b[i%(alphaLen/2)]+b[(i+1)%(alphaLen/2)])/2))) end[i]=(b[i%(alphaLen/2)]+b[(i+1)%(alphaLen/2)])/2;
else end[i]=alpha[i]>alpha[i+1]?x3:x4;
}
}
for(i=0,s=0;i<alphaLen-1;i++)
{
if(i==0||i==5) nstart=b[0];
else nstart=end[i-1];
bi=b[i%(alphaLen/2)];
pl=a*alpha[i]-a+bi;
pr=a+bi-a*alpha[i];
if(alpha[i]!=0)
{
if(pl>nstart)
{
s+=(bi-pl)*alpha[i];
s+=pl*pl/2/a+(1-bi/a)*pl-(nstart*nstart/2/a+(1-bi/a)*nstart);
}
else
{
s+=(bi-nstart)*alpha[i];
}
if(pr<end[i])
{
s+=(pr-bi)*alpha[i];
s+=(1+bi/a)*end[i]-end[i]*end[i]/a/2-((1+bi/a)*pr-pr*pr/a/2);
}
else
{
s+=(end[i]-bi)*alpha[i];
}
}
}
delete []end;
return s;
}
/* 函数: GetW(float curTemper,float desTemper,float curDE,float * b,float a)
返回: 获得温度的修正值
参数:
float curTemper 当前的温度值
float desTemper 目标温度值
float curDE 当前温度变化率
float b 各模糊状态隶属函数为1时的温度确切值
float a 模糊范围大小,如(-2~2)时为2
*/
float GetW(float curTemper,float desTemper,float curDE,float * b,float a)
{
float m[5]; //存放当前温度与目标温度的差对各个模糊状态的隶属度
float dm[5]; //存放当前温度变化率对各个模糊状态的隶属度
float alpha[10]; //存放用到的规则的权重,
//{(ZO,NB),(ZO,NS),(ZO,ZO),(ZO,PS),(ZO,PB),(NB,ZO),(NS,ZO),(ZO,ZO),(PS,ZO),(PB,ZO)}
float mw[2]; //存放于规则相关的W的隶属度
int estat[6]; //当前温度差属于哪几个状态,首位为状态数
int destat[6]; //当前温度变化率属于那几个状态,首位为状态数
int ruleNum; //用到的规则数目
int i=0,j=0,k=0;
float e; //温度差
float t;
e=curTemper-desTemper;
if(e<b[0]) e=b[0];
if(e>b[4]) e=b[4];
for(i=0;i<5;i++) //初始化
{
m[i]=0.0f;
dm[i]=0.0f;
estat[i]=2;
destat[i]=2;
if(i<2)
{
mw[i]=0.0f;
}
}
estat[0]=0;
destat[0]=0;
for(i=0;i<10;i++)
alpha[i]=0.0f;
for(i=0,j=0,k=0;i<5;i++)
{
//算出当前温度差对各个状态的隶属度并存入相应的m数组中
t=(a-Fabs(e-b[i]))/a;
if(t>=0.001f)
{
m[i]=t;
if(j<5)
{
estat[j+1]=i;
j++;
}
}
else
m[i]=0.0f;
estat[0]=j;
//算出当前温度变化率对各个状态的隶属度并存入相应的m数组中
t=(a-Fabs(curDE-b[i]))/a;
if(t>=0.001f)
{
dm[i]=t;
if(k<5)
{
destat[k+1]=i;
k++;
}
}
else
dm[i]=0.0f;
destat[0]=k;
}
//计算用到的规则数并申请能装下所有规则权重的数组
/*ruleNum=estat[0]*destat[0];
alpha=new float[ruleNum];*/
for(i=0;i<estat[0];i++) //算出用到规则的权重
for(j=0;j<destat[0];j++)
{
if(estat[i+1]==ZO||destat[j+1]==ZO) //至少有一个状态是ZO
alpha[estat[i+1]==ZO?4-destat[j+1]:(4-estat[i+1]+5)]=m[estat[i+1]]<dm[destat[j+1]]?m[estat[i+1]]:dm[destat[j+1]];
}
if(Fabs(alpha[2])<0.0001)
alpha[2]=alpha[7];
else
alpha[7]=alpha[2];
/*for(i=0;i<ruleNum;i++)
{
nstart
}*/
return GetWup(b,a,alpha,10)/GetWdown(b,a,alpha,10);
}
/*void main()
{
int i;
float b[5];
float a;
float curTemper,desTemper,curDe;
float r;
while(1)
{
printf("\nInput NB,NS,ZO,PS,PB:\n");
for(i=0;i<5;i++)
scanf("%f",&b[i]);
printf("\nInput a\n");
scanf("%f",&a);
printf("curTemper:");
scanf("%f",&curTemper);
printf("desTemper:");
scanf("%f",&desTemper);
printf("curDe:");
scanf("%f",&curDe);
r=GetW(curTemper,desTemper,curDe,b,a);
printf("resualt: w=%f",r);
}
}*/
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -