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

📄 fsa.cpp

📁 采用FORTRAN编制的小生境遗传算法反演程序
💻 CPP
字号:

/*           功能:模拟退火反演算法                      */
/*           文献:地球物理反演                          */
/*           作者:王家映教授                            */
/*           出版:高等教育出版社(第二版)                */
/*           编程:蒋龙聪                                */
/*           单位:中国地质大学(武汉)地球物理与空间信息  */
/*           专业:地球探测与信息技术                    */

#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<time.h>

/*           功能:模拟退火反演算法                      */
#define DS     0.99
#define ERRO   0.50
#define Lambda 6
#define LayerN 4
#define H      5
#define MarkT  10
#define MinT   0.001
#define POINTS 1001
#define SF     0.5

void   SA(double,double);
double ranD(void);
double obfun(double[]);
double OBS[POINTS];
double Temperature;
FILE * SATXT;

double ranD(void)
{
	double ranD=0.0;
	ranD=(rand()%5000)/5000.0;
//	ranD=0.1+(0.6-0.2)*ranD;
	return(ranD);
	
}

double obfun(double x[])
{
	double g[POINTS],b[201],r[POINTS];//定义数组
	double dt=0.5,f0=60;  //数组赋值
	double t[3];//时间
	double v[4];
	double SUM=0.0;
    int mx=1;  
    int i=0,j=0,nw=100;
    double h[3]={50,20,50};   


	v[0]=x[0];
	
	v[1]=x[1];
	
	v[2]=x[2];

	v[3]=x[3];
   
	
	//初始化反射系数数组		  
	for(i=0;i<POINTS;i++)
		r[i]=0.0;

	t[0]=2*h[0]/v[0];
	j=(int)(1000*t[0]/dt);
	r[j]=(v[1]-v[0])/(v[1]+v[0]);

	
	for(i=1;i<MarkT;i++)
	{
		t[i]=t[i-1]+2*h[i]/v[i];
		j=(int)(1000*t[i]/dt);
		r[j]=(v[i+1]-v[i])/(v[i+1]+v[i]);
	}	

	//求取子波
	for(i=-nw;i<nw+1;i++)
	{
		double a=(0.001*3.1415926*f0*i*dt);
        b[i+nw]=100.0*(1.0-2.0*a*a)*exp(-a*a);
        
	}

	
	//Convolution
	for(i=0;i<POINTS;i++)//从第一道循环
	{
		double sum=0.0;
	    for(j=-nw;j<nw+1;j++)
		{
			if(i-j>=0&&i-j<POINTS)
		    sum=sum+b[j+nw]*r[i-j];
		}
		g[i]=sum;
		
	}

	for(i=0;i<POINTS;i++)
		SUM+=sqrt((OBS[i]-g[i])*(OBS[i]-g[i]));
	
	return(SUM);

}

