using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using EvoBoat.EvoAlg;

namespace NumTest
{
    using NOP = NumOptProblem<VecSolution<EvoBoat.EvoAlg.Vector, double>>;

    public class CEC14TestProblems
    {
        const double INF = 1.0e99;
        const double EPS = 1.0e-14;
        const double E = 2.7182818284590452353602874713526625;
        const double PI = 3.1415926535897932384626433832795029;

        static Vector[] shifts, rotates;
        static int[][] shuffles;
        //static int ini_flag, n_flag, func_flag;

        static int cf_num = 10;

        public static NOP[] Problems30D;

        static CEC14TestProblems()
        {
            shifts = new Vector[30];
            rotates = new Vector[30];
            shuffles = new int[30][];
            Problems30D = new NOP[30];
            for (int i = 0; i < 30; i++)
            {
                Problems30D[i] = Problem(i + 1, 30);
            }
        }

        static Vector LoadRotateMatrix(int num, int D)
        {
            double[] array;
            string[] lines = File.ReadLines(string.Format("testproblems\\cec14data\\M_{0}_D{1}.txt", num, D)).ToArray();
            if (num < 23)
            {
                array = new double[D * D];
            }
            else
            {
                array = new double[D * D * cf_num];
            }
            for (int i = 0, p = 0; i < lines.Length; i++)
            {
                string[] ss = lines[i].Trim().Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
                for (int j = 0; j < ss.Length; j++)
                    array[p++] = double.Parse(ss[j].Trim());
            }
            return new Vector(array);
        }

