コード例 #1
0
        private double CalculateGCVelocityUpdate(PSO.Particle particle, PSO.Particle gbest, int i)
        {
            PSO.Settings settings = (PSO.Settings)Job.Optimizer.Configuration;
            double       ret;

            // The idea here is to set the new particle position in an area around
            // the best solution, while holding the constraint

            // Cancel momentum update
            ret = -particle.Velocity[i] * settings.Constriction;

            // Reset position
            ret -= particle.Parameters[i].Value;

            // Move to particle best position
            ret += gbest.Parameters[i].Value;

            // Add random perturbation
            string name = particle.Parameters[i].Name;

            ConstraintMatrix     cons = d_constraintsFor[name];
            List <Linear.Vector> eqs  = cons.NullspaceEquations;

            int idx = cons.ParameterIndex(name);

            // Generate random value on the null space of the constraints
            for (int j = 0; j < eqs[idx].Count; ++j)
            {
                ret += cons.RN[j] * eqs[idx][j];
            }

            return(ret * Configuration.GuaranteedConvergence);
        }
コード例 #2
0
        public double CalculateVelocityUpdate(PSO.Particle particle, PSO.Particle best, int i)
        {
            if (particle.Id != best.Id)
            {
                double multiplier = (double)particle.Data["dpso::multiplier"];
                double up         = particle.CalculateVelocityUpdate(best, i);

                return((particle.Velocity[i] + up) * multiplier - up - particle.Velocity[i]);
            }

            double ret = 0;

            // Special velocity update, first reset the position
            ret -= particle.Parameters[i].Value;

            // Then move the particle to its best position
            ret += particle.PersonalBest.Parameters[i].Value;

            // Finally, add the random sample search
            Boundary boundary = particle.Parameters[i].Boundary;

            ret += d_sampleSize * (boundary.Max - boundary.Min) * (1 - 2 * particle.State.Random.NextDouble());

            return(ret);
        }
コード例 #3
0
        public override void FromStorage(Storage.Storage storage, Storage.Records.Optimizer optimizer)
        {
            base.FromStorage(storage, optimizer);
            uint priority = 0;

            storage.Query("SELECT `expression`, `condition` FROM `stages` ORDER BY `id`", delegate(IDataReader reader)
            {
                string expression = Storage.Storage.As <string>(reader[0]);
                string condition  = Storage.Storage.As <string>(reader[1]);

                d_stages.Add(new Stage(expression, condition, priority++));
                return(true);
            });

            foreach (Solution sol in Job.Optimizer.Population)
            {
                UpdateFitnessStage(sol);

                PSO.Particle p = (PSO.Particle)sol;

                UpdateFitnessStage(p.PersonalBest);
            }

            UpdateFitnessStage(Job.Optimizer.Best);

            Setup();
        }
コード例 #4
0
 public void ValidateVelocityUpdate(PSO.Particle particle, double[] velocityUpdate)
 {
     // Make sure that we are within the parameter boundaries by linearly scaling the velocity vector (if needed)
     foreach (ConstraintMatrix cons in d_constraints)
     {
         ValidateVelocityUpdate(particle, velocityUpdate, cons);
     }
 }
コード例 #5
0
        private void UpdateFitnessStage(Solution sol)
        {
            PSO.Particle p = (PSO.Particle)sol;

            int stage = int.Parse(p.Data["StagePSO::stage"] as string);

            p.Fitness.SetUserData("StagePSOStage", d_stages[stage]);
        }
