PPSO算法的实现

本文主要介绍了实现PPSO算法的代码部分,是本人根据论文的描述独立进行编码,并且基于cec14测试集进行了测试。由于未得到原作者的代码,导致部分函数的优化结果与原作者的实验结果差距较大,基本情况如下:14个函数优化结果与实现结果相近,6个函数的优化结果与实现结果差距为10倍,10个函数的优化结果与实验结果差距大于100倍。(原作代码采用Matlab编码,本人采用C++进行编码。论文名称:A Promotive Particle Swarm Optimizer With Double Hierarchical Structures,可自行前往ScienceDirect官网进行阅读)

代码:
PPSO.cpp


#include "Self_Define_Functions.h"
#include<iostream>

using namespace std;

int main(int argc, char* argv[])
{
    //double func[] = {};                                       //函数矩阵            
    int p, q, V, i, j, k,t;                                           //循环变量
    int func_num;                                                //函数编号
    double final_val;                                           //最优适应度
    char fitness_file_name[256];                         //文件名称
    int run_index;                                               //运行次数
    const int num_of_tiers = 7;                                   //层数(每个亚种群中粒子的分成的层数)
    const int hierarchical = 4;                                     //层次数(亚种群的个数)
    int fitness_counter;                                      //适应度计算次数
    int current_generation;                                //当前代数
    const double phi = 4.1;
    const double lambda = 1.2;
    int subpopulation_size = Population_Size / hierarchical;//亚种群的种群大小
    int subpopulation_length = subpopulation_size;            //亚种群中的粒子个数(亚种群的长度)
    const int exchange_frequency = 30;                                        //交换频率
    const int reinitialization_frequency = 80;                                //重新初始化频率
    double r1,r2;
    const int lowerbound=-100;                                                      //变量最小值
    const int upperbound=100;                                                       //变量最大值

    double** subpopulation_tier_gbest = new double* [num_of_tiers];//存储当前亚种群每层每个subwarm的gbest
    double** population = new double* [Population_Size];//存储整个种群(每个粒子的位置向量)
    double** speed = new double* [Population_Size];//存储每个粒子的速度向量
    double** personal_best = new double* [Population_Size];//存储每个粒子的pbest的位置信息
    int** subpopulation = new int* [hierarchical];//存储每个亚种群的粒子在population中的位置(理解为第i个亚种群中的第j个粒子为t,t为该粒子在population中的位置)
    double* Admission_threshold = new double[hierarchical];//每个亚种群的准入阈值
    int** Buffer_fields = new int* [hierarchical];//每个亚种群的准入缓冲区
    double* current_subpopulation_results = new double[subpopulation_size];//存储当前亚种群的粒子适应度
    double* temp_subpopulation_result = new double[subpopulation_size];//暂时存储当前亚种群的粒子的适应度                 
    double* temp_buffer_field_result = new double[Population_Size];//暂时存储缓冲区的粒子的适应度
    int* buffer_field_length = new int[Population_Size];//存储缓冲区的粒子个数
    int*** subpopulation_gbest_index = new int** [hierarchical];//存储每个亚种群中每一层中每个subwarms的最优解
    double* results = new double[Population_Size];//存储所有粒子的适应度    
    double* personal_best_results = new double[Population_Size];//存储每个粒子的历史最佳适应度
    double* acceleration = new double[num_of_tiers];//存储每层亚种群的加速系数
    double* temp1 = new double[Population_Size];
     //分配空间
    for (i = 0; i < Population_Size; ++i)
    {
        population[i] = new double[dim];
        speed[i] = new double[dim];
        personal_best[i] = new double[dim];
    }

    for (i = 0; i < hierarchical; i++)
    {
        subpopulation[i] = new int[subpopulation_size];
        Buffer_fields[i] = new int[Population_Size];
    }

    for (i = 0; i < num_of_tiers; i++)
    {
        subpopulation_tier_gbest[i] = new double[subpopulation_size];
    }
    
    for (i = 0; i < hierarchical; i++)
    {
        subpopulation_gbest_index[i] = new int* [num_of_tiers];
        for (j = 0; j < num_of_tiers; j++)
        {
            subpopulation_gbest_index[i][j] = new int[subpopulation_size];
        }
    }

    //初始化每层的加速系数
    double temp = phi / (2 * lambda + num_of_tiers - 2);
    acceleration[0] = lambda * temp;                                                   //第零层   
    acceleration[num_of_tiers - 1] = lambda * temp;                           //第num_of_tiers-1层
    for (i = 1; i < num_of_tiers - 1; i++)
    {
        acceleration[i] = temp;
    }

   

    //独立实验
    for (V = 0; V < 30; V++)
    {
       
        func_num = V + 1;
        sprintf_s(fitness_file_name, "F%d/convergency.txt", func_num);
        string FileName = string(fitness_file_name);
        ofstream  out_fitness(FileName);
        cout << "Start to optimize the function" << func_num << endl;
        for (run_index = 1; run_index <= 10; run_index++)
        {
            boost::mt19937 generator(time(0) * rand());
            boost::uniform_real<> uniform_real_generate_r(0, 1);
            boost::variate_generator< boost::mt19937&, boost::uniform_real<> > random_real_num_r(generator, uniform_real_generate_r);//to generate a random number within [0,1]

            fitness_counter = 0;
            current_generation = 1;

            //初始化population和speed
            for (i = 0; i < dim; ++i)
            {
                boost::uniform_real<> uniform_real_generate_x(lowerbound, upperbound);
                boost::variate_generator< boost::mt19937&, boost::uniform_real<> > random_real_num_x(generator, uniform_real_generate_x);

                for (j = 0; j < Population_Size; ++j)
                {
                    personal_best[j][i] = population[j][i] = random_real_num_x();
                    speed[j][i] = 0;
                }
            }


            //对整个种群进行分组,分成H个subpopulation
            i = 0;
            j = 0;
            for (p = 0; p < Population_Size; p++)                   //p代表粒子在population中的位置
            {
                if (j == subpopulation_size - 1)                   //如果达到subpopulation_size,换行
                {
                    subpopulation[i][j] = p;
                    i++;
                    j = 0;
                }
                else
                {
                    subpopulation[i][j] = p;
                    j++;
                }
            }

            //适应度计算
            for (i = 0; i < Population_Size; i++)
            {
                cec14_test_func(population[i], &results[i], dim, 1, func_num);
                results[i] = results[i] - (func_num) * 100;
                // cout<<results[i]<<endl;
            }

            //初始化每个粒子的历史最优适应度
            memcpy(personal_best_results, results, sizeof(double) * Population_Size);

            //寻找最优适应度
            final_val = results[0];
            //cout << results[0]<<endl;

            for (i = 0; i < hierarchical; i++)
            {
                subpopulation_length = subpopulation_size;

                //初始化第0层的最优适应度以及最有适应度粒子在population中的位置

                for (j = 0; j < subpopulation_size; j++)
                {
                    subpopulation_tier_gbest[0][j] = results[subpopulation[i][j]];
                    subpopulation_gbest_index[i][0][j] = subpopulation[i][j];
                    //cout << results[subpopulation[i][j]]<<" ";
                }
                //由于遵从{1,2,2,2,2,2,2}的分布,即第k层的subwarm是由两个第k-1层的subwarm构成,故length需要每次除以2
                //第0层已经计算完毕,故此处要除2
                subpopulation_length /= 2;

                //寻找每层每个subwarm的gbest
                for (k = 1; k < num_of_tiers; k++)                          //k代表第k层
                {
                    j = 0;                                                                     //j代表第j个subwarm
                    t = 0;                                                                     //t代表第t个subwarm
                    while (j < subpopulation_length)
                    {
                        //第k层第j个subwarm是由第k-1层第t个subwarm和第k-1层第t+1个subwarm组成,取最小值
                        subpopulation_tier_gbest[k][j] = min(subpopulation_tier_gbest[k - 1][t], subpopulation_tier_gbest[k - 1][t + 1]);
                        if (subpopulation_tier_gbest[k - 1][t] >= subpopulation_tier_gbest[k - 1][t + 1])
                        {
                            subpopulation_gbest_index[i][k][j] = subpopulation_gbest_index[i][k - 1][t + 1];
                        }
                        else  subpopulation_gbest_index[i][k][j] = subpopulation_gbest_index[i][k - 1][t];
                        //cout << gbest_index[i][k][j] << " ";
                        j++;
                        t += 2;
                    }
                    //cout << endl;
                    subpopulation_length /= 2;
                }

                //每一个subpopulation中的第k-1层的第0个subwarm即这一subpopulation的全部粒子
                // cout << gbest[k - 1][0] << endl;
                if (final_val > subpopulation_tier_gbest[k - 1][0])
                {
                    final_val = subpopulation_tier_gbest[k - 1][0];
                    //gl_best = gbest_index[i][k - 1][0];
                }
                //cout << final_val << endl;
            }
            while (fitness_counter < MAX_FV)
            {


                if (current_generation % exchange_frequency == 0)
                {
                    for (i = 0; i < hierarchical; i++)
                    {
                        for (j = 0; j < subpopulation_size; j++)
                        {
                            current_subpopulation_results[j] = results[subpopulation[i][j]];
                        }
                        sort(current_subpopulation_results, current_subpopulation_results + subpopulation_size);
                        Admission_threshold[i] = current_subpopulation_results[subpopulation_size / 2];
                    }

                    for (i = hierarchical - 1; i >= 1; i--)
                    {
                        p = 0;
                        for (j = 0; j < i; j++)
                        {
                            for (t = 0; t < subpopulation_size; t++)
                            {
                                if (results[subpopulation[j][t]] < Admission_threshold[i])
                                {
                                    Buffer_fields[i][p] = subpopulation[j][t];
                                    //cout << Buffer_fields[i][p] << endl;
                                    p++;
                                }
                            }
                        }
                        buffer_field_length[i] = p;
                        // cout << sublength[i]<<endl;
                    }
                    for (i = hierarchical - 1; i >= 1; i--)
                    {

                        for (j = 0; j < buffer_field_length[i]; j++)
                        {
                            temp_buffer_field_result[j] = results[Buffer_fields[i][j]];
                            temp1[j] = results[Buffer_fields[i][j]];
                        }
                        for (j = 0; j < subpopulation_size; j++)
                        {
                            temp_subpopulation_result[j] = results[subpopulation[i][j]];
                            
                        }
                        replaceinfo(results, Buffer_fields, subpopulation[i], i, temp_subpopulation_result, temp_buffer_field_result, subpopulation_size, buffer_field_length[i], temp1);

                    }
                    if (current_generation % reinitialization_frequency == 0)
                    {
                        for (i = 0; i < dim; ++i)
                        {
                            boost::uniform_real<> uniform_real_generate_x(lowerbound, upperbound);
                            boost::variate_generator< boost::mt19937&, boost::uniform_real<> > random_real_num_x(generator, uniform_real_generate_x);

                            for (j = 0; j < subpopulation_size; ++j)
                            {
                                population[subpopulation[0][j]][i] = random_real_num_x();
                            }
                        }
                    }

                }

                //更新公式
                r1 = random_real_num_r();
                r2= random_real_num_r();
                //r2 = random_real_num_r();
                //cout << r << endl;
                for (i = 0; i < hierarchical; i++)
                {
                    for (j = 0; j < subpopulation_size; j++)
                    {
                        for (k = 0; k < dim; k++)
                        {

                            speed[subpopulation[i][j]][k] = weight * r1 * speed[subpopulation[i][j]][k] + acceleration[0] * r2 * (personal_best[subpopulation[i][j]][k] - population[subpopulation[i][j]][k]) + cal_glbest(j, subpopulation_tier_gbest, acceleration, num_of_tiers, population, subpopulation, i, k, subpopulation_gbest_index);
                            //speed[subpopulation[i][j]][k] = weight * r * speed[subpopulation[i][j]][k] + c[0] * r * (pbest[subpopulation[i][j]][k] - population[subpopulation[i][j]][k]) + c[i] * r * (population[gl_best][k] - population[subpopulation[i][j]][k]);
                            population[subpopulation[i][j]][k] += speed[subpopulation[i][j]][k];
                            
                            if (population[subpopulation[i][j]][k] > 100)
                                population[subpopulation[i][j]][k] = 100;
                            else if (population[subpopulation[i][j]][k] < -100)
                                population[subpopulation[i][j]][k] = -100;
                                
                        }
                    }
                }

                //适应度计算
                for (i = 0; i < Population_Size; i++)
                {
                    cec14_test_func(population[i], &results[i], dim, 1, func_num);
                    results[i] = results[i] - (func_num) * 100;
                    if (results[i] < personal_best_results[i])
                    {
                        personal_best_results[i] = results[i];
                        memcpy(personal_best[i], population[i], sizeof(double) * dim);
                    }
                }

                for (i = 0; i < hierarchical; i++)
                {
                    subpopulation_length = subpopulation_size;

                    //初始化第0层的最优适应度以及最有适应度粒子在population中的位置

                    for (j = 0; j < subpopulation_size; j++)
                    {
                        subpopulation_tier_gbest[0][j] = results[subpopulation[i][j]];
                        subpopulation_gbest_index[i][0][j] = subpopulation[i][j];
                        //cout << results[subpopulation[i][j]]<<" ";
                    }
                    //由于遵从{1,2,2,2,2,2,2}的分布,即第k层的subwarm是由两个第k-1层的subwarm构成,故length需要每次除以2
                    //第0层已经计算完毕,故此处要除2
                    subpopulation_length /= 2;

                    //寻找每层每个subwarm的gbest
                    for (k = 1; k < num_of_tiers; k++)                          //k代表第k层
                    {
                        j = 0;                                                                     //j代表第j个subwarm
                        t = 0;                                                                     //t代表第t个subwarm
                        while (j < subpopulation_length)
                        {
                            //第k层第j个subwarm是由第k-1层第t个subwarm和第k-1层第t+1个subwarm组成,取最小值
                            subpopulation_tier_gbest[k][j] = min(subpopulation_tier_gbest[k - 1][t], subpopulation_tier_gbest[k - 1][t + 1]);
                            if (subpopulation_tier_gbest[k - 1][t] >= subpopulation_tier_gbest[k - 1][t + 1])
                            {
                                subpopulation_gbest_index[i][k][j] = subpopulation_gbest_index[i][k - 1][t + 1];
                            }
                            else  subpopulation_gbest_index[i][k][j] = subpopulation_gbest_index[i][k - 1][t];
                            //cout << gbest_index[i][k][j] << " ";
                            j++;
                            t += 2;
                        }
                        //cout << endl;
                        subpopulation_length /= 2;
                    }

                    //每一个subpopulation中的第k-1层的第0个subwarm即这一subpopulation的全部粒子
                    // cout << gbest[k - 1][0] << endl;
                    if (final_val > subpopulation_tier_gbest[k - 1][0])
                    {
                        final_val = subpopulation_tier_gbest[k - 1][0];
                        //gl_best = gbest_index[i][k - 1][0];
                    }
                    //cout << final_val << endl;
                }
                current_generation += 1;
                fitness_counter += Population_Size;
                
            }
            out_fitness << final_val << endl;
            cout << final_val << endl;
        }
       
        
        cout << "The optimization of the function "<<func_num<<"  is finished!!" << endl;
       
        
    }
    
    for (i = 0; i < Population_Size; ++i)
    {
        delete[]population[i];
        delete[]speed[i];
        delete[]personal_best[i];

    }
    //cout << 1 <<endl;
    for (i = 0; i < hierarchical; i++)
    {
        delete[]Buffer_fields[i];
    }
    //cout << 2 << endl;
    delete[]population;
    delete[]speed;
    delete[]personal_best;
    //cout << 3 << endl;
    delete[]buffer_field_length;
    delete[]Buffer_fields;
    delete[]personal_best_results;
    //cout << 4 << endl;
    delete[]temp_subpopulation_result;
    delete[]temp_buffer_field_result;
    //cout << 5 << endl;
    delete[]current_subpopulation_results;
    //cout << 5.1 << endl;
    delete[]temp1;
    //cout << 6 << endl;
    for (i = 0; i < hierarchical; i++)
    {
        for (j = 0; j < num_of_tiers; j++)
        {
            delete[]subpopulation_gbest_index[i][j];
        }
        delete[]subpopulation_gbest_index[i];
    }
   // cout << 7 << endl;
    delete[]subpopulation_gbest_index;
    //cout << 8 << endl;
    for (i = 0; i < num_of_tiers; i++)
    {
        delete[]subpopulation_tier_gbest[i];
    }
    delete[]subpopulation_tier_gbest;
    //cout << 9 << endl;



    return 0;
}//end of main




Self_Define_Functions.cpp


#include "Self_Define_Functions.h"
#include <math.h>
#include <iostream>
#include <fstream>
#include<algorithm>
using namespace std;

const double PI = 3.1415926535897932384626433832795;


double cal_glbest(int index, double** gbest, double* c, int N, double** population,int **subpopulation,int h,int t,int ***gbest_index)
{
    boost::mt19937 generator(time(0) * rand());
    boost::uniform_real<> uniform_real_generate_r(0, 1);
    boost::variate_generator< boost::mt19937&, boost::uniform_real<> > random_real_num_r(generator, uniform_real_generate_r);
    
    double value = 0.0;
    int i, j, k,x;
    double r1;
    x = subpopulation[h][index];
    for (k = 1; k < N; k++)
    {
        r1 = random_real_num_r();
        //if (index == 0 )  index = 0;
        if (index % 2 == 1)
        {
            index = (index - 1) / 2;
        }
        else index /= 2;
        //printf("%E\n", population[gbest_index[H][k][index]][t]);
        value += c[k] * r1 * (population[gbest_index[h][k][index]][t] - population[x][t]);
        
    }
    
    //value += c[1] * r * (population[gl_best][t] - population[subpopulation[h][index]][t]);
    return value;
}

void replaceinfo(double* results, int** Buffer, int *subpopulation, int hierarchical,double *subpopulation_fitness,double *buffer_field_fitness,int subpopulationsize,int length,double *temp_buffer_field_result)
{
    int i, j,index1,index2;
    double temp;
    /*
    for (i = 0; i < subpopulationsize; i++)
    {
        index1[i] = fitness1[i];
        
    }
    for (i = 0; i < length; i++)
    {
        index2[i] = fitness2[i];
    }
    */

    //将缓冲区的粒子进行排序
    sort(buffer_field_fitness, buffer_field_fitness + length);
    
    //找到亚种群中适应度最大的一个粒子,将适应值赋值给temp
    temp = search_max_num(subpopulation_fitness, subpopulationsize);
    i = 0;
    while (buffer_field_fitness[i] < temp && i<length)
    {
        index1 = search_index(temp, subpopulation_fitness, subpopulationsize);  //寻找temp在亚种群中的位置
        index2 = search_index(buffer_field_fitness[i], temp_buffer_field_result, length);  //寻找当前缓冲区粒子在缓冲区的位置
        if (index1 == -1)
        {
            break;
        }
        else
        {
            subpopulation[index1] = Buffer[hierarchical][index2];
            subpopulation_fitness[index1] = Buffer[hierarchical][index2];
            i++;
            temp = search_max_num(subpopulation_fitness, subpopulationsize);
        }
    }
    
    
    /*
    for (i = 0,j=subpopulationsize-1; i < subpopulationsize / 2 && i<length; i++,j--)
    {
        index11 = searchindex(fitness1[j], index1, subpopulationsize);
        index22 = searchindex(fitness2[i], index2, length);
        subpopulation[index11] = Buffer[h][index22];
    }
    */
}


int search_index(double x, double* fitness,int length)
{
    int i;
    for (i = 0; i < length; i++)
    {
        if (x == fitness[i])       return i;
    }
    return -1;
}

int search_max_num(double *goal,int length)
{
    sort(goal, goal + length);
    return goal[length - 1];
}






Self_Define_Functions.h

#pragma once
#pragma once
#ifndef SELF_DEFINE_FUNCTIONS_H_INCLUDED
#define SELF_DEFINE_FUNCTIONS_H_INCLUDED


#include <time.h>
#include <cstdio>
#include "unistd.h"
#include <algorithm>
#include <iostream>
#include <fstream>
#include <stdlib.h>
#include <iomanip>
#include <math.h>
#include <string>
#include <string.h>

// The following is the library of random number generators in boost
#include <boost/random.hpp>
#include <boost/random/uniform_int.hpp>
#include <boost/random/cauchy_distribution.hpp>
#include <boost/random/normal_distribution.hpp>
#include <boost/random/uniform_real.hpp>



//the settings of the program parameters
const int dim = 30;//the dimension size of the problem to be optimized
const int MAX_FV = 10000 * dim;//the maximum number of fitness evaluations

//the settings of parameters in PSO
const int Population_Size = 256;
const double weight = 1.0;


void cec14_test_func(double* x, double* f, int nx, int mx, int func_num);
double cal_glbest(int index, double** gbest, double* c, int N, double** population, int** subpopulation, int h,int t,int ***gbest_index);
void replaceinfo(double* results, int** Buffer, int* subpopulation, int hierarchical, double* subpopulation_fitness, double* buffer_field_fitness, int subpopulationsize, int length, double* temp_buffer_field_result);
int search_index(double x, double* fitness, int length);
int search_max_num(double* goal, int length);
#endif // SELF_DEFINE_FUNCTIONS_H_INCLUDED

unistd.h

#pragma once
#pragma once
#ifndef _UNISTD_H

#define _UNISTD_H
#include <io.h>
#include <process.h>
#endif /* _UNISTD_H */

cec14_test_func.cpp

/*
  CEC14 Test Function Suite for Single Objective Optimization
  Jane Jing Liang (email: liangjing@zzu.edu.cn; liangjing@pmail.ntu.edu.cn)
  Dec. 20th 2013
*/


#include <WINDOWS.H>      
#include <stdio.h>
#include <math.h>
#include <malloc.h>

#define INF 1.0e99
#define EPS 1.0e-14
#define E  2.7182818284590452353602874713526625
#define PI 3.1415926535897932384626433832795029

void sphere_func(double*, double*, int, double*, double*, int, int); /* Sphere */
void ellips_func(double*, double*, int, double*, double*, int, int); /* Ellipsoidal */
void bent_cigar_func(double*, double*, int, double*, double*, int, int); /* Discus */
void discus_func(double*, double*, int, double*, double*, int, int);  /* Bent_Cigar */
void dif_powers_func(double*, double*, int, double*, double*, int, int);  /* Different Powers */
void rosenbrock_func(double*, double*, int, double*, double*, int, int); /* Rosenbrock's */
void schaffer_F7_func(double*, double*, int, double*, double*, int, int); /* Schwefel's F7 */
void ackley_func(double*, double*, int, double*, double*, int, int); /* Ackley's */
void rastrigin_func(double*, double*, int, double*, double*, int, int); /* Rastrigin's  */
void weierstrass_func(double*, double*, int, double*, double*, int, int); /* Weierstrass's  */
void griewank_func(double*, double*, int, double*, double*, int, int); /* Griewank's  */
void schwefel_func(double*, double*, int, double*, double*, int, int); /* Schwefel's */
void katsuura_func(double*, double*, int, double*, double*, int, int); /* Katsuura */
void bi_rastrigin_func(double*, double*, int, double*, double*, int, int); /* Lunacek Bi_rastrigin */
void grie_rosen_func(double*, double*, int, double*, double*, int, int); /* Griewank-Rosenbrock  */
void escaffer6_func(double*, double*, int, double*, double*, int, int); /* Expanded Scaffer??s F6  */
void step_rastrigin_func(double*, double*, int, double*, double*, int, int); /* Noncontinuous Rastrigin's  */
void happycat_func(double*, double*, int, double*, double*, int, int); /* HappyCat */
void hgbat_func(double*, double*, int, double*, double*, int, int); /* HGBat  */

void hf01(double*, double*, int, double*, double*, int*, int, int); /* Hybrid Function 1 */
void hf02(double*, double*, int, double*, double*, int*, int, int); /* Hybrid Function 2 */
void hf03(double*, double*, int, double*, double*, int*, int, int); /* Hybrid Function 3 */
void hf04(double*, double*, int, double*, double*, int*, int, int); /* Hybrid Function 4 */
void hf05(double*, double*, int, double*, double*, int*, int, int); /* Hybrid Function 5 */
void hf06(double*, double*, int, double*, double*, int*, int, int); /* Hybrid Function 6 */

void cf01(double*, double*, int, double*, double*, int); /* Composition Function 1 */
void cf02(double*, double*, int, double*, double*, int); /* Composition Function 2 */
void cf03(double*, double*, int, double*, double*, int); /* Composition Function 3 */
void cf04(double*, double*, int, double*, double*, int); /* Composition Function 4 */
void cf05(double*, double*, int, double*, double*, int); /* Composition Function 5 */
void cf06(double*, double*, int, double*, double*, int); /* Composition Function 6 */
void cf07(double*, double*, int, double*, double*, int*, int); /* Composition Function 7 */
void cf08(double*, double*, int, double*, double*, int*, int); /* Composition Function 8 */

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 */
void asyfunc(double*, double* x, int, double);
void oszfunc(double*, double*, int);
void cf_cal(double*, double*, int, double*, double*, double*, double*, int);

