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

📄 temperature.h

📁 基于模糊原理的温度控制演示程序
💻 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 + -