コード例 #6
0
        private bool ValidateConstraints()
        {
            double maxvel = ((PSO.Settings)Job.Optimizer.Configuration).MaxVelocity;
            bool   isok   = true;

            foreach (Solution solution in Job.Optimizer.Population)
            {
                PSO.Particle p = (PSO.Particle)solution;

                for (int i = 0; i < solution.Parameters.Count; ++i)
                {
                    Parameter param = solution.Parameters[i];
                    double    mv    = (param.Boundary.Max - param.Boundary.Min) * maxvel;

                    if (maxvel > 0 && ((PSO.Particle)solution).Velocity[i] > mv)
                    {
                        Console.WriteLine("Velocity boundary violated: {0} = {1}", param.Name, ((PSO.Particle)solution).Velocity[i]);
                        isok = false;
                    }
                }

                foreach (ConstraintMatrix cons in d_constraints)
                {
                    Linear.Constraint           constraint;
                    Dictionary <string, double> values = new Dictionary <string, double>();

                    foreach (Parameter param in solution.Parameters)
                    {
                        values[param.Name] = param.Value;
                    }

                    if (!cons.Validate(values, out constraint))
                    {
                        ConstraintViolationError("pos", cons, solution, values, constraint);
                        isok = false;

                        continue;
                    }

                    values.Clear();

                    for (int i = 0; i < p.Parameters.Count; ++i)
                    {
                        values[p.Parameters[i].Name] = p.Velocity[i];
                    }

                    if (!cons.ValidateNull(values, out constraint))
                    {
                        ConstraintViolationError("vel", cons, solution, values, constraint);
                        isok = false;

                        continue;
                    }
                }
            }

            return(isok);
        }
コード例 #7
0
 public PSO.State.VelocityUpdateType VelocityUpdateComponents(PSO.Particle particle)
 {
     if (particle.Id != Job.Optimizer.Best.Id)
     {
         // Use default update when not the best
         return(PSO.State.VelocityUpdateType.Default);
     }
     else
     {
         // Keep the momentum
         return(PSO.State.VelocityUpdateType.DisableGlobal | PSO.State.VelocityUpdateType.DisableLocal);
     }
 }
コード例 #8
0
        public double CalculateVelocityUpdate(PSO.Particle particle, PSO.Particle gbest, int i)
        {
            // If there are no constraints, then just use the default
            double r1;
            double r2;

            Parameter parameter = particle.Parameters[i];
            string    name      = parameter.Name;

            if (d_constraintsFor.ContainsKey(name))
            {
                if (particle.Id == gbest.Id && Configuration.GuaranteedConvergence > 0)
                {
                    return(CalculateGCVelocityUpdate(particle, gbest, i));
                }

                ConstraintMatrix cons = d_constraintsFor[name];

                r1 = cons.R1[particle.Id];
                r2 = cons.R2[particle.Id];
            }
            else
            {
                r1 = particle.State.Random.NextDouble();
                r2 = particle.State.Random.NextDouble();
            }

            PSO.Settings settings = (PSO.Settings)Job.Optimizer.Configuration;

            double pg = 0;
            double pl = 0;

            // Global best difference
            if (gbest != null)
            {
                pg = gbest.Parameters[i].Value - parameter.Value;
            }

            // Local best difference
            if (particle.PersonalBest != null)
            {
                pl = particle.PersonalBest.Parameters[i].Value - parameter.Value;
            }

            // PSO velocity update rule
            return(settings.Constriction * (r1 * settings.CognitiveFactor * pl +
                                            r2 * settings.SocialFactor * pg));
        }
コード例 #9
0
        public override void Initialize(Solution solution)
        {
            base.Initialize(solution);

            PSO.Particle p = (PSO.Particle)solution;

            // Generate initial conditions to adhere to the constraints...
            foreach (ConstraintMatrix cons in d_constraints)
            {
                Initialize(p, cons);
                double[] vel = p.Velocity;

                ValidateVelocityUpdate(p, vel, cons);
                p.Velocity = vel;
            }
        }
コード例 #10
0
        public override void AfterUpdate()
        {
            base.AfterUpdate();

            UpdateContext();

            // Calculate swarm radius
            double radius = SwarmRadius();

            // Check stagnation
            if (radius / d_diagonal >= d_stagnationThreshold.Evaluate(d_context, Biorob.Math.Constants.Context))
            {
                return;
            }

            // Regroup
            double[] range = new double[Job.Optimizer.Parameters.Count];
            range.Initialize();
            Solution best = Job.Optimizer.Best;

            for (int i = 0; i < range.Length; ++i)
            {
                foreach (Solution solution in Job.Optimizer.Population)
                {
                    double dist = System.Math.Abs(solution.Parameters[i].Value - best.Parameters[i].Value);

                    if (dist > range[i])
                    {
                        range[i] = dist;
                    }
                }

                Boundary boundary = Job.Optimizer.Parameters[i].Boundary;
                range[i] = System.Math.Min(boundary.Max - boundary.Min, d_regroupingFactor.Evaluate(d_context, Biorob.Math.Constants.Context) * range[i]);
            }

            // Reinitialize particles
            foreach (Solution solution in Job.Optimizer.Population)
            {
                PSO.Particle particle = (PSO.Particle)solution;

                for (int i = 0; i < particle.Parameters.Count; ++i)
                {
                    particle.SetPosition(i, best.Parameters[i].Value + Job.Optimizer.State.Random.Range(-0.5, 0.5) * range[i]);
                }
            }
        }