double* OShift, * M, * y, * z, * x_bound;
int ini_flag, n_flag, func_flag, * SS;


void cec14_test_func(double* x, double* f, int nx, int mx, int func_num)
{
	errno_t err;
	int cf_num = 10, i, j;
	if (ini_flag == 1)
	{
		if ((n_flag != nx) || (func_flag != func_num))
		{
			ini_flag = 0;
		}
	}

	if (ini_flag == 0)
	{
		FILE* fpt;
		char FileName[256];
		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_s(FileName, "input_data/M_%d_D%d.txt", func_num, nx);
		err = fopen_s(&fpt, FileName, "r");
		if (err != 0)
		{
			printf("\n Error: Cannot open input file for reading \n");
		}
		if (func_num < 23)
		{
			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++)
			{
				fscanf_s(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++)
			{
				fscanf_s(fpt, "%Lf", &M[i]);
			}
		}
		fclose(fpt);

		/* Load shift_data */
		sprintf_s(FileName, "input_data/shift_data_%d.txt", func_num);
		err = fopen_s(&fpt, FileName, "r");
		if (err != 0)
		{
			printf("\n Error: Cannot open input file for reading1 \n");
		}

		if (func_num < 23)
		{
			OShift = (double*)malloc(nx * sizeof(double));
			if (OShift == NULL)
				printf("\nError: there is insufficient memory available!\n");
			for (i = 0; i < nx; i++)
			{
				fscanf_s(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++)
				{
					fscanf_s(fpt, "%Lf", &OShift[i * nx + j]);
				}
				fscanf_s(fpt, "%*[^\n]%*c");
			}
			for (j = 0; j < nx; j++)
			{
				fscanf_s(fpt, "%Lf", &OShift[(cf_num - 1) * nx + j]);
			}

		}
		fclose(fpt);


		/* Load Shuffle_data */

		if (func_num >= 17 && func_num <= 22)
		{
			sprintf_s(FileName, "input_data/shuffle_data_%d_D%d.txt", func_num, nx);
			err = fopen_s(&fpt, FileName, "r");
			if (err != 0)
			{
				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++)
			{
				fscanf_s(fpt, "%d", &SS[i]);
			}
			fclose(fpt);
		}
		else if (func_num == 29 || func_num == 30)
		{
			sprintf_s(FileName, "input_data/shuffle_data_%d_D%d.txt", func_num, nx);
			err = fopen_s(&fpt, FileName, "r");
			if (err != 0)
			{
				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++)
			{
				fscanf_s(fpt, "%d", &SS[i]);
			}
			fclose(fpt);
		}


		n_flag = nx;
		func_flag = func_num;
		ini_flag = 1;
		//printf("Function has been initialized!\n");
	}


	for (i = 0; i < mx; i++)
	{
		switch (func_num)
		{
		case 1:
			ellips_func(&x[i * nx], &f[i], nx, OShift, M, 1, 1);
			f[i] += 100.0;
			break;
		case 2:
			bent_cigar_func(&x[i * nx], &f[i], nx, OShift, M, 1, 1);
			f[i] += 200.0;
			break;
		case 3:
			discus_func(&x[i * nx], &f[i], nx, OShift, M, 1, 1);
			f[i] += 300.0;
			break;
		case 4:
			rosenbrock_func(&x[i * nx], &f[i], nx, OShift, M, 1, 1);
			f[i] += 400.0;
			break;
		case 5:
			ackley_func(&x[i * nx], &f[i], nx, OShift, M, 1, 1);
			f[i] += 500.0;
			break;
		case 6:
			weierstrass_func(&x[i * nx], &f[i], nx, OShift, M, 1, 1);
			f[i] += 600.0;
			break;
		case 7:
			griewank_func(&x[i * nx], &f[i], nx, OShift, M, 1, 1);
			f[i] += 700.0;
			break;
		case 8:
			rastrigin_func(&x[i * nx], &f[i], nx, OShift, M, 1, 0);
			f[i] += 800.0;
			break;
		case 9:
			rastrigin_func(&x[i * nx], &f[i], nx, OShift, M, 1, 1);
			f[i] += 900.0;
			break;
		case 10:
			schwefel_func(&x[i * nx], &f[i], nx, OShift, M, 1, 0);
			f[i] += 1000.0;
			break;
		case 11:
			schwefel_func(&x[i * nx], &f[i], nx, OShift, M, 1, 1);
			f[i] += 1100.0;
			break;
		case 12:
			katsuura_func(&x[i * nx], &f[i], nx, OShift, M, 1, 1);
			f[i] += 1200.0;
			break;
		case 13:
			happycat_func(&x[i * nx], &f[i], nx, OShift, M, 1, 1);
			f[i] += 1300.0;
			break;
		case 14:
			hgbat_func(&x[i * nx], &f[i], nx, OShift, M, 1, 1);
			f[i] += 1400.0;
			break;
		case 15:
			grie_rosen_func(&x[i * nx], &f[i], nx, OShift, M, 1, 1);
			f[i] += 1500.0;
			break;
		case 16:
			escaffer6_func(&x[i * nx], &f[i], nx, OShift, M, 1, 1);
			f[i] += 1600.0;
			break;
		case 17:
			hf01(&x[i * nx], &f[i], nx, OShift, M, SS, 1, 1);
			f[i] += 1700.0;
			break;
		case 18:
			hf02(&x[i * nx], &f[i], nx, OShift, M, SS, 1, 1);
			f[i] += 1800.0;
			break;
		case 19:
			hf03(&x[i * nx], &f[i], nx, OShift, M, SS, 1, 1);
			f[i] += 1900.0;
			break;
		case 20:
			hf04(&x[i * nx], &f[i], nx, OShift, M, SS, 1, 1);
			f[i] += 2000.0;
			break;
		case 21:
			hf05(&x[i * nx], &f[i], nx, OShift, M, SS, 1, 1);
			f[i] += 2100.0;
			break;
		case 22:
			hf06(&x[i * nx], &f[i], nx, OShift, M, SS, 1, 1);
			f[i] += 2200.0;
			break;
		case 23:
			cf01(&x[i * nx], &f[i], nx, OShift, M, 1);
			f[i] += 2300.0;
			break;
		case 24:
			cf02(&x[i * nx], &f[i], nx, OShift, M, 1);
			f[i] += 2400.0;
			break;
		case 25:
			cf03(&x[i * nx], &f[i], nx, OShift, M, 1);
			f[i] += 2500.0;
			break;
		case 26:
			cf04(&x[i * nx], &f[i], nx, OShift, M, 1);
			f[i] += 2600.0;
			break;
		case 27:
			cf05(&x[i * nx], &f[i], nx, OShift, M, 1);
			f[i] += 2700.0;
			break;
		case 28:
			cf06(&x[i * nx], &f[i], nx, OShift, M, 1);
			f[i] += 2800.0;
			break;
		case 29:
			cf07(&x[i * nx], &f[i], nx, OShift, M, SS, 1);
			f[i] += 2900.0;
			break;
		case 30:
			cf08(&x[i * nx], &f[i], nx, OShift, M, SS, 1);
			f[i] += 3000.0;
			break;
		default:
			printf("\nError: There are only 30 test functions in this test suite!\n");
			f[i] = 0.0;
			break;
		}

	}
}

void sphere_func(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 ellips_func(double* x, double* f, int nx, double* Os, double* Mr, int s_flag, int r_flag) /* Ellipsoidal */
{
	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] += pow(10.0, 6.0 * i / (nx - 1)) * z[i] * z[i];
	}
}

void bent_cigar_func(double* x, double* f, int nx, double* Os, double* Mr, int s_flag, int r_flag) /* Bent_Cigar */
{
	int i;
	sr_func(x, z, nx, Os, Mr, 1.0, s_flag, r_flag); /* shift and rotate */

	f[0] = z[0] * z[0];
	for (i = 1; i < nx; i++)
	{
		f[0] += pow(10.0, 6.0) * z[i] * z[i];
	}


}

void discus_func(double* x, double* f, int nx, double* Os, double* Mr, int s_flag, int r_flag) /* Discus */
{
	int i;
	sr_func(x, z, nx, Os, Mr, 1.0, s_flag, r_flag); /* shift and rotate */
	f[0] = pow(10.0, 6.0) * z[0] * z[0];
	for (i = 1; i < nx; i++)
	{
		f[0] += z[i] * z[i];
	}
}

