📄 guzhangdingwei.cpp
字号:
#include <stdio.h>
#include<stdlib.h>
#include <iostream.h>
#include<time.h>
#include<math.h>
#include <memory.h>
#define POPSIZE 500
#define maximization 1
#define minimization 2
#define cmax 10000
#define cmin 0
#define length1 10
#define length2 10
#define chromlength 15 //染色体长度
#define K 1 // 交叉系数
#define N 9
#define PI 3.1415926
#define E 0.00001
int functionmode=minimization;
int popsize; //种群大小
int maxgeneration; //最大遗传代数
int Mmax; // 最优个体最小保存代数
int OptCnt; // 直接遗传个体数
double pm; //变异率
double pc; //交叉率
char *gFTU = NULL; // FTU 上传故障信息
char gIS[chromlength]; // 开关函数值缓存
struct individual
{
char chrom[chromlength];
double value;
int fitness; //适应度
short mCnt; // 直接遗传代数
};
int best_index;
int worst_index;
struct individual bestindividual; //最佳个体
struct individual worstindividual; //最差个体
struct individual currentbest;
struct individual population[POPSIZE];
//函数声明
void generatenextpopulation();//生成下一代
void calculatefitnessvalue();//计算适应度
void findbestandworstindividual();//求最佳个体和最差个体
void performevolution();//演示评价结果
void selectoperator();//比例选择算法
void crossoveroperator();//交叉算法
void mutationoperator();//变异操作
void input();//数据输入
float GetPc(short mCnt)
{
float temp = 1.0f * mCnt / Mmax;
if( temp <= 0.5 )
return 0.5;
else if ( temp < 0.9 )
return temp*K;
else
return 0.9f;
}
float GetPm(short mCnt)
{
float temp = 0.5f * (float)exp(10*(1.0f*mCnt/Mmax-1));
if( temp <= 0.01)
return 0.01f;
else
return temp;
}
void generateinitialpopulation( ) //种群初始化
{
srand( (unsigned)time(NULL) );
int i, j;
for ( i = chromlength; i < popsize; i++)
{
memset(population[i].chrom, 0, chromlength*sizeof(char));
for (j = 0; j < chromlength; j ++)
population[i].chrom[j] = rand() % 2;
}
for ( i = 0; i < chromlength; i++)
{
memset(population[i].chrom, 0, chromlength*sizeof(char));
population[i].chrom[i] = 1;
}
}
int FitnessValue(int i)
{
int sum = 0, sum1 = 0;
memset(gIS, 0, sizeof(char)*chromlength);
for(int j = chromlength - 1; j >= 0; j --) {
if(population[i].chrom[j])
break;
}
for( int k = 0; k <= j; k ++)
gIS[k] = 1;
for(j = 0; j < chromlength; j ++) {
sum += abs(gFTU[j] - gIS[j]);
sum1 += population[i].chrom[j];
}
sum += abs(1-sum1);
return sum;
}
void generatenextpopulation() //生成下一代
{
selectoperator();//选择运算
crossoveroperator();//交叉运算
mutationoperator();//变异运算
for( int i = OptCnt; i < popsize; i++ )
population[i].mCnt = 0;
}
void calculatefitnessvalue()//计算适应度
{
int i, k;
for(i=0;i<popsize;i++)
{
population[i].fitness = 100 - FitnessValue(i);
// printf("%3d : %3d : %3d : ", i+1,population[i].mCnt,population[i].fitness);
// for (k=0;k<chromlength;k++)
// printf("%d",population[i].chrom[k]);
// printf("\t");
}
int index = 0;
struct individual tempIndi;
for(i = 0; i < OptCnt; i++) { // 只需找出前OptCnt个最大值即可
index = i; // 假设第i+1个个体适应度最大
for(int j = i+1; j < popsize; j++) {
if ( population[index].fitness < population[j].fitness )
index = j;
}
// 把最大适应度个体放在前面
if(i != index) {
tempIndi = population[i];
population[i] = population[index];
population[index] = tempIndi;
}
population[i].mCnt += 1; // 直接遗传代数加 1
printf("%3d : %3d : %3d : ", i+1,population[i].mCnt,population[i].fitness);
for (k=0;k<chromlength;k++)
printf("%d",population[i].chrom[k]);
printf("\t");
}
printf("\n");
}
void selectoperator() //比例选择算法
{
int i,j,k;
double sum=0.0;
srand( (unsigned)time(NULL) );
struct individual newpopulation[POPSIZE];
for(i=0;i<popsize-OptCnt;i++)
{
j = rand()%popsize;
k = rand()%popsize;
if(population[j].fitness < population[k].fitness)
newpopulation[i] = population[j];
else
newpopulation[i] = population[k];
}
for(i=OptCnt;i<popsize; i++)
population[i]=newpopulation[i-OptCnt];
}
void crossoveroperator() //交叉算法
{
int i,j;
int index[POPSIZE];
int point,temp;
double p;
char ch;
srand( (unsigned)time(NULL) );
for (i=OptCnt;i<popsize;i++)
{
index[i]=i;
}
for (i=OptCnt;i<popsize;i++) // 随机选择要交叉的数组下标
{
point=rand()%(popsize-i)+i;
temp=index[i];
index[i]=index[point];
index[point]=temp;
}
for (i=OptCnt;i<popsize-1;i+=2)
{
p=rand()%1000/1000.0;
pc = GetPc( population[index[i]].mCnt > population[index[i+1]].mCnt ? population[index[i]].mCnt : population[index[i+1]].mCnt );
if (p<pc)
{
point=rand() % chromlength;
for (j = point; j < chromlength; j++)
{
ch = population[index[i]].chrom[j];
population[index[i]].chrom[j] = population[index[i+1]].chrom[j];
population[index[i+1]].chrom[j] = ch;
}
}
}
}
void mutationoperator() //变异操作
{
short i, point;
double p;
for(i=OptCnt;i<popsize;i++)
{
p=rand()%1000/1000.0;
if (p<GetPm(i))
{
point=rand() % chromlength;
population[i].chrom[point] = population[i].chrom[point] == 0 ? 1 : 0;
}
}
}
void input() //数据输入
{
printf("初始化全局变量:\n");
printf("种群大小(50-500):");
scanf("%d", &popsize);
if((popsize%2) != 0)
{
printf( "种群大小已设置为偶数\n");
popsize++;
};
printf("最优个体最小保留代数(20-50):");
scanf("%d", &Mmax);
printf("最优个体遗传数:",popsize/2);
scanf("%d", &OptCnt);
memset(gFTU, 0, sizeof(char)*chromlength);
printf("请输入%d个FTU上传开关信息:1-过流,0-正常\n",chromlength);
char cFTU[chromlength*2];
scanf("%s",cFTU);
for (int i = 0; i < chromlength; i ++) {
// getchar(&cFTU[i]);
if (cFTU[i] != '0' && cFTU[i] != '1')
gFTU[i] = 0;
else
gFTU[i] = cFTU[i] - '0';
}
printf("\n");
//
// popsize = 500;
// OptCnt = 30;
// Mmax = 30;
}
void main() //主函数
{
int i, k = 1;;
char uc[chromlength] = { 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0};
gFTU = uc;
srand( (unsigned)time(NULL) );
// 初始化直接遗传代数
input();
for( i = 0; i < popsize; i++ )
population[i].mCnt = 0;
generateinitialpopulation();
calculatefitnessvalue();
int j = -1;
while(j < 0 )
{
generatenextpopulation();
calculatefitnessvalue();
k++;
for(i = 0; i < OptCnt; i ++) {
if (population[i].mCnt >= Mmax) {
j = i;
break;
}
}
}
printf("迭代次数%d\n", k);
printf("\n");
int maxfitness = population[0].fitness;
printf("FTU上传开关信息:");
for (i=0;i<chromlength;i++)
printf("%d",gFTU[i]);
printf("\n");
j = 0;
do {
printf("染色体编码: ");
for (i=0;i<chromlength;i++) {
if (population[j].chrom[i])
k = i + 1;
printf("%d",population[j].chrom[i]);
}
printf("\t第 %d 条可能的故障支路为 %d, 适应度为: %d\n", j + 1, k, population[j].fitness);
j ++;
} while(population[j].fitness == maxfitness);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -