进击的小白Day023——遗传算法(五)(完结)

代码能够正常运行,得到结果接近最优解,之后进行代码优化。
进化代数为1000,在979代取得最优解。
在这里插入图片描述

贴代码:

#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <math.h>
#include <time.h>
#define PI 3.1415926
#define BOUND_DOWN 0
#define BOUND_UP (0.9 * PI)
#define POP_SIZE 50
#define CHROM_LEN 5
#define EVO_NUM 1000
#define CROSS_PROBABILITY 0.6
#define VARY_PROBABILITY 0.1

typedef struct best
{
	int num;
	float funcVal;
	float bestChrom[CHROM_LEN];
}Best;

/*目标函数值*/
float objFuncVal(float *a)
{
	float x[5];
	float f = 0;
	memset(x, 0, sizeof(x));
	x[0] = *a;
	x[1] = *(a + 1);
	x[2] = *(a + 2);
	x[3] = *(a + 3);
	x[4] = *(a + 4);
	f = -5 * sin(x[0])*sin(x[1])*sin(x[2])*sin(x[3])*sin(x[4]) -
		sin(5 * x[0])*sin(5 * x[1])*sin(5 * x[2])*sin(5 * x[3])*sin(5 * x[4]) + 8;
	return f;
}

/*初始化*/
void creat(float chrom[POP_SIZE][CHROM_LEN])
{
	int i = 0, j = 0;	
	for (i = 0; i < POP_SIZE; i++)
	{
		for (j = 0; j < CHROM_LEN; j++)
		{
			chrom[i][j] = BOUND_UP * ((float)rand() / RAND_MAX);
		}
	}
}

/*计算适应度*/
float fit(float *a)
{
	float funcVal = 0, fitness = 0;
	funcVal = objFuncVal(a);
	fitness = 1 / funcVal;
	return fitness;
}

/*计算选择概率和累积概率*/
void fitnessP(float *fitness, float *chooseP, float *accuP)
{
	float fitnessSum = 0;
	int i = 0;
	for (i = 0; i < POP_SIZE; i++)
	{
		fitnessSum += *(fitness + i);
	}
	for (i = 0; i < POP_SIZE; i++)
	{
		*(chooseP + i) = (*(fitness + i)) / fitnessSum;
		if (i == 0)
		{
			*accuP = *chooseP;
		}
		else
		{
			*(accuP + i) = *(accuP + (i - 1)) + *(chooseP + i);
		}
	}
}

/*选择,轮盘赌*/
void roulette(float *accuP, float chrom[POP_SIZE][CHROM_LEN])
{
	float m = 0;
	float tmp[POP_SIZE][CHROM_LEN];
	int i = 0, j = 0, k = 0;
	for (i = 0; i < POP_SIZE; i++)
	{
		memset(tmp[i], 0, sizeof(tmp[i]));
	}
	for (i = 0; i < POP_SIZE; i++)  //控制进行i次轮盘赌
	{
		m = ((float)rand()) / RAND_MAX;
		if (m <= *accuP)
		{
			for (k = 0; k < CHROM_LEN; k++)
			{
				tmp[i][k] = chrom[0][k];
			}
		}
		else
		{
			for (j = 0; j < POP_SIZE; j++)  //控制轮盘赌后的比较
			{
				if (m >= *(accuP + j) && m < *(accuP + (j + 1)))
				{
					for (k = 0; k < CHROM_LEN; k++)
					{
						tmp[i][k] = chrom[j + 1][k];
					}
				}
			}
		}
	}
	for (i = 0; i < POP_SIZE; i++)
	{
		for (j = 0; j < CHROM_LEN; j++)
		{
			chrom[i][j] = tmp[i][j];
		}
	}
}