void dif_powers_func(double* x, double* f, int nx, double* Os, double* Mr, int s_flag, int r_flag) /* Different Powers */
{
	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] += pow(fabs(z[i]), 2 + 4 * i / (nx - 1));
	}
	f[0] = pow(f[0], 0.5);
}


void rosenbrock_func(double* x, double* f, int nx, double* Os, double* Mr, int s_flag, int r_flag) /* Rosenbrock's */
{
	int i;
	double tmp1, tmp2;
	f[0] = 0.0;
	sr_func(x, z, nx, Os, Mr, 2.048 / 100.0, s_flag, r_flag); /* shift and rotate */
	z[0] += 1.0;//shift to orgin
	for (i = 0; i < nx - 1; i++)
	{
		z[i + 1] += 1.0;//shift to orgin
		tmp1 = z[i] * z[i] - z[i + 1];
		tmp2 = z[i] - 1.0;
		f[0] += 100.0 * tmp1 * tmp1 + tmp2 * tmp2;
	}
}

void schaffer_F7_func(double* x, double* f, int nx, double* Os, double* Mr, int s_flag, int r_flag) /* Schwefel's 1.2  */
{
	int i;
	double tmp;
	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 - 1; i++)
	{
		z[i] = pow(y[i] * y[i] + y[i + 1] * y[i + 1], 0.5);
		tmp = sin(50.0 * pow(z[i], 0.2));
		f[0] += pow(z[i], 0.5) + pow(z[i], 0.5) * tmp * tmp;
	}
	f[0] = f[0] * f[0] / (nx - 1) / (nx - 1);
}

void ackley_func(double* x, double* f, int nx, double* Os, double* Mr, int s_flag, int r_flag) /* Ackley's  */
{
	int i;
	double sum1, sum2;
	sum1 = 0.0;
	sum2 = 0.0;

	sr_func(x, z, nx, Os, Mr, 1.0, s_flag, r_flag); /* shift and rotate */

	for (i = 0; i < nx; i++)
	{
		sum1 += z[i] * z[i];
		sum2 += cos(2.0 * PI * z[i]);
	}
	sum1 = -0.2 * sqrt(sum1 / nx);
	sum2 /= nx;
	f[0] = E - 20.0 * exp(sum1) - exp(sum2) + 20.0;
}


void weierstrass_func(double* x, double* f, int nx, double* Os, double* Mr, int s_flag, int r_flag) /* Weierstrass's  */
{
	int i, j, k_max;
	double sum, sum2, a, b;
	a = 0.5;
	b = 3.0;
	k_max = 20;
	f[0] = 0.0;

	sr_func(x, z, nx, Os, Mr, 0.5 / 100.0, s_flag, r_flag); /* shift and rotate */

	for (i = 0; i < nx; i++)
	{
		sum = 0.0;
		sum2 = 0.0;
		for (j = 0; j <= k_max; j++)
		{
			sum += pow(a, j) * cos(2.0 * PI * pow(b, j) * (z[i] + 0.5));
			sum2 += pow(a, j) * cos(2.0 * PI * pow(b, j) * 0.5);
		}
		f[0] += sum;
	}
	f[0] -= nx * sum2;
}


void griewank_func(double* x, double* f, int nx, double* Os, double* Mr, int s_flag, int r_flag) /* Griewank's  */
{
	int i;
	double s, p;
	s = 0.0;
	p = 1.0;

	sr_func(x, z, nx, Os, Mr, 600.0 / 100.0, s_flag, r_flag); /* shift and rotate */

	for (i = 0; i < nx; i++)
	{
		s += z[i] * z[i];
		p *= cos(z[i] / sqrt(1.0 + i));
	}
	f[0] = 1.0 + s / 4000.0 - p;
}

void rastrigin_func(double* x, double* f, int nx, double* Os, double* Mr, int s_flag, int r_flag) /* Rastrigin's  */
{
	int i;
	f[0] = 0.0;

	sr_func(x, z, nx, Os, Mr, 5.12 / 100.0, s_flag, r_flag); /* shift and rotate */

	for (i = 0; i < nx; i++)
	{
		f[0] += (z[i] * z[i] - 10.0 * cos(2.0 * PI * z[i]) + 10.0);
	}
}

void step_rastrigin_func(double* x, double* f, int nx, double* Os, double* Mr, int s_flag, int r_flag) /* Noncontinuous Rastrigin's  */
{
	int i;
	f[0] = 0.0;
	for (i = 0; i < nx; i++)
	{
		if (fabs(y[i] - Os[i]) > 0.5)
			y[i] = Os[i] + floor(2 * (y[i] - Os[i]) + 0.5) / 2;
	}

	sr_func(x, z, nx, Os, Mr, 5.12 / 100.0, s_flag, r_flag); /* shift and rotate */

	for (i = 0; i < nx; i++)
	{
		f[0] += (z[i] * z[i] - 10.0 * cos(2.0 * PI * z[i]) + 10.0);
	}
}

void schwefel_func(double* x, double* f, int nx, double* Os, double* Mr, int s_flag, int r_flag) /* Schwefel's  */
{
	int i;
	double tmp;
	f[0] = 0.0;

	sr_func(x, z, nx, Os, Mr, 1000.0 / 100.0, s_flag, r_flag); /* shift and rotate */

	for (i = 0; i < nx; i++)
	{
		z[i] += 4.209687462275036e+002;
		if (z[i] > 500)
		{
			f[0] -= (500.0 - fmod(z[i], 500)) * sin(pow(500.0 - fmod(z[i], 500), 0.5));
			tmp = (z[i] - 500.0) / 100;
			f[0] += tmp * tmp / nx;
		}
		else if (z[i] < -500)
		{
			f[0] -= (-500.0 + fmod(fabs(z[i]), 500)) * sin(pow(500.0 - fmod(fabs(z[i]), 500), 0.5));
			tmp = (z[i] + 500.0) / 100;
			f[0] += tmp * tmp / nx;
		}
		else
			f[0] -= z[i] * sin(pow(fabs(z[i]), 0.5));
	}
	f[0] += 4.189828872724338e+002 * nx;

}

void katsuura_func(double* x, double* f, int nx, double* Os, double* Mr, int s_flag, int r_flag) /* Katsuura  */
{
	int i, j;
	double temp, tmp1, tmp2, tmp3;
	f[0] = 1.0;
	tmp3 = pow(1.0 * nx, 1.2);

	sr_func(x, z, nx, Os, Mr, 5.0 / 100.0, s_flag, r_flag); /* shift and rotate */

	for (i = 0; i < nx; i++)
	{
		temp = 0.0;
		for (j = 1; j <= 32; j++)
		{
			tmp1 = pow(2.0, j);
			tmp2 = tmp1 * z[i];
			temp += fabs(tmp2 - floor(tmp2 + 0.5)) / tmp1;
		}
		f[0] *= pow(1.0 + (i + 1) * temp, 10.0 / tmp3);
	}
	tmp1 = 10.0 / nx / nx;
	f[0] = f[0] * tmp1 - tmp1;

}

void bi_rastrigin_func(double* x, double* f, int nx, double* Os, double* Mr, int s_flag, int r_flag) /* Lunacek Bi_rastrigin Function */
{
	int i;
	double mu0 = 2.5, d = 1.0, s, mu1, tmp, tmp1, tmp2;
	double* tmpx;
	tmpx = (double*)malloc(sizeof(double) * nx);
	s = 1.0 - 1.0 / (2.0 * pow(nx + 20.0, 0.5) - 8.2);
	mu1 = -pow((mu0 * mu0 - d) / s, 0.5);

	if (s_flag == 1)
		shiftfunc(x, y, nx, Os);
	else
	{
		for (i = 0; i < nx; i++)//shrink to the orginal search range
		{
			y[i] = x[i];
		}
	}
	for (i = 0; i < nx; i++)//shrink to the orginal search range
	{
		y[i] *= 10.0 / 100.0;
	}

	for (i = 0; i < nx; i++)
	{
		tmpx[i] = 2 * y[i];
		if (Os[i] < 0.0)
			tmpx[i] *= -1.;
	}
	for (i = 0; i < nx; i++)
	{
		z[i] = tmpx[i];
		tmpx[i] += mu0;
	}
	tmp1 = 0.0; tmp2 = 0.0;
	for (i = 0; i < nx; i++)
	{
		tmp = tmpx[i] - mu0;
		tmp1 += tmp * tmp;
		tmp = tmpx[i] - mu1;
		tmp2 += tmp * tmp;
	}
	tmp2 *= s;
	tmp2 += d * nx;
	tmp = 0.0;

	if (r_flag == 1)
	{
		rotatefunc(z, y, nx, Mr);
		for (i = 0; i < nx; i++)
		{
			tmp += cos(2.0 * PI * y[i]);
		}
		if (tmp1 < tmp2)
			f[0] = tmp1;
		else
			f[0] = tmp2;
		f[0] += 10.0 * (nx - tmp);
	}
	else
	{
		for (i = 0; i < nx; i++)
		{
			tmp += cos(2.0 * PI * z[i]);
		}
		if (tmp1 < tmp2)
			f[0] = tmp1;
		else
			f[0] = tmp2;
		f[0] += 10.0 * (nx - tmp);
	}

	free(tmpx);
}

