示例#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 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));
        }
示例#3
0
        private void StoreConstraints()
        {
            Storage.Storage storage = Job.Optimizer.Storage;

            storage.Query("DROP TABLE IF EXISTS `constraints`");
            storage.Query("DROP TABLE IF EXISTS `constraint_parameters`");
            storage.Query("DROP TABLE IF EXISTS `constraint_equations`");
            storage.Query("DROP TABLE IF EXISTS `constraint_coefficients`");

            storage.Query("CREATE TABLE `constraints` (`id` INTEGER PRIMARY KEY)");
            storage.Query("CREATE TABLE `constraint_parameters` (`id` INTEGER PRIMARY KEY, `constraint` INT, `parameter` TEXT)");
            storage.Query("CREATE TABLE `constraint_equations` (`id` INTEGER PRIMARY KEY, `constraint` INT, `equality` INT, `value` DOUBLE)");
            storage.Query("CREATE TABLE `constraint_coefficients` (`id` INTEGER PRIMARY KEY, `equation` INT, `value` DOUBLE)");

            for (int i = 0; i < d_constraints.Count; ++i)
            {
                ConstraintMatrix cons = d_constraints[i];

                storage.Query(@"INSERT INTO `constraints` DEFAULT VALUES");

                long cid = storage.LastInsertId;

                foreach (string p in cons.Parameters)
                {
                    storage.Query(@"INSERT INTO `constraint_parameters` (`constraint`, `parameter`) VALUES (@0, @1)",
                                  cid,
                                  p);
                }

                foreach (Linear.Constraint eq in cons.Constraints)
                {
                    storage.Query(@"INSERT INTO `constraint_equations` (`constraint`, `equality`, `value`) VALUES (@0, @1, @2)",
                                  cid,
                                  eq.Equality ? 1 : 0,
                                  eq.Value);

                    long eqid = storage.LastInsertId;

                    foreach (double coefficient in eq.Coefficients)
                    {
                        storage.Query(@"INSERT INTO `constraint_coefficients` (`equation`, `value`) VALUES (@0, @1)",
                                      eqid,
                                      coefficient);
                    }
                }
            }
        }
示例#4
0
        private void ConstraintViolationError(string msg, ConstraintMatrix cons, Solution solution, Dictionary <string, double> values, Linear.Constraint constraint)
        {
            List <string> s   = new List <string>();
            double        tot = 0;

            for (int i = 0; i < cons.Parameters.Count; ++i)
            {
                string name = cons.Parameters[i];
                s.Add(String.Format("{0:0.000} * {1} ({2:0.000})", constraint.Coefficients[i], name, values[name]));

                tot += constraint.Coefficients[i] * values[name];
            }

            string ss = String.Join(" + ", s.ToArray());

            Console.WriteLine("Constraint violated ({4}): {0} {1} {2:0.000} (expected {3:0.000})", ss, constraint.Equality ? "=" : "<=", tot, constraint.Value, msg);
        }
示例#5
0
        public override void FromStorage(Storage.Storage storage, Storage.Records.Optimizer optimizer)
        {
            base.FromStorage(storage, optimizer);

            storage.Query("SELECT `id` FROM `constraints` ORDER BY `id`", delegate(IDataReader reader) {
                ConstraintMatrix cons = new ConstraintMatrix(Job.Optimizer.Configuration.PopulationSize);

                int consid = reader.GetInt32(0);

                storage.Query("SELECT `parameter` FROM `constraint_parameters` WHERE `constraint` = @0", delegate(IDataReader rd) {
                    string name = reader.GetString(0);

                    cons.Add(Job.Optimizer.Parameter(name));
                    d_constraintsFor[name] = cons;

                    return(true);
                }, consid);

                storage.Query("SELECT `id`, `equality`, `value` FROM `constraint_equations` WHERE `constraint` = @0 ORDER BY `id`", delegate(IDataReader eqreader) {
                    int eqid      = eqreader.GetInt32(0);
                    bool equality = eqreader.GetInt32(1) == 1;
                    double val    = eqreader.GetDouble(2);

                    Linear.Vector coefficients = new Linear.Vector();

                    storage.Query("SELECT `value` FROM `constraint_coefficients` WHERE `equation` = @0 ORDER BY `id`", delegate(IDataReader cfreader) {
                        coefficients.Add(cfreader.GetDouble(0));
                        return(true);
                    }, eqid);

                    cons.Add(new Linear.Constraint(equality, coefficients, val));
                    return(true);
                }, consid);

                d_constraints.Add(cons);

                return(true);
            });
        }
示例#6
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;
                    }
                }
            }
        }
示例#7
0
        private void AddConstraint(XmlNode node)
        {
            XmlNodeList lst = node.SelectNodes("parameters/parameter");

            List <string> pars = new List <string>();

            if (lst.Count == 0)
            {
                XmlNode parameters = node.SelectSingleNode("parameters");

                if (parameters != null && !String.IsNullOrEmpty(parameters.InnerText.Trim()))
                {
                    pars.AddRange(Array.ConvertAll(parameters.InnerText.Trim().Split(','), item => item.Trim()));
                }
            }
            else
            {
                foreach (XmlNode p in lst)
                {
                    pars.Add(p.InnerText.Trim());
                }
            }

            if (pars.Count == 0)
            {
                throw new Exception("No parameters were specified");
            }

            ConstraintMatrix constr = new ConstraintMatrix(Job.Optimizer.Configuration.PopulationSize);

            foreach (string pname in pars)
            {
                Parameter p = Job.Optimizer.Parameter(pname);

                if (p == null)
                {
                    throw new Exception(String.Format("The parameter `{0}' could not be found", pname));
                }

                constr.Add(p);
            }

            foreach (XmlNode eq in node.SelectNodes("equation"))
            {
                XmlAttribute val        = eq.Attributes["value"];
                double       v          = 0;
                bool         isequality = true;

                if (val != null)
                {
                    Biorob.Math.Expression expr;
                    Biorob.Math.Expression.Create(val.Value.Trim(), out expr);

                    v = expr.Evaluate(Biorob.Math.Constants.Context);
                }

                XmlAttribute equality = eq.Attributes["equality"];

                if (equality != null)
                {
                    isequality = (equality.Value.Trim() == "yes");
                }

                string[] coefs = Array.ConvertAll(eq.InnerText.Split(','), item => item.Trim());

                if (coefs.Length != pars.Count)
                {
                    throw new Exception(String.Format("The number of coefficients is not equal to the number of parameters (expected {0}, but got {1})", pars.Count, coefs.Length));
                }

                Linear.Vector coefficients = new Linear.Vector(coefs.Length);

                for (int i = 0; i < coefs.Length; ++i)
                {
                    Biorob.Math.Expression expr;
                    Biorob.Math.Expression.Create(coefs[i].Trim(), out expr);

                    coefficients.Add(expr.Evaluate(Biorob.Math.Constants.Context));
                }

                constr.Add(new Linear.Constraint(isequality, coefficients, v));
            }

            if (!constr.Solve())
            {
                throw new Exception("Could not solve system of linear constraints!");
            }

            foreach (string param in constr.Parameters)
            {
                if (d_constraintsFor.ContainsKey(param))
                {
                    throw new Exception(String.Format("The parameter `{0}' is already part of another constraint...", param));
                }
            }

            d_constraints.Add(constr);

            foreach (string param in constr.Parameters)
            {
                d_constraintsFor[param] = constr;
            }
        }
示例#8
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);
            }
        }