请问如何实现MPI并行粒子群算法?该怎么改?

/*
取得最大值
*/
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<time.h>
#include<mpi.h>
#define c1 1.49445 //加速度因子一般是根据大量实验所得
#define c2 1.49445
#define maxgen 2000 // 迭代次数
#define sizepop 800 // 种群规模
#define popmax 10 // 个体最大取值
#define popmin -10 // 个体最小取值
#define Vmax 0.5 // 速度最大值
#define Vmin -0.5 //速度最小值
#define dim 10 // 粒子的维数

double pop[sizepop][dim]; // 定义种群数组
double V[sizepop][dim]; // 定义种群速度数组
double fitness[sizepop]; // 定义种群的适应度数组
double result[maxgen]; //定义存放每次迭代种群最优值的数组
double pbest[sizepop][dim]; // 个体极值的位置
double gbest[dim]; //群体极值的位置
double fitnesspbest[sizepop]; //个体极值适应度的值
double fitnessgbest; // 群体极值适应度值
double genbest[maxgen][dim]; //每一代最优值取值粒子

						 //适应度函数

double func(double * arr, int n)
{
double fitness = 0;
for (int i = 0; i < n; i++)
{
fitness += arr[i] * arr[i];
}
return fitness;

}

// 种群初始化
void pop_init(void)
{
for (int i = 0; i < sizepop; i++)
{
for (int j = 0; j < dim; j++)
{
pop[i][j] = (((double)rand()) / RAND_MAX - 0.5) * 4; //-2到2之间的随机数
V[i][j] = ((double)rand()) / RAND_MAX - 0.5; //-0.5到0.5之间
}
fitness[i] = func(pop[i], dim); //计算适应度函数值
}
}
// max()函数定义
double * max(double * fit, int size)
{
int index = 0; // 初始化序号
double max = fit; // 初始化最大值为数组第一个元素
static double best_fit_index[2];
for (int i = 1; i < size; i++)
{
if (
(fit + i) < max)
{
max = *(fit + i);
index = i;
}
}
best_fit_index[0] = index;
best_fit_index[1] = max;
return best_fit_index;

}
// 迭代寻优
void PSO_func(void)
{
pop_init();
double * best_fit_index; // 用于存放群体极值和其位置(序号)
best_fit_index = max(fitness, sizepop); //求群体极值
int index = (int)(*best_fit_index);
// 群体极值位置
for (int i = 0; i < dim; i++)
{
gbest[i] = pop[index][i];
}
// 个体极值位置
for (int i = 0; i < sizepop; i++)
{
for (int j = 0; j < dim; j++)
{
pbest[i][j] = pop[i][j];
}
}
// 个体极值适应度值
for (int i = 0; i < sizepop; i++)
{
fitnesspbest[i] = fitness[i];
}
//群体极值适应度值
double bestfitness = *(best_fit_index + 1);
fitnessgbest = bestfitness;

//迭代寻优
for (int i = 0; i < maxgen; i++)
{
	for (int j = 0; j < sizepop; j++)
	{
		//速度更新及粒子更新
		for (int k = 0; k < dim; k++)
		{
			// 速度更新
			double rand1 = (double)rand() / RAND_MAX; //0到1之间的随机数
			double rand2 = (double)rand() / RAND_MAX;
			V[j][k] = V[j][k] + c1 * rand1*(pbest[j][k] - pop[j][k]) + c2 * rand2*(gbest[k] - pop[j][k]);
			if (V[j][k] > Vmax)
				V[j][k] = Vmax;
			if (V[j][k] < Vmin)
				V[j][k] = Vmin;
			// 粒子更新
			pop[j][k] = pop[j][k] + V[j][k];
			if (pop[j][k] > popmax)
				pop[j][k] = popmax;
			if (pop[j][k] < popmin)
				pop[j][k] = popmin;
		}
		fitness[j] = func(pop[j], dim); //新粒子的适应度值
	}
	for (int j = 0; j < sizepop; j++)
	{
		// 个体极值更新
		if (fitness[j] < fitnesspbest[j])
		{
			for (int k = 0; k < dim; k++)
			{
				pbest[j][k] = pop[j][k];
			}
			fitnesspbest[j] = fitness[j];
		}
		// 群体极值更新
		if (fitness[j] < fitnessgbest)
		{
			for (int k = 0; k < dim; k++)
				gbest[k] = pop[j][k];
			fitnessgbest = fitness[j];
		}
	}
	for (int k = 0; k < dim; k++)
	{
		genbest[i][k] = gbest[k]; // 每一代最优值取值粒子位置记录
	}
	result[i] = fitnessgbest; // 每代的最优值记录到数组
}

}

// 主函数
int main(int argc,char**argv)
{
srand((unsigned)time(NULL));
int j,m;
double* buf3 = NULL;
int* buf4 = NULL;
int my_rank, comm_sz;
double * best_arr;
int best_gen_number;
double best;
clock_t start, finish; //程序开始和结束时间
srand((unsigned)time(NULL)); // 初始化随机数种子
pop_init();
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
MPI_Comm_size(MPI_COMM_WORLD, &comm_sz);
start = clock();
srand((unsigned)time(NULL));
if (my_rank = 0) {
buf3 = (double*)malloc(comm_sz * sizeof(double));
buf4 = (int*)malloc(comm_sz * sizeof(int));
}
MPI_Barrier(MPI_COMM_WORLD);
for (m = 0; m < 10; m++) {
PSO_func();
MPI_Gather(&fitnessgbest, 1, MPI_DOUBLE, buf3, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
if (my_rank == 0) {
fitnessgbest = buf3[0];
for (int i = 0; i < comm_sz; i++)
{
if (buf3[i] < fitnessgbest) {
j = i;
}
}
}
}
MPI_Bcast(&j, 1, MPI_INT, 0, MPI_COMM_WORLD);
MPI_Bcast(gbest, dim, MPI_DOUBLE, j, MPI_COMM_WORLD);
MPI_Finalize();
best_arr = max(result, maxgen);
best_gen_number = *best_arr;
best = *(best_arr + 1);
printf(“迭代了%d次,在第%d次取到最优值,最优值为:%lf.\n”, maxgen, best_gen_number + 1, best);
printf(“取到最优值的位置为(%lf,%lf).\n”, genbest[best_gen_number][0], genbest[best_gen_number][1]);
finish = clock(); //结束时间
double duration = (double)(finish - start) / CLOCKS_PER_SEC; // 程序运行时间
printf(“程序运行耗时:%lf\n”, duration);
system(“pause”);
return 0;
}

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值