void grie_rosen_func(double* x, double* f, int nx, double* Os, double* Mr, int s_flag, int r_flag) /* Griewank-Rosenbrock  */
{
	int i;
	double temp, tmp1, tmp2;
	f[0] = 0.0;

	sr_func(x, z, nx, Os, Mr, 5.0 / 100.0, s_flag, r_flag); /* shift and rotate */

	z[0] += 1.0;//shift to orgin
	for (i = 0; i < nx - 1; i++)
	{
		z[i + 1] += 1.0;//shift to orgin
		tmp1 = z[i] * z[i] - z[i + 1];
		tmp2 = z[i] - 1.0;
		temp = 100.0 * tmp1 * tmp1 + tmp2 * tmp2;
		f[0] += (temp * temp) / 4000.0 - cos(temp) + 1.0;
	}
	tmp1 = z[nx - 1] * z[nx - 1] - z[0];
	tmp2 = z[nx - 1] - 1.0;
	temp = 100.0 * tmp1 * tmp1 + tmp2 * tmp2;
	f[0] += (temp * temp) / 4000.0 - cos(temp) + 1.0;
}


void escaffer6_func(double* x, double* f, int nx, double* Os, double* Mr, int s_flag, int r_flag) /* Expanded Scaffer??s F6  */
{
	int i;
	double temp1, temp2;

	sr_func(x, z, nx, Os, Mr, 1.0, s_flag, r_flag); /* shift and rotate */

	f[0] = 0.0;
	for (i = 0; i < nx - 1; i++)
	{
		temp1 = sin(sqrt(z[i] * z[i] + z[i + 1] * z[i + 1]));
		temp1 = temp1 * temp1;
		temp2 = 1.0 + 0.001 * (z[i] * z[i] + z[i + 1] * z[i + 1]);
		f[0] += 0.5 + (temp1 - 0.5) / (temp2 * temp2);
	}
	temp1 = sin(sqrt(z[nx - 1] * z[nx - 1] + z[0] * z[0]));
	temp1 = temp1 * temp1;
	temp2 = 1.0 + 0.001 * (z[nx - 1] * z[nx - 1] + z[0] * z[0]);
	f[0] += 0.5 + (temp1 - 0.5) / (temp2 * temp2);
}

void happycat_func(double* x, double* f, int nx, double* Os, double* Mr, int s_flag, int r_flag) /* HappyCat, provdided by Hans-Georg Beyer (HGB) */
/* original global optimum: [-1,-1,...,-1] */
{
	int i;
	double alpha, r2, sum_z;
	alpha = 1.0 / 8.0;

	sr_func(x, z, nx, Os, Mr, 5.0 / 100.0, s_flag, r_flag); /* shift and rotate */

	r2 = 0.0;
	sum_z = 0.0;
	for (i = 0; i < nx; i++)
	{
		z[i] = z[i] - 1.0;//shift to orgin
		r2 += z[i] * z[i];
		sum_z += z[i];
	}
	f[0] = pow(fabs(r2 - nx), 2 * alpha) + (0.5 * r2 + sum_z) / nx + 0.5;
}

void hgbat_func(double* x, double* f, int nx, double* Os, double* Mr, int s_flag, int r_flag) /* HGBat, provdided by Hans-Georg Beyer (HGB)*/
/* original global optimum: [-1,-1,...,-1] */
{
	int i;
	double alpha, r2, sum_z;
	alpha = 1.0 / 4.0;

	sr_func(x, z, nx, Os, Mr, 5.0 / 100.0, s_flag, r_flag); /* shift and rotate */

	r2 = 0.0;
	sum_z = 0.0;
	for (i = 0; i < nx; i++)
	{
		z[i] = z[i] - 1.0;//shift to orgin
		r2 += z[i] * z[i];
		sum_z += z[i];
	}
	f[0] = pow(fabs(pow(r2, 2.0) - pow(sum_z, 2.0)), 2 * alpha) + (0.5 * r2 + sum_z) / nx + 0.5;
}

void hf01(double* x, double* f, int nx, double* Os, double* Mr, int* S, int s_flag, int r_flag) /* Hybrid Function 1 */
{
	int i, tmp, cf_num = 3;
	double fit[3];
	int G[3], G_nx[3];
	double Gp[3] = { 0.3,0.3,0.4 };

	tmp = 0;
	for (i = 0; i < cf_num - 1; i++)
	{
		G_nx[i] = ceil(Gp[i] * nx);
		tmp += G_nx[i];
	}
	G_nx[cf_num - 1] = nx - tmp;
	G[0] = 0;
	for (i = 1; i < cf_num; i++)
	{
		G[i] = G[i - 1] + G_nx[i - 1];
	}

	sr_func(x, z, nx, Os, Mr, 1.0, s_flag, r_flag); /* shift and rotate */

	for (i = 0; i < nx; i++)
	{
		y[i] = z[S[i] - 1];
	}
	i = 0;
	schwefel_func(&y[G[i]], &fit[i], G_nx[i], Os, Mr, 0, 0);
	i = 1;
	rastrigin_func(&y[G[i]], &fit[i], G_nx[i], Os, Mr, 0, 0);
	i = 2;
	ellips_func(&y[G[i]], &fit[i], G_nx[i], Os, Mr, 0, 0);
	f[0] = 0.0;
	for (i = 0; i < cf_num; i++)
	{
		f[0] += fit[i];
	}
}

void hf02(double* x, double* f, int nx, double* Os, double* Mr, int* S, int s_flag, int r_flag) /* Hybrid Function 2 */
{
	int i, tmp, cf_num = 3;
	double fit[3];
	int G[3], G_nx[3];
	double Gp[3] = { 0.3,0.3,0.4 };

	tmp = 0;
	for (i = 0; i < cf_num - 1; i++)
	{
		G_nx[i] = ceil(Gp[i] * nx);
		tmp += G_nx[i];
	}
	G_nx[cf_num - 1] = nx - tmp;

	G[0] = 0;
	for (i = 1; i < cf_num; i++)
	{
		G[i] = G[i - 1] + G_nx[i - 1];
	}

	sr_func(x, z, nx, Os, Mr, 1.0, s_flag, r_flag); /* shift and rotate */

	for (i = 0; i < nx; i++)
	{
		y[i] = z[S[i] - 1];
	}
	i = 0;
	bent_cigar_func(&y[G[i]], &fit[i], G_nx[i], Os, Mr, 0, 0);
	i = 1;
	hgbat_func(&y[G[i]], &fit[i], G_nx[i], Os, Mr, 0, 0);
	i = 2;
	rastrigin_func(&y[G[i]], &fit[i], G_nx[i], Os, Mr, 0, 0);

	f[0] = 0.0;
	for (i = 0; i < cf_num; i++)
	{
		f[0] += fit[i];
	}
}

void hf03(double* x, double* f, int nx, double* Os, double* Mr, int* S, int s_flag, int r_flag) /* Hybrid Function 3 */
{
	int i, tmp, cf_num = 4;
	double fit[4];
	int G[4], G_nx[4];
	double Gp[4] = { 0.2,0.2,0.3,0.3 };

	tmp = 0;
	for (i = 0; i < cf_num - 1; i++)
	{
		G_nx[i] = ceil(Gp[i] * nx);
		tmp += G_nx[i];
	}
	G_nx[cf_num - 1] = nx - tmp;

	G[0] = 0;
	for (i = 1; i < cf_num; i++)
	{
		G[i] = G[i - 1] + G_nx[i - 1];
	}

	sr_func(x, z, nx, Os, Mr, 1.0, s_flag, r_flag); /* shift and rotate */

	for (i = 0; i < nx; i++)
	{
		y[i] = z[S[i] - 1];
	}
	i = 0;
	griewank_func(&y[G[i]], &fit[i], G_nx[i], Os, Mr, 0, 0);
	i = 1;
	weierstrass_func(&y[G[i]], &fit[i], G_nx[i], Os, Mr, 0, 0);
	i = 2;
	rosenbrock_func(&y[G[i]], &fit[i], G_nx[i], Os, Mr, 0, 0);
	i = 3;
	escaffer6_func(&y[G[i]], &fit[i], G_nx[i], Os, Mr, 0, 0);

	f[0] = 0.0;
	for (i = 0; i < cf_num; i++)
	{
		f[0] += fit[i];
	}
}