/*交叉*/
void cross(float chrom[POP_SIZE][CHROM_LEN])
{
	float b = 0, tmp_1, tmp_2, p = 0;
	int pick_1 = 0, pick_2 = 0, i = 0, j = 0, flag = 0, hh = 0;
	for (i = 0; i < POP_SIZE; i++)
	{
		p = ((float)rand()) / RAND_MAX;
		if (p > CROSS_PROBABILITY)
		{
			continue;
		}
		pick_1 = rand() % POP_SIZE;
		pick_2 = rand() % POP_SIZE;
		j = rand() % CHROM_LEN;
		
		while (flag == 0)
		{
			b = ((float)rand()) / RAND_MAX;
			tmp_1 = chrom[pick_1][j] * (1 - b) + chrom[pick_2][j] * b;
			tmp_2 = chrom[pick_2][j] * (1 - b) + chrom[pick_1][j] * b;
			chrom[pick_1][j] = tmp_1;
			chrom[pick_2][j] = tmp_2;
			if (chrom[pick_1][j] <= BOUND_UP && chrom[pick_1][j] >= BOUND_DOWN && chrom[pick_2][j] <= BOUND_UP && chrom[pick_2][j] >= BOUND_DOWN)
			{
				flag = 1;
			}
		}
	}
}

/*变异*/
void vary(float chrom[POP_SIZE][CHROM_LEN])
{
	float r_1 = 0, r_2 = 0, ff = 0, p = 0;
	int i = 0, j = 0;
	for (i = 0; i < POP_SIZE; i++)
	{
		p = ((float)rand()) / RAND_MAX;
		if (p > VARY_PROBABILITY)
		{
			continue;
		}
		r_1 = ((float)rand()) / RAND_MAX;
		r_2 = ((float)rand()) / RAND_MAX;
		j = rand() % CHROM_LEN;
		ff = r_2 * pow(1 - ((float)i / EVO_NUM), 2);
		if (r_1 >= 0.5)
		{
			chrom[i][j] = chrom[i][j] - (chrom[i][j] - BOUND_UP) * ff;
		}
		else
		{
			chrom[i][j] = chrom[i][j] + (BOUND_DOWN - chrom[i][j]) * ff;
		}
	}
}

void testPrint(float chrom[POP_SIZE][CHROM_LEN])
{
	int a = 0, b = 0;
	for (a = 0; a < POP_SIZE; a++)
	{
		for (b = 0; b < CHROM_LEN; b++)
		{
			printf("chrom[%d][%d]=%f  ", a, b, chrom[a][b]);
		}
		printf("\n");
	}
	printf("\n");
}

void main(void)
{
	float chrom[POP_SIZE][CHROM_LEN];
	float fitness[POP_SIZE], chooseP[POP_SIZE], accuP[POP_SIZE], funcVal[POP_SIZE];
	int i = 0, j = 0, a = 0, b = 0, h = 0, x = 0, y = 0;
	Best best;

	best.num = 0;
	best.funcVal = 10;
	memset(best.bestChrom, 0, sizeof(best.bestChrom));

	for (i = 0; i < POP_SIZE; i++)
	{
		memset(chrom[i], 0, sizeof(chrom[i]));
	}
	memset(fitness, 0, sizeof(fitness));
	memset(chooseP, 0, sizeof(chooseP));
	memset(accuP, 0, sizeof(accuP));
	memset(funcVal, 0, sizeof(funcVal));

	srand(time(NULL));

	creat(chrom);

	for (i = 0; i < EVO_NUM; i++)
	{
		h++;
		for (j = 0; j < POP_SIZE; j++)
		{
			fitness[j] = fit(chrom[j]);
			funcVal[j] = objFuncVal(chrom[j]);
		}

		fitnessP(fitness, chooseP, accuP);

		roulette(accuP, chrom);

		cross(chrom);

		vary(chrom);
		
		for (x = 0; x < POP_SIZE; x++)
		{
			if (best.funcVal > funcVal[x])
			{
				best.funcVal = funcVal[x];
				for (y = 0; y < CHROM_LEN; y++)
				{
					best.bestChrom[y] = chrom[x][y];
				}
				best.num = i;
			}
		}
	}

	printf("在第%d代产生最优解\n最优值为%f\n最优解为[%f, %f, %f, %f, %f]",
		best.num, best.funcVal, best.bestChrom[0], best.bestChrom[1], best.bestChrom[2], best.bestChrom[3], best.bestChrom[4]);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值