@TangWill
2019-06-29T13:51:03.000000Z
字数 47280
阅读 903
cpp
目标函数优化问题可以描述为:
这里为搜索空间,为目标函数。(1)式描述的优化问题称为极大化问题,(2)式描述的称为极小化问题。
粒子群优化算法PSO(Particle Swarm Optimization)是一种基于群体的自适应的搜索优化方法。PSO 中,每个优化问题的潜在解都是搜索空间中的一只鸟,称之为粒子。所有的粒子都有一个由被优化的函数决定的适值( fitness value) ,每个粒子还有一个速度决定它们飞翔的方向和距离。然后粒子们就追随当前的最优粒子在解空间中搜索。
PSO初始化为一群随机粒子(随机解),然后通过迭代找到最优解。在每一次迭代中,粒子通过跟踪两个极值来更新自己;第一个就是粒子本身所找到的最优解,这个解称为个体极值;另一个极值是整个种群目前找到的最优解,这个极值是全局极值。另外也可以不用整个种群而只是用其中一部分作为粒子的邻居,那么在所有邻居中的极值就是局部极值。
假设在一个 维的目标搜索空间中,有 个粒子组成一个群落,其中第 个粒子表示为一个维的向量
第个粒子的“飞行”速度也是一个维的向量,记为
第个粒子迄今为止搜索到的最优位置称为个体极值,记为
整个粒子群迄今为止搜索到的最优位置为全局极值,记为
在找到这两个最优值时,粒子根据如下的公式(1.1)和( 1.2)来更新自己的速度和位置:
其中:和 为学习因子,也称加速常数(acceleration constant), 和 为[0,1]范围内的均匀随机数。式(3)右边由三部分组成,第一部分为“惯性(inertia)”或“动量(momentum)”部分,反映了粒子的运动“习惯(habit)”,代表粒子有维持自己先前速度的趋势;第二部分为“认知(cognition)”部分,反映了粒子对自身历史经验的记忆(memory)或回忆(remembrance),代表粒子有向自身历史最佳位置逼近的趋势;第三部分为“社会(social)”部分,反映了粒子间协同合作与知识共享的群体历史经验。
这部分内容主要是针对本文主要研究问题的类型确定粒子群算法具体实现过程和一些参数的选择。
算法流程框图
算法实现
算法的流程如下:
算法的构成要素
对于构成粒子群算法的各个参数进行设定。本算法中主要的参数变量为惯性权值 ,学习因子 , ,群体的大小 ,迭代次数 ,粒子维数 。
(1)群体大小
通常,群体太小则不能提供足够的采样点,以致算法性能很差,容易陷入局部最优;群体太大尽管可以增加优化信息,阻止早熟收敛的发生,但无疑会增加计算量,造成收敛时间太长,表现为收敛速度缓慢。本文对函数的优化选择种群规模为40000。
(2)最大迭代次数
迭代次数越多能保证解的收敛性,但是影响运算速度,本文对函数的优化选最大迭代次数为80次,利用大量的种群和较少的迭代次数,优化效果明显。
(3)惯性权值
惯性权重 表示在多大程度上保留原来的速度。 较大,全局收敛能力强,局部收敛能力弱; 较小,局部收敛能力强,全局收敛能力弱。
(4)学习因子
加速常数 和 分别用于控制粒子指向自身或邻域最佳位置的运动。建议 ,并通常取 。本文中取 。
(5)粒子维数
粒子维数取决于待优化函数的维数。
(6)粒子空间的初始化
较好的选择粒子初始化空间,将大大缩短收敛的时间。在本文中我们主要是选用随机对粒子进行初始化。
测试函数
| 编号 | 函数 | 取值范围 | 维度 |
|---|---|---|---|
| 10 | |||
| 10 | |||
| 10 | |||
| 10 | |||
| 10 | |||
| 10 | |||
| 10 | |||
| 10 | |||
| 10 | |||
| 10 | |||
| 10 | |||
| 10 | |||
| 10 | |||
| 2 | |||
| 4 |
class Particle
封装了单个粒子的类;
Particle.h
//// Created by tq on 2019/6/18.//#ifndef _PARTICLE_H_#define _PARTICLE_H_/*Particle:封装了单个粒子的类;该类的数据成员,包括粒子的:坐标维度:in_dims,坐标,适应值,位置上下限,速度上下限,惯性系数,全局速度因子,局部速度因子,速度上下限,速度范围因子,局部最优解,全局最优解,方法: 随机初始化、计算适应值、更新全局最优、更新局部最优*/class Particle {public:float *velocity; //速度float fitness; //粒子的适应值float *position; //粒子的坐标float fitness_pbest; //粒子的历史最优适应值float *position_pbest; //粒子的历史最优坐标float fitness_gbest; //粒子的全局最优适应值float *position_gbest; //粒子的全局最优坐标Particle(int dims, float *inmax, float *inmin, float *vmax, float *vmin, float _w, float _c1, float _c2,int _index); //Particle:构造函数void init();//init:随机初始化粒子的速度和位置void get_fitness();//get_fitness:计算当前坐标的适应值void init_pbest();//init_pbest:初始化历史最优void updata_pbest();//updata_pbest:更新历史最优void get_gbest(float *_in_gbest, float _fitness_gbest);//get_gbest: 更新全局最优void updata_v();//updata_v::更新速度void updata_in();//updata_in:更新坐标private:int index; //函数索引int dimension; //坐标维度float *position_max, *position_min; //位置上下限float *velocity_max, *velocity_min; //速度上下限float w, c1, c2; //惯性系数,局部速度因子、全局速度因子};#endif // _PARTICLE_H_
particle.cpp
//// Created by tq on 2019/6/18.//#include <iostream>#include<algorithm>#include"Particle.h"#include"funs.h"using namespace std;Particle::Particle(int dims, float *inmax, float *inmin, float *vmax, float *vmin, float _w, float _c1,float _c2, int _index) {index = _index;dimension = dims; //坐标维度fitness = 0.0; //粒子的适应值position = new float[dimension]; //粒子的坐标velocity = new float[dimension]; //速度fitness_pbest = 0.0; //粒子的历史最优适应值position_pbest = new float[dimension]; //粒子的历史最优坐标fitness_gbest = 0.0; //粒子的全局最优适应值position_gbest = new float[dimension]; //粒子的全局最优坐标position_max = inmax; //位置上限position_min = inmin; //位置下限velocity_max = vmax; //速度上限velocity_min = vmin; //速度下限w = _w; //惯性系数,c1 = _c1; //历史速度因子c2 = _c2; //全局速度因子}void Particle::init() { // 随机初始化坐标position = random_array(dimension, position_max, position_min);// 随机初始化速度velocity = random_array(dimension, velocity_max, velocity_min);}void Particle::get_fitness() {//计算适应值fitness = fitness_fun(position, index, dimension);}void Particle::init_pbest() {//将坐标值和适应值,直接拷贝copy_(position, position_pbest, dimension);fitness_pbest = fitness;}void Particle::updata_pbest() { //如果当前粒子的适应值大于历史最优值pbest,重新拷贝if (fitness <= fitness_pbest)copy_(position, position_pbest, dimension);fitness_pbest = fitness;}void Particle::get_gbest(float *_in_gbest, float _fitness_gbest) { //将传入的全局最优,赋值给当前粒子的全局最优//全局最优需要比较所有粒子的适应值,//所以先在外部对所有粒子进行比较。然后再传入。copy_(_in_gbest, position_gbest, dimension);fitness_gbest = _fitness_gbest;}void Particle::updata_v() {//根据如下公式更新速度//v=v*w + (pbestin-in)*c1 + (gbestin-in)*c2//速度不得超过上限、下限for (int i = 0; i < dimension; i++) {velocity[i] = velocity[i] * w + (position_pbest[i] - position[i]) * c1 + (position_gbest[i] - position[i]) * c2;if (velocity[i] > velocity_max[i]) { velocity[i] = velocity_max[i]; }if (velocity[i] < velocity_min[i]) { velocity[i] = velocity_min[i]; }}}void Particle::updata_in() {//更新位置。位置不得超过上限、下限for (int i = 0; i < dimension; i++) {position[i] = position[i] + velocity[i];if (position[i] > position_max[i]) { position[i] = position_max[i]; }if (position[i] < position_min[i]) { position[i] = position_min[i]; }}}
class Pso
标准粒子群算法
成员:多个Particle,速度因子、惯性因子等
Pso.h
//// Created by tq on 2019/6/18.//#ifndef _PSO_H_#define _PSO_H_#include "Particle.h"#include <vector>using namespace std;/*Pso类:标准粒子群算法成员:多个Particle,速度因子、惯性因子等*/class Pso {protected:int index;int swarm_amount; //粒子群数量int in_dim; //粒子坐标的维度float w, c1, c2;float *max_in;float *min_in;float *max_v;float *min_v;float *fitness_list;float v_scale = 0.1; //速度范围因子。建议0.05<v_scale<0.2float w_col = 1.0; // 惯性衰减因子,建议0.96<w_col<1.0float v_col = 1.0; //速度衰减因子,建议0.96<v_col<1.0vector<Particle> vector_pso; //存储所有粒子的容器public:float *in_gbest_final; //存放最终的最优坐标float fitness_gbest_final; //最优坐标对应的最优适应值Pso(int _swarm_amount, int dim, float _w, float *_max, float *_min, float v_scale_, int _index);//Pso:构造函数void set_w_col(float w_col); //set_w_col:设置惯性衰减因子void set_v_col(float v_col);//set_v_col:设置速度衰减因子void gbest(int flag);//gbest:计算全局最优gbestvoid initialize(); //initialize:初始化每个粒子的坐标值、速度、适应值、局部最优、全局最优、void update();//update:更新坐标值、速度、适应值、局部最优、全局最优、void pso_iteration(int circle_);//pso_iteration:循环迭代。circle_表示迭代次数};#endif // _PSO_H_
Pso.cpp
//// Created by tq on 2019/6/18.//#include <iostream>#include <stdlib.h>#include <vector>#include <time.h>#include<algorithm>#include "Pso.h"#include"funs.h"using namespace std;//构造函数:初始化参数Pso::Pso(int _swarm_amount, int dim, float _w, float *_max, float *_min, float v_scale_, int _index) {index = _index;in_dim = dim;in_gbest_final = new float[in_dim];swarm_amount = _swarm_amount;fitness_list = new float[swarm_amount];w = _w;c1 = (1 - w) / 2;c2 = (1 - w) / 2;min_in = new float[in_dim];max_in = new float[in_dim];min_v = new float[in_dim];max_v = new float[in_dim];max_in = _max;min_in = _min;v_scale = v_scale_;for (int i = 0; i < in_dim; i++) {max_v[i] = (_max[i] - _min[i]) * v_scale;min_v[i] = -(_max[i] - _min[i]) * v_scale;}}//设置惯性衰减系数void Pso::set_w_col(float w_col_) {w_col = w_col_;}//设置速度范围的衰减系数void Pso::set_v_col(float v_col_) {v_col = v_col_;}//更新粒子群的全局最优解gbestvoid Pso::gbest(int init_flag) {float *in_gbest_temp = new float[in_dim]; //存放每轮的最优粒子坐标float fitness_gbest_temp; //每一轮最优适应值get_min(swarm_amount, vector_pso, in_gbest_temp, &fitness_gbest_temp, in_dim);for (int i = 0; i < swarm_amount; i++) {//如果是处于第一轮迭代,或者fitness_gbest_temp优于粒子的gbest//将粒子的gbest替换为fitness_gbest_temp和in_gbest_tempif (init_flag == 0 || fitness_gbest_temp < vector_pso[i].fitness_gbest) {vector_pso[i].get_gbest(in_gbest_temp, fitness_gbest_temp);}}}//初始化粒子群的坐标、速度、历史最优、全局最优void Pso::initialize() {for (int i = 0; i < swarm_amount; i++) {Particle single(in_dim, max_in, min_in, max_v, min_v, w, c1, c2, index);single.init();single.get_fitness();single.init_pbest();vector_pso.push_back(single);}gbest(0);}//更新粒子群的速度、坐标、历史最优、全局最优void Pso::update() {if (w_col != 1.0) {w = w * w_col; //衰减wc1 = (1 - w) / 2; //增加c1c2 = (1 - w) / 2; //增加c2}if (v_col != 1.0) {v_scale = v_scale * v_col; //衰减v_scale}for (int i = 0; i < swarm_amount; i++) {vector_pso[i].updata_v();vector_pso[i].updata_in();vector_pso[i].get_fitness();vector_pso[i].updata_pbest();}gbest(1);}//初始化,并且反复进行circle_轮的迭代void Pso::pso_iteration(int circle_) {this->initialize();for (int i = 0; i < circle_; i++) {if (i % 5 == 0) {cout << i << "nd iteration ..." << endl;}this->update();}//get_final_gbest:计算最终的最优粒子get_final_gbest(swarm_amount, vector_pso, in_gbest_final, &fitness_gbest_final, in_dim);}
function
提供了适应度函数的计算等方法
functions.h
//// Created by tq on 2019/6/18.//#ifndef FUNS_H_#define FUNS_H_#include <vector>#include "Particle.h"using namespace std;//random_single:生成0-1的浮点数float random_single();//random_array:随机生成dims维度的数组float *random_array(int dims, float *max_, float *min_);//fitness_fun:生成适应值的函数float fitness_fun(float *x, int mode, int dimension);//copy_:数组 深拷贝void copy_(float src[], float dst[], int dims);//get_min:通过计算,得到适应值最小的粒子void get_min(int mount, vector<Particle> temp_pso, float *max_in, float *max_fit, int in_dims_);//get_final_gbest:通过计算,得到最终的最优解void get_final_gbest(int mount, vector<Particle> temp_pso, float *final_in, float *final_fit, int in_dims_);#endif // FUNS_H_
functions.cpp
//// Created by tq on 2019/6/18.//#include <iostream>#include <stdlib.h>#include <time.h>#include <vector>#include <math.h>#include "Particle.h"#include "functions.h"using namespace std;//生成随机数float random_single() {return ((float) (rand() % 1000)) / 1000.0;}//生成维度为dims的随机数组float *random_array(int dims, float *max_, float *min_) {float *temp = new float[dims];for (int i = 0; i < dims; i++) {float random_ = random_single();temp[i] = (max_[i] - min_[i]) * random_ + min_[i];}return temp;}//fitness_fun:适应度函数使用float fitness_fun(float *x, int index, int dimension) {float sum = 0;switch (index) {case 1: {for (auto i = 0; i < dimension; i++) {sum += pow(x[i], 2);}break;}case 2: {double temp = 1;for (auto i = 0; i < dimension; i++) {temp *= abs(x[i]);}for (auto i = 0; i < dimension; i++) {sum += abs(x[i]);}sum = sum + temp;break;}case 3: {double temp = 0;for (auto i = 0; i < dimension; i++) {for (auto j = 0; j < i; j++) {temp += x[i];}sum += pow(temp, 2);}break;}case 4: {sum = abs(x[0]);for (auto i = 1; i < dimension; i++) {if (abs(x[i]) > sum)sum = abs(x[i]);}break;}case 5: {sum = 10 * (100 * pow((x[1] - pow(x[0], 2)), 2) + pow(x[0] - 1, 2));break;}case 6: {for (auto i = 0; i < dimension; i++) {sum += pow(floor(x[i] + 0.5), 2);}break;}case 7: {for (auto i = 0; i < dimension; i++) {sum += ((i + 1) * pow(x[i], 4) + (rand() % (1 - 0)) + 0);}break;}case 8: {sum = 10 * (-x[0] * sin(sqrt(abs(x[0]))));break;}case 9: {sum = 10 * (pow(x[0], 2) - 10 * cos(2 * M_PI * x[0]) + 10);break;}case 10: {double e = 1.0;int n = 0;double u = 1.0;do {n++;u = u / n;e = e + u;} while (u >= 1.0E-6);float temp1 = 0, temp2 = 0;for (auto i = 0; i < dimension; i++) {temp1 += pow(x[i], 2);temp2 += cos(2 * M_PI * x[i]);}sum += (-20 * exp(-0.2 * sqrt(temp1 / dimension)) - exp(temp2 / dimension) + 20 + e);break;}case 11: {float temp1 = 0, temp2 = 1;for (auto i = 0; i < dimension; i++) {temp1 += pow(x[i], 2);temp2 *= cos(x[i] / sqrt(i + 1));}sum = temp1 / 4000 - temp2 + 1;break;}case 12: {float y[10] = {0};for (auto i = 0; i < dimension; i++) {y[i] = 1 + (x[i] + 1) / 4;}float temp = 0;for (auto i = 0; i < dimension - 1; i++) {temp += pow(y[i] - 1, 2) * (1 + 10 * pow(sin(M_PI * y[i + 1]), 2));}sum = (10 * pow(sin(M_PI * y[0]), 2) + temp + pow(y[dimension - 1], 2)) * M_PI / dimension;for (auto i = 0; i < dimension; i++) {sum +=(x[i] > 10 ? 100 * pow((x[i] - 10), 4) : x[i] < -10 ? 100 * pow((-x[i] - 10), 4): 0);}break;}case 13: {float temp = 0;for (auto i = 0; i < dimension; i++) {temp += pow(x[i] - 1, 2) * (1 + pow(sin(3 * M_PI * x[i]) + 1, 2));}sum = 0.1 * (pow(sin(3 * M_PI * x[0]), 2) + temp +pow(x[dimension - 1] - 1, 2) * (1 + pow(sin(2 * M_PI * x[dimension - 1]), 2)));for (auto i = 0; i < dimension; i++) {sum +=(x[i] > 5 ? 100 * pow((x[i] - 5), 4) : x[i] < -5 ? 100 * pow((-x[i] - 5), 4): 0);}break;}case 14: {float temp = 0;int matrix[2][25] = {{-32, 16, 0, 16, 32, -32, -16, 0, 16, 32, -32, -16, 0, 16, 32, -32, -16, 0, 16, 32, -32, -16, 0, 16, 32},{-32, -32, -32, -32, -32, -16, -16, -16, -16, -16, 0, 0, 0, 0, 0, 16, 16, 16, 16, 16, 32, 32, 32, 32, 32}};for (auto j = 0; j < 25; j++) {float _temp = 0;for (auto i = 0; i < dimension; i++) {_temp += pow(x[i] - matrix[i][j], 6);}temp += (1 / (j + 1 + _temp));}sum = pow(1 / 500 + temp, -1);break;}case 15: {float a[11] = {0.1957, 0.1947, 0.1735, 0.16, 0.0844, 0.0627, 0.0456, 0.0342, 0.0323, 0.0235, 0.0246};float b[11] = {0.25, 0.5, 1, 2, 4, 6, 8, 10, 12, 14, 16};for (auto i = 0; i < 11; i++) {sum += pow(a[i] - (x[0] * (pow(1 / b[i], 2) + 1 / b[i] * x[1])) /(pow(1 / b[i], 2) + 1 / b[i] * x[2] + x[3]), 2);}break;}}return sum;}//数组复制void copy_(float src[], float dst[], int dims) {for (int i = 0; i < dims; i++) {dst[i] = src[i];}}//通过计算,得到vector中的最小适应值和对应的坐标void get_min(int mount, vector<Particle> temp_pso, float *min_in, float *min_fit, int in_dims_) {for (int i = 0; i < mount; i++) {if (i == 0 || temp_pso[i].fitness < *min_fit) {*min_fit = temp_pso[i].fitness;copy_(temp_pso[i].position, min_in, in_dims_);}}}//通过计算,得到最终的最优解void get_final_gbest(int mount, vector<Particle> temp_pso, float *final_in, float *final_fit, int in_dims_) {for (int i = 0; i < mount; i++) {if (i == 0 || temp_pso[i].fitness < *final_fit) {*final_fit = temp_pso[i].fitness_gbest;copy_(temp_pso[i].position, final_in, in_dims_);}}}
main
//// Created by tq on 2019/6/18.//#include <iostream>#include <stdlib.h>#include <vector>#include <time.h>#include <math.h>#include "Particle.h"#include "Pso.h"#include "functions.h"#include <iomanip>using namespace std;int main() {srand(time(0)); //随机种子int amout_ = 40000; //粒子数float w_ = 0.8; // 惯性权重// 通常情况下,全局加速因子 c1、历史加速因子c2 ,等于 (1-w)/2float v_scale_ = 0.1; //速度比例因子。最大速度、最小速度的范围int iteration = 80;//迭代次数//本适应度函数是两维。网友可以根据自身需要更改适应度函数、int index, in_dims_, up_low;cout << "*********选择函数********" << endl;cout << "1. Sphere Model " << endl;cout << "2. Schwefel’s Problem 2.22 " << endl;cout << "3. Schwefel’s Problem 1.2 " << endl;cout << "4. Schwefel’s Problem 2.21 " << endl;cout << "5. Generalized Rosenbrock’s Function " << endl;cout << "6. Step Function " << endl;cout << "7. Quartic Function i.e. Niose " << endl;cout << "8. Generalized Schwefel’s Problem 2.26 " << endl;cout << "9. Generalized Rastrigin’s Function " << endl;cout << "10. Ackley’s Function " << endl;cout << "11. Generalized Griewank Function " << endl;cout << "12. Generalized Penalized Function " << endl;cout << "13. Generalized Penalized Function " << endl;cout << "14. Shekel’s Foxholes Function " << endl;cout << "15. Kowalik’s Function " << endl;cout << "*************************" << endl;cout << "Please input the function index: " << endl;cin >> index;cout << "Please input the dimension: " << endl;cin >> in_dims_;cout << "Please input the up and low: " << endl;cin >> up_low;;float max_in[10]; //输入参数的上限for (auto i = 0; i < in_dims_; i++) {max_in[i] = up_low;;}float min_in[10]; //输入参数的下限for (auto i = 0; i < in_dims_; i++) {min_in[i] = -up_low;;}Pso pso_(amout_, in_dims_, w_, max_in, min_in, v_scale_, index);pso_.set_w_col(0.99); //设置惯性衰减系数。惯性系数每次迭代乘以0.99。c1和c2相应增加pso_.set_v_col(0.99); //设置速度衰减因子。速度的上限和下限。随着迭代衰减pso_.pso_iteration(iteration); //执行cout << "********* Complete Iteration ********" << endl;cout << "*****final_gbest fitness:" << setiosflags(ios::fixed) << setprecision(4) << pso_.fitness_gbest_final<< endl;cout << "********* Complete Iteration ********" << endl;}





