void hf04(double* x, double* f, int nx, double* Os, double* Mr, int* S, int s_flag, int r_flag) /* Hybrid Function 4 */
{
	int i, tmp, cf_num = 4;
	double fit[4];
	int G[4], G_nx[4];
	double Gp[4] = { 0.2,0.2,0.3,0.3 };

	tmp = 0;
	for (i = 0; i < cf_num - 1; i++)
	{
		G_nx[i] = ceil(Gp[i] * nx);
		tmp += G_nx[i];
	}
	G_nx[cf_num - 1] = nx - tmp;

	G[0] = 0;
	for (i = 1; i < cf_num; i++)
	{
		G[i] = G[i - 1] + G_nx[i - 1];
	}

	sr_func(x, z, nx, Os, Mr, 1.0, s_flag, r_flag); /* shift and rotate */

	for (i = 0; i < nx; i++)
	{
		y[i] = z[S[i] - 1];
	}
	i = 0;
	hgbat_func(&y[G[i]], &fit[i], G_nx[i], Os, Mr, 0, 0);
	i = 1;
	discus_func(&y[G[i]], &fit[i], G_nx[i], Os, Mr, 0, 0);
	i = 2;
	grie_rosen_func(&y[G[i]], &fit[i], G_nx[i], Os, Mr, 0, 0);
	i = 3;
	rastrigin_func(&y[G[i]], &fit[i], G_nx[i], Os, Mr, 0, 0);

	f[0] = 0.0;
	for (i = 0; i < cf_num; i++)
	{
		f[0] += fit[i];
	}
}
void hf05(double* x, double* f, int nx, double* Os, double* Mr, int* S, int s_flag, int r_flag) /* Hybrid Function 5 */
{
	int i, tmp, cf_num = 5;
	double fit[5];
	int G[5], G_nx[5];
	double Gp[5] = { 0.1,0.2,0.2,0.2,0.3 };

	tmp = 0;
	for (i = 0; i < cf_num - 1; i++)
	{
		G_nx[i] = ceil(Gp[i] * nx);
		tmp += G_nx[i];
	}
	G_nx[cf_num - 1] = nx - tmp;

	G[0] = 0;
	for (i = 1; i < cf_num; i++)
	{
		G[i] = G[i - 1] + G_nx[i - 1];
	}

	sr_func(x, z, nx, Os, Mr, 1.0, s_flag, r_flag); /* shift and rotate */

	for (i = 0; i < nx; i++)
	{
		y[i] = z[S[i] - 1];
	}
	i = 0;
	escaffer6_func(&y[G[i]], &fit[i], G_nx[i], Os, Mr, 0, 0);
	i = 1;
	hgbat_func(&y[G[i]], &fit[i], G_nx[i], Os, Mr, 0, 0);
	i = 2;
	rosenbrock_func(&y[G[i]], &fit[i], G_nx[i], Os, Mr, 0, 0);
	i = 3;
	schwefel_func(&y[G[i]], &fit[i], G_nx[i], Os, Mr, 0, 0);
	i = 4;
	ellips_func(&y[G[i]], &fit[i], G_nx[i], Os, Mr, 0, 0);

	f[0] = 0.0;
	for (i = 0; i < cf_num; i++)
	{
		f[0] += fit[i];
	}
}

void hf06(double* x, double* f, int nx, double* Os, double* Mr, int* S, int s_flag, int r_flag) /* Hybrid Function 6 */
{
	int i, tmp, cf_num = 5;
	double fit[5];
	int G[5], G_nx[5];
	double Gp[5] = { 0.1,0.2,0.2,0.2,0.3 };

	tmp = 0;
	for (i = 0; i < cf_num - 1; i++)
	{
		G_nx[i] = ceil(Gp[i] * nx);
		tmp += G_nx[i];
	}
	G_nx[cf_num - 1] = nx - tmp;

	G[0] = 0;
	for (i = 1; i < cf_num; i++)
	{
		G[i] = G[i - 1] + G_nx[i - 1];
	}

	sr_func(x, z, nx, Os, Mr, 1.0, s_flag, r_flag); /* shift and rotate */

	for (i = 0; i < nx; i++)
	{
		y[i] = z[S[i] - 1];
	}
	i = 0;
	katsuura_func(&y[G[i]], &fit[i], G_nx[i], Os, Mr, 0, 0);
	i = 1;
	happycat_func(&y[G[i]], &fit[i], G_nx[i], Os, Mr, 0, 0);
	i = 2;
	grie_rosen_func(&y[G[i]], &fit[i], G_nx[i], Os, Mr, 0, 0);
	i = 3;
	schwefel_func(&y[G[i]], &fit[i], G_nx[i], Os, Mr, 0, 0);
	i = 4;
	ackley_func(&y[G[i]], &fit[i], G_nx[i], Os, Mr, 0, 0);
	f[0] = 0.0;
	for (i = 0; i < cf_num; i++)
	{
		f[0] += fit[i];
	}
}

void cf01(double* x, double* f, int nx, double* Os, double* Mr, int r_flag) /* Composition Function 1 */
{
	int i, cf_num = 5;
	double fit[5];
	double delta[5] = { 10, 20, 30, 40, 50 };
	double bias[5] = { 0, 100, 200, 300, 400 };

	i = 0;
	rosenbrock_func(x, &fit[i], nx, &Os[i * nx], &Mr[i * nx * nx], 1, r_flag);
	fit[i] = 10000 * fit[i] / 1e+4;
	i = 1;
	ellips_func(x, &fit[i], nx, &Os[i * nx], &Mr[i * nx * nx], 1, r_flag);
	fit[i] = 10000 * fit[i] / 1e+10;
	i = 2;
	bent_cigar_func(x, &fit[i], nx, &Os[i * nx], &Mr[i * nx * nx], 1, r_flag);
	fit[i] = 10000 * fit[i] / 1e+30;
	i = 3;
	discus_func(x, &fit[i], nx, &Os[i * nx], &Mr[i * nx * nx], 1, r_flag);
	fit[i] = 10000 * fit[i] / 1e+10;
	i = 4;
	ellips_func(x, &fit[i], nx, &Os[i * nx], &Mr[i * nx * nx], 1, 0);
	fit[i] = 10000 * fit[i] / 1e+10;
	cf_cal(x, f, nx, Os, delta, bias, fit, cf_num);
}

void cf02(double* x, double* f, int nx, double* Os, double* Mr, int r_flag) /* Composition Function 2 */
{
	int i, cf_num = 3;
	double fit[3];
	double delta[3] = { 20,20,20 };
	double bias[3] = { 0, 100, 200 };

	i = 0;
	schwefel_func(x, &fit[i], nx, &Os[i * nx], &Mr[i * nx * nx], 1, 0);
	i = 1;
	rastrigin_func(x, &fit[i], nx, &Os[i * nx], &Mr[i * nx * nx], 1, r_flag);
	i = 2;
	hgbat_func(x, &fit[i], nx, &Os[i * nx], &Mr[i * nx * nx], 1, r_flag);
	cf_cal(x, f, nx, Os, delta, bias, fit, cf_num);
}

void cf03(double* x, double* f, int nx, double* Os, double* Mr, int r_flag) /* Composition Function 3 */
{
	int i, cf_num = 3;
	double fit[3];
	double delta[3] = { 10,30,50 };
	double bias[3] = { 0, 100, 200 };
	i = 0;
	schwefel_func(x, &fit[i], nx, &Os[i * nx], &Mr[i * nx * nx], 1, r_flag);
	fit[i] = 1000 * fit[i] / 4e+3;
	i = 1;
	rastrigin_func(x, &fit[i], nx, &Os[i * nx], &Mr[i * nx * nx], 1, r_flag);
	fit[i] = 1000 * fit[i] / 1e+3;
	i = 2;
	ellips_func(x, &fit[i], nx, &Os[i * nx], &Mr[i * nx * nx], 1, r_flag);
	fit[i] = 1000 * fit[i] / 1e+10;
	cf_cal(x, f, nx, Os, delta, bias, fit, cf_num);
}

