Example #1
0
        /// <summary>
        /// Creates a new Back Propagation Network, with the specified input and output layers. (You
        /// are required to connect all layers using appropriate synapses, before using the constructor.
        /// Any changes made to the structure of the network after its creation may lead to complete
        /// malfunctioning)
        /// </summary>
        /// <param name="inputLayer">
        /// The input layer
        /// </param>
        /// <param name="outputLayer">
        /// The output layer
        /// </param>
        /// <exception cref="ArgumentNullException">
        /// If <c>inputLayer</c> or <c>outputLayer</c> is <c>null</c>
        /// </exception>
        public PSONetwork(ActivationLayer inputLayer, ActivationLayer outputLayer)
            : base(inputLayer, outputLayer, TrainingMethod.Supervised)
        {
            this.meanSquaredError = 0d;
            this.isValidMSE = false;

            // Re-Initialize the network
            Initialize();

            double[] weights = getAllWeights();

            PsoProblem = new Problem(OptimisationProblem.Neural_Network, new Problem.FitnessHandler(getFitness), weights);
        }
Example #2
0
        // =================================================
        public Algorithm(Problem pb, Parameters param)
        {
            this.pb = pb;
            bestBest = new Position(pb.SS.D);
            PX = new Velocity(pb.SS.D);
            R = new SPSO_2007.Result(pb.SS.D);

            //f_run = File.OpenWrite("f_run.txt");
            //f_synth = File.OpenWrite("f_synth.txt");

            // ----------------------------------------------- PROBLEM

            this.param = param;
            runMax = 100;
            if (runMax > R_max) runMax = R_max;

            this.vMax = param.vMax;

            Utils.Logger.Log("\n c = {0},  w = {1}", param.c, param.w);
            //---------------
            sqrtD = Math.Sqrt(pb.SS.D);

            //------------------------------------- RUNS
            /*
            for (run = 0; run < runMax; run++)
            {

            }		// End loop on "run"
            */
            // ---------------------END

            // Save
            //TODO: Fix up writing out to files
            /*fUtils.Logger.Log(f_synth, "%f %f %.0f%% %f   ",
                     errorMean, variance, successRate, evalMean);
            for (d = 0; d < pb.SS.D; d++) fUtils.Logger.Log(f_synth, " %f", bestBest.x[d]);
            fUtils.Logger.Log(f_synth, "\n");
             * */

            return; // End of main program
        }