        static Vector LoadShiftData(int num, int D)
        {
            double[] array;
            string s = File.ReadAllText(string.Format("testproblems\\cec14data\\shift_data_{0}.txt", num));
            string[] ss;
            if (num < 23)
            {
                array = new double[D];
                ss = s.Trim().Split(new Char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
                for (int i = 0; i < array.Length; i++)
                    array[i] = double.Parse(ss[i].Trim());
            }
            else
            {
                array = new double[D * cf_num];
                ss = s.Trim().Split(new Char[] { '\n' }, StringSplitOptions.RemoveEmptyEntries);
                string[] sss;
                for (int j = 0; j < cf_num; j++)
                {
                    sss = ss[j].Trim().Split(new Char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
                    for (int i = 0; i < D; i++)
                        array[j * D + i] = double.Parse(sss[i].Trim());
                }
            }
            return new Vector(array);
        }

        static int[] LoadShuffleData(int num, int D)
        {
            int[] array = null;
            string s = File.ReadAllText(string.Format("testproblems\\cec14data\\shuffle_data_{0}_D{1}.txt", num, D));
            string[] ss = s.Trim().Split(new Char[] { '\t' }, StringSplitOptions.RemoveEmptyEntries);
            if (num >= 17 && num <= 22)
            {
                array = new int[D];
                for (int i = 0; i < ss.Length; i++)
                    array[i] = int.Parse(ss[i].Trim());
            }
            else if (num == 29 || num == 30)
            {
                array = new int[D * cf_num];
                for (int i = 0; i < ss.Length; i++)
                    array[i] = int.Parse(ss[i].Trim());
            }
            return array;
        }

        public static NOP Problem(int num, int D)
        {
            if (object.ReferenceEquals(shifts[num - 1], null))
                shifts[num - 1] = LoadShiftData(num, D);
            if (object.ReferenceEquals(rotates[num - 1], null))
                rotates[num - 1] = LoadRotateMatrix(num, D);
            if (((num >= 17 && num <= 22) || num == 29 || num == 30) && object.ReferenceEquals(shuffles[num - 1], null))
                shuffles[num - 1] = LoadShuffleData(num, D);
            string name = string.Format("F{0}_{1}D", num, D);
            return new NOP(funs[num - 1], Vector.Create(D, -100), Vector.Create(D, 100), name, num * 100);
        }


        static Vector rotatefunc(Vector x, Vector Mr)
        {
            double[] xrot = new double[x.Length];
            for (int i = 0; i < x.Length; i++)
            {
                xrot[i] = 0;
                for (int j = 0; j < x.Length; j++)
                    xrot[i] = xrot[i] + x[j] * Mr[i * x.Length + j];
            }
            return xrot;
        }

        static Vector sr_func(Vector x, Vector Os, Vector Mr, double sh_rate, int s_flag, int r_flag)
        {
            Vector r;
            if (s_flag == 1)
            {
                r = (x - Os) * sh_rate;
                if (r_flag == 1)
                    r = rotatefunc(r, Mr);
            }
            else
            {
                r = x * sh_rate;
                if (r_flag == 1)
                    r = rotatefunc(r, Mr);
            }
            return r;
        }

        public static double ellips_func(Vector x, Vector Os, Vector Mr, int s_flag, int r_flag) /* Ellipsoidal */
        {
            double r = 0.0;
            Vector z = sr_func(x, Os, Mr, 1.0, s_flag, r_flag);/*shift and rotate*/
            for (int i = 0; i < x.Length; i++)
                r += Math.Pow(10.0, 6.0 * i / (x.Length - 1)) * z[i] * z[i];
            return r;
        }

        public static double bentCigar_func(Vector x, Vector Os, Vector Mr, int s_flag, int r_flag) /* Ellipsoidal */
        {
            Vector z = sr_func(x, Os, Mr, 1.0, s_flag, r_flag);/*shift and rotate*/
            double r = z[0] * z[0];
            for (int i = 1; i < x.Length; i++)
                r += 1000000 * z[i] * z[i];
            return r;
        }

        public static double discus_func(Vector x, Vector Os, Vector Mr, int s_flag, int r_flag) /* Ellipsoidal */
        {
            Vector z = sr_func(x, Os, Mr, 1.0, s_flag, r_flag);/*shift and rotate*/
            double r = Math.Pow(10.0, 6.0) * z[0] * z[0];
            for (int i = 1; i < x.Length; i++)
                r += z[i] * z[i];
            return r;
        }

        public static double rosenbrock_func(Vector x, Vector Os, Vector Mr, int s_flag, int r_flag) /* Ellipsoidal */
        {
            Vector z = sr_func(x, Os, Mr, 2.048 / 100.0, s_flag, r_flag);/*shift and rotate*/
            double r = 0, t1, t2;
            z[0] += 1.0;
            for (int i = 0; i < x.Length - 1; i++)
            {
                z[i + 1] += 1.0;
                t1 = z[i] * z[i] - z[i + 1];
                t2 = z[i] - 1.0;
                r += 100 * t1 * t1 + t2 * t2;
            }
            return r;
        }

        public static double ackley_func(Vector x, Vector Os, Vector Mr, int s_flag, int r_flag) /* Ellipsoidal */
        {
            Vector z = sr_func(x, Os, Mr, 1.0, s_flag, r_flag);/*shift and rotate*/
            //return YaoTestProblems.Ackley(z);
            double r = 0, t1 = 0, t2 = 0;
            for (int i = 0; i < x.Length; i++)
            {
                t1 += z[i] * z[i];
                t2 += Math.Cos(2 * Math.PI * z[i]);
            }
            t1 = -0.2 * Math.Sqrt(t1 / x.Length);
            t2 /= x.Length;
            r = Math.E - 20.0 * Math.Exp(t1) - Math.Exp(t2) + 20.0;
            return r;
        }

        public static double weierstrass_func(Vector x, Vector Os, Vector Mr, int s_flag, int r_flag) /* Ellipsoidal */
        {
            Vector z = sr_func(x, Os, Mr, 0.5 / 100.0, s_flag, r_flag);/*shift and rotate*/
            double r = 0, t1 = 0, t2 = 0;
            double a = 0.5, b = 3.0, kmax = 20;
            for (int i = 0; i < x.Length; i++)
            {
                t1 = 0;
                for (int j = 0; j <= kmax; j++)
                    t1 += Math.Pow(a, j) * Math.Cos(2 * Math.PI * Math.Pow(b, j) * (z[i] + 0.5));
                r += t1;
            }
            for (int j = 0; j <= kmax; j++)
                t2 += Math.Pow(a, j) * Math.Cos(2 * Math.PI * Math.Pow(b, j) * 0.5);
            r -= (t2 * x.Length);
            return r;
        }

        public static double griewank_func(Vector x, Vector Os, Vector Mr, int s_flag, int r_flag) /* Ellipsoidal */
        {
            Vector z = sr_func(x, Os, Mr, 600.0 / 100.0, s_flag, r_flag);/*shift and rotate*/
            double r = 0, s = 0.0, p = 1.0;
            for (int i = 0; i < x.Length; i++)
            {
                s += z[i] * z[i];
                p *= Math.Cos(z[i] / Math.Sqrt(1.0 + i));
            }
            r = 1.0 + s / 4000 - p;
            return r;
        }

        public static double rastrigin_func(Vector x, Vector Os, Vector Mr, int s_flag, int r_flag) /* Ellipsoidal */
        {
            Vector z = sr_func(x, Os, Mr, 5.12 / 100.0, s_flag, r_flag);/*shift and rotate*/
            double r = 0;
            for (int i = 0; i < x.Length; i++)
                r += (z[i] * z[i] - 10.0 * Math.Cos(2 * Math.PI * z[i]) + 10.0);
            return r;
        }

        public static double schwefel_func(Vector x, Vector Os, Vector Mr, int s_flag, int r_flag) /* Schwefel's  */
        {
            Vector z = sr_func(x, Os, Mr, 1000.0 / 100.0, s_flag, r_flag);/*shift and rotate*/
            double r = 0, t;
            for (int i = 0; i < x.Length; i++)
            {
                z[i] += 420.9687462275036;
                if (z[i] > 500)
                {
                    t = 500.0 - (z[i] % 500.0);
                    r -= (t * Math.Sin(Math.Sqrt(t)));
                    t = (z[i] - 500.0) / 100;
                    r += (t * t / x.Length);
                }
                else if (z[i] < -500)
                {
                    t = 500.0 - (-z[i] % 500.0);
                    r -= (-t * Math.Sin(Math.Sqrt(t)));
                    t = (z[i] + 500.0) / 100;
                    r += (t * t / x.Length);
                }
                else
                    r -= z[i] * Math.Sin(Math.Sqrt(Math.Abs(z[i])));
            }
            return r + 418.9828872724338 * x.Length;
        }

        public static double katsuura_func(Vector x, Vector Os, Vector Mr, int s_flag, int r_flag) /* Katsuura  */
        {
            Vector z = sr_func(x, Os, Mr, 5.0 / 100.0, s_flag, r_flag);/*shift and rotate*/
            double r = 1.0, t, t1 = 0, t2 = 0, t3 = Math.Pow(1.0 * x.Length, 1.2);
            for (int i = 0; i < x.Length; i++)
            {
                t = 0;
                for (int j = 1; j <= 32; j++)
                {
                    t1 = Math.Pow(2.0, j);
                    t2 = t1 * z[i];
                    t += Math.Abs(t2 - Math.Floor(t2 + 0.5)) / t1;
                }
                r *= Math.Pow(1.0 + (i + 1) * t, 10.0 / t3);
            }
            t1 = 10.0 / x.Length / x.Length;
            r = r * t1 - t1;
            return r;
        }

        public static double happycat_func(Vector x, Vector Os, Vector Mr, int s_flag, int r_flag) /* HappyCat, provdided by Hans-Georg Beyer (HGB) */
        /* original global optimum: [-1,-1,...,-1] */
        {
            Vector z = sr_func(x, Os, Mr, 5.0 / 100.0, s_flag, r_flag);/*shift and rotate*/
            double r = 0, r2 = 0, sumz = 0;
            for (int i = 0; i < x.Length; i++)
            {
                z[i] = z[i] - 1.0;//shift to orgin
                r2 += (z[i] * z[i]);
                sumz += z[i];
            }
            r = Math.Pow(Math.Abs(r2 - x.Length), 0.25) + (0.5 * r2 + sumz) / x.Length + 0.5;
            return r;
        }

        public static double hgbat_func(Vector x, Vector Os, Vector Mr, int s_flag, int r_flag) /* HGBat, provdided by Hans-Georg Beyer (HGB)*/
        /* original global optimum: [-1,-1,...,-1] */
        {
            Vector z = sr_func(x, Os, Mr, 5.0 / 100.0, s_flag, r_flag);/*shift and rotate*/
            double r = 0, r2 = 0, sumz = 0, alpha = 1.0 / 4.0;
            for (int i = 0; i < x.Length; i++)
            {
                z[i] = z[i] - 1.0;//shift to orgin
                r2 += z[i] * z[i];
                sumz += z[i];
            }
            r = Math.Pow(Math.Abs(Math.Pow(r2, 2.0) - Math.Pow(sumz, 2.0)), 2 * alpha) + (0.5 * r2 + sumz) / x.Length + 0.5;
            return r;
        }

        public static double grie_rosen_func(Vector x, Vector Os, Vector Mr, int s_flag, int r_flag) /* Griewank-Rosenbrock  */
        {
            Vector z = sr_func(x, Os, Mr, 5.0 / 100.0, s_flag, r_flag);/*shift and rotate*/
            double r = 0, t = 0, t1 = 0, t2 = 0;
            z[0] += 1.0;//shift to orgin
            for (int i = 0; i < x.Length - 1; i++)
            {
                z[i + 1] += 1.0;//shift to orgin
                t1 = z[i] * z[i] - z[i + 1];
                t2 = z[i] - 1.0;
                t = 100.0 * t1 * t1 + t2 * t2;
                r += (t * t) / 4000.0 - Math.Cos(t) + 1.0;
            }
            t1 = z[x.Length - 1] * z[x.Length - 1] - z[0];
            t2 = z[x.Length - 1] - 1.0;
            t = 100.0 * t1 * t1 + t2 * t2;
            r += (t * t) / 4000.0 - Math.Cos(t) + 1.0;
            return r;
        }

        public static double escaffer6_func(Vector x, Vector Os, Vector Mr, int s_flag, int r_flag) /* Expanded Scaffer??s F6  */
        {
            Vector z = sr_func(x, Os, Mr, 1.0, s_flag, r_flag);/*shift and rotate*/
            double r = 0, t1 = 0, t2 = 0;
            for (int i = 0; i < x.Length - 1; i++)
            {
                t1 = Math.Sin(Math.Sqrt(z[i] * z[i] + z[i + 1] * z[i + 1]));
                t1 = t1 * t1;
                t2 = 1.0 + 0.001 * (z[i] * z[i] + z[i + 1] * z[i + 1]);
                r += 0.5 + (t1 - 0.5) / (t2 * t2);
            }
            t1 = Math.Sin(Math.Sqrt(z[x.Length - 1] * z[x.Length - 1] + z[0] * z[0]));
            t1 = t1 * t1;
            t2 = 1.0 + 0.001 * (z[x.Length - 1] * z[x.Length - 1] + z[0] * z[0]);
            r += 0.5 + (t1 - 0.5) / (t2 * t2);
            return r;
        }

        public static double hf01(Vector x, Vector Os, Vector Mr, int[] S, int s_flag, int r_flag) /* Hybrid Function 1 */
        {
            double r = 0;
            int i, tmp = 0, cf_num = 3;
            double[] fit = new double[3];
            int[] G = new int[3], G_nx = new int[3];
            double[] Gp = { 0.3, 0.3, 0.4 };
            for (i = 0; i < cf_num - 1; i++)
            {
                G_nx[i] = (int)Math.Ceiling(Gp[i] * x.Length);
                tmp += G_nx[i];
            }
            G_nx[cf_num - 1] = x.Length - tmp;
            G[0] = 0;
            for (i = 1; i < cf_num; i++)
            {
                G[i] = G[i - 1] + G_nx[i - 1];
            }
            Vector z = sr_func(x, Os, Mr, 1.0, s_flag, r_flag);/*shift and rotate*/
            Vector y = Vector.Create(x.Length);
            for (i = 0; i < x.Length; i++)
            {
                y[i] = z[S[i] - 1];
            }
            i = 0;
            fit[i] = schwefel_func(y.SubVector(G[i], G_nx[i]), Os, Mr, 0, 0);
            i = 1;
            fit[i] = rastrigin_func(y.SubVector(G[i], G_nx[i]), Os, Mr, 0, 0);
            i = 2;
            fit[i] = ellips_func(y.SubVector(G[i], G_nx[i]), Os, Mr, 0, 0);
            for (i = 0; i < cf_num; i++)
            {
                r += fit[i];
            }
            return r;
        }

        public static double hf02(Vector x, Vector Os, Vector Mr, int[] S, int s_flag, int r_flag) /* Hybrid Function 2 */
        {
            double r = 0;
            int i, t = 0, cf_num = 3;
            double[] fit = new double[3];
            int[] G = new int[3], G_nx = new int[3];
            double[] Gp = { 0.3, 0.3, 0.4 };
            for (i = 0; i < cf_num - 1; i++)
            {
                G_nx[i] = (int)Math.Ceiling(Gp[i] * x.Length);
                t += G_nx[i];
            }
            G_nx[cf_num - 1] = x.Length - t;
            G[0] = 0;
            for (i = 1; i < cf_num; i++)
            {
                G[i] = G[i - 1] + G_nx[i - 1];
            }
            Vector z = sr_func(x, Os, Mr, 1.0, s_flag, r_flag);/*shift and rotate*/
            Vector y = Vector.Create(x.Length);
            for (i = 0; i < x.Length; i++)
            {
                y[i] = z[S[i] - 1];
            }
            i = 0;
            fit[i] = bentCigar_func(y.SubVector(G[i], G_nx[i]), Os, Mr, 0, 0);
            i = 1;
            fit[i] = hgbat_func(y.SubVector(G[i], G_nx[i]), Os, Mr, 0, 0);
            i = 2;
            fit[i] = rastrigin_func(y.SubVector(G[i], G_nx[i]), Os, Mr, 0, 0);
            for (i = 0; i < cf_num; i++)
            {
                r += fit[i];
            }
            return r;
        }

        public static double hf03(Vector x, Vector Os, Vector Mr, int[] S, int s_flag, int r_flag) /* Hybrid Function 3 */
        {
            double r = 0;
            int i, tmp = 0, cf_num = 4;
            double[] fit = new double[4];
            int[] G = new int[4], G_nx = new int[4];
            double[] Gp = { 0.2, 0.2, 0.3, 0.3 };
            for (i = 0; i < cf_num - 1; i++)
            {
                G_nx[i] = (int)Math.Ceiling(Gp[i] * x.Length);
                tmp += G_nx[i];
            }
            G_nx[cf_num - 1] = x.Length - tmp;
            G[0] = 0;
            for (i = 1; i < cf_num; i++)
            {
                G[i] = G[i - 1] + G_nx[i - 1];
            }
            Vector z = sr_func(x, Os, Mr, 1.0, s_flag, r_flag);/*shift and rotate*/
            Vector y = Vector.Create(x.Length);
            for (i = 0; i < x.Length; i++)
            {
                y[i] = z[S[i] - 1];
            }
            i = 0;
            fit[i] = griewank_func(y.SubVector(G[i], G_nx[i]), Os, Mr, 0, 0);
            i = 1;
            fit[i] = weierstrass_func(y.SubVector(G[i], G_nx[i]), Os, Mr, 0, 0);
            i = 2;
            fit[i] = rosenbrock_func(y.SubVector(G[i], G_nx[i]), Os, Mr, 0, 0);
            i = 3;
            fit[i] = escaffer6_func(y.SubVector(G[i], G_nx[i]), Os, Mr, 0, 0);
            for (i = 0; i < cf_num; i++)
            {
                r += fit[i];
            }
            return r;
        }

        public static double hf04(Vector x, Vector Os, Vector Mr, int[] S, int s_flag, int r_flag) /* Hybrid Function 4 */
        {
            double r = 0;
            int i, t = 0, cf_num = 4;
            double[] fit = new double[4];
            int[] G = new int[4], G_nx = new int[4];
            double[] Gp = { 0.2, 0.2, 0.3, 0.3 };
            for (i = 0; i < cf_num - 1; i++)
            {
                G_nx[i] = (int)Math.Ceiling(Gp[i] * x.Length);
                t += G_nx[i];
            }
            G_nx[cf_num - 1] = x.Length - t;
            G[0] = 0;
            for (i = 1; i < cf_num; i++)
            {
                G[i] = G[i - 1] + G_nx[i - 1];
            }
            Vector z = sr_func(x, Os, Mr, 1.0, s_flag, r_flag);/*shift and rotate*/
            Vector y = Vector.Create(x.Length);
            for (i = 0; i < x.Length; i++)
            {
                y[i] = z[S[i] - 1];
            }
            i = 0;
            fit[i] = hgbat_func(y.SubVector(G[i], G_nx[i]), Os, Mr, 0, 0);
            i = 1;
            fit[i] = discus_func(y.SubVector(G[i], G_nx[i]), Os, Mr, 0, 0);
            i = 2;
            fit[i] = grie_rosen_func(y.SubVector(G[i], G_nx[i]), Os, Mr, 0, 0);
            i = 3;
            fit[i] = rastrigin_func(y.SubVector(G[i], G_nx[i]), Os, Mr, 0, 0);
            for (i = 0; i < cf_num; i++)
            {
                r += fit[i];
            }
            return r;
        }

        public static double hf05(Vector x, Vector Os, Vector Mr, int[] S, int s_flag, int r_flag) /* Hybrid Function 5 */
        {
            double r = 0;
            int i, t = 0, cf_num = 5;
            double[] fit = new double[5];
            int[] G = new int[5], G_nx = new int[5];
            double[] Gp = { 0.1, 0.2, 0.2, 0.2, 0.3 };
            for (i = 0; i < cf_num - 1; i++)
            {
                G_nx[i] = (int)Math.Ceiling(Gp[i] * x.Length);
                t += G_nx[i];
            }
            G_nx[cf_num - 1] = x.Length - t;
            G[0] = 0;
            for (i = 1; i < cf_num; i++)
            {
                G[i] = G[i - 1] + G_nx[i - 1];
            }
            Vector z = sr_func(x, Os, Mr, 1.0, s_flag, r_flag);/*shift and rotate*/
            Vector y = Vector.Create(x.Length);
            for (i = 0; i < x.Length; i++)
            {
                y[i] = z[S[i] - 1];
            }
            i = 0;
            fit[i] = escaffer6_func(y.SubVector(G[i], G_nx[i]), Os, Mr, 0, 0);
            i = 1;
            fit[i] = hgbat_func(y.SubVector(G[i], G_nx[i]), Os, Mr, 0, 0);
            i = 2;
            fit[i] = rosenbrock_func(y.SubVector(G[i], G_nx[i]), Os, Mr, 0, 0);
            i = 3;
            fit[i] = schwefel_func(y.SubVector(G[i], G_nx[i]), Os, Mr, 0, 0);
            i = 4;
            fit[i] = ellips_func(y.SubVector(G[i], G_nx[i]), Os, Mr, 0, 0);
            for (i = 0; i < cf_num; i++)
            {
                r += fit[i];
            }
            return r;
        }

        public static double hf06(Vector x, Vector Os, Vector Mr, int[] S, int s_flag, int r_flag) /* Hybrid Function 6 */
        {
            double r = 0;
            int i, t = 0, cf_num = 5;
            double[] fit = new double[5];
            int[] G = new int[5], G_nx = new int[5];
            double[] Gp = { 0.1, 0.2, 0.2, 0.2, 0.3 };
            for (i = 0; i < cf_num - 1; i++)
            {
                G_nx[i] = (int)Math.Ceiling(Gp[i] * x.Length);
                t += G_nx[i];
            }
            G_nx[cf_num - 1] = x.Length - t;
            G[0] = 0;
            for (i = 1; i < cf_num; i++)
            {
                G[i] = G[i - 1] + G_nx[i - 1];
            }
            Vector z = sr_func(x, Os, Mr, 1.0, s_flag, r_flag);/*shift and rotate*/
            Vector y = Vector.Create(x.Length);
            for (i = 0; i < x.Length; i++)
            {
                y[i] = z[S[i] - 1];
            }
            i = 0;
            fit[i] = katsuura_func(y, Os, Mr, 0, 0);
            i = 1;
            fit[i] = happycat_func(y.SubVector(G[i], G_nx[i]), Os, Mr, 0, 0);
            i = 2;
            fit[i] = grie_rosen_func(y.SubVector(G[i], G_nx[i]), Os, Mr, 0, 0);
            i = 3;
            fit[i] = schwefel_func(y.SubVector(G[i], G_nx[i]), Os, Mr, 0, 0);
            i = 4;
            fit[i] = ackley_func(y.SubVector(G[i], G_nx[i]), Os, Mr, 0, 0);
            for (i = 0; i < cf_num; i++)
            {
                r += fit[i];
            }
            return r;
        }

        public static double cf01(Vector x, Vector Os, Vector Mr, int r_flag) /* Composition Function 1 */
        {
            int i, cf_num = 5;
            double r = 0;
            double[] fit = new double[5];
            double[] delta = { 10, 20, 30, 40, 50 };
            double[] bias = { 0, 100, 200, 300, 400 };
            i = 0;
            fit[i] = rosenbrock_func(x, Os, Mr, 1, r_flag);
            fit[i] = 10000 * fit[i] / 1e+4;
            i = 1;
            fit[i] = ellips_func(x, Os.SubVector(i * x.Length, x.Length), Mr.SubVector(i * x.Length * x.Length, Mr.Length - i * x.Length * x.Length), 1, r_flag);
            fit[i] = 10000 * fit[i] / 1e+10;
            i = 2;
            fit[i] = bentCigar_func(x, Os.SubVector(i * x.Length, x.Length), Mr.SubVector(i * x.Length * x.Length, Mr.Length - i * x.Length * x.Length), 1, r_flag);
            fit[i] = 10000 * fit[i] / 1e+30;
            i = 3;
            fit[i] = discus_func(x, Os.SubVector(i * x.Length, x.Length), Mr.SubVector(i * x.Length * x.Length, Mr.Length - i * x.Length * x.Length), 1, r_flag);
            fit[i] = 10000 * fit[i] / 1e+10;
            i = 4;
            fit[i] = ellips_func(x, Os.SubVector(i * x.Length, x.Length), Mr.SubVector(i * x.Length * x.Length, Mr.Length - i * x.Length * x.Length), 1, 0);
            fit[i] = 10000 * fit[i] / 1e+10;
            r = cf_cal(x, Os, delta, bias, fit, cf_num);
            return r;
        }

        public static double cf02(Vector x, Vector Os, Vector Mr, int r_flag) /* Composition Function 2 */
        {
            int i, cf_num = 3;
            double r = 0;
            double[] fit = new double[3];
            double[] delta = { 20, 20, 20 };
            double[] bias = { 0, 100, 200 };
            i = 0;
            fit[i] = schwefel_func(x, Os.SubVector(x.Length), Mr.SubVector(x.Length * x.Length), 1, 0);
            i = 1;
            Vector tOS = Os.SubVector(i * x.Length, x.Length), tMr = Mr.SubVector(i * x.Length * x.Length, x.Length * x.Length);
            fit[i] = rastrigin_func(x, tOS, tMr, 1, r_flag);
            i = 2;
            tOS = Os.SubVector(i * x.Length, x.Length);
            tMr = Mr.SubVector(i * x.Length * x.Length, x.Length * x.Length);
            fit[i] = hgbat_func(x, tOS, tMr, 1, r_flag);
            r = cf_cal(x, Os, delta, bias, fit, cf_num);
            return r;
        }

        public static double cf03(Vector x, Vector Os, Vector Mr, int r_flag) /* Composition Function 3 */
        {
            int i, cf_num = 3;
            double r = 0;
            double[] fit = new double[3];
            double[] delta = { 10, 30, 50 };
            double[] bias = { 0, 100, 200 };
            i = 0;
            fit[i] = schwefel_func(x, Os.SubVector(i * x.Length, x.Length), Mr.SubVector(i * x.Length * x.Length, x.Length * x.Length), 1, r_flag);
            fit[i] = 0.25 * fit[i];
            i = 1;
            fit[i] = rastrigin_func(x, Os.SubVector(i * x.Length, x.Length), Mr.SubVector(i * x.Length * x.Length, x.Length * x.Length), 1, r_flag);
            //fit[i] = 1000.0 * fit[i] / (1e+3);
            i = 2;
            fit[i] = ellips_func(x, Os.SubVector(i * x.Length, x.Length), Mr.SubVector(i * x.Length * x.Length, x.Length * x.Length), 1, r_flag);
            fit[i] = fit[i] / (1e+7);
            r = cf_cal(x, Os, delta, bias, fit, cf_num);
            return r;
        }

        public static double cf04(Vector x, Vector Os, Vector Mr, int r_flag) /* Composition Function 4 */
        {
            int i, cf_num = 5;
            double r = 0;
            double[] fit = new double[5];
            double[] delta = { 10, 10, 10, 10, 10 };
            double[] bias = { 0, 100, 200, 300, 400 };
            i = 0;
            fit[i] = schwefel_func(x, Os.SubVector(i * x.Length, x.Length), Mr.SubVector(i * x.Length * x.Length, x.Length * x.Length), 1, r_flag);
            fit[i] = 1000 * fit[i] / 4e+3;
            i = 1;
            fit[i] = happycat_func(x, Os.SubVector(i * x.Length, x.Length), Mr.SubVector(i * x.Length * x.Length, x.Length * x.Length), 1, r_flag);
            fit[i] = 1000 * fit[i] / 1e+3;
            i = 2;
            fit[i] = ellips_func(x, Os.SubVector(i * x.Length, x.Length), Mr.SubVector(i * x.Length * x.Length, x.Length * x.Length), 1, r_flag);
            fit[i] = 1000 * fit[i] / 1e+10;
            i = 3;
            fit[i] = weierstrass_func(x, Os.SubVector(i * x.Length, x.Length), Mr.SubVector(i * x.Length * x.Length, x.Length * x.Length), 1, r_flag);
            fit[i] = 1000 * fit[i] / 400;
            i = 4;
            fit[i] = griewank_func(x, Os.SubVector(i * x.Length, x.Length), Mr.SubVector(i * x.Length * x.Length, x.Length * x.Length), 1, r_flag);
            fit[i] = 1000 * fit[i] / 100;
            r = cf_cal(x, Os, delta, bias, fit, cf_num);
            return r;
        }

        public static double cf05(Vector x, Vector Os, Vector Mr, int r_flag) /* Composition Function 5 */
        {
            int i, cf_num = 5;
            double r = 0;
            double[] fit = new double[5];
            double[] delta = { 10, 10, 10, 20, 20 };
            double[] bias = { 0, 100, 200, 300, 400 };
            i = 0;
            fit[i] = hgbat_func(x, Os.SubVector(i * x.Length, x.Length), Mr.SubVector(i * x.Length * x.Length, x.Length * x.Length), 1, r_flag);//参数可能有问题
            fit[i] = 10000 * fit[i] / 1000;
            i = 1;
            fit[i] = rastrigin_func(x, Os.SubVector(i * x.Length, x.Length), Mr.SubVector(i * x.Length * x.Length, x.Length * x.Length), 1, r_flag);
            fit[i] = 10000 * fit[i] / 1e+3;
            i = 2;
            fit[i] = schwefel_func(x, Os.SubVector(i * x.Length, x.Length), Mr.SubVector(i * x.Length * x.Length, x.Length * x.Length), 1, r_flag);
            fit[i] = 10000 * fit[i] / 4e+3;
            i = 3;
            fit[i] = weierstrass_func(x, Os.SubVector(i * x.Length, x.Length), Mr.SubVector(i * x.Length * x.Length, x.Length * x.Length), 1, r_flag);
            fit[i] = 10000 * fit[i] / 400;
            i = 4;
            fit[i] = ellips_func(x, Os.SubVector(i * x.Length, x.Length), Mr.SubVector(i * x.Length * x.Length, x.Length * x.Length), 1, r_flag);
            fit[i] = 10000 * fit[i] / 1e+10;
            r = cf_cal(x, Os, delta, bias, fit, cf_num);
            return r;
        }

        public static double cf06(Vector x, Vector Os, Vector Mr, int r_flag) /* Composition Function 6 */
        {
            int i, cf_num = 5;
            double r = 0;
            double[] fit = new double[5];
            double[] delta = { 10, 20, 30, 40, 50 };
            double[] bias = { 0, 100, 200, 300, 400 };
            i = 0;
            fit[i] = grie_rosen_func(x, Os.SubVector(i * x.Length, x.Length), Mr.SubVector(i * x.Length * x.Length, x.Length * x.Length), 1, r_flag);//参数可能有问题
            fit[i] = 10000 * fit[i] / 4e+3;
            i = 1;
            fit[i] = happycat_func(x, Os.SubVector(i * x.Length, x.Length), Mr.SubVector(i * x.Length * x.Length, x.Length * x.Length), 1, r_flag);
            fit[i] = 10000 * fit[i] / 1e+3;
            i = 2;
            fit[i] = schwefel_func(x, Os.SubVector(i * x.Length, x.Length), Mr.SubVector(i * x.Length * x.Length, x.Length * x.Length), 1, r_flag);
            fit[i] = 10000 * fit[i] / 4e+3;
            i = 3;
            fit[i] = escaffer6_func(x, Os.SubVector(i * x.Length, x.Length), Mr.SubVector(i * x.Length * x.Length, x.Length * x.Length), 1, r_flag);
            fit[i] = 10000 * fit[i] / 2e+7;
            i = 4;
            fit[i] = ellips_func(x, Os.SubVector(i * x.Length, x.Length), Mr.SubVector(i * x.Length * x.Length, x.Length * x.Length), 1, r_flag);
            fit[i] = 10000 * fit[i] / 1e+10;
            r = cf_cal(x, Os, delta, bias, fit, cf_num);
            return r;
        }

        public static double cf07(Vector x, Vector Os, Vector Mr, int[] SS, int r_flag) /* Composition Function 7 */
        {
            int i, cf_num = 3;
            double r = 0;
            double[] fit = new double[3];
            double[] delta = { 10, 30, 50 };
            double[] bias = { 0, 100, 200 };
            i = 0;
            fit[i] = hf01(x, Os.SubVector(i * x.Length, x.Length), Mr.SubVector(i * x.Length * x.Length, x.Length * x.Length), SS, 1, r_flag);
            i = 1;
            int[] tSS = SS.Skip(i * x.Length).Take(x.Length).ToArray();
            fit[i] = hf02(x, Os.SubVector(i * x.Length, x.Length), Mr.SubVector(i * x.Length * x.Length, x.Length * x.Length), tSS, 1, r_flag);
            i = 2;
            tSS = SS.Skip(i * x.Length).Take(x.Length).ToArray();
            fit[i] = hf03(x, Os.SubVector(i * x.Length, x.Length), Mr.SubVector(i * x.Length * x.Length, x.Length * x.Length), tSS, 1, r_flag);
            r = cf_cal(x, Os, delta, bias, fit, cf_num);
            return r;
        }

        public static double cf08(Vector x, Vector Os, Vector Mr, int[] SS, int r_flag) /* Composition Function 8 */
        {
            int i, cf_num = 3;
            double r = 0;
            double[] fit = new double[3];
            double[] delta = { 10, 30, 50 };
            double[] bias = { 0, 100, 200 };
            i = 0;
            fit[i] = hf04(x, Os.SubVector(i * x.Length, x.Length), Mr.SubVector(i * x.Length * x.Length, x.Length * x.Length), SS, 1, r_flag);
            i = 1;
            int[] tSS = SS.Skip(i * x.Length).Take(x.Length).ToArray();
            fit[i] = hf05(x, Os.SubVector(i * x.Length, x.Length), Mr.SubVector(i * x.Length * x.Length, x.Length * x.Length), tSS, 1, r_flag);
            i = 2;
            tSS = SS.Skip(i * x.Length).Take(x.Length).ToArray();
            fit[i] = hf06(x, Os.SubVector(i * x.Length, x.Length), Mr.SubVector(i * x.Length * x.Length, x.Length * x.Length), tSS, 1, r_flag);
            r = cf_cal(x, Os, delta, bias, fit, cf_num);
            return r;
        }

        public static double cf_cal(Vector x, Vector Os, double[] delta, double[] bias, double[] fit, int cf_num)
        {
            double w_max = 0, w_sum = 0, r = 0;
            double[] w = new double[cf_num];
            for (int i = 0; i < cf_num; i++)
            {
                fit[i] += bias[i];
                w[i] = 0;
                for (int j = 0; j < x.Length; j++)
                {
                    w[i] += (x[j] - Os[i * x.Length + j]) * (x[j] - Os[i * x.Length + j]);
                }
                if (w[i] != 0)
                    w[i] = Math.Pow(1.0 / w[i], 0.5) * Math.Exp(-w[i] / 2.0 / x.Length / delta[i] / delta[i]);
                else
                    w[i] = INF;
                if (w[i] > w_max)
                    w_max = w[i];
            }
            for (int i = 0; i < cf_num; i++)
            {
                w_sum = w_sum + w[i];
            }
            if (w_max == 0)
            {
                for (int i = 0; i < cf_num; i++)
                    w[i] = 1;
                w_sum = cf_num;
            }
            for (int i = 0; i < cf_num; i++)
            {
                r = r + w[i] / w_sum * fit[i];
            }
            return r;
        }

        public static Func<Vector, double> fun1 = (x) => ellips_func(x, shifts[0], rotates[0], 1, 1) + 100;
        public static Func<Vector, double> fun2 = (x) => bentCigar_func(x, shifts[1], rotates[1], 1, 1) + 200;
        public static Func<Vector, double> fun3 = (x) => discus_func(x, shifts[2], rotates[2], 1, 1) + 300;
        public static Func<Vector, double> fun4 = (x) => rosenbrock_func(x, shifts[3], rotates[3], 1, 1) + 400;
        public static Func<Vector, double> fun5 = (x) => ackley_func(x, shifts[4], rotates[4], 1, 1) + 500;
        public static Func<Vector, double> fun6 = (x) => weierstrass_func(x, shifts[5], rotates[5], 1, 1) + 600;
        public static Func<Vector, double> fun7 = (x) => griewank_func(x, shifts[6], rotates[6], 1, 1) + 700;
        public static Func<Vector, double> fun8 = (x) => rastrigin_func(x, shifts[7], rotates[7], 1, 0) + 800;
        public static Func<Vector, double> fun9 = (x) => rastrigin_func(x, shifts[8], rotates[8], 1, 1) + 900;
        public static Func<Vector, double> fun10 = (x) => schwefel_func(x, shifts[9], rotates[9], 1, 0) + 1000;
        public static Func<Vector, double> fun11 = (x) => schwefel_func(x, shifts[10], rotates[10], 1, 1) + 1100;
        public static Func<Vector, double> fun12 = (x) => katsuura_func(x, shifts[11], rotates[11], 1, 1) + 1200;
        public static Func<Vector, double> fun13 = (x) => happycat_func(x, shifts[12], rotates[12], 1, 1) + 1300;
        public static Func<Vector, double> fun14 = (x) => hgbat_func(x, shifts[13], rotates[13], 1, 1) + 1400;
        public static Func<Vector, double> fun15 = (x) => grie_rosen_func(x, shifts[14], rotates[14], 1, 1) + 1500;
        public static Func<Vector, double> fun16 = (x) => escaffer6_func(x, shifts[15], rotates[15], 1, 1) + 1600;
        public static Func<Vector, double> fun17 = (x) => hf01(x, shifts[16], rotates[16], shuffles[16], 1, 1) + 1700;
        public static Func<Vector, double> fun18 = (x) => hf02(x, shifts[17], rotates[17], shuffles[17], 1, 1) + 1800;
        public static Func<Vector, double> fun19 = (x) => hf03(x, shifts[18], rotates[18], shuffles[18], 1, 1) + 1900;
        public static Func<Vector, double> fun20 = (x) => hf04(x, shifts[19], rotates[19], shuffles[19], 1, 1) + 2000;
        public static Func<Vector, double> fun21 = (x) => hf05(x, shifts[20], rotates[20], shuffles[20], 1, 1) + 2100;
        public static Func<Vector, double> fun22 = (x) => hf06(x, shifts[21], rotates[21], shuffles[21], 1, 1) + 2200;
        public static Func<Vector, double> fun23 = (x) => cf01(x, shifts[22], rotates[22], 1) + 2300;//shift的array长度变成1000了
        public static Func<Vector, double> fun24 = (x) => cf02(x, shifts[23], rotates[23], 1) + 2400;
        public static Func<Vector, double> fun25 = (x) => cf03(x, shifts[24], rotates[24], 1) + 2500;
        public static Func<Vector, double> fun26 = (x) => cf04(x, shifts[25], rotates[25], 1) + 2600;
        public static Func<Vector, double> fun27 = (x) => cf05(x, shifts[26], rotates[26], 1) + 2700;
        public static Func<Vector, double> fun28 = (x) => cf06(x, shifts[27], rotates[27], 1) + 2800;
        public static Func<Vector, double> fun29 = (x) => cf07(x, shifts[28], rotates[28], shuffles[28], 1) + 2900;
        public static Func<Vector, double> fun30 = (x) => cf08(x, shifts[29], rotates[29], shuffles[29], 1) + 3000;
        public static Func<Vector, double>[] funs = { fun1, fun2, fun3, fun4, fun5, fun6, fun7, fun8, fun9, fun10, fun11, fun12, fun13, fun14, fun15, fun16, fun17, fun18, fun19, fun20, fun21, fun22, fun23, fun24, fun25, fun26, fun27, fun28, fun29, fun30 };
        
    }
}