void cf04(double* x, double* f, int nx, double* Os, double* Mr, int r_flag) /* Composition Function 4 */
{
	int i, cf_num = 5;
	double fit[5];
	double delta[5] = { 10,10,10,10,10 };
	double bias[5] = { 0, 100, 200, 300, 400 };
	i = 0;
	schwefel_func(x, &fit[i], nx, &Os[i * nx], &Mr[i * nx * nx], 1, r_flag);
	fit[i] = 1000 * fit[i] / 4e+3;
	i = 1;
	happycat_func(x, &fit[i], nx, &Os[i * nx], &Mr[i * nx * nx], 1, r_flag);
	fit[i] = 1000 * fit[i] / 1e+3;
	i = 2;
	ellips_func(x, &fit[i], nx, &Os[i * nx], &Mr[i * nx * nx], 1, r_flag);
	fit[i] = 1000 * fit[i] / 1e+10;
	i = 3;
	weierstrass_func(x, &fit[i], nx, &Os[i * nx], &Mr[i * nx * nx], 1, r_flag);
	fit[i] = 1000 * fit[i] / 400;
	i = 4;
	griewank_func(x, &fit[i], nx, &Os[i * nx], &Mr[i * nx * nx], 1, r_flag);
	fit[i] = 1000 * fit[i] / 100;
	cf_cal(x, f, nx, Os, delta, bias, fit, cf_num);
}

void cf05(double* x, double* f, int nx, double* Os, double* Mr, int r_flag) /* Composition Function 4 */
{
	int i, cf_num = 5;
	double fit[5];
	double delta[5] = { 10,10,10,20,20 };
	double bias[5] = { 0, 100, 200, 300, 400 };
	i = 0;
	hgbat_func(x, &fit[i], nx, &Os[i * nx], &Mr[i * nx * nx], 1, r_flag);
	fit[i] = 10000 * fit[i] / 1000;
	i = 1;
	rastrigin_func(x, &fit[i], nx, &Os[i * nx], &Mr[i * nx * nx], 1, r_flag);
	fit[i] = 10000 * fit[i] / 1e+3;
	i = 2;
	schwefel_func(x, &fit[i], nx, &Os[i * nx], &Mr[i * nx * nx], 1, r_flag);
	fit[i] = 10000 * fit[i] / 4e+3;
	i = 3;
	weierstrass_func(x, &fit[i], nx, &Os[i * nx], &Mr[i * nx * nx], 1, r_flag);
	fit[i] = 10000 * fit[i] / 400;
	i = 4;
	ellips_func(x, &fit[i], nx, &Os[i * nx], &Mr[i * nx * nx], 1, r_flag);
	fit[i] = 10000 * fit[i] / 1e+10;
	cf_cal(x, f, nx, Os, delta, bias, fit, cf_num);
}

void cf06(double* x, double* f, int nx, double* Os, double* Mr, int r_flag) /* Composition Function 6 */
{
	int i, cf_num = 5;
	double fit[5];
	double delta[5] = { 10,20,30,40,50 };
	double bias[5] = { 0, 100, 200, 300, 400 };
	i = 0;
	grie_rosen_func(x, &fit[i], nx, &Os[i * nx], &Mr[i * nx * nx], 1, r_flag);
	fit[i] = 10000 * fit[i] / 4e+3;
	i = 1;
	happycat_func(x, &fit[i], nx, &Os[i * nx], &Mr[i * nx * nx], 1, r_flag);
	fit[i] = 10000 * fit[i] / 1e+3;
	i = 2;
	schwefel_func(x, &fit[i], nx, &Os[i * nx], &Mr[i * nx * nx], 1, r_flag);
	fit[i] = 10000 * fit[i] / 4e+3;
	i = 3;
	escaffer6_func(x, &fit[i], nx, &Os[i * nx], &Mr[i * nx * nx], 1, r_flag);
	fit[i] = 10000 * fit[i] / 2e+7;
	i = 4;
	ellips_func(x, &fit[i], nx, &Os[i * nx], &Mr[i * nx * nx], 1, r_flag);
	fit[i] = 10000 * fit[i] / 1e+10;
	cf_cal(x, f, nx, Os, delta, bias, fit, cf_num);
}

void cf07(double* x, double* f, int nx, double* Os, double* Mr, int* SS, int r_flag) /* Composition Function 7 */
{
	int i, cf_num = 3;
	double fit[3];
	double delta[3] = { 10,30,50 };
	double bias[3] = { 0, 100, 200 };
	i = 0;
	hf01(x, &fit[i], nx, &Os[i * nx], &Mr[i * nx * nx], &SS[i * nx], 1, r_flag);
	i = 1;
	hf02(x, &fit[i], nx, &Os[i * nx], &Mr[i * nx * nx], &SS[i * nx], 1, r_flag);
	i = 2;
	hf03(x, &fit[i], nx, &Os[i * nx], &Mr[i * nx * nx], &SS[i * nx], 1, r_flag);
	cf_cal(x, f, nx, Os, delta, bias, fit, cf_num);
}

void cf08(double* x, double* f, int nx, double* Os, double* Mr, int* SS, int r_flag) /* Composition Function 8 */
{
	int i, cf_num = 3;
	double fit[3];
	double delta[3] = { 10,30,50 };
	double bias[3] = { 0, 100, 200 };
	i = 0;
	hf04(x, &fit[i], nx, &Os[i * nx], &Mr[i * nx * nx], &SS[i * nx], 1, r_flag);
	i = 1;
	hf05(x, &fit[i], nx, &Os[i * nx], &Mr[i * nx * nx], &SS[i * nx], 1, r_flag);
	i = 2;
	hf06(x, &fit[i], nx, &Os[i * nx], &Mr[i * nx * nx], &SS[i * nx], 1, r_flag);
	cf_cal(x, f, nx, Os, delta, bias, fit, cf_num);
}



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 (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);
		}
		else
			for (i = 0; i < nx; i++)//shrink to the original search range
			{
				sr_x[i] = x[i] * sh_rate;
			}
	}
}

void asyfunc(double* x, double* xasy, int nx, double beta)
{
	int i;
	for (i = 0; i < nx; i++)
	{
		if (x[i] > 0)
			xasy[i] = pow(x[i], 1.0 + beta * i / (nx - 1) * pow(x[i], 0.5));
	}
}

void oszfunc(double* x, double* xosz, int nx)
{
	int i, sx;
	double c1, c2, xx;
	for (i = 0; i < nx; i++)
	{
		if (i == 0 || i == nx - 1)
		{
			if (x[i] != 0)
				xx = log(fabs(x[i]));
			if (x[i] > 0)
			{
				c1 = 10;
				c2 = 7.9;
			}
			else
			{
				c1 = 5.5;
				c2 = 3.1;
			}
			if (x[i] > 0)
				sx = 1;
			else if (x[i] == 0)
				sx = 0;
			else
				sx = -1;
			xosz[i] = sx * exp(xx + 0.049 * (sin(c1 * xx) + sin(c2 * xx)));
		}
		else
			xosz[i] = x[i];
	}
}


void cf_cal(double* x, double* f, int nx, double* Os, double* delta, double* bias, double* fit, int cf_num)
{
	int i, j;
	double* w;
	double w_max = 0, w_sum = 0;
	w = (double*)malloc(cf_num * sizeof(double));
	for (i = 0; i < cf_num; i++)
	{
		fit[i] += bias[i];
		w[i] = 0;
		for (j = 0; j < nx; j++)
		{
			w[i] += pow(x[j] - Os[i * nx + j], 2.0);
		}
		if (w[i] != 0)
			w[i] = pow(1.0 / w[i], 0.5) * exp(-w[i] / 2.0 / nx / pow(delta[i], 2.0));
		else
			w[i] = INF;
		if (w[i] > w_max)
			w_max = w[i];
	}

	for (i = 0; i < cf_num; i++)
	{
		w_sum = w_sum + w[i];
	}
	if (w_max == 0)
	{
		for (i = 0; i < cf_num; i++)
			w[i] = 1;
		w_sum = cf_num;
	}
	f[0] = 0.0;
	for (i = 0; i < cf_num; i++)
	{
		f[0] = f[0] + w[i] / w_sum * fit[i];
	}
	free(w);
}


由于仍与实验结果存在差距,本人也会继续更新代码,以达到是预期结果

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ttzif

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值