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); }
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); }
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(); }
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); } }
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]); }
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); }
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); } }
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)); }
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; } }
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]); } } }
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)); }
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); }
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); }
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; } } }
public bool UpdateParticleBest(PSO.Particle particle) { return(false); }
public void ValidateVelocityUpdate(PSO.Particle particle, double[] velocityUpdate) { // Don't need to do anything special here }
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; } } } }
public PSO.Particle GetUpdateBest(PSO.Particle particle) { return(null); }
public PSO.State.VelocityUpdateType VelocityUpdateComponents(PSO.Particle particle) { return(PSO.State.VelocityUpdateType.DisableMomentum | PSO.State.VelocityUpdateType.DisableGlobal | PSO.State.VelocityUpdateType.DisableLocal); }
public double Value(PSO.Particle particle) { return(Value(particle.Fitness)); }
public bool Validate(PSO.Particle particle) { return(Validate(particle.Fitness.Context, Biorob.Math.Constants.Context)); }
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); } }