コード例 #11
0
        public int Compare(PSO.Particle p1, PSO.Particle p2)
        {
            if (p1 == null && p2 == null)
            {
                return(0);
            }
            else if (p1 == null)
            {
                return(-1);
            }
            else if (p2 == null)
            {
                return(1);
            }

            return(Compare(p1.Fitness, p2.Fitness));
        }
コード例 #12
0
        public double CalculateVelocityUpdate(PSO.Particle particle, PSO.Particle best, int i)
        {
            if (particle.Id != best.Id)
            {
                // Only care about being the best
                return(0.0);
            }

            double ret = 0;

            // Special velocity update, first reset the position
            ret -= particle.Parameters[i].Value;

            // Then move the particle to its best position
            ret += particle.PersonalBest.Parameters[i].Value;

            // Finally, add the random sample search
            Boundary boundary = particle.Parameters[i].Boundary;

            ret += d_sampleSize * (boundary.Max - boundary.Min) * (1 - 2 * particle.State.Random.NextDouble());

            return(ret);
        }
コード例 #13
0
        public bool UpdateParticleBest(PSO.Particle particle)
        {
            particle.Data["dpso::multiplier"] = 1.0;

            if (particle.PersonalBest == null || particle.Fitness > particle.PersonalBest.Fitness)
            {
                particle.Data["dpso::failures"]   = 0;
                particle.Data["dpso::multiplier"] = 1 / Configuration.EnergyInjectionFactor;
            }
            else
            {
                int failures = (int)(particle.Data["dpso::failures"]) + 1;
                particle.Data["dpso::failures"] = failures;

                if (failures > Configuration.FailureThreshold)
                {
                    particle.Data["dpso::multiplier"] = Configuration.EnergyInjectionFactor;
                    particle.Data["dpso::failures"]   = 0;
                }
            }

            return(false);
        }
コード例 #14
0
        public override void UpdateFitness(Solution solution)
        {
            base.UpdateFitness(solution);

            PSO.Particle particle = (PSO.Particle)solution;

            for (int i = 0; i < d_stages.Count; ++i)
            {
                Stage stage = d_stages[i];
                Stage next  = i != d_stages.Count - 1 ? d_stages[i + 1] : null;

                if (next == null || !next.Validate(particle.Fitness.Context))
                {
                    particle.Fitness.SetUserData("StagePSOStage", stage);
                    particle.Fitness.Value = stage.Value(particle.Fitness.Context);

                    particle.Data["StagePSO::stage"]   = i;
                    particle.Data["StagePSO::waslast"] = particle.Data["StagePSO::islast"];
                    particle.Data["StagePSO::islast"]  = (i == d_stages.Count - 1 ? "1" : "0");

                    break;
                }
            }
        }
コード例 #15
0
 public bool UpdateParticleBest(PSO.Particle particle)
 {
     return(false);
 }
コード例 #16
0
 public void ValidateVelocityUpdate(PSO.Particle particle, double[] velocityUpdate)
 {
     // Don't need to do anything special here
 }
