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

📄 cc1.cpp

📁 炉温模糊控制的一般性程序
💻 CPP
字号:
#include <iostream.h>
#include <fstream.h>
#include <stdlib.h>
#include <math.h>

#define FASMNUM 5//模糊子集数
#define CTLAIM 30//设定值
#define ERROR 0xFF





//#define qtnlevnum 9

//database
int qtnlevnum;//量化等级数
int poutnum=200;//输出点数

double m_e[][15]={{-30,-5,-1,-0.6,0,0.6,1,5,30},{-30,-22.5,-15,-7.5,0,7.5,15,22.5,30},{-30,-15,-10,-3,-1.5,-0.8,-0.5,0,0.5,0.8,1.5,3,10,15,30}};
double m_de[][15]={{-8,-6,-5,-1,0,1,5,6,8},{-14,-10.5,-7,-3.5,0,3.5,7,10.5,14},{-35,-30,-25,-18,-12,-8,-5,0,5,8,12,18,25,30,35}};
double m_v[][15]={{-80,-60,-40,-35,0,35,40,60,80},{-140,-105,-70,-35,0,35,70,105,140},{-200,-140,-90,-60,-45,-35,-30,0,30,35,45,60,90,140,200}};


//规则隶属度函数
double m_fasm[][FASMNUM][15]={{{0,0,0,0,0,0,0,0.35,1},{0,0,0,0,0,0.4,1,0.4,0},{0,0,0,0.2,1,0.2,0,0,0},{0,0.4,1,0.4,0,0,0,0,0},{1,0.35,0,0,0,0,0,0,0}},
{{0,0,0,0,0,0,0,0.35,1},{0,0,0,0,0,0.4,1,0.4,0},{0,0,0,0.2,1,0.2,0,0,0},{0,0.4,1,0.4,0,0,0,0,0},{1,0.35,0,0,0,0,0,0,0}},
{{0,0,0,0,0,0,0,0,0,0,0,0,0.3,0.5,1},{0,0,0,0,0,0,0,0,0,0.3,0.6,1,0.6,0.3,0},{0,0,0,0,0,0.2,0.8,1,0.8,0.2,0,0,0,0,0},{0,0.3,0.6,1,0.6,0.3,0,0,0,0,0,0,0,0,0},{1,0.8,0.3,0,0,0,0,0,0,0,0,0,0,0,0}}};

double data_e[15];
double data_de[15];
double data_v[15];
double data_fasm[FASMNUM][15];

//规则库
int data_rule[FASMNUM][FASMNUM]={4,4,4,3,0,
								4,3,3,2,0,
								4,3,2,1,0,
								4,2,1,1,0,
								4,1,0,0,0};

//控制表
int data_fclist[15][15];



//根据选择设定操作数据
void numset(int mode)
{
	int i;

	if (mode==0 || mode==1)
	{
		qtnlevnum=9;
	}
	else if (mode==2)
	{
		qtnlevnum=15;
	}


	for (i=0;i<qtnlevnum;i++)
	{
		data_e[i]=m_e[mode][i];
		data_de[i]=m_de[mode][i];
		data_v[i]=m_v[mode][i];
		data_fasm[0][i]=m_fasm[mode][0][i];
		data_fasm[1][i]=m_fasm[mode][1][i];
		data_fasm[2][i]=m_fasm[mode][2][i];
		data_fasm[3][i]=m_fasm[mode][3][i];
		data_fasm[4][i]=m_fasm[mode][4][i];
	}
}



//设置数据输出点数
void ponset()
{
	int i;
	char j[2];

		while (1)
		{
			cout<<"\n\n\n\t设置数据输出点数\n\n\tnumber :"<<poutnum<<"\tmodify to (1-600) : ";
			cin>>i;
			if (cin.rdstate())
			{
				char cj[255];
				cin.clear();
				cin.getline(cj,255);
				cout<<"\n\n\n\tinput error !!!\n\n";
				continue;
			}
			if (i<=0)
			{
				cout<<"\n\n\tSet error !!! It has to over 0 . Set it again :  ";
				continue;
			}
			else if (i>600)
			{
				cin.get();
				cout<<"\n\n\t数据量太多 !!!\n\t有可能会花较长时间\n\t而且曲线有可不能画完整 .\n\t确定? (Y/N)? ";
				cin.getline(j,2);
				cout<<"\n\n\n";
				if ((j[0]=='y' || j[0]=='Y') && j[1]==NULL)
					break;
				else
				{
					continue;
				}
			}
			else
				break;
		}
		poutnum=i;


}

//获取数据在对应表中的量化等级
int qtnlevget(double data_var,double data_base[])
{
	int i;

	if (data_var==0) return(0);
	else if (data_var<0)
	{
		//量化等级四舍五入
		for (i=-(int(qtnlevnum/2));i<=0;i++)
		{
			if (data_var<=(data_base[int(qtnlevnum/2)+1+i]+data_base[int(qtnlevnum/2)+i])/2) return(i);
		}
	}

	else
	{
		for (i=int(qtnlevnum/2);i>=0;i--)
		{
			if (data_var>(data_base[int(qtnlevnum/2)-1+i]+data_base[int(qtnlevnum/2)+i])/2) return(i);
		}
	}

	return(ERROR);
}

//取数列中非0最小值
double getmin(double a[])
{
	int i;
	double p=1;
	for (i=0;i<qtnlevnum;i++)
	{
		if (a[i]>0 && p>a[i])
		{
			p=a[i];
		}
	}
	return(p);
}

//取数列中最大值
double getmax(double a[])
{
	int i;
	double p=0;
	for (i=0;i<qtnlevnum;i++)
	{
		if (a[i]>p)
		{
			p=a[i];
		}
	}
	return(p);
}