Example #3
0
        public static Problem problemDef(int functionCode)
        {
            int d;
            Problem pb = new Problem();

            int nAtoms; // For Lennard-Jones problem
            double[] lennard_jones = new[] { -1, -3, -6, -9.103852, -12.71, -16.505384, -19.821489, -24.113360, -28.422532, -32.77, -37.97, -44.33, -47.84, -52.32 };

            pb.function = functionCode;
            pb.epsilon = 0.00000;	// Acceptable error (default). May be modified below
            pb.objective = 0;       // Objective value (default). May be modified below

            // Define the solution point, for test
            // NEEDED when param.stop = 2
            // i.e. when stop criterion is distance_to_solution < epsilon
            for (d = 0; d < 30; d++)
            {
                pb.solution.x[d] = 0;
            }

            // ------------------ Search space
            switch (pb.function)
            {
                case 0:			// Parabola
                    pb.SS.D = 30;//  Dimension

                    for (d = 0; d < pb.SS.D; d++)
                    {
                        pb.SS.min[d] = -100; // -100
                        pb.SS.max[d] = 100;	// 100
                        pb.SS.q.q[d] = 0;	// Relative quantisation, in [0,1].
                    }

                    pb.evalMax = 100000;// Max number of evaluations for each run
                    pb.epsilon = 0.0; // 1e-3;
                    pb.objective = 0;

                    // For test purpose, the initialisation space may be different from
                    // the search space. If so, just modify the code below

                    for (d = 0; d < pb.SS.D; d++)
                    {
                        pb.SS.maxInit[d] = pb.SS.max[d]; // May be a different value
                        pb.SS.minInit[d] = pb.SS.min[d]; // May be a different value
                    }

                    break;
                case 100: // CEC 2005 F1
                    pb.SS.D = 30;//30;
                    for (d = 0; d < pb.SS.D; d++)
                    {
                        pb.SS.min[d] = -100;
                        pb.SS.max[d] = 100;
                        pb.SS.q.q[d] = 0;

                    }
                    pb.evalMax = pb.SS.D * 10000;
                    pb.epsilon = 0.000001;	//Acceptable error
                    pb.objective = -450;       // Objective value

                    for (d = 0; d < pb.SS.D; d++)
                    {
                        pb.SS.maxInit[d] = pb.SS.max[d];
                        pb.SS.minInit[d] = pb.SS.min[d];
                    }
                    break;

                case 102:		// Rosenbrock. CEC 2005 F6
                    pb.SS.D = 10;	// 10

                    // Boundaries
                    for (d = 0; d < pb.SS.D; d++)
                    {
                        pb.SS.min[d] = -100; pb.SS.max[d] = 100;
                        pb.SS.q.q[d] = 0;

                    }

                    pb.evalMax = pb.SS.D * 10000;
                    pb.epsilon = 0.01;	//0.01 Acceptable error
                    pb.objective = 390;

                    for (d = 0; d < pb.SS.D; d++)
                    {
                        pb.SS.maxInit[d] = pb.SS.max[d];
                        pb.SS.minInit[d] = pb.SS.min[d];
                    }
                    break;

                case 103:// CEC 2005 F9, Rastrigin
                    pb.SS.D = 30;
                    for (d = 0; d < pb.SS.D; d++)
                    {
                        pb.SS.min[d] = -5;
                        pb.SS.max[d] = 5;
                        pb.SS.q.q[d] = 0;

                    }
                    pb.epsilon = 0.01; // 0.01;	// Acceptable error
                    pb.objective = -330;       // Objective value
                    pb.evalMax = pb.SS.D * 10000;

                    for (d = 0; d < pb.SS.D; d++)
                    {
                        pb.SS.maxInit[d] = pb.SS.max[d];
                        pb.SS.minInit[d] = pb.SS.min[d];
                    }
                    break;

                case 104:// CEC 2005 F2  Schwefel
                    pb.SS.D = 10;
                    for (d = 0; d < pb.SS.D; d++)
                    {
                        pb.SS.min[d] = -100;
                        pb.SS.max[d] = 100;
                        pb.SS.q.q[d] = 0;

                    }
                    pb.epsilon = 0.00001;	// Acceptable error
                    pb.objective = -450;       // Objective value
                    pb.evalMax = pb.SS.D * 10000;

                    for (d = 0; d < pb.SS.D; d++)
                    {
                        pb.SS.maxInit[d] = pb.SS.max[d];
                        pb.SS.minInit[d] = pb.SS.min[d];
                    }
                    break;

                case 105:// CEC 2005 F7  Griewank (NON rotated)
                    pb.SS.D = 10;	 // 10
                    for (d = 0; d < pb.SS.D; d++)
                    {
                        pb.SS.min[d] = -600;
                        pb.SS.max[d] = 600;
                        pb.SS.q.q[d] = 0;

                    }
                    pb.epsilon = 0.01;	//Acceptable error
                    pb.objective = -180;       // Objective value
                    pb.evalMax = pb.SS.D * 10000;

                    for (d = 0; d < pb.SS.D; d++)
                    {
                        pb.SS.maxInit[d] = pb.SS.max[d];
                        pb.SS.minInit[d] = pb.SS.min[d];
                    }
                    break;

                case 106:// CEC 2005 F8 Ackley (NON rotated)
                    pb.SS.D = 10;
                    for (d = 0; d < pb.SS.D; d++)
                    {
                        pb.SS.min[d] = -32;
                        pb.SS.max[d] = 32;
                        pb.SS.q.q[d] = 0;
                    }
                    pb.epsilon = 0.0001;	// Acceptable error
                    pb.objective = -140;       // Objective value
                    pb.evalMax = pb.SS.D * 10000;
                    for (d = 0; d < pb.SS.D; d++)
                    {
                        pb.SS.maxInit[d] = pb.SS.max[d];
                        pb.SS.minInit[d] = pb.SS.min[d];
                    }
                    break;
                    /*
                        case 100:			// Parabola
                            pb.SS.D =10;//  Dimension

                        for (d = 0; d < pb.SS.D; d++)
                        {
                            pb.SS.min[d] = -100; // -100
                            pb.SS.max[d] = 100;	// 100
                            pb.SS.q.q[d] = 0;	// Relative quantisation, in [0,1].
                        }

                        pb.evalMax = 100000;// Max number of evaluations for each run
                        pb.epsilon=0.00000;

                        for (d = 0; d < pb.SS.D; d++)
                        {
                            pb.SS.maxInit[d]=pb.SS.max[d];
                            pb.SS.minInit[d]=pb.SS.min[d];
                        }
                        break;
                */
                case 1:		// Griewank
                    pb.SS.D = 10;

                    // Boundaries
                    for (d = 0; d < pb.SS.D; d++)
                    {
                        pb.SS.min[d] = -100;
                        pb.SS.max[d] = 100;
                        pb.SS.q.q[d] = 0;
                    }

                    pb.evalMax = 400000;
                    pb.epsilon = 0.05;
                    pb.objective = 0;

                    for (d = 0; d < pb.SS.D; d++)
                    {
                        pb.SS.maxInit[d] = pb.SS.max[d];
                        pb.SS.minInit[d] = pb.SS.min[d];
                    }
                    break;

                case 2:		// Rosenbrock
                    pb.SS.D = 30;	// 30

                    // Boundaries
                    for (d = 0; d < pb.SS.D; d++)
                    {
                        pb.SS.min[d] = -30; // -30;
                        pb.SS.max[d] = 30; // 30;
                        pb.SS.q.q[d] = 0;
                    }
                    pb.epsilon = 0;
                    pb.evalMax = 300000; //2.e6;  // 40000
                    pb.objective = 0;

                    for (d = 0; d < pb.SS.D; d++)
                    {
                        pb.SS.maxInit[d] = 30; //pb.SS.max[d];
                        pb.SS.minInit[d] = 15; //pb.SS.min[d];
                    }
                    break;

                case 3:		// Rastrigin
                    pb.SS.D = 10;

                    // Boundaries
                    for (d = 0; d < pb.SS.D; d++)
                    {
                        pb.SS.min[d] = -5.12;
                        pb.SS.max[d] = 5.12;
                        pb.SS.q.q[d] = 0;
                    }

                    pb.evalMax = 3200;
                    pb.epsilon = 0.0;
                    pb.objective = 0;

                    for (d = 0; d < pb.SS.D; d++)
                    {
                        pb.SS.minInit[d] = pb.SS.min[d];
                        pb.SS.maxInit[d] = pb.SS.max[d];
                    }
                    break;

                case 4:		// Tripod
                    pb.SS.D = 2;	// Dimension

                    // Boundaries
                    for (d = 0; d < pb.SS.D; d++)
                    {
                        pb.SS.min[d] = -100;
                        pb.SS.max[d] = 100;
                        pb.SS.q.q[d] = 0;
                    }

                    pb.evalMax = 10000;
                    pb.epsilon = 0.0001;

                    for (d = 0; d < pb.SS.D; d++)
                    {
                        pb.SS.maxInit[d] = pb.SS.max[d];
                        pb.SS.minInit[d] = pb.SS.min[d];
                    }
                    break;

                case 5: // Ackley
                    pb.SS.D = 10;
                    // Boundaries
                    for (d = 0; d < pb.SS.D; d++)
                    {
                        pb.SS.min[d] = -32; // 32
                        pb.SS.max[d] = 32;
                        pb.SS.q.q[d] = 0;
                    }
                    pb.evalMax = 3200;
                    pb.epsilon = 0.0;
                    pb.objective = 0;

                    for (d = 0; d < pb.SS.D; d++)
                    {
                        pb.SS.maxInit[d] = pb.SS.max[d];
                        pb.SS.minInit[d] = pb.SS.min[d];
                    }
                    break;

                case 6: // Schwefel. Min on (A=420.8687, ..., A)
                    pb.SS.D = 30;
                    //pb.objective=-pb.SS.D*420.8687*sin(Math.Sqrt(420.8687));
                    pb.objective = -12569.5;
                    pb.epsilon = 2569.5;

                    for (d = 0; d < pb.SS.D; d++)
                    {
                        pb.SS.min[d] = -500;
                        pb.SS.max[d] = 500;
                        pb.SS.q.q[d] = 0;
                    }
                    pb.evalMax = 300000;

                    for (d = 0; d < pb.SS.D; d++)
                    {
                        pb.SS.maxInit[d] = pb.SS.max[d];
                        pb.SS.minInit[d] = pb.SS.min[d];
                    }
                    break;

                case 7: // Schwefel 1.2
                    pb.SS.D = 40;
                    pb.objective = 0;
                    for (d = 0; d < pb.SS.D; d++)
                    {
                        pb.SS.min[d] = -100;
                        pb.SS.max[d] = 100;
                        pb.SS.q.q[d] = 0;
                    }
                    pb.evalMax = 40000;

                    for (d = 0; d < pb.SS.D; d++)
                    {
                        pb.SS.maxInit[d] = pb.SS.max[d];
                        pb.SS.minInit[d] = pb.SS.min[d];
                    }
                    break;

                case 8: // Schwefel 2.22
                    pb.SS.D = 30;
                    pb.objective = 0;
                    for (d = 0; d < pb.SS.D; d++)
                    {
                        pb.SS.min[d] = -10;
                        pb.SS.max[d] = 10;
                        pb.SS.q.q[d] = 0;
                    }
                    pb.evalMax = 100000;

                    for (d = 0; d < pb.SS.D; d++)
                    {
                        pb.SS.maxInit[d] = pb.SS.max[d];
                        pb.SS.minInit[d] = pb.SS.min[d];
                    }
                    break;

                case 9: // Neumaier 3
                    pb.SS.D = 40;
                    pb.objective = 0;
                    for (d = 0; d < pb.SS.D; d++)
                    {
                        pb.SS.min[d] = -pb.SS.D * pb.SS.D;
                        pb.SS.max[d] = -pb.SS.min[d];
                        pb.SS.q.q[d] = 0;
                    }
                    pb.evalMax = 40000;

                    for (d = 0; d < pb.SS.D; d++)
                    {
                        pb.SS.maxInit[d] = pb.SS.max[d];
                        pb.SS.minInit[d] = pb.SS.min[d];
                    }
                    break;

                case 10: // G3 (constrained)
                    pb.SS.D = 10;

                    for (d = 0; d < pb.SS.D; d++)
                    {
                        pb.SS.min[d] = 0;
                        pb.SS.max[d] = 1;
                        pb.SS.q.q[d] = 0;
                    }
                    pb.evalMax = 340000;
                    pb.objective = 0;
                    pb.epsilon = 1e-6;

                    for (d = 0; d < pb.SS.D; d++)
                    {
                        pb.SS.maxInit[d] = pb.SS.max[d];
                        pb.SS.minInit[d] = pb.SS.min[d];
                    }

                    break;

                case 11: // Network
                    // btsNb=5; bcsNb=2;
                    btsNb = 19; bcsNb = 4;
                    pb.SS.D = bcsNb * btsNb + 2 * bcsNb;
                    pb.objective = 0;
                    for (d = 0; d < bcsNb * btsNb; d++) // Binary representation. 1 means: there is a link
                    {
                        pb.SS.min[d] = 0;
                        pb.SS.max[d] = 1;
                        pb.SS.q.q[d] = 1;
                    }

                    for (d = bcsNb * btsNb; d < pb.SS.D; d++) // 2D space for the BSC positions
                    {
                        pb.SS.min[d] = 0;
                        pb.SS.max[d] = 20; //15;
                        pb.SS.q.q[d] = 0;
                    }

                    pb.evalMax = 50;
                    pb.objective = 0;
                    pb.epsilon = 0;

                    break;

                case 12: // Schwefel
                    pb.SS.D = 30;
                    pb.objective = 0;
                    for (d = 0; d < pb.SS.D; d++)
                    {
                        pb.SS.min[d] = -500;
                        pb.SS.max[d] = 500;
                        pb.SS.q.q[d] = 0;
                    }
                    pb.evalMax = 200000;

                    for (d = 0; d < pb.SS.D; d++)
                    {
                        pb.SS.maxInit[d] = pb.SS.max[d];
                        pb.SS.minInit[d] = pb.SS.min[d];
                    }
                    break;

                case 13:		  // 2D Goldstein-Price function (f_min=3, on (0,-1))
                    pb.SS.D = 2;	// Dimension
                    pb.objective = 0;

                    pb.SS.min[0] = -100;
                    pb.SS.max[0] = 100;
                    pb.SS.q.q[0] = 0;
                    pb.SS.min[1] = -100;
                    pb.SS.max[1] = 100;
                    pb.SS.q.q[1] = 0;
                    pb.evalMax = 720;

                    for (d = 0; d < pb.SS.D; d++)
                    {
                        pb.SS.maxInit[d] = pb.SS.max[d];
                        pb.SS.minInit[d] = pb.SS.min[d];
                    }
                    break;
                case 14: // Schaffer f6
                    pb.SS.D = 2;	// Dimension
                    pb.objective = 0;

                    pb.SS.min[0] = -100;
                    pb.SS.max[0] = 100;
                    pb.SS.q.q[0] = 0;
                    pb.SS.min[1] = -100;
                    pb.SS.max[1] = 100;
                    pb.SS.q.q[1] = 0;

                    pb.evalMax = 4000;

                    for (d = 0; d < pb.SS.D; d++)
                    {
                        pb.SS.maxInit[d] = pb.SS.max[d];
                        pb.SS.minInit[d] = pb.SS.min[d];
                    }

                    break;

                case 15: // Step
                    pb.SS.D = 20;
                    pb.objective = 0;
                    for (d = 0; d < pb.SS.D; d++)
                    {
                        pb.SS.min[d] = -100;
                        pb.SS.max[d] = 100;
                        pb.SS.q.q[d] = 0;
                    }
                    pb.evalMax = 2500;

                    for (d = 0; d < pb.SS.D; d++)
                    {
                        pb.SS.maxInit[d] = pb.SS.max[d];
                        pb.SS.minInit[d] = pb.SS.min[d];
                    }
                    break;

                case 16: // Schwefel 2.21
                    pb.SS.D = 30;
                    pb.objective = 0;
                    for (d = 0; d < pb.SS.D; d++)
                    {
                        pb.SS.min[d] = -100;
                        pb.SS.max[d] = 100;
                        pb.SS.q.q[d] = 0;
                    }
                    pb.evalMax = 100000;

                    for (d = 0; d < pb.SS.D; d++)
                    {
                        pb.SS.maxInit[d] = pb.SS.max[d];
                        pb.SS.minInit[d] = pb.SS.min[d];
                    }
                    break;

                case 17: // Lennard-Jones
                    nAtoms = 2; // in {2, ..., 15}
                    pb.SS.D = 3 * nAtoms; pb.objective = lennard_jones[nAtoms - 2];
                    pb.evalMax = 5000 + 3000 * nAtoms * (nAtoms - 1); // Empirical rule
                    pb.epsilon = 1e-6;
                    // Note: with this acceptable error, nAtoms=10 seems to be the maximum
                    //       possible value for a non-null success rate  (5%)

                    //pb.SS.D=3*21; pb.objective=-81.684;
                    //pb.SS.D=3*27; pb.objective=-112.87358;
                    //pb.SS.D=3*38; pb.objective=-173.928427;

                    for (d = 0; d < pb.SS.D; d++)
                    {
                        pb.SS.min[d] = -2;
                        pb.SS.max[d] = 2;
                        pb.SS.q.q[d] = 0;
                    }

                    for (d = 0; d < pb.SS.D; d++)
                    {
                        pb.SS.maxInit[d] = pb.SS.max[d];
                        pb.SS.minInit[d] = pb.SS.min[d];
                    }
                    break;
                case 18: //Gear Train
                    pb.SS.D=4;

                    for (d = 0; d < pb.SS.D; d++)
                    {
                        pb.SS.min[d]=12;
                        pb.SS.max[d]=60;
                        pb.SS.q.q[d] = 1;
                        pb.SS.maxInit[d] = pb.SS.max[d];
                        pb.SS.minInit[d] = pb.SS.min[d];
                    }

                    pb.evalMax = 20000 ;
                    pb.epsilon = 1e-13;
                    pb.objective =2.7e-12 ;
                    break;
                case 19: // Compression spring
                    pb.constraint = 4;
                    pb.SS.D = 3;

                    pb.SS.min[0] = 1; pb.SS.max[0] = 70; pb.SS.q.q[0] = 1;
                    pb.SS.min[1] = 0.6; pb.SS.max[1] = 3; pb.SS.q.q[1] = 0;
                    pb.SS.min[2] = 0.207; pb.SS.max[2] = 0.5; pb.SS.q.q[2] = 0.001;

                    //for (d = 0; d < pb.SS.D; d++)
                    //{
                    //    pb.SS.maxS[d] = pb.SS.max[d];
                    //    pb.SS.minS[d] = pb.SS.min[d];
                    //}
                    pb.evalMax = 20000;
                    pb.epsilon = 1e-10;
                    pb.objective = 2.6254214578;
                    break;

                case 99: // Test

                    pb.SS.D = 2;

                    for (d = 0; d < pb.SS.D; d++)
                    {
                        pb.SS.min[d] = -100;
                        pb.SS.max[d] = 100;
                        pb.SS.q.q[d] = 0;
                    }

                    pb.evalMax = 40000;
                    pb.objective = 0.0;
                    pb.epsilon = 0.00;

                    for (d = 0; d < pb.SS.D; d++)
                    {
                        pb.SS.maxInit[d] = pb.SS.max[d];
                        pb.SS.minInit[d] = pb.SS.min[d];
                    }
                    break;

                    //TODO: Figure out why the following is unreachable
                    /*
                    // 2D Peaks function
                    pb.SS.D = 2;

                    for (d = 0; d < pb.SS.D; d++)
                    {
                        pb.SS.min[d] = -3;
                        pb.SS.max[d] = 3;
                        pb.SS.q.q[d] = 0;
                    }

                    pb.evalMax = 50000;
                    pb.objective = -6.551133;
                    pb.epsilon = 0.001;

                    for (d = 0; d < pb.SS.D; d++)
                    {
                        pb.SS.maxInit[d] = pb.SS.max[d];
                        pb.SS.minInit[d] = pb.SS.min[d];
                    }
                    break;
                    // Quartic
                    pb.SS.D = 50;
                    pb.objective = 0;
                    for (d = 0; d < pb.SS.D; d++)
                    {
                        pb.SS.min[d] = -10;
                        pb.SS.max[d] = 10;
                        pb.SS.q.q[d] = 0;
                    }
                    pb.evalMax = 25000;

                    for (d = 0; d < pb.SS.D; d++)
                    {
                        pb.SS.maxInit[d] = pb.SS.max[d];
                        pb.SS.minInit[d] = pb.SS.min[d];
                    }

                    break;

                    pb.SS.D = 2;	// Dimension
                    pb.objective = -2;

                    pb.SS.min[0] = -2;
                    pb.SS.max[0] = 2;
                    pb.SS.q.q[0] = 0;
                    pb.SS.min[1] = -3;
                    pb.SS.max[1] = 3;
                    pb.SS.q.q[1] = 0;

                    pb.evalMax = 10000;

                    for (d = 0; d < pb.SS.D; d++)
                    {
                        pb.SS.maxInit[d] = pb.SS.max[d];
                        pb.SS.minInit[d] = pb.SS.min[d];
                    }

                    break;
                    pb.SS.D = 1;	// Dimension
                    // Boundaries
                    for (d = 0; d < pb.SS.D; d++)
                    {
                        pb.SS.min[d] = -10;
                        pb.SS.max[d] = 10;
                        pb.SS.q.q[d] = 0;
                    }
                    pb.objective = -1000; // Just a sure too small value for the above search space
                    pb.evalMax = 1000;

                    for (d = 0; d < pb.SS.D; d++)
                    {
                        pb.SS.maxInit[d] = pb.SS.max[d];
                        pb.SS.minInit[d] = pb.SS.min[d];
                    }
                    break;
                     */

            }

            pb.SS.q.size = pb.SS.D;
            return pb;
        }
