/*在输入文件中,按以下格式输入
n1 n2 n3
n1为调压发电机数
n2为变比可调变压器数
n3为投切电容器组数
site lbound ubound step
位置 下限 上限 步长
site:变压器填其编号
发电机和电容器填其所连节点号
按发电机、变压器、电容器顺序填写。
*/
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<time.h>
#define POPSIZE 40 //种群规模
#define MAXGENS 100 //最大繁殖代数
#define NVARS 50 //所需处理的变量数(一般不超过50,在此可以固定为50)
#define PC1 0.9 //最大交叉概率
#define PC2 0.8 //最小交叉概率
#define PM1 0.1 //最大变异概率
#define PM2 0.05 //最小变异概率
extern double PowerFlow();
extern void read_data();
extern void outputPowerFlow();
extern double ph,error_max;
char FILENAME[50];
char FILENAME1[50];
int generation; //当前繁殖代数
int cur_best; //最佳个体
int seed;
double *gav,*gak,*gaq;
double fmax,favg;
int *gagene,*gatran,*gacap;
int num_gagene,num_gatran,num_gacap;
int site;
int FLAG2;
double k1,k2;
FILE *galog; //输出文件
struct genotype
{
double gene[NVARS]; //变量
double fitness; //适应值
double upper[NVARS]; //变量上限
double lower[NVARS]; //变量下限
double step[NVARS]; //变化步长
double rfitness; //相对适应值
double cfitness; //之前适应值之和
};
struct genotype population[POPSIZE+ 1];
struct genotype newpopulation[POPSIZE+ 1];
struct genotype savepopulation[MAXGENS];
int *newSpaceInt(int);
double *newSpaceDouble(int);
void initialize(void);
double randval(double,double,double);
void randpopulation(int,int);
void evaluate(void);
void keep_the_best(void);
void elitist(void);
void select(void);
void crossover(void);
void Xover(int,int);
void swap(double* ,double* );
void mutate(void);
void report(void);
void bubble(int);
double compare(int ,int);
int *newSpaceInt(int n1)
{
int i;
int *a=(int *)calloc(n1,sizeof(int));
if(a==NULL) { printf("\nno memory in a"); exit(0); }
for(i=0;i<n1;i++)
a[i]=0;
return a;
}
double *newSpaceDouble(int n1)
{
int i;
double *a=(double *)calloc(n1,sizeof(double));
if(a==NULL) { printf("\nno memory in a"); exit(0); }
for(i=0;i<n1;i++)
a[i]=0.0;
return a;
}
void bubble(int num)//冒泡排序(大数在后)
{
int i,j;
struct genotype temp;
for(j=0;j<num-1;j++)
{
for(i=0;i<num-1-j;i++)
{
if(population[i].fitness >population[i+1].fitness )
{
temp=population[i];
population[i]=population[i+1];
population[i+1] =temp;
}
}
}
}
void randpopulation(int num1,int num2)//随机产生新个体
{
int i,j;
for (i = 0; i< num_gagene+num_gatran+num_gacap; i++)
for( j = num1; j < num2; j++)
population[j].gene[i] = randval(population[j].lower[i], population[j].upper[i],population[j].step[i]);
}
void initialize(void)//初始化
{
FILE *fin;
int i,j,k,n;
//int *gagene,*gatran,*gacap;
double lbound, ubound,step;
if ((fin = fopen(FILENAME1, "r")) ==NULL)
{
printf("打开遗传算法数据文件出错!");
exit(1);
}
if ((galog = fopen("遗传算法进化结果.dat","w"))==NULL)
{
printf("生成遗传算法结果文件出错!");
exit(1);
}
/* initialize variables within the bounds */
fscanf(fin, "%d %d %d",&num_gagene,&num_gatran,&num_gacap);
gagene=newSpaceInt(num_gagene);
gatran=newSpaceInt(num_gatran);
gacap=newSpaceInt(num_gacap);
for (i = 0; i< num_gagene+num_gatran+num_gacap; i++)
{
fscanf(fin, "%d %lf %lf %lf",&site,&ubound,&lbound,&step);
//printf("\n%lf",step);
if(i>=0&&i<num_gagene)
gagene[i]=site;
if(i>=num_gagene&&i<num_gagene+num_gatran)
gatran[i-num_gagene]=site;
if(i>=num_gagene+num_gatran&&i<num_gagene+num_gatran+num_gacap)
gacap[i-num_gagene-num_gatran]=site;
for( j = 0; j < POPSIZE; j++)
{
population[j].fitness = 0;
population[j].rfitness = 0;
population[j].cfitness = 0;
population[j].lower[i] =lbound;
population[j].upper[i] =ubound;
population[j].step[i] =step;
population[j].gene[i] = randval(population[j].lower[i], population[j].upper[i],population[j].step[i]);
//printf("%d %d %lf ",j,i,population[j].gene[i]);
}
}
n=POPSIZE/2;//竞争选择初始群体
k=0;
do
{
evaluate();
bubble(POPSIZE);
for(i=k;i<k+n;i++)
savepopulation[i]=population[i+n-k];
randpopulation(0,POPSIZE);
k+=n;
}while(k<POPSIZE);
for(i=0;i<POPSIZE;i++)
population[i]=savepopulation[i];
fclose(fin);
}
/**********************************************************************/
/* Random value generator: Generates a value within bounds */
/**********************************************************************/
double randval(double low, double high ,double step)//随机产生新个体
{
double val;
val = rand()%(int)((high-low)/step+1)*step+low;
return(val);
}
/********************************************************************/
/* Evaluation function: This takes a user defined function. */
/* Each time this is changed, the code has to be recompiled. */
/*The current function is: x[l]^2-x[1]*x[2]+x[3] */
/********************************************************************/
void evaluate(void)//适应度评估
{
int mem;
int i;
k1=exp(generation);
// k1=200000;
k2=k1;
gav=newSpaceDouble(num_gagene);
gak=newSpaceDouble(num_gatran);
gaq=newSpaceDouble(num_gacap);
for (mem = 0; mem < POPSIZE; mem++)
{
for (i = 0; i < num_gagene+num_gatran+num_gacap; i++)
{
if(i>=0&&i<num_gagene) gav[i]=population[mem].gene[i];
if(i>=num_gagene&&i<num_gagene+num_gatran) gak[i-num_gagene]=population[mem].gene[i];
if(i>=num_gagene+num_gatran&&i<num_gagene+num_gatran+num_gacap) gaq[i-num_gagene-num_gatran]=population[mem].gene[i];
}
population[mem].fitness=1.0/PowerFlow();
}
free(gav);
free(gak);
free(gaq);
favg=0;
for (mem = 0; mem <POPSIZE; mem++)
favg += population[mem].fitness;
favg/=POPSIZE;
bubble(POPSIZE);
fmax=population[POPSIZE-1].fitness;
}
void keep_the_best()//选择最优个体
{
int i;
for(i = 0; i<num_gagene+num_gatran+num_gacap; i++)
population[POPSIZE].gene[i] = population[POPSIZE-1].gene[i];
population[POPSIZE].fitness = fmax;
}
void elitist()//最优个体替换
{
int i,k;
static int j=1;
savepopulation[j].fitness=population[POPSIZE].fitness;
if(j>1&&savepopulation[j].fitness==savepopulation[j-1].fitness)
{
for( k = 1; k <=POPSIZE/5; k++)
{
for(i=0;i<num_gagene+num_gatran+num_gacap;i++)
population[k].gene[i] = randval(population[k].lower[i], population[k].upper[i],population[k].step[i]);
}
}
j++;
if(fmax>=population[POPSIZE].fitness)
{
for(i=0;i<num_gagene+num_gatran+num_gacap;i++)
{
population[0].gene[i] = population[POPSIZE].gene[i];
population[POPSIZE].gene[i]=population[POPSIZE-1].gene[i];
}
population[0].fitness = population[POPSIZE].fitness;
population[POPSIZE].fitness= fmax;
}
else
{
for(i=0;i<num_gagene+num_gatran+num_gacap;i++)
population[0].gene[i] = population[POPSIZE].gene[i];
population[0].fitness = population[POPSIZE].fitness;
}
}
void select(void)//选择
{
int i;
for(i=0;i<POPSIZE;i++)
{
int mem1,mem2;
mem1=rand()%POPSIZE;
mem2=rand()%POPSIZE;
if(population[mem