在实现PSO算法对15个函数的测试后,尝试用Qt对PSO优化过程进行可视化,如图。



代码如下:
psoparameters.h
#ifndef PSOPARAMETERS_H#define PSOPARAMETERS_H#include <QWidget>#include <map>namespace Ui {class PSOParameters;}class PSOParameters : public QWidget{Q_OBJECTpublic:explicit PSOParameters(QWidget *parent = 0);~PSOParameters();void setResult(double result);void setProgress(const double &ratio);void showParameters( std::map<QString,double> &pso);signals:void changeParameter(QString target, double value, bool type);void beginToProcess(bool type);private slots:void on_LineEditGroup_textChanged(const QString &arg1);void on_LineEditGroup_textEdited(const QString &arg1);void on_LineEditGroup_editingFinished();void on_LineEditGeneration_editingFinished();void on_LineEditSpeed1_editingFinished();void on_LineEditSpeed2_editingFinished();void on_LineEditUp_editingFinished();void on_LineEditDown_cursorPositionChanged(int arg1, int arg2);void on_LineEditDown_editingFinished();void on_LineEditGroup_D_editingFinished();void on_LineEditGeneration_D_editingFinished();void on_LineEditUp_D_editingFinished();void on_LineEditDown_D_editingFinished();void on_horizontalSliderWeight_valueChanged(int value);void on_ComboBoxDimension_currentTextChanged(const QString &arg1);void on_horizontalSliderFactor_D_valueChanged(int value);void on_horizontalSliderCR_D_valueChanged(int value);void on_ComboBoxDimension_D_currentTextChanged(const QString &arg1);void on_pushButtonProcess_clicked();void on_comboBoxFunction_currentIndexChanged(int index);private:Ui::PSOParameters *ui;};#endif // PSOPARAMETERS_H
psoparameters.cpp
#include "psoparameters.h"#include "ui_psoparameters.h"#include <QDebug>PSOParameters::PSOParameters(QWidget *parent) :QWidget(parent),ui(new Ui::PSOParameters){ui->setupUi(this);//设置输入限制ui->LineEditGroup->setValidator(new QIntValidator(10, 300));ui->LineEditGeneration->setValidator(new QIntValidator());ui->LineEditSpeed1->setValidator(new QDoubleValidator(0.0,10.0,10));ui->LineEditSpeed2->setValidator(new QDoubleValidator(0.0, 10.0,10));ui->LineEditUp->setValidator(new QDoubleValidator());ui->LineEditDown->setValidator(new QDoubleValidator());ui->LineEditGroup_D->setValidator(new QIntValidator());ui->LineEditGeneration_D->setValidator(new QIntValidator());ui->LineEditUp_D->setValidator(new QDoubleValidator());ui->LineEditDown_D->setValidator(new QDoubleValidator());ui->lineEditResult->setReadOnly(true);}PSOParameters::~PSOParameters(){delete ui;}void PSOParameters::setResult(double result){ui->lineEditResult->setText(QString::number(result,10,3));ui->lineEditResult->repaint();}void PSOParameters::setProgress(const double &ratio){double tmp = ratio + 0.01;ui->progressBar->setValue(tmp*100);ui->progressBar->repaint();}void PSOParameters::showParameters( std::map<QString,double> &pso){//设置pso的参数ui->LineEditGroup->setText(QString::number(static_cast<int>(pso["population"]),10));ui->LineEditGeneration->setText(QString::number(static_cast<int>(pso["generation"]),10));double ratio = pso["w"];ui->horizontalSliderWeight->setValue(static_cast<int>(ratio*100));ui->LineEditSpeed1->setText(QString::number(pso["c1"],10,2));ui->LineEditSpeed2->setText(QString::number(pso["c1"],10,2));ui->ComboBoxDimension->setCurrentText(QString::number(static_cast<int>(pso["dimension"])));ui->LineEditUp->setText(QString::number(pso["upbounding"],10,2));ui->LineEditDown->setText(QString::number(pso["lowbounding"],10,2));}void PSOParameters::on_LineEditGroup_textChanged(const QString &arg1){Q_UNUSED(arg1);}void PSOParameters::on_LineEditGroup_textEdited(const QString &arg1){Q_UNUSED(arg1);}void PSOParameters::on_LineEditGroup_editingFinished(){double value = ui->LineEditGroup->text().toDouble();emit changeParameter(tr("population"),value, false);}void PSOParameters::on_LineEditGeneration_editingFinished(){double value = ui->LineEditGeneration->text().toDouble();emit changeParameter(tr("generation"),value, false);}void PSOParameters::on_LineEditSpeed1_editingFinished(){double value = ui->LineEditSpeed1->text().toDouble();emit changeParameter(tr("c1"),value, false);}void PSOParameters::on_LineEditSpeed2_editingFinished(){double value = ui->LineEditSpeed2->text().toDouble();emit changeParameter(tr("c2"),value, false);}void PSOParameters::on_LineEditUp_editingFinished(){double value = ui->LineEditUp->text().toDouble();emit changeParameter(tr("upbounding"),value, false);}void PSOParameters::on_LineEditDown_cursorPositionChanged(int arg1, int arg2){Q_UNUSED(arg1);Q_UNUSED(arg2);}void PSOParameters::on_LineEditDown_editingFinished(){double value = ui->LineEditDown->text().toDouble();emit changeParameter(tr("lowbounding"),value, false);}void PSOParameters::on_LineEditGroup_D_editingFinished(){double value = ui->LineEditGroup_D->text().toDouble();emit changeParameter(tr("population"),value, true);}void PSOParameters::on_LineEditGeneration_D_editingFinished(){double value = ui->LineEditGeneration_D->text().toDouble();emit changeParameter(tr("generation"),value, true);}void PSOParameters::on_LineEditUp_D_editingFinished(){double value = ui->LineEditUp_D->text().toDouble();emit changeParameter(tr("upbounding"),value, true);}void PSOParameters::on_LineEditDown_D_editingFinished(){double value = ui->LineEditDown_D->text().toDouble();emit changeParameter(tr("lowbounding"),value, true);}void PSOParameters::on_horizontalSliderWeight_valueChanged(int value){double ratio = value/100.0;ui->labelWeight->setText(QString::number(ratio,10,1));emit changeParameter(tr("w"),ratio,false);}void PSOParameters::on_ComboBoxDimension_currentTextChanged(const QString &arg1){int value = arg1.toInt();emit changeParameter(tr("dimension"),static_cast<double>(value),false);}void PSOParameters::on_horizontalSliderFactor_D_valueChanged(int value){double ratio = value/200.0;ui->labelFactor_D->setText(QString::number(ratio,10,1));emit changeParameter(tr("F"),ratio,true);}void PSOParameters::on_horizontalSliderCR_D_valueChanged(int value){double ratio = value/100.0;ui->labelCR_D->setText(QString::number(ratio,10,1));emit changeParameter(tr("CR"),ratio,true);}void PSOParameters::on_ComboBoxDimension_D_currentTextChanged(const QString &arg1){int value = arg1.toInt();emit changeParameter(tr("dimension"),static_cast<double>(value),true);}void PSOParameters::on_pushButtonProcess_clicked(){emit beginToProcess(true);}void PSOParameters::on_comboBoxFunction_currentIndexChanged(int index){int value = index + 1;emit changeParameter(tr("function"),value, false);emit changeParameter(tr("function"),value, true);}
algorithm.h
#ifndef ALGORITHM_H#define ALGORITHM_H#include <map>#include <QString>#include <QObject>#include <vector>class Algorithm : public QObject{Q_OBJECTpublic://double result;//存储结果static void dataInitialization(int func_num, int dimension);Algorithm():minY(0.0),maxY(10000000000.0){}void setParameters(const QString &target, double value){parameters[target] = value;}double getParameters(const QString &target){return parameters[target];}void resetParameters(std::vector<std::pair<QString,double> > &parm);//设置参数virtual void initial();virtual void process(){return;}double getResult(std::vector<double> ans);std::map<QString,double>& getParameterList(){return parameters;}signals:void processFinished(double result);void frameUpdate(double midret,const std::vector<double>& target,const double &ymin,const double &ymax,const int &curGen,const int &totalGen,const std::pair<int,double> &bestValue);//运行过程中的动态更新protected:std::vector<std::vector<std::vector<double> > > group;//群体std::vector<double> currentValue;std::pair<int,double> bestValue;double minY,maxY,avgValue;void calcCurrentValue(const std::vector<std::vector<double> > &target);private:std::map<QString, double> parameters;//参数列表};class PSOAlgorithm : public Algorithm{//粒子群算法Q_OBJECTpublic:std::vector<double> gBest; //全局最优解PSOAlgorithm(){}virtual void initial();virtual void process();void update(int curGeneration);//更新速度和位置void curAndgloBest(int curGeneration);//计算全局最优与当前最优private:std::vector<std::vector<double> >velocity;//速度std::vector<std::vector<double> >pBest;//当前每个的最优解};#endif // ALGORITHM_H
algorithm.cpp
#include <ctime>#include <cmath>#include <cstdlib>#include "algorithm.h"#include "MyFunction.cpp"#include <QDebug>#include <iostream>#include <float.h>void Algorithm::dataInitialization(int func_num, int dimension){initialization(func_num, dimension);}void Algorithm::resetParameters(std::vector<std::pair<QString, double> > &parm){for(auto it = parm.begin();it != parm.end();++it){this->setParameters(it->first,it->second);}}void Algorithm::initial(){//初始化minY = DBL_MAX;maxY = -11000000;srand((unsigned)time(nullptr));int population = static_cast<int>(getParameters(tr("population")));//种群大小int dimension = static_cast<int>(getParameters(tr("dimension")));//维度int generation = static_cast<int>(getParameters(tr("generation")));//迭代次数double lowbounding = getParameters(tr("lowbounding"));double upbounding = getParameters(tr("upbounding"));group.clear();group.resize(generation,std::vector<std::vector<double> >(population,std::vector<double>(dimension,0.0)));for (int i = 0; i < population; i++) {for (int j = 0; j < dimension; j++) {group[0][i][j] = lowbounding +(double)(rand() / (double)RAND_MAX) * (upbounding - lowbounding);}}currentValue.clear();currentValue.resize(population,0.0);}double Algorithm::getResult(std::vector<double> ans){int dimension = static_cast<int>(getParameters(tr("dimension")));int func_num = static_cast<int>(getParameters(tr("function")));//函数编号return functions(ans,func_num,dimension);}void Algorithm::calcCurrentValue(const std::vector<std::vector<double> > &target){minY = DBL_MAX;maxY = -11000000;avgValue = 0;int dimension = static_cast<int>(getParameters(tr("dimension")));int func_num = static_cast<int>(getParameters(tr("function")));//函数编号for(uint x = 0;x < target.size();++x){currentValue[x] = functions(target[x],func_num,dimension);avgValue += currentValue[x];minY = std::min(minY,currentValue[x]);maxY = std::max(maxY,currentValue[x]);}avgValue /= target.size();}//以下为粒子群算法void PSOAlgorithm::initial(){Algorithm::initial();int population = static_cast<int>(getParameters(tr("population")));//种群大小int dimension = static_cast<int>(getParameters(tr("dimension")));//维度gBest.clear();pBest.clear();velocity.clear();gBest.resize(dimension, 0.0);pBest.resize(population,std::vector<double>(dimension, 0.0));velocity.resize(population,std::vector<double>(dimension,0.0));bestValue.first = 0;bestValue.second = DBL_MAX;}void PSOAlgorithm::process(){curAndgloBest(0);//计算初始代最优解int generation = static_cast<int>(getParameters(tr("generation")));//迭代次数for (auto current = 1; current < generation; ++current) {update(current);curAndgloBest(current);calcCurrentValue(pBest);if(generation <= 100 || (generation > 100 && generation % 2 == 0))emit frameUpdate(avgValue,currentValue,minY,maxY,current,generation,bestValue);}emit processFinished(bestValue.second);}void PSOAlgorithm::update(int curGeneration){//更新速度和位置int dimension = static_cast<int>(getParameters(tr("dimension")));int population = static_cast<int>(getParameters(tr("population")));double w = getParameters(tr("w"));//惯性权重double c1 = getParameters(tr("c1"));//加速系数double c2 = getParameters(tr("c2"));//加速系数double upbounding = getParameters(tr("upbounding"));//上界double lowbounding = getParameters(tr("lowbounding"));//下界for(auto i = 0;i < population;++i){for(auto j = 0;j < dimension;++j){double pre = velocity[i][j];//更新速度velocity[i][j] = w*pre +c1*(double)(rand()/(double)RAND_MAX)*(pBest[i][j] - group[curGeneration - 1][i][j])+c2*(double)(rand()/(double)RAND_MAX)*(gBest[j] - group[curGeneration - 1][i][j]);if(velocity[i][j] > 200)velocity[i][j] = 200;//位置更新group[curGeneration][i][j] = group[curGeneration-1][i][j] + velocity[i][j];//边界处理if(group[curGeneration][i][j] > upbounding)group[curGeneration][i][j] = upbounding;if(group[curGeneration][i][j] < lowbounding)group[curGeneration][i][j] = lowbounding;}}}void PSOAlgorithm::curAndgloBest(int curGeneration){//计算当前最优解和全局最优解int population = static_cast<int>(getParameters(tr("population")));int dimension = static_cast<int>(getParameters(tr("dimension")));int func_num = static_cast<int>(getParameters(tr("function")));//函数编号for (auto i = 0; i < population; ++i) {double value = functions(group[curGeneration][i], func_num, dimension);if (value < functions(pBest[i], func_num, dimension))pBest[i] = group[curGeneration][i];if (functions(pBest[i], func_num, dimension) < functions(gBest, func_num, dimension)){gBest = pBest[i];bestValue.first = i;bestValue.second = functions(pBest[i], func_num, dimension);}}}
curvedialog.h
#ifndef CURVEDIALOG_H#define CURVEDIALOG_H#include <QDialog>namespace Ui {class CurveDialog;}class PSOParameters;class CurveDialog : public QDialog{Q_OBJECTpublic:explicit CurveDialog(QWidget *parent = 0);~CurveDialog();PSOParameters *setting;private:Ui::CurveDialog *ui;};#endif // CURVEDIALOG_H
curvedialog.cpp
#include "curvedialog.h"#include "ui_curvedialog.h"#include "psoparameters.h"#include <QHBoxLayout>#include <QDebug>CurveDialog::CurveDialog(QWidget *parent) :QDialog(parent),ui(new Ui::CurveDialog){ui->setupUi(this);//非模态对话框this->setModal(false);//布局setting = new PSOParameters(this);QHBoxLayout *layout = new QHBoxLayout;layout->addWidget(setting);this->setLayout(layout);}CurveDialog::~CurveDialog(){delete ui;}
mainwindow.h
#ifndef MAINWINDOW_H#define MAINWINDOW_H#include <QMainWindow>#include <QtCharts/QChartView>#include <QtCharts/QScatterSeries>#include <QtCharts/QLineSeries>#include <QString>namespace Ui {class MainWindow;}class PSOParameters;class PSOAlgorithm;class CurveDialog;class MainWindow : public QMainWindow{Q_OBJECTpublic:explicit MainWindow(QWidget *parent = 0);~MainWindow();void addPoint(int x,double y);//曲线点void reset();//曲线重置void loadStyleSheet(const QString &styleSheetFile);protected slots:void setParameters(QString target, double value);void beginProcess();//开始运行void setResult(double result);//设置结果数值void frameUpdate(double midret,const std::vector<double>& target,const double &ymin,const double &ymax,const int &curGen,const int &totalGen,const std::pair<int,double> &bestValue);//运行过程中的动态设置private:bool begin;Ui::MainWindow *ui;PSOAlgorithm* pso_algo;QtCharts::QScatterSeries *series;QtCharts::QScatterSeries *bestSol;QtCharts::QLineSeries *seriesCurve;QtCharts::QChartView *chartView;QtCharts::QChartView *chartViewCurve;CurveDialog *curveDlg;double maxY;//参数列表std::vector<std::pair<QString,double> > psoParm;void createChart();};#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"#include "ui_mainwindow.h"#include "psoparameters.h"#include "curvedialog.h"#include "algorithm.h"#include <QtCharts/QChart>#include <QMessageBox>#include <QHBoxLayout>#include <float.h>#include <QDebug>using namespace QtCharts;MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent),begin(false), ui(new Ui::MainWindow){ui->setupUi(this);QWidget *centeral = new QWidget(this);this->setCentralWidget(centeral);this->setWindowTitle("PSO");this->loadStyleSheet(":/qss/new.qss");//创建图表createChart();//布局QHBoxLayout *layout = new QHBoxLayout();layout->addWidget(chartView);layout->addWidget(chartViewCurve);centeral->setLayout(layout);curveDlg = new CurveDialog(this);connect(curveDlg->setting,&PSOParameters::changeParameter,this,&MainWindow::setParameters);connect(curveDlg->setting,&PSOParameters::beginToProcess,this,&MainWindow::beginProcess);//算法处理部分pso_algo = new PSOAlgorithm();connect(pso_algo,&PSOAlgorithm::processFinished,this,&MainWindow::setResult);connect(pso_algo,&PSOAlgorithm::frameUpdate,this,&MainWindow::frameUpdate);psoParm = {std::pair<QString,double>("population",100.0),std::pair<QString,double>("dimension",10.0),std::pair<QString,double>("function",1.0),std::pair<QString,double>("generation",500),std::pair<QString,double>("w",0.5),std::pair<QString,double>("c1",2.0),std::pair<QString,double>("c2",2.0),std::pair<QString,double>("upbounding",100.0),std::pair<QString,double>("lowbounding",-100.0)};pso_algo->resetParameters(psoParm);curveDlg->setting->showParameters(pso_algo->getParameterList());curveDlg->show();}MainWindow::~MainWindow(){delete ui;delete pso_algo;}void MainWindow::addPoint(int x, double y){chartViewCurve->chart()->axisX()->setRange(1,x+1);if(y > maxY){maxY = y;double lowb = 100.0*pso_algo->getParameters(tr("function"));chartViewCurve->chart()->axisY()->setRange(lowb-100.0,maxY);}seriesCurve->append(QPointF(x,y));chartViewCurve->repaint();}void MainWindow::reset(){seriesCurve->clear();maxY = DBL_MIN;}void MainWindow::setParameters(QString target, double value){for(auto it = psoParm.begin();it != psoParm.end();++it){if(it->first == target){it->second = value;pso_algo->setParameters(target,value);break;}}}void MainWindow::beginProcess(){//检查当前的函数是否有对应的维度if(begin){QMessageBox::warning(this,tr(u8"警告"),tr(u8"当前算法任务尚未完成!"));return;}begin = true;reset();//曲线重置int func_num = pso_algo->getParameters("function");int dimension = pso_algo->getParameters("dimension");Algorithm::dataInitialization(func_num,dimension);pso_algo->initial();pso_algo->process();}void MainWindow::setResult(double result){curveDlg->setting->setResult(result);begin = false;}void MainWindow::frameUpdate(double midret,const std::vector<double> &target,const double &ymin,const double &ymax,const int &curGen,const int &totalGen,const std::pair<int,double> &bestValue){//设置显示结果curveDlg->setting->setResult(bestValue.second);//设置显示图表chartView->chart()->axisX()->setRange(0,target.size()+2);chartView->chart()->axisY()->setRange(ymin-10,ymax+10);series->clear();for(uint x = 0;x < target.size();++x){series->append(x+1,target[x]);}chartView->repaint();//设置显示最优解bestSol->clear();bestSol->append(bestValue.first,bestValue.second);//设置显示进度double ratio = static_cast<double>(curGen)/totalGen;curveDlg->setting->setProgress(ratio);//设置显示收敛曲线addPoint(curGen,midret);//防止未响应qApp->processEvents();}void MainWindow::createChart(){// 构建图表,种群个体是适应值QChart *chart = new QChart();chart->legend()->hide(); // 隐藏图例// 构建 series,作为图表的数据源series = new QtCharts::QScatterSeries(chart);series->setMarkerSize(10.0);bestSol = new QScatterSeries(chart);bestSol->setMarkerSize(25.0);chart->addSeries(series); // 将 series 添加至图表中chart->addSeries(new QScatterSeries(chart));chart->addSeries(bestSol); //将bestSol 添加至图表中chart->createDefaultAxes(); // 基于已添加到图表的 series 来创轴chart->setTitle(tr(u8"种群个体函数值")); // 设置图表的标题// 构建 QChartView,并设置抗锯齿、标题、大小chartView = new QChartView(this);chartView->setChart(chart);chartView->setRenderHint(QPainter::Antialiasing);QChart::ChartTheme theme = static_cast<QChart::ChartTheme>(2);chartView->chart()->setTheme(theme);QChart *chart2 = new QChart();chart2->legend()->hide(); // 隐藏图例seriesCurve = new QLineSeries(chart);chart2->addSeries(seriesCurve); // 将 series 添加至图表中chart2->createDefaultAxes(); // 基于已添加到图表的 series 来创轴chart2->setTitle(tr(u8"收敛曲线")); // 设置图表的标题chartViewCurve = new QChartView(this);chartViewCurve->setChart(chart2);chartViewCurve->setRenderHint(QPainter::Antialiasing);chartViewCurve->chart()->setTheme(theme);chartViewCurve->chart()->axisX()->gridVisibleChanged(false);chartViewCurve->chart()->axisY()->gridVisibleChanged(false);}/*load qss style*/void MainWindow::loadStyleSheet(const QString &styleSheetFile){QFile file(styleSheetFile);file.open(QFile::ReadOnly);if (file.isOpen()){QString styleSheet = this->styleSheet();styleSheet += QLatin1String(file.readAll());//读取样式表文件this->setStyleSheet(styleSheet);//把文件内容传参file.close();}else{QMessageBox::information(this,"tip","cannot find qss file");}}
main.cpp
#include <QApplication>#include "algorithm.h"#include "mainwindow.h"int main(int argc, char* argv[]){QApplication app(argc,argv);MainWindow window;window.show();return app.exec();}
MyFunction.cpp
//#include <WINDOWS.H>#include <stdio.h>#include <math.h>#include <stdlib.h>#include <malloc.h>#include <fstream>#include <string>#include <vector>#include <iostream>#include <QDebug>using namespace std;#define INF 1.0e99#define EPS 1.0e-14#define E 2.7182818284590452353602874713526625#define PI 3.1415926535897932384626433832795029void initialization(int func_num, int dimension);double functions(vector<double> x, int func_name,int dimension);void F1(double *, double *, int, double *, double *, int, int); /* Sphere */void F2(double *, double *, int, double *, double *, int, int);void F3(double *, double *, int, double *, double *, int, int);void F4(double *, double *, int, double *, double *, int, int);void F5(double *, double *, int, double *, double *, int, int);void F6(double *, double *, int, double *, double *, int, int);void F7(double *, double *, int, double *, double *, int, int);void F8(double *, double *, int, double *, double *, int, int);void F9(double *, double *, int, double *, double *, int, int);void F10(double *, double *, int, double *, double *, int, int);void F11(double *, double *, int, double *, double *, int, int);void F12(double *, double *, int, double *, double *, int, int);void F13(double *, double *, int, double *, double *, int, int);void F14(double *, double *, int, double *, double *, int, int);void F15(double *, double *, int, double *, double *, int, int);void shiftfunc(double*, double*, int, double*);void rotatefunc(double*, double*, int, double*);void sr_func(double *, double *, int, double*, double*, double, int, int); /* shift and rotate */double *OShift, *M, *y, *z, *x_bound;int ini_flag = 0, n_flag, func_flag, *SS;void initialization(int func_num, int dimension) {int cf_num = 10, i, j;fstream infile;char FileName[256];int nx = dimension;free(M);free(OShift);free(y);free(z);free(x_bound);y = (double *)malloc(sizeof(double) * nx);z = (double *)malloc(sizeof(double) * nx);x_bound = (double *)malloc(sizeof(double) * nx);for (i = 0; i<nx; i++) {x_bound[i] = 100.0;}if (!(nx == 2 || nx == 10 || nx == 20 || nx == 30 || nx == 50 || nx == 100)){printf("\nError: Test functions are only defined for D=2,10,20,30,50,100.\n");}if (nx == 2 && ((func_num >= 17 && func_num <= 22) || (func_num >= 29 && func_num <= 30))){printf("\nError: hf01,hf02,hf03,hf04,hf05,hf06,cf07&cf08 are NOT defined for D=2.\n");}/* Load Matrix M*/sprintf(FileName, "D:/BJTU/CPP/Pso/AILearning-master/SingleObjectiveOpt/input_data/M_%d_D%d.txt", func_num, nx);infile.open(FileName);//std::cout << FileName << "\n";//fpt = fopen(FileName, "r");if (!infile){printf("\n Error: Cannot open input file %s for reading \n", FileName);}if (func_num<20){M = (double*)malloc(nx*nx * sizeof(double));if (M == NULL)printf("\nError: there is insufficient memory available!\n");for (i = 0; i<nx*nx; i++){infile >> M[i];//cout << M[i] << endl;//fscanf(fpt, "%Lf", &M[i]);}}else{M = (double*)malloc(cf_num*nx*nx * sizeof(double));if (M == NULL)printf("\nError: there is insufficient memory available!\n");for (i = 0; i<cf_num*nx*nx; i++){infile >> M[i];//fscanf(fpt, "%Lf", &M[i]);}}infile.close();//fclose(fpt);/* Load shift_data */sprintf(FileName, "D:/BJTU/CPP/Pso/AILearning-master/SingleObjectiveOpt/input_data/shift_data_%d.txt", func_num);//std::cout << "fileName->" << FileName << std::endl;infile.open(FileName);//fpt = fopen(FileName, "r");if (!infile){printf("\n Error: Cannot open input file for reading \n");}if (func_num<20){OShift = (double *)malloc(nx * sizeof(double));if (OShift == NULL)printf("\nError: there is insufficient memory available!\n");for (i = 0; i<nx; i++){infile >> OShift[i];//fscanf(fpt, "%Lf", &OShift[i]);}}else{OShift = (double *)malloc(nx*cf_num * sizeof(double));if (OShift == NULL)printf("\nError: there is insufficient memory available!\n");for (i = 0; i<cf_num - 1; i++){for (j = 0; j<nx; j++){infile >> OShift[i*nx + j];//fscanf(fpt, "%Lf", &OShift[i*nx + j]);}//fscanf(fpt, "%*[^\n]%*c");}for (j = 0; j<nx; j++){infile >> OShift[(cf_num - 1)*nx + j];//fscanf(fpt, "%Lf", &OShift[(cf_num - 1)*nx + j]);}}infile.close();//fclose(fpt);/* Load Shuffle_data */if (func_num >= 11 && func_num <= 20){sprintf(FileName, "D:/BJTU/CPP/Pso/AILearning-master/SingleObjectiveOpt/input_data/shuffle_data_%d_D%d.txt", func_num, nx);infile.open(FileName);//fpt = fopen(FileName, "r");if (!infile){printf("\n Error: Cannot open input file for reading \n");}SS = (int *)malloc(nx * sizeof(int));if (SS == NULL)printf("\nError: there is insufficient memory available!\n");for (i = 0; i<nx; i++){infile >> SS[i];cout << "Shuffle->" << SS[i];//fscanf(fpt, "%d", &SS[i]);}infile.close();//fclose(fpt);}else if (func_num == 29 || func_num == 30){sprintf(FileName, "D:/BJTU/CPP/Pso/AILearning-master/SingleObjectiveOpt/input_data/shuffle_data_%d_D%d.txt", func_num, nx);infile.open(FileName);//fpt = fopen(FileName, "r");if (!infile){printf("\n Error: Cannot open input file for reading \n");}SS = (int *)malloc(nx*cf_num * sizeof(int));if (SS == NULL)printf("\nError: there is insufficient memory available!\n");for (i = 0; i<nx*cf_num; i++){infile >> SS[i];//fscanf(fpt, "%d", &SS[i]);}infile.close();//fclose(fpt);}n_flag = nx;func_flag = func_num;ini_flag = 1;}double functions(vector<double> v, int func_num,int dimension) {double* x = (double *)malloc(dimension * sizeof(double));for (int i = 0; i<dimension; i++)x[i] = v[i];int nx = dimension;//qDebug()<<nx;double result = 0;if (func_num>0 && func_num <= 30){switch (func_num){case 1:F1(x, &result, nx, OShift, M, 1, 1);break;case 2:F2(x, &result, nx, OShift, M, 1, 1);break;case 3:F3(x, &result, nx, OShift, M, 1, 1);break;case 4:F4(x, &result, nx, OShift, M, 1, 1);break;case 5:F5(x, &result, nx, OShift, M, 1, 1);break;case 6:F6(x, &result, nx, OShift, M, 1, 1);break;case 7:F7(x, &result, nx, OShift, M, 1, 1);break;case 8:F8(x, &result, nx, OShift, M, 1, 1);break;case 9:F9(x, &result, nx, OShift, M, 1, 1);break;case 10:F10(x, &result, nx, OShift, M, 1, 1);break;case 11:F11(x, &result, nx, OShift, M, 1, 1);break;case 12:F12(x, &result, nx, OShift, M, 1, 1);break;case 13:F13(x, &result, nx, OShift, M, 1, 1);break;case 14:F14(x, &result, nx, OShift, M, 1, 1);break;case 15:F15(x, &result, nx, OShift, M, 1, 1);break;default:printf("\nError: There are only 30 test functions in this test suite!\n");result = 0.0;break;}return result;}}void F1(double *x, double *f, int nx, double *Os, double *Mr, int s_flag, int r_flag) /* Sphere */{int i;f[0] = 0.0;sr_func(x, z, nx, Os, Mr, 1.0, s_flag, r_flag); /* shift and rotate */for (i = 0; i<nx; i++){f[0] += z[i] * z[i];}}void F2(double *x, double *f, int nx, double *Os, double *Mr, int s_flag, int r_flag){int i;f[0] = 0.0;sr_func(x, z, nx, Os, Mr, 1.0, s_flag, r_flag); /* shift and rotate */double temp = 1;for (i = 0; i < nx; i++) {temp *= fabs(z[i]);}for (auto i = 0; i < nx; i++) {f[0] += fabs(z[i]);}f[0] = f[0] + temp;}void F3(double *x, double *f, int nx, double *Os, double *Mr, int s_flag, int r_flag){f[0] = 0.0;sr_func(x, z, nx, Os, Mr, 1.0, s_flag, r_flag); /* shift and rotate */double temp = 0;for (auto i = 0; i < nx; i++) {for (auto j = 0; j < i; j++) {temp += z[i];}f[0]+= pow(temp, 2);}}void F4(double *x, double *f, int nx, double *Os, double *Mr, int s_flag, int r_flag){f[0] = 0.0;sr_func(x, z, nx, Os, Mr, 1.0, s_flag, r_flag); /* shift and rotate */f[0] = abs(z[0]);for (auto i = 1; i < nx; i++) {if (abs(z[i]) > f[0] )f[0] = abs(z[i]);}}void F5(double *x, double *f, int nx, double *Os, double *Mr, int s_flag, int r_flag){f[0] = 0.0;sr_func(x, z, nx, Os, Mr, 1.0, s_flag, r_flag); /* shift and rotate */f[0] = 10 * (100 * pow((z[1] - pow(z[0], 2)), 2) + pow(z[0] - 1, 2));}void F6(double *x, double *f, int nx, double *Os, double *Mr, int s_flag, int r_flag){f[0] = 0.0;sr_func(x, z, nx, Os, Mr, 1.0, s_flag, r_flag); /* shift and rotate */for (auto i = 0; i <nx; i++) {f[0] += pow(floor(z[i] + 0.5), 2);}}void F7(double *x, double *f, int nx, double *Os, double *Mr, int s_flag, int r_flag){f[0] = 0.0;sr_func(x, z, nx, Os, Mr, 1.0, s_flag, r_flag); /* shift and rotate */for (auto i = 0; i < nx; i++) {f[0] += ((i + 1) * pow(z[i], 4) + (rand() % (1 - 0)) + 0);}}void F8(double *x, double *f, int nx, double *Os, double *Mr, int s_flag, int r_flag){f[0] = 0.0;sr_func(x, z, nx, Os, Mr, 1.0, s_flag, r_flag); /* shift and rotate */for(auto i=0;i<nx;i++){f[0]+=(z[i] * sin(sqrt(abs(z[i]))));}f[0]=-f[0];}void F9(double *x, double *f, int nx, double *Os, double *Mr, int s_flag, int r_flag){f[0] = 0.0;sr_func(x, z, nx, Os, Mr, 1.0, s_flag, r_flag); /* shift and rotate */f[0] = 10 * (pow(z[0], 2) - 10 * cos(2 * PI *z[0]) + 10);}void F10(double *x, double *f, int nx, double *Os, double *Mr, int s_flag, int r_flag){f[0] = 0.0;sr_func(x, z, nx, Os, Mr, 1.0, s_flag, r_flag); /* shift and rotate */float temp1 = 0, temp2 = 0;for (auto i = 0; i < nx; i++) {temp1 += pow(z[i], 2);temp2 += cos(2 * PI * z[i]);}f[0] += (-20 * exp(-0.2 * sqrt(temp1 / nx)) - exp(temp2 / nx) + 20 + E);}void F11(double *x, double *f, int nx, double *Os, double *Mr, int s_flag, int r_flag){f[0] = 0.0;sr_func(x, z, nx, Os, Mr, 1.0, s_flag, r_flag); /* shift and rotate */float temp1 = 0, temp2 = 1;for (auto i = 0; i < nx; i++) {temp1 += pow(z[i], 2);temp2 *= cos(z[i] / sqrt(i + 1));}f[0]= temp1 / 4000 - temp2 + 1;}void F12(double *x, double *f, int nx, double *Os, double *Mr, int s_flag, int r_flag){f[0] = 0.0;sr_func(x, z, nx, Os, Mr, 1.0, s_flag, r_flag); /* shift and rotate */float y[10] = {0};for (auto i = 0; i < nx; i++) {y[i] = 1 + (z[i] + 1) / 4;}float temp = 0;for (auto i = 0; i < nx - 1; i++) {temp += pow(y[i] - 1, 2) * (1 + 10 * pow(sin(PI * y[i + 1]), 2));}f[0] = (10 * pow(sin(PI * y[0]), 2) + temp + pow(y[nx - 1], 2)) * PI / nx;for (auto i = 0; i < nx; i++) {f[0] +=(z[i] > 10 ? 100 * pow((z[i] - 10), 4) : z[i] < -10 ? 100 * pow((-z[i] - 10), 4): 0);}}void F13(double *x, double *f, int nx, double *Os, double *Mr, int s_flag, int r_flag){f[0] = 0.0;sr_func(x, z, nx, Os, Mr, 1.0, s_flag, r_flag); /* shift and rotate */float temp = 0;for (auto i = 0; i < nx; i++) {temp += pow(z[i] - 1, 2) * (1 + pow(sin(3 * PI *z[i]) + 1, 2));}f[0] = 0.1 * (pow(sin(3 * PI * z[0]), 2) + temp +pow(z[nx - 1] - 1, 2) * (1 + pow(sin(2 * PI * z[nx - 1]), 2)));for (auto i = 0; i < nx; i++) {f[0] +=(z[i] > 5 ? 100 * pow((z[i] - 5), 4) : z[i] < -5 ? 100 * pow((-z[i] - 5), 4): 0);}}void F14(double *x, double *f, int nx, double *Os, double *Mr, int s_flag, int r_flag){f[0] = 0.0;sr_func(x, z, nx, Os, Mr, 1.0, s_flag, r_flag); /* shift and rotate */float temp = 0;int matrix[2][25] = {{-32, 16, 0, 16, 32, -32, -16, 0, 16, 32, -32, -16, 0, 16, 32, -32, -16, 0, 16, 32, -32, -16, 0, 16, 32},{-32, -32, -32, -32, -32, -16, -16, -16, -16, -16, 0, 0, 0, 0, 0, 16, 16, 16, 16, 16, 32, 32, 32, 32, 32}};for (auto j = 0; j < 25; j++) {float _temp = 0;for (auto i = 0; i < nx; i++) {_temp += pow(z[i] - matrix[i][j], 6);}temp += (1 / (j + 1 + _temp));}f[0] = pow(1 / 500 + temp, -1);}void F15(double *x, double *f, int nx, double *Os, double *Mr, int s_flag, int r_flag){f[0] = 0.0;sr_func(x, z, nx, Os, Mr, 1.0, s_flag, r_flag); /* shift and rotate */float a[11] = {0.1957, 0.1947, 0.1735, 0.16, 0.0844, 0.0627, 0.0456, 0.0342, 0.0323, 0.0235, 0.0246};float b[11] = {0.25, 0.5, 1, 2, 4, 6, 8, 10, 12, 14, 16};for (auto i = 0; i < 11; i++) {f[0] += pow(a[i] - (z[0] * (pow(1 / b[i], 2) + 1 / b[i] * z[1])) /(pow(1 / b[i], 2) + 1 / b[i] * z[2] + z[3]), 2);}}void shiftfunc(double *x, double *xshift, int nx, double *Os){int i;for (i = 0; i<nx; i++){xshift[i] = x[i] - Os[i];}}void rotatefunc(double *x, double *xrot, int nx, double *Mr){int i, j;for(i=0;i<nx;i++)xrot[i] = 0;for (i = 0; i<nx; i++){for (j = 0; j<nx; j++){xrot[i] = xrot[i] + x[j] * Mr[i*nx + j];}}}void sr_func(double *x, double *sr_x, int nx, double *Os, double *Mr, double sh_rate, int s_flag, int r_flag) /* shift and rotate */{int i;if (s_flag == 1){if (r_flag == 1){shiftfunc(x, y, nx, Os);for (i = 0; i<nx; i++)//shrink to the original search range{y[i] = y[i] * sh_rate;}rotatefunc(y, sr_x, nx, Mr);}else{shiftfunc(x, sr_x, nx, Os);for (i = 0; i<nx; i++)//shrink to the original search range{sr_x[i] = sr_x[i] * sh_rate;}}}else{if (r_flag == 1){for (i = 0; i<nx; i++)//shrink to the original search range{y[i] = x[i] * sh_rate;}rotatefunc(y, sr_x, nx, Mr);}elsefor (i = 0; i<nx; i++)//shrink to the original search range{sr_x[i] = x[i] * sh_rate;}}}