/*采用保留局部最优解方式*/
void SA(double lbounds[],double ubounds[])
{
	int MaxGen=0;
	int Gen=0;
	int Counter=0;
	int i=0,j=0,k=0;
	double R=0.0;
	double E0=0.0;
	double E1=0.0;
	double DeltaE=0.0;
	double P=0.0;
	double T=0.0;
	double Val=0.0;
	double BestVal=0.0;
	double Local[LayerN];
	double Global[LayerN];
	double CurSol[LayerN];
	double NexSol[LayerN];
	
	T=Temperature;
	MaxGen=(int)(log(MinT/Temperature)/log(DS)+0.5);
	MaxGen=MaxGen;

	//第一步:随机选择初始值

	for(i=0;i<(LayerN);i++)
	{
		CurSol[i]=(ubounds[i])*ranD();
//		cout<<CurSol[i];
	}
	
/*
  	for(i=0;i<LayerN;i++)
	{
		CurSol[i]=500+i*200;
	}
*/
	//初始化局部变量和全局变量值
	for(i=0;i<(LayerN);i++)
	{
		Local[i]=CurSol[i];
		Global[i]=CurSol[i];
	}

	//第二步:在某一温度下,对当前模型进行扰动,得到新的模型值NextSol
	while(T>MinT)
	{
		
		Gen++;
		for(i=0;i<MarkT;i++)
		{
			
			Counter++;
			R=Gen/(2*MaxGen);

			if( (int) ( ranD()+0.5 )==0 )
			{
				for(i=0;i<LayerN;i++)
					NexSol[i]=CurSol[i]+(ubounds[i]-CurSol[i])*( pow( ranD()*(1.0-R),Lambda) );
			}
			else
			{
				for(i=0;i<LayerN;i++)
					NexSol[i]=CurSol[i]-(CurSol[i]-lbounds[i])*( pow( ranD()*(1.0-R),Lambda) );

			}

/*
			if( (int) ( ranD()+0.5 )==0 )
			{
				for(i=0;i<LayerN;i++)
					NexSol[i]=CurSol[i]+(ubounds[i]-lbounds[i])*( pow( ranD()*(1.0-R),Lambda) );
			}
			else
			{
				for(i=0;i<LayerN;i++)
					NexSol[i]=CurSol[i]-(ubounds[i]-lbounds[i])*( pow( ranD()*(1.0-R),Lambda) );
			}
*/		
			//判断是否为全局最优解
			if(obfun(NexSol)<obfun(Global))
			{
				for(i=0;i<(LayerN);i++)
				{
					Local[i]=Global[i];
					Global[i]=NexSol[i];
				}
			}

			E1=obfun(NexSol);
			E0=obfun(CurSol);
			DeltaE=E1-E0;
			P=exp(-DeltaE/T);
			P=pow((1-H*P*E1/(E0*E0)),1/H);
		//	cout<<"DeltaE"<<DeltaE<<endl;
			if(DeltaE<0)
			{
				for(i=0;i<(LayerN);i++)
					CurSol[i]=NexSol[i];
			}
			//else if//( exp(-DeltaE/T)<ranD() )
			else if(P<ranD())
			{
				for(i=0;i<(LayerN);i++)
					CurSol[i]=NexSol[i];
			}

			Val=obfun(NexSol);
			BestVal=obfun(Global);
			fprintf(SATXT,"%10.6f   %10.6f",Val,BestVal);
			

			/*               把最优解输出到文件中去           */
			if(Val<=ERRO||BestVal<=ERRO)
			{
				printf("寻找解得次数为:%5d\n",Counter);
/*				
				if ((salog = fopen("galog.txt","w"))==NULL)
				{
					exit(1);
				}
*/
				fprintf(SATXT,"\n\n");
				for(i=0;i<(LayerN);i++)
					fprintf(SATXT," %10.7f   ",Global[i]);
//				fclose(salog);
				printf("Sucess\n");
				exit(0);
			}
			//第三步:降低温度
			T=T*DS;
		//	simulated(BestVal);
//			cout<<" T= "<<T<<"  Val= "<<Val<<"  BestVal= "<<BestVal<<" Counter= "<<Counter <<endl;
		}
//		simulated(BestVal);
	}


}

void main(void)
{	
	int i=0,j=0,k=0;
	double tim=0.0,E1=0,E0=0,DeltaE=0;
	double amptitude=0.0;
	double Time[POINTS];
	double CurSol[LayerN],NexSol[LayerN];
	double lbound[LayerN]={1000,800,1000,1000};
	double ubound[LayerN]={3000,1500,3000,3000};

	srand((unsigned int)time(NULL));
/*           从文件中读取数据                      */

	FILE *INFILE;

	if ((INFILE = fopen("result.txt","r"))==NULL)
	{
		printf("打开的文件不存在,请调试!\n");
		exit(1);
	}
	for (i=0; i<POINTS; i++)
	{
		fscanf(INFILE, "%lf",&amptitude);
        fscanf(INFILE, "%lf",&tim);
		Time[i]=tim;
		OBS[i]=amptitude;	
	}
	for (i=0; i<POINTS; i++)
		printf("F=%f  Data=%f\n",Time[i],OBS[i]);
	
	fclose(INFILE);

	SATXT=fopen("simulate.txt","w");
/*           确定初始温度值                      */	
	for(i=0;i<(LayerN);i++)
	{
		CurSol[i]=(ubound[i])*ranD();
		fprintf(SATXT,"  %10.7f   ",CurSol[i]);
	}

//	fprintf(salog," \n   ");

	for(i=0;i<LayerN;i++)
	{
		NexSol[i]=CurSol[i]+(2*ranD()-1)*SF;
	}

	E1=obfun(NexSol);
	E0=obfun(CurSol);
	DeltaE=E1-E0;
	Temperature=-DeltaE/log(0.995);
	printf("初始温度为:%f\n",Temperature);

	SA(lbound,ubound);
   
	fclose(SATXT);
	


}

⌨️ 快捷键说明

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