//根据极大极小法获取当前规则下的隶属度函数
void rulefitcomplex(int ql_e,int ql_de,double a[])
{
	int i,j,l;
	double p;

	for (i=0;i<FASMNUM;i++)
	{
		if (data_fasm[i][ql_e+int(qtnlevnum/2)]>0)
		{
			for (j=0;j<FASMNUM;j++)
			{
				if (data_fasm[j][ql_de+int(qtnlevnum/2)]>0)
				{
					p=getmin(data_fasm[i])<getmax(data_fasm[j])?getmin(data_fasm[i]):getmax(data_fasm[j]);
					for (l=0;l<qtnlevnum;l++)
					{
						if (a[l]<data_fasm[data_rule[j][i]][l] && a[l]<p)
						{
							a[l]=(data_fasm[data_rule[j][i]][l]<p?data_fasm[data_rule[j][i]][l]:p);
						}
					}
				}
			}
		}
	}
	return;
}

//生成控制表
void fclistpdt()
{
	int i,j,m;
	double rulecomplex[15];
	double p,q;

	for (i=0;i<qtnlevnum;i++)
	{
		for (j=0;j<qtnlevnum;j++)
		{
			for (m=0;m<qtnlevnum;m++)
			{
				rulecomplex[m]=0;
			}
			rulefitcomplex(i-int(qtnlevnum/2),j-int(qtnlevnum/2),rulecomplex);
			p=0;q=0;
			//重心法计算量化等级
			for (m=0;m<qtnlevnum;m++)
			{
				p+=rulecomplex[m]*(m-int(qtnlevnum/2));
				q+=rulecomplex[m];
			}
			p=p/q;
			if (p>0)
			{
				p+=0.5;
			}
			else if (p<0)
			{
				p-=0.5;
			}
			//填充控制表
			data_fclist[i][j]=int(p);
		}
	}
	return;
}





void main()
{
	int i,m,n;
	double ctl_e,ctl_de,ctl_v,ctl_y,ctl_sum=0;


	cout<<"\t\t智能控制第一次实验\n\t\t\t\t\t 08001429\n\t\t\t\t\t  吴炜杰\n\t\t\t\t\t2004.12.15\n\n\n";
	while (1)
	{
		ctl_e=0,ctl_de=0,ctl_v=0,ctl_y=0;//初始化变量
		
		//显示提示,获取选择
		do
		{
			cout<<"主选单\n\n1. 输出第一组数据(非线性、9个量化等级)\n2. 输出第二组数据(线性、9个量化等级)\n3. 输出第三组数据(非线性、15个量化等级)\n4. 设置数据输出点数\n0. 退出\n";
			cin>>i;
			if (cin.rdstate())
			{
				char cj[255];
				cin.clear();
				cin.getline(cj,255);
				cout<<"\ninput error !!!\n\n\n\n";
				continue;
			}
			if (i<0 || i>4)
			{
				cout<<"\n\ninvailable choose !!!\n\n";
				continue;
			}
			else
				break;

		}while (1);
		if (i==0)
			exit(0);
		//根据选择设定数值
		if (i==4)
		{
			ponset();
			continue;
		}
		else
			numset(i-1);
		
		//生成控制表
		fclistpdt();


		//打开输出文件
		ofstream outfile("dataout.txt");//完整数据文件
		ofstream outfiler("dataoutr.txt");//控制表文件
		ofstream outfile1("drawdatay.txt");//画y曲线数据文件
		ofstream outfile2("drawdatav.txt");//画v曲线数据文件

		if (!outfile || !outfile1 || !outfile2)
		{
			cout<<"Can't open the file(s)\n";
			exit(1);
		}


		//输出控制表
		int j;
		for (i=0;i<qtnlevnum;i++)
		{
			for (j=0;j<qtnlevnum;j++)
			{
				outfiler<<data_fclist[i][j]<<'\t';
			}
			outfiler<<'\n';
		}
		outfiler.close();




		outfile<<"t\te\tde\tv\ty\tgradeget\n";
		outfile1<<poutnum<<'\t'<<CTLAIM<<endl;
		outfile2<<poutnum<<endl;
		for (i=0;i<poutnum;i++)
		{
			if (ctl_e!=0) ctl_de=((ctl_y-CTLAIM)-ctl_e);
			else ctl_de=0;
			ctl_e=ctl_y-CTLAIM;
			m=int(qtnlevnum/2)+qtnlevget(ctl_e,data_e);
			n=int(qtnlevnum/2)+qtnlevget(ctl_de,data_de);
			ctl_v=data_v[int(qtnlevnum/2)+data_fclist[m][n]];

			outfile<<i*0.5<<'\t'<<ctl_e<<'\t'<<ctl_de<<'\t'<<ctl_v<<'\t'<<ctl_y<<'\n';
			outfile1<<i*0.5<<'\t'<<ctl_y<<'\n';
			outfile2<<i*0.5<<'\t'<<ctl_v<<'\n';

			ctl_y=exp(-0.05)*ctl_y+(1-exp(-0.05))*ctl_v;
			ctl_sum+=ctl_y;
		}
		ctl_sum=ctl_sum/poutnum;
		outfile<<"\t\t\taverage y\t"<<ctl_sum<<endl;
		outfile1<<ctl_sum<<endl;
		outfile.close();
		outfile1.close();
		outfile2.close();

		cout<<"\n数据已生成 ...\n使用 \"vdraw.exe\" and \"ydraw.exe\" 查看曲线\n或再次选择选项生成其它数据\n\n\n";
	}
}

⌨️ 快捷键说明

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