Example #4
0
        // ===============================================================
        // PSO
        static Result PSO(Parameters param, Problem pb)
        {
            Velocity aleaV = new Velocity();
            int d;
            int g;
            int[] index = new int[S_max];
            int[] indexTemp = new int[S_max];
            // Iteration number (time step)
            int iterBegin;
            int[,] LINKS = new int[S_max, S_max];	// Information links
            int m;
            int noEval;
            double normPX = 0.0, normGX = 0.0;
            int noStop;
            int outside;
            double p;
            Velocity PX = new Velocity();
            Result R = new Result();
            Matrix RotatePX = new Matrix();
            Matrix RotateGX = new Matrix();
            int s0, s, s1;
            double zz;

            aleaV.size = pb.SS.D;
            RotatePX.size = pb.SS.D;
            RotateGX.size = pb.SS.D;
            // -----------------------------------------------------
            // INITIALISATION
            p = param.p; // Probability threshold for random topology
            R.SW.S = param.S; // Size of the current swarm

            // Position and velocity
            for (s = 0; s < R.SW.S; s++)
            {
                R.SW.X[s].size = pb.SS.D;
                R.SW.V[s].size = pb.SS.D;

                for (d = 0; d < pb.SS.D; d++)
                {
                    R.SW.X[s].x[d] = rand.NextDouble(pb.SS.minInit[d], pb.SS.maxInit[d]);
                    R.SW.V[s].v[d] = (rand.NextDouble(pb.SS.min[d], pb.SS.max[d]) - R.SW.X[s].x[d]) / 2;
                }
                // Take quantisation into account
                Position.quantis(R.SW.X[s], pb.SS);

                // First evaluations
                R.SW.X[s].f =
                    Problem.perf(R.SW.X[s], pb.function, pb.objective);

                R.SW.P[s] = R.SW.X[s].Clone();	// Best position = current one
                R.SW.P[s].improved = 0;	// No improvement
            }

            // If the number max of evaluations is smaller than
            // the swarm size, just keep evalMax particles, and finish
            if (R.SW.S > pb.evalMax) R.SW.S = pb.evalMax;
            R.nEval = R.SW.S;

            // Find the best
            R.SW.best = 0;
            double errorPrev;
            switch (param.stop)
            {
                default:
                    errorPrev = R.SW.P[R.SW.best].f; // "distance" to the wanted f value (objective)
                    break;

                case 2:
                    errorPrev = Position.distanceL(R.SW.P[R.SW.best], pb.solution, 2); // Distance to the wanted solution
                    break;
            }

            for (s = 1; s < R.SW.S; s++)
            {
                switch (param.stop)
                {
                    default:
                        zz = R.SW.P[s].f;
                        if (zz < errorPrev)
                        {
                            R.SW.best = s;
                            errorPrev = zz;
                        }
                        break;

                    case 2:
                        zz = Position.distanceL(R.SW.P[R.SW.best], pb.solution, 2);
                        if (zz < errorPrev)
                        {
                            R.SW.best = s;
                            errorPrev = zz;
                        }
                        break;
                }
            }
            // Display the best
            Console.Write(" Best value after init. {0} ", errorPrev);
            //	Console.Write( "\n Position :\n" );
            //	for ( d = 0; d < SS.D; d++ ) Console.Write( " %f", R.SW.P[R.SW.best].x[d] );

            int initLinks = 1;		// So that information links will beinitialized
            // Note: It is also a flag saying "No improvement"
            noStop = 0;
            double error = errorPrev;
            // ---------------------------------------------- ITERATIONS
            int iter = 0;
            while (noStop == 0)
            {
                iter++;

                if (initLinks == 1)	// Random topology
                {
                    // Who informs who, at random
                    for (s = 0; s < R.SW.S; s++)
                    {
                        for (m = 0; m < R.SW.S; m++)
                        {
                            if (rand.NextDouble() < p) LINKS[m, s] = 1;	// Probabilistic method
                            else LINKS[m, s] = 0;
                        }
                        LINKS[s, s] = 1;
                    }
                }

                // The swarm MOVES
                //Console.Write("\nIteration %i",iter);
                for (int i = 0; i < R.SW.S; i++)
                    index[i] = i;
                //Permutate the index order
                if (param.randOrder == 1)
                {
                    index.Shuffle(7, R.SW.S);
                }

                Velocity GX = new Velocity();
                for (s0 = 0; s0 < R.SW.S; s0++)	// For each particle ...
                {
                    s = index[s0];
                    // ... find the first informant
                    s1 = 0;
                    while (LINKS[s1, s] == 0) s1++;
                    if (s1 >= R.SW.S) s1 = s;

                    // Find the best informant
                    g = s1;
                    for (m = s1; m < R.SW.S; m++)
                    {
                        if (LINKS[m, s] == 1 && R.SW.P[m].f < R.SW.P[g].f)
                            g = m;
                    }

                    //.. compute the new velocity, and move

                    // Exploration tendency
                    for (d = 0; d < pb.SS.D; d++)
                    {
                        R.SW.V[s].v[d] = param.w * R.SW.V[s].v[d];
                        // Prepare Exploitation tendency  p-x
                        PX.v[d] = R.SW.P[s].x[d] - R.SW.X[s].x[d];
                        if (g != s)
                            GX.v[d] = R.SW.P[g].x[d] - R.SW.X[s].x[d];// g-x
                    }
                    PX.size = pb.SS.D;
                    GX.size = pb.SS.D;

                    // Option "non sentivity to rotation"
                    if (param.rotation > 0)
                    {
                        normPX = Velocity.normL(PX, 2);
                        if (g != s) normGX = Velocity.normL(GX, 2);
                        if (normPX > 0)
                        {
                            RotatePX = Matrix.MatrixRotation(PX);
                        }

                        if (g != s && normGX > 0)
                        {
                            RotateGX = Matrix.MatrixRotation(GX);
                        }
                    }

                    // Exploitation tendencies
                    switch (param.rotation)
                    {
                        default:
                            for (d = 0; d < pb.SS.D; d++)
                            {
                                R.SW.V[s].v[d] = R.SW.V[s].v[d] + rand.NextDouble(0.0, param.c) * PX.v[d];
                                if(g!=s)
                                    R.SW.V[s].v[d] = R.SW.V[s].v[d] + rand.NextDouble(0.0, param.c) * GX.v[d];
                            }
                            break;

                        case 1:
                            // First exploitation tendency
                            if (normPX > 0)
                            {
                                zz = param.c * normPX / sqrtD;
                                aleaV = rand.NextVector(pb.SS.D, zz);
                                Velocity expt1 = RotatePX.VectorProduct(aleaV);

                                for (d = 0; d < pb.SS.D; d++)
                                {
                                    R.SW.V[s].v[d] = R.SW.V[s].v[d] + expt1.v[d];
                                }
                            }

                            // Second exploitation tendency
                            if (g != s && normGX > 0)
                            {
                                zz = param.c * normGX / sqrtD;
                                aleaV = rand.NextVector(pb.SS.D, zz);
                                Velocity expt2 = RotateGX.VectorProduct(aleaV);
                                for (d = 0; d < pb.SS.D; d++)
                                {
                                    R.SW.V[s].v[d] = R.SW.V[s].v[d] + expt2.v[d];
                                }
                            }
                            break;
                    }

                    // Update the position
                    for (d = 0; d < pb.SS.D; d++)
                    {
                        R.SW.X[s].x[d] = R.SW.X[s].x[d] + R.SW.V[s].v[d];
                    }

                    if (R.nEval >= pb.evalMax)
                    {
                        //error= fabs(error - pb.objective);
                        goto end;
                    }
                    // --------------------------
                    noEval = 1;

                    // Quantisation
                    Position.quantis(R.SW.X[s], pb.SS);

                    switch (param.clamping)
                    {
                        case 0:	// No clamping AND no evaluation
                            outside = 0;

                            for (d = 0; d < pb.SS.D; d++)
                            {
                                if (R.SW.X[s].x[d] < pb.SS.min[d] || R.SW.X[s].x[d] > pb.SS.max[d])
                                    outside++;
                            }

                            if (outside == 0)	// If inside, the position is evaluated
                            {
                                R.SW.X[s].f =
                                    Problem.perf(R.SW.X[s], pb.function, pb.objective);
                                R.nEval = R.nEval + 1;
                            }
                            break;

                        case 1:	// Set to the bounds, and v to zero
                            for (d = 0; d < pb.SS.D; d++)
                            {
                                if (R.SW.X[s].x[d] < pb.SS.min[d])
                                {
                                    R.SW.X[s].x[d] = pb.SS.min[d];
                                    R.SW.V[s].v[d] = 0;
                                }

                                if (R.SW.X[s].x[d] > pb.SS.max[d])
                                {
                                    R.SW.X[s].x[d] = pb.SS.max[d];
                                    R.SW.V[s].v[d] = 0;
                                }
                            }

                            R.SW.X[s].f = Problem.perf(R.SW.X[s], pb.function, pb.objective);
                            R.nEval = R.nEval + 1;
                            break;
                    }

                    // ... update the best previous position
                    if (R.SW.X[s].f < R.SW.P[s].f)	// Improvement
                    {
                        R.SW.P[s] = R.SW.X[s].Clone();

                        // ... update the best of the bests
                        if (R.SW.P[s].f < R.SW.P[R.SW.best].f)
                        {
                            R.SW.best = s;
                        }
                    }
                }			// End of "for (s0=0 ...  "
                // Check if finished
                switch (param.stop)
                {
                    default:
                        error = R.SW.P[R.SW.best].f;
                        break;

                    case 2:
                        error = Position.distanceL(R.SW.P[R.SW.best], pb.solution, 2);
                        break;
                }
                //error= fabs(error - pb.epsilon);

                if (error < errorPrev)	// Improvement
                {
                    initLinks = 0;
                }
                else			// No improvement
                {
                    initLinks = 1;	// Information links will be	reinitialized
                }

                if (param.initLink == 1) initLinks = 1 - initLinks;

                errorPrev = error;
            end:

                switch (param.stop)
                {
                    case 0:
                    case 2:
                        if (error > pb.epsilon && R.nEval < pb.evalMax)
                        {
                            noStop = 0;	// Won't stop
                        }
                        else
                        {
                            noStop = 1;	// Will stop
                        }
                        break;

                    case 1:
                        if (R.nEval < pb.evalMax)
                            noStop = 0;	// Won't stop
                        else
                            noStop = 1;	// Will stop
                        break;
                }

            } // End of "while nostop ...

            // Console.Write( "\n and the winner is ... %i", R.SW.best );
            // fConsole.Write( f_stag, "\nEND" );
            R.error = error;
            return R;
        }