コード例 #17
0
        private void ValidateVelocityUpdate(PSO.Particle particle, double[] velocityUpdate, ConstraintMatrix cons)
        {
            double maxsc = -1;

            double maxvel = ((PSO.Settings)Job.Optimizer.Configuration).MaxVelocity;

            foreach (string name in cons.Parameters)
            {
                Parameter param = particle.Parameter(name);
                int       idx   = particle.Parameters.IndexOf(param);

                double newvel = velocityUpdate[idx];
                double newpos = param.Value + newvel;
                double sc     = -1;

                if (newvel == 0)
                {
                    continue;
                }

                double maxpv = maxvel * (param.Boundary.Max - param.Boundary.Min);

                if (maxvel > 0 && System.Math.Abs(newvel) > maxpv)
                {
                    sc = System.Math.Abs(maxpv / newvel);

                    if (maxsc == -1 || sc < maxsc)
                    {
                        maxsc = sc;
                    }
                }

                if (newpos < param.Boundary.Min)
                {
                    sc = System.Math.Abs((param.Boundary.Min - param.Value) / newvel);
                }
                else if (newpos > param.Boundary.Max)
                {
                    sc = System.Math.Abs((param.Boundary.Max - param.Value) / newvel);
                }
                else if (sc == -1)
                {
                    continue;
                }

                if (maxsc == -1 || (sc != -1 && sc < maxsc))
                {
                    maxsc = sc;
                }
            }

            if (maxsc != -1)
            {
                foreach (string name in cons.Parameters)
                {
                    Parameter param = particle.Parameter(name);
                    int       idx   = particle.Parameters.IndexOf(param);

                    velocityUpdate[idx] *= maxsc;

                    /* This is a bit strange, but it is needed to solve numerical
                     * inaccuracies when multipying/dividing and we MUST ensure the
                     * boundaries (in particular if a sign would change) */
                    if (param.Value + velocityUpdate[idx] > param.Boundary.Max)
                    {
                        velocityUpdate[idx] = param.Boundary.Max - param.Value;
                    }
                    else if (param.Value + velocityUpdate[idx] < param.Boundary.Min)
                    {
                        velocityUpdate[idx] = param.Boundary.Min - param.Value;
                    }
                }
            }
        }
コード例 #18
0
 public PSO.Particle GetUpdateBest(PSO.Particle particle)
 {
     return(null);
 }
コード例 #19
0
 public PSO.State.VelocityUpdateType VelocityUpdateComponents(PSO.Particle particle)
 {
     return(PSO.State.VelocityUpdateType.DisableMomentum | PSO.State.VelocityUpdateType.DisableGlobal | PSO.State.VelocityUpdateType.DisableLocal);
 }
コード例 #20
0
 public double Value(PSO.Particle particle)
 {
     return(Value(particle.Fitness));
 }
コード例 #21
0
 public bool Validate(PSO.Particle particle)
 {
     return(Validate(particle.Fitness.Context, Biorob.Math.Constants.Context));
 }
コード例 #22
0
        private void Initialize(PSO.Particle particle, ConstraintMatrix constraint)
        {
            List <Linear.Vector> eqs     = constraint.Equations;
            List <Linear.Vector> nulleqs = constraint.NullspaceEquations;

            double[] rr  = new double[eqs[0].Count];
            double[] rrn = new double[nulleqs[0].Count];
            double   s   = 0;
            double   sn  = 0;

            PSO.Settings settings = (PSO.Settings)Job.Optimizer.Configuration;

            // Generate random variables
            for (int i = 0; i < rr.Length; ++i)
            {
                rr[i] = particle.State.Random.NextDouble();

                s += rr[i];
            }

            for (int i = 0; i < rrn.Length; ++i)
            {
                rrn[i] = particle.State.Random.NextDouble();
                sn    += rrn[i];
            }

            // Normalize such that sum == 1
            for (int i = 0; i < rr.Length; ++i)
            {
                rr[i] /= s;
            }

            for (int i = 0; i < rrn.Length; ++i)
            {
                rrn[i] /= sn;
            }

            // Initialize parameters of particle according to linear equations
            for (int i = 0; i < constraint.Parameters.Count; ++i)
            {
                string name = constraint.Parameters[i];

                Parameter param = particle.Parameter(name);
                double    v     = 0;

                for (int j = 0; j < rr.Length; ++j)
                {
                    v += rr[j] * constraint.Equations[i][j];
                }

                param.Value = v;

                v = 0;

                if (Configuration.HasInitialVelocity)
                {
                    for (int j = 0; j < rrn.Length; ++j)
                    {
                        v += rrn[j] * constraint.NullspaceEquations[i][j];
                    }

                    if (settings.MaxVelocity > 0)
                    {
                        v *= settings.MaxVelocity;
                    }
                }

                int idx = particle.Parameters.IndexOf(param);

                // Also set velocity to v
                particle.SetVelocity(idx, v);
            }
        }