Beispiel #1
0
        /// <summary>
        /// Performs a discrete crossover operation of any number of given parents.
        /// </summary>
        /// <exception cref="ArgumentException">Thrown when the vectors of the parents are of different length or when there are less than 2 parents.</exception>
        /// <param name="random">A random number generator.</param>
        /// <param name="parents">The list of parents for the crossover operation.</param>
        /// <returns>The newly created integer vector, resulting from the crossover operation.</returns>
        public static IntegerVector Apply(IRandom random, ItemArray <IntegerVector> parents)
        {
            if (parents.Length < 2)
            {
                throw new ArgumentException("DiscreteCrossover: There are less than two parents to cross.");
            }
            int length = parents[0].Length;

            for (int i = 0; i < parents.Length; i++)
            {
                if (parents[i].Length != length)
                {
                    throw new ArgumentException("DiscreteCrossover: The parents' vectors are of different length.", "parents");
                }
            }

            var result = new IntegerVector(length);

            for (int i = 0; i < length; i++)
            {
                result[i] = parents[random.Next(parents.Length)][i];
            }

            return(result);
        }
Beispiel #2
0
        /// <summary>
        /// Perfomrs a heuristic crossover on the two given parents.
        /// </summary>
        /// <exception cref="ArgumentException">Thrown when two parents are not of the same length.</exception>
        /// <param name="random">The random number generator.</param>
        /// <param name="betterParent">The first parent for the crossover operation.</param>
        /// <param name="worseParent">The second parent for the crossover operation.</param>
        /// <param name="bounds">The bounds and step size for each dimension (will be cycled in case there are less rows than elements in the parent vectors).</param>
        /// <returns>The newly created integer vector, resulting from the heuristic crossover.</returns>
        public static IntegerVector Apply(IRandom random, IntegerVector betterParent, IntegerVector worseParent, IntMatrix bounds)
        {
            if (betterParent.Length != worseParent.Length)
            {
                throw new ArgumentException("HeuristicCrossover: the two parents are not of the same length");
            }

            int    length = betterParent.Length;
            var    result = new IntegerVector(length);
            double factor = random.NextDouble();

            int min, max, step = 1;

            for (int i = 0; i < length; i++)
            {
                min = bounds[i % bounds.Rows, 0];
                max = bounds[i % bounds.Rows, 1];
                if (bounds.Columns > 2)
                {
                    step = bounds[i % bounds.Rows, 2];
                }
                max       = FloorFeasible(min, max, step, max - 1);
                result[i] = RoundFeasible(min, max, step, betterParent[i] + factor * (betterParent[i] - worseParent[i]));
            }
            return(result);
        }
Beispiel #3
0
        public static double CalculateSimilarity(IntegerVector left, IntegerVector right)
        {
            if (left == null || right == null)
            {
                throw new ArgumentException("Cannot calculate similarity because one or both of the provided solutions is null.");
            }
            if (left.Length != right.Length)
            {
                throw new ArgumentException("Cannot calculate similarity because the provided solutions have different lengths.");
            }
            if (left.Length == 0)
            {
                throw new ArgumentException("Cannot calculate similarity because solutions are of length 0.");
            }
            if (ReferenceEquals(left, right))
            {
                return(1.0);
            }

            double similarity = 0.0;

            for (int i = 0; i < left.Length; i++)
            {
                if (left[i] == right[i])
                {
                    similarity++;
                }
            }
            return(similarity / left.Length);
        }
        /// <summary>
        /// Performs a local crossover on the two given parent vectors.
        /// </summary>
        /// <exception cref="ArgumentException">Thrown when two parents are not of the same length.</exception>
        /// <param name="random">The random number generator.</param>
        /// <param name="parent1">The first parent for the crossover operation.</param>
        /// <param name="parent2">The second parent for the crossover operation.</param>
        /// <returns>The newly created integer vector, resulting from the local crossover.</returns>
        public static IntegerVector Apply(IRandom random, IntegerVector parent1, IntegerVector parent2, IntMatrix bounds)
        {
            if (parent1.Length != parent2.Length)
            {
                throw new ArgumentException("RoundedLocalCrossover: the two parents are not of the same length");
            }

            double factor;
            int    length = parent1.Length;
            var    result = new IntegerVector(length);

            int min, max, step = 1;

            for (int i = 0; i < length; i++)
            {
                min = bounds[i % bounds.Rows, 0];
                max = bounds[i % bounds.Rows, 1];
                if (bounds.Columns > 2)
                {
                    step = bounds[i % bounds.Rows, 2];
                }
                max       = FloorFeasible(min, max, step, max - 1);
                factor    = random.NextDouble();
                result[i] = RoundFeasible(min, max, step, (factor * parent1[i]) + ((1 - factor) * parent2[i]));
            }
            return(result);
        }
        public static void Manipulate(IRandom random, IntegerVector vector, IntMatrix bounds, int index)
        {
            if (bounds == null || bounds.Rows == 0 || bounds.Columns < 2)
            {
                throw new ArgumentException("UniformOnePositionManipulator: Invalid bounds specified", "bounds");
            }
            int min = bounds[index % bounds.Rows, 0], max = bounds[index % bounds.Rows, 1], step = 1;

            if (min == max)
            {
                vector[index] = min;
            }
            else
            {
                if (bounds.Columns > 2)
                {
                    step = bounds[index % bounds.Rows, 2];
                }
                // max has to be rounded to the lower feasible value
                // e.g. min...max / step = 0...100 / 5, max is exclusive so it would be 0..99
                // but 99 is not a feasible value, so max needs to be adjusted => min = 0, max = 95
                max           = FloorFeasible(min, max, step, max - 1);
                vector[index] = RoundFeasible(min, max, step, random.Next(min, max));
            }
        }
    /// <summary>
    /// Genotype-to-Phenotype mapper (iterative breath-first approach, by using a queue -> FIFO).
    /// </summary>
    /// <param name="startNode">first node of the tree with arity 1</param>
    /// <param name="genotype">integer vector, which should be mapped to a tree</param>
    /// <param name="grammar">grammar to determine the allowed child symbols for each node</param>
    /// <param name="maxSubtreeCount">maximum allowed subtrees (= number of used genomes)</param>
    /// <param name="random">random number generator</param>
    private void MapBreathFirstIteratively(ISymbolicExpressionTreeNode startNode,
                                          IntegerVector genotype,
                                          ISymbolicExpressionGrammar grammar,
                                          int maxSubtreeCount, IRandom random) {

      Queue<Tuple<ISymbolicExpressionTreeNode, int>> queue
        = new Queue<Tuple<ISymbolicExpressionTreeNode, int>>(); // tuples of <node, arity>

      int genotypeIndex = 0;
      queue.Enqueue(new Tuple<ISymbolicExpressionTreeNode, int>(startNode, 1));

      while (queue.Count > 0) {

        Tuple<ISymbolicExpressionTreeNode, int> current = queue.Dequeue();

        // foreach subtree of the current node, create a new node and enqueue it, if it is no terminal node
        for (int i = 0; i < current.Item2; ++i) {

          if (genotypeIndex >= maxSubtreeCount) {
            // if all genomes were used, only add terminal nodes to the remaining subtrees
            current.Item1.AddSubtree(GetRandomTerminalNode(current.Item1, grammar, random));
          } else {
            var newNode = GetNewChildNode(current.Item1, genotype, grammar, genotypeIndex, random);
            int arity = SampleArity(random, newNode, grammar);

            current.Item1.AddSubtree(newNode);
            genotypeIndex++;
            if (arity > 0) {
              // new node has subtrees so enqueue the node 
              queue.Enqueue(new Tuple<ISymbolicExpressionTreeNode, int>(newNode, arity));
            }
          }
        }
      }
    }
    /// <summary>
    /// Performs the rounded blend alpha crossover (BLX-a) of two integer vectors.<br/>
    /// It creates new offspring by sampling a new value in the range [min_i - d * alpha, max_i + d * alpha) at each position i
    /// and rounding the result to the next integer.
    /// Here min_i and max_i are the smaller and larger value of the two parents at position i and d is max_i - min_i.
    /// </summary>
    /// <exception cref="ArgumentException">
    /// Thrown when <paramref name="parent1"/> and <paramref name="parent2"/> are of different length or<br/>
    /// when <paramref name="alpha"/> is less than 0.
    /// </exception>
    /// <param name="random">The random number generator.</param>
    /// <param name="parent1">The first parent for the crossover operation.</param>
    /// <param name="parent2">The second parent for the crossover operation.</param>
    /// <param name="bounds">The bounds and step size for each dimension (will be cycled in case there are less rows than elements in the parent vectors).</param>
    /// <param name="alpha">The alpha value for the crossover.</param>
    /// <returns>The newly created integer vector resulting from the crossover operation.</returns>
    public static IntegerVector Apply(IRandom random, IntegerVector parent1, IntegerVector parent2, IntMatrix bounds, DoubleValue alpha) {
      if (parent1.Length != parent2.Length) throw new ArgumentException("RoundedBlendAlphaCrossover: The parents' vectors are of different length.", "parent1");
      if (alpha.Value < 0) throw new ArgumentException("RoundedBlendAlphaCrossover: Paramter alpha must be greater or equal than 0.", "alpha");
      if (bounds == null || bounds.Rows < 1 || bounds.Columns < 2) throw new ArgumentException("RoundedBlendAlphaCrossover: Invalid bounds specified.", "bounds");

      int length = parent1.Length;
      var result = new IntegerVector(length);
      double max = 0, min = 0, d = 0, resMin = 0, resMax = 0;
      int minBound, maxBound, step = 1;

      for (int i = 0; i < length; i++) {
        minBound = bounds[i % bounds.Rows, 0];
        maxBound = bounds[i % bounds.Rows, 1];
        if (bounds.Columns > 2) step = bounds[i % bounds.Rows, 2];
        maxBound = FloorFeasible(minBound, maxBound, step, maxBound - 1);

        max = Math.Max(parent1[i], parent2[i]);
        min = Math.Min(parent1[i], parent2[i]);
        d = Math.Abs(max - min);
        resMin = FloorFeasible(minBound, maxBound, step, min - d * alpha.Value);
        resMax = CeilingFeasible(minBound, maxBound, step, max + d * alpha.Value);

        result[i] = RoundFeasible(minBound, maxBound, step, resMin + random.NextDouble() * Math.Abs(resMax - resMin));
      }
      return result;
    }
        public static double CalculateSimilarity(IntegerVector left, IntegerVector right, double scaling = 1.0)
        {
            if (left == null || right == null)
            {
                throw new ArgumentException("Cannot calculate similarity because one or both of the provided solutions is null.");
            }
            if (left.Length != right.Length)
            {
                throw new ArgumentException("Cannot calculate similarity because the provided solutions have different lengths.");
            }
            if (left.Length == 0)
            {
                throw new ArgumentException("Cannot calculate similarity because solutions are of length 0.");
            }
            if (scaling <= 0)
            {
                throw new ArgumentException("Cannot choose a 0 or negative scaling value.");
            }
            if (ReferenceEquals(left, right))
            {
                return(1.0);
            }

            var distance = 0.0;

            for (int i = 0; i < left.Length; i++)
            {
                distance += (left[i] - right[i]) * (left[i] - right[i]);
            }
            return(1.0 / (1.0 + Math.Sqrt(distance) / scaling));
        }
Beispiel #9
0
        /// <summary>
        /// Generates a new random integer vector with the given <paramref name="length"/>.
        /// </summary>
        /// <param name="random">The random number generator.</param>
        /// <param name="length">The length of the int vector.</param>
        /// <param name="bounds">A matrix containing the inclusive lower and inclusive upper bound in the first and second column and a step size in the third column.
        /// Each line represents the bounds for a certain dimension. If fewer lines are given, the lines are cycled.</param>
        /// <returns>The newly created integer vector.</returns>
        public static IntegerVector Apply(IRandom random, int length, IntMatrix bounds)
        {
            var result = new IntegerVector(length);

            result.Randomize(random, bounds);
            return(result);
        }
        /// <summary>
        /// Performs a normally distributed all position manipulation on the given
        /// <paramref name="vector"/> and rounds the result to the next feasible value.
        /// </summary>
        /// <exception cref="InvalidOperationException">Thrown when the sigma vector is null or of length 0.</exception>
        /// <param name="sigma">The sigma vector determining the strength of the mutation.</param>
        /// <param name="random">A random number generator.</param>
        /// <param name="vector">The integer vector to manipulate.</param>#
        /// <param name="bounds">The bounds and step size for each dimension (will be cycled in case there are less rows than elements in the parent vectors).</param>
        /// <returns>The manipulated integer vector.</returns>
        public static void Apply(IRandom random, IntegerVector vector, IntMatrix bounds, DoubleArray sigma)
        {
            if (sigma == null || sigma.Length == 0)
            {
                throw new ArgumentException("RoundedNormalAllPositionsManipulator: Vector containing the standard deviations is not defined.", "sigma");
            }
            if (bounds == null || bounds.Rows == 0 || bounds.Columns < 2)
            {
                throw new ArgumentException("RoundedNormalAllPositionsManipulator: Invalid bounds specified.", "bounds");
            }
            var N = new NormalDistributedRandom(random, 0.0, 1.0);

            for (int i = 0; i < vector.Length; i++)
            {
                int min = bounds[i % bounds.Rows, 0], max = bounds[i % bounds.Rows, 1], step = 1;
                if (bounds.Columns > 2)
                {
                    step = bounds[i % bounds.Rows, 2];
                }

                int value = (vector[i] + (int)Math.Round((N.NextDouble() * sigma[i % sigma.Length])) - min) / step;
                max       = FloorFeasible(min, max, step, max - 1);
                vector[i] = RoundFeasible(min, max, step, value);
            }
        }
 /// <summary>
 /// Changes randomly a single position in the given integer <paramref name="vector"/>.
 /// </summary>
 /// <remarks>Calls <see cref="Apply"/>.</remarks>
 /// <param name="random">A random number generator.</param>
 /// <param name="vector">The integer vector to manipulate.</param>
 /// <param name="bounds">The bounds and step size for each dimension (will be cycled in case there are less rows than elements in the parent vectors).</param>
 protected override void ManipulateBounded(IRandom random, IntegerVector vector, IntMatrix bounds)
 {
     if (BoundsParameter.ActualValue == null)
     {
         throw new InvalidOperationException("UniformOnePositionManipulator: Parameter " + BoundsParameter.ActualName + " could not be found.");
     }
     Apply(random, vector, bounds);
 }
 protected sealed override void Manipulate(IRandom random, IntegerVector integerVector)
 {
     if (BoundsParameter.ActualValue == null)
     {
         throw new InvalidOperationException("BoundedIntegerVectorManipulator: Parameter " + BoundsParameter.ActualName + " could not be found.");
     }
     ManipulateBounded(random, integerVector, BoundsParameter.ActualValue);
 }
    /// <summary>
    /// Performs a normally distributed all position manipulation on the given 
    /// <paramref name="vector"/> and rounds the result to the next feasible value.
    /// </summary>
    /// <exception cref="InvalidOperationException">Thrown when the sigma vector is null or of length 0.</exception>
    /// <param name="sigma">The sigma vector determining the strength of the mutation.</param>
    /// <param name="random">A random number generator.</param>
    /// <param name="vector">The integer vector to manipulate.</param>#
    /// <param name="bounds">The bounds and step size for each dimension (will be cycled in case there are less rows than elements in the parent vectors).</param>
    /// <returns>The manipulated integer vector.</returns>
    public static void Apply(IRandom random, IntegerVector vector, IntMatrix bounds, DoubleArray sigma) {
      if (sigma == null || sigma.Length == 0) throw new ArgumentException("RoundedNormalAllPositionsManipulator: Vector containing the standard deviations is not defined.", "sigma");
      if (bounds == null || bounds.Rows == 0 || bounds.Columns < 2) throw new ArgumentException("RoundedNormalAllPositionsManipulator: Invalid bounds specified.", "bounds");
      var N = new NormalDistributedRandom(random, 0.0, 1.0);
      for (int i = 0; i < vector.Length; i++) {
        int min = bounds[i % bounds.Rows, 0], max = bounds[i % bounds.Rows, 1], step = 1;
        if (bounds.Columns > 2) step = bounds[i % bounds.Rows, 2];

        int value = (vector[i] + (int)Math.Round((N.NextDouble() * sigma[i % sigma.Length])) - min) / step;
        max = FloorFeasible(min, max, step, max - 1);
        vector[i] = RoundFeasible(min, max, step, value);
      }
    }
    /// <summary>
    /// Changes randomly several, but at least one, positions in the given integer <paramref name="vector"/>, according to the given probabilities.
    /// </summary>
    /// <param name="random">A random number generator.</param>
    /// <param name="vector">The integer vector to manipulate.</param>
    /// <param name="bounds"> Contains the minimum value (inclusive), maximum value (exclusive), and step size of the sampling range for 
    /// the vector element to change.</param>
    /// <param name="probability">The probability for each dimension to be manipulated..</param>
    public static void Apply(IRandom random, IntegerVector vector, IntMatrix bounds, double probability) {
      if (bounds == null || bounds.Rows == 0 || bounds.Columns < 2) throw new ArgumentException("UniformSomePositionsManipulator: Invalid bounds specified", "bounds");
      bool atLeastOneManipulated = false;
      for (int index = 0; index < vector.Length; index++) {
        if (random.NextDouble() < probability) {
          atLeastOneManipulated = true;
          UniformOnePositionManipulator.Manipulate(random, vector, bounds, index);
        }
      }

      if (!atLeastOneManipulated) {
        UniformOnePositionManipulator.Manipulate(random, vector, bounds, random.Next(vector.Length));
      }
    }
 public static void Manipulate(IRandom random, IntegerVector vector, IntMatrix bounds, int index) {
   if (bounds == null || bounds.Rows == 0 || bounds.Columns < 2) throw new ArgumentException("UniformOnePositionManipulator: Invalid bounds specified", "bounds");
   int min = bounds[index % bounds.Rows, 0], max = bounds[index % bounds.Rows, 1], step = 1;
   if (min == max) {
     vector[index] = min;
   } else {
     if (bounds.Columns > 2) step = bounds[index % bounds.Rows, 2];
     // max has to be rounded to the lower feasible value
     // e.g. min...max / step = 0...100 / 5, max is exclusive so it would be 0..99
     // but 99 is not a feasible value, so max needs to be adjusted => min = 0, max = 95
     max = FloorFeasible(min, max, step, max - 1);
     vector[index] = RoundFeasible(min, max, step, random.Next(min, max));
   }
 }
        /// <summary>
        /// Performs the rounded blend alpha beta crossover (BLX-a-b) on two parent vectors.
        /// </summary>
        /// <exception cref="ArgumentException">
        /// Thrown when either:<br/>
        /// <list type="bullet">
        /// <item><description>The length of <paramref name="betterParent"/> and <paramref name="worseParent"/> is not equal.</description></item>
        /// <item><description>The parameter <paramref name="alpha"/> is smaller than 0.</description></item>
        /// <item><description>The parameter <paramref name="beta"/> is smaller than 0.</description></item>
        /// </list>
        /// </exception>
        /// <param name="random">The random number generator to use.</param>
        /// <param name="betterParent">The better of the two parents with regard to their fitness.</param>
        /// <param name="worseParent">The worse of the two parents with regard to their fitness.</param>
        /// <param name="bounds">The bounds and step size for each dimension (will be cycled in case there are less rows than elements in the parent vectors).</param>
        /// <param name="alpha">The parameter alpha.</param>
        /// <param name="beta">The parameter beta.</param>
        /// <returns>The integer vector that results from the crossover.</returns>
        public static IntegerVector Apply(IRandom random, IntegerVector betterParent, IntegerVector worseParent, IntMatrix bounds, DoubleValue alpha, DoubleValue beta)
        {
            if (betterParent.Length != worseParent.Length)
            {
                throw new ArgumentException("RoundedBlendAlphaBetaCrossover: The parents' vectors are of different length.", "betterParent");
            }
            if (alpha.Value < 0)
            {
                throw new ArgumentException("RoundedBlendAlphaBetaCrossover: Parameter alpha must be greater or equal to 0.", "alpha");
            }
            if (beta.Value < 0)
            {
                throw new ArgumentException("RoundedBlendAlphaBetaCrossover: Parameter beta must be greater or equal to 0.", "beta");
            }
            if (bounds == null || bounds.Rows < 1 || bounds.Columns < 2)
            {
                throw new ArgumentException("RoundedBlendAlphaBetaCrossover: Invalid bounds specified.", "bounds");
            }

            int    length = betterParent.Length;
            double min, max, d;
            var    result = new IntegerVector(length);
            int    minBound, maxBound, step = 1;

            for (int i = 0; i < length; i++)
            {
                minBound = bounds[i % bounds.Rows, 0];
                maxBound = bounds[i % bounds.Rows, 1];
                if (bounds.Columns > 2)
                {
                    step = bounds[i % bounds.Rows, 2];
                }
                maxBound = FloorFeasible(minBound, maxBound, step, maxBound - 1);

                d = Math.Abs(betterParent[i] - worseParent[i]);
                if (betterParent[i] <= worseParent[i])
                {
                    min = FloorFeasible(minBound, maxBound, step, betterParent[i] - d * alpha.Value);
                    max = CeilingFeasible(minBound, maxBound, step, worseParent[i] + d * beta.Value);
                }
                else
                {
                    min = FloorFeasible(minBound, maxBound, step, worseParent[i] - d * beta.Value);
                    max = CeilingFeasible(minBound, maxBound, step, betterParent[i] + d * alpha.Value);
                }
                result[i] = RoundFeasible(minBound, maxBound, step, min + random.NextDouble() * (max - min));
            }
            return(result);
        }
Beispiel #17
0
    public PWREncoding(int nrOfJobs, int nrOfResources, IRandom random)
      : base() {
      PermutationWithRepetition = new IntegerVector(nrOfJobs * nrOfResources);
      int[] lookUpTable = new int[nrOfJobs];

      for (int i = 0; i < PermutationWithRepetition.Length; i++) {
        int newValue = random.Next(nrOfJobs);
        while (lookUpTable[newValue] >= nrOfResources)
          newValue = random.Next(nrOfJobs);

        PermutationWithRepetition[i] = newValue;

        lookUpTable[newValue]++;
      }
    }
    /// <summary>
    /// Performs a single point crossover at a randomly chosen position of the two 
    /// given parent integer vectors.
    /// </summary>
    /// <param name="random">A random number generator.</param>
    /// <param name="parent1">The first parent for crossover.</param>
    /// <param name="parent2">The second parent for crossover.</param>
    /// <returns>The newly created integer vector, resulting from the single point crossover.</returns>
    public static IntegerVector Apply(IRandom random, IntegerVector parent1, IntegerVector parent2) {
      if (parent1.Length != parent2.Length)
        throw new ArgumentException("SinglePointCrossover: The parents are of different length.");

      int length = parent1.Length;
      int[] result = new int[length];
      int breakPoint = random.Next(1, length);

      for (int i = 0; i < breakPoint; i++)
        result[i] = parent1[i];
      for (int i = breakPoint; i < length; i++)
        result[i] = parent2[i];

      return new IntegerVector(result);
    }
Beispiel #19
0
    /// <summary>
    /// Maps a genotype (an integer vector) to a phenotype (a symbolic expression tree).
    /// Random approach.
    /// </summary>
    /// <param name="random">random number generator</param>
    /// <param name="bounds">only used for PIGEMapper (ignore here)</param>
    /// <param name="length">only used for PIGEMapper (ignore here)</param>
    /// <param name="grammar">grammar definition</param>
    /// <param name="genotype">integer vector, which should be mapped to a tree</param>
    /// <returns>phenotype (a symbolic expression tree)</returns>
    public override SymbolicExpressionTree Map(IRandom random, IntMatrix bounds, int length,
                                               ISymbolicExpressionGrammar grammar,
                                               IntegerVector genotype) {

      SymbolicExpressionTree tree = new SymbolicExpressionTree();
      var rootNode = (SymbolicExpressionTreeTopLevelNode)grammar.ProgramRootSymbol.CreateTreeNode();
      var startNode = (SymbolicExpressionTreeTopLevelNode)grammar.StartSymbol.CreateTreeNode();
      rootNode.AddSubtree(startNode);
      tree.Root = rootNode;

      MapRandomIteratively(startNode, genotype, grammar,
                           genotype.Length, random);

      return tree;
    }
    /// <summary>
    /// Performs a discrete crossover operation of any number of given parents.
    /// </summary>
    /// <exception cref="ArgumentException">Thrown when the vectors of the parents are of different length or when there are less than 2 parents.</exception>
    /// <param name="random">A random number generator.</param>
    /// <param name="parents">The list of parents for the crossover operation.</param>
    /// <returns>The newly created integer vector, resulting from the crossover operation.</returns>
    public static IntegerVector Apply(IRandom random, ItemArray<IntegerVector> parents) {
      if (parents.Length < 2) throw new ArgumentException("DiscreteCrossover: There are less than two parents to cross.");
      int length = parents[0].Length;

      for (int i = 0; i < parents.Length; i++) {
        if (parents[i].Length != length)
          throw new ArgumentException("DiscreteCrossover: The parents' vectors are of different length.", "parents");
      }

      var result = new IntegerVector(length);
      for (int i = 0; i < length; i++) {
        result[i] = parents[random.Next(parents.Length)][i];
      }

      return result;
    }
    /// <summary>
    /// Performs the arithmetic crossover on some positions by taking either x = alpha * p1 + (1 - alpha) * p2 or x = p1 depending on the probability for a gene to be crossed.
    /// </summary>
    /// <param name="random">The random number generator.</param>
    /// <param name="parent1">The first parent vector.</param>
    /// <param name="parent2">The second parent vector.</param>
    /// <param name="bounds">The bounds and step size for each dimension (will be cycled in case there are less rows than elements in the parent vectors).</param>
    /// <param name="alpha">The alpha parameter (<see cref="AlphaParameter"/>).</param>
    /// <param name="probability">The probability parameter (<see cref="ProbabilityParameter"/>).</param>
    /// <returns>The vector resulting from the crossover.</returns>
    public static IntegerVector Apply(IRandom random, IntegerVector parent1, IntegerVector parent2, IntMatrix bounds, DoubleValue alpha, DoubleValue probability) {
      int length = parent1.Length;
      if (length != parent2.Length) throw new ArgumentException("RoundedUniformArithmeticCrossover: The parent vectors are of different length.", "parent1");
      if (alpha.Value < 0 || alpha.Value > 1) throw new ArgumentException("RoundedUniformArithmeticCrossover: Parameter alpha must be in the range [0;1]", "alpha");
      if (probability.Value < 0 || probability.Value > 1) throw new ArgumentException("RoundedUniformArithmeticCrossover: Parameter probability must be in the range [0;1]", "probability");

      var result = new IntegerVector(length);
      for (int i = 0; i < length; i++) {
        if (random.NextDouble() < probability.Value) {
          int min = bounds[i % bounds.Rows, 0], max = bounds[i % bounds.Rows, 1], step = 1;
          if (bounds.Columns > 2) step = bounds[i % bounds.Rows, 2];
          max = FloorFeasible(min, max, step, max - 1);
          double value = alpha.Value * parent1[i] + (1 - alpha.Value) * parent2[i];
          result[i] = RoundFeasible(min, max, step, value);
        } else result[i] = parent1[i];
      }
      return result;
    }
    /// <summary>
    /// Perfomrs a heuristic crossover on the two given parents.
    /// </summary>
    /// <exception cref="ArgumentException">Thrown when two parents are not of the same length.</exception>
    /// <param name="random">The random number generator.</param>
    /// <param name="betterParent">The first parent for the crossover operation.</param>
    /// <param name="worseParent">The second parent for the crossover operation.</param>
    /// <param name="bounds">The bounds and step size for each dimension (will be cycled in case there are less rows than elements in the parent vectors).</param>
    /// <returns>The newly created integer vector, resulting from the heuristic crossover.</returns>
    public static IntegerVector Apply(IRandom random, IntegerVector betterParent, IntegerVector worseParent, IntMatrix bounds) {
      if (betterParent.Length != worseParent.Length)
        throw new ArgumentException("HeuristicCrossover: the two parents are not of the same length");

      int length = betterParent.Length;
      var result = new IntegerVector(length);
      double factor = random.NextDouble();

      int min, max, step = 1;
      for (int i = 0; i < length; i++) {
        min = bounds[i % bounds.Rows, 0];
        max = bounds[i % bounds.Rows, 1];
        if (bounds.Columns > 2) step = bounds[i % bounds.Rows, 2];
        max = FloorFeasible(min, max, step, max - 1);
        result[i] = RoundFeasible(min, max, step, betterParent[i] + factor * (betterParent[i] - worseParent[i]));
      }
      return result;
    }
    /// <summary>
    /// Performs a local crossover on the two given parent vectors.
    /// </summary>
    /// <exception cref="ArgumentException">Thrown when two parents are not of the same length.</exception>
    /// <param name="random">The random number generator.</param>
    /// <param name="parent1">The first parent for the crossover operation.</param>
    /// <param name="parent2">The second parent for the crossover operation.</param>
    /// <returns>The newly created integer vector, resulting from the local crossover.</returns>
    public static IntegerVector Apply(IRandom random, IntegerVector parent1, IntegerVector parent2, IntMatrix bounds) {
      if (parent1.Length != parent2.Length)
        throw new ArgumentException("RoundedLocalCrossover: the two parents are not of the same length");

      double factor;
      int length = parent1.Length;
      var result = new IntegerVector(length);

      int min, max, step = 1;
      for (int i = 0; i < length; i++) {
        min = bounds[i % bounds.Rows, 0];
        max = bounds[i % bounds.Rows, 1];
        if (bounds.Columns > 2) step = bounds[i % bounds.Rows, 2];
        max = FloorFeasible(min, max, step, max - 1);
        factor = random.NextDouble();
        result[i] = RoundFeasible(min, max, step, (factor * parent1[i]) + ((1 - factor) * parent2[i]));
      }
      return result;
    }
    public static OrienteeringEvaluationResult Apply(IntegerVector solution, DoubleArray scores,
      DistanceMatrix distances, double maximumDistance, double pointVisitingCosts, double distancePenaltyFactor) {

      double score = solution.Sum(t => scores[t]);
      double distance = distances.CalculateTourLength(solution.ToList(), pointVisitingCosts);

      double distanceViolation = distance - maximumDistance;

      double penalty = 0.0;
      penalty += distanceViolation > 0 ? distanceViolation * distancePenaltyFactor : 0;

      double quality = score - penalty;

      return new OrienteeringEvaluationResult {
        Quality = new DoubleValue(quality),
        Penalty = new DoubleValue(penalty),
        Distance = new DoubleValue(distance)
      };
    }
        /// <summary>
        /// Performs the rounded blend alpha crossover (BLX-a) of two integer vectors.<br/>
        /// It creates new offspring by sampling a new value in the range [min_i - d * alpha, max_i + d * alpha) at each position i
        /// and rounding the result to the next integer.
        /// Here min_i and max_i are the smaller and larger value of the two parents at position i and d is max_i - min_i.
        /// </summary>
        /// <exception cref="ArgumentException">
        /// Thrown when <paramref name="parent1"/> and <paramref name="parent2"/> are of different length or<br/>
        /// when <paramref name="alpha"/> is less than 0.
        /// </exception>
        /// <param name="random">The random number generator.</param>
        /// <param name="parent1">The first parent for the crossover operation.</param>
        /// <param name="parent2">The second parent for the crossover operation.</param>
        /// <param name="bounds">The bounds and step size for each dimension (will be cycled in case there are less rows than elements in the parent vectors).</param>
        /// <param name="alpha">The alpha value for the crossover.</param>
        /// <returns>The newly created integer vector resulting from the crossover operation.</returns>
        public static IntegerVector Apply(IRandom random, IntegerVector parent1, IntegerVector parent2, IntMatrix bounds, DoubleValue alpha)
        {
            if (parent1.Length != parent2.Length)
            {
                throw new ArgumentException("RoundedBlendAlphaCrossover: The parents' vectors are of different length.", "parent1");
            }
            if (alpha.Value < 0)
            {
                throw new ArgumentException("RoundedBlendAlphaCrossover: Paramter alpha must be greater or equal than 0.", "alpha");
            }
            if (bounds == null || bounds.Rows < 1 || bounds.Columns < 2)
            {
                throw new ArgumentException("RoundedBlendAlphaCrossover: Invalid bounds specified.", "bounds");
            }

            int    length = parent1.Length;
            var    result = new IntegerVector(length);
            double max = 0, min = 0, d = 0, resMin = 0, resMax = 0;
            int    minBound, maxBound, step = 1;

            for (int i = 0; i < length; i++)
            {
                minBound = bounds[i % bounds.Rows, 0];
                maxBound = bounds[i % bounds.Rows, 1];
                if (bounds.Columns > 2)
                {
                    step = bounds[i % bounds.Rows, 2];
                }
                maxBound = FloorFeasible(minBound, maxBound, step, maxBound - 1);

                max    = Math.Max(parent1[i], parent2[i]);
                min    = Math.Min(parent1[i], parent2[i]);
                d      = Math.Abs(max - min);
                resMin = FloorFeasible(minBound, maxBound, step, min - d * alpha.Value);
                resMax = CeilingFeasible(minBound, maxBound, step, max + d * alpha.Value);

                result[i] = RoundFeasible(minBound, maxBound, step, resMin + random.NextDouble() * Math.Abs(resMax - resMin));
            }
            return(result);
        }
Beispiel #26
0
        /// <summary>
        /// Performs an average crossover of the two given parent integer vectors.
        /// The average is rounded and mapped to the nearest valid value (e.g. if step size is > 1)
        /// </summary>
        /// <param name="random">A random number generator.</param>
        /// <param name="parents">The parents for crossover.</param>
        /// <param name="bounds">The bounds matrix that contains for each dimension one row with minimum (inclusive), maximum (exclusive), and step size columns.
        /// If the number of rows is smaller than the number of dimensions the matrix is cycled.</param>
        /// <returns>The newly created integer vector, resulting from the single point crossover.</returns>
        public static IntegerVector Apply(IRandom random, ItemArray <IntegerVector> parents, IntMatrix bounds)
        {
            int length = parents[0].Length, parentsCount = parents.Length;

            if (parents.Length < 2)
            {
                throw new ArgumentException("RoundedAverageCrossover: The number of parents is less than 2.", "parents");
            }
            if (bounds == null || bounds.Rows < 1 || bounds.Columns < 2)
            {
                throw new ArgumentException("AverageCrossover: Invalid bounds specified.", "bounds");
            }

            var result = new IntegerVector(length);

            try {
                double avg;
                for (int i = 0; i < length; i++)
                {
                    avg = 0;
                    for (int j = 0; j < parentsCount; j++)
                    {
                        avg += parents[j][i];
                    }
                    avg /= parentsCount;
                    int min = bounds[i % bounds.Rows, 0], max = bounds[i % bounds.Rows, 1], step = 1;
                    if (bounds.Columns > 2)
                    {
                        step = bounds[i % bounds.Rows, 2];
                    }
                    max       = FloorFeasible(min, max, step, max - 1);
                    result[i] = RoundFeasible(min, max, step, avg);
                }
            } catch (IndexOutOfRangeException) {
                throw new ArgumentException("RoundedAverageCrossover: The parents' vectors are of different length.", "parents");
            }

            return(result);
        }
        /// <summary>
        /// Changes randomly several, but at least one, positions in the given integer <paramref name="vector"/>, according to the given probabilities.
        /// </summary>
        /// <param name="random">A random number generator.</param>
        /// <param name="vector">The integer vector to manipulate.</param>
        /// <param name="bounds"> Contains the minimum value (inclusive), maximum value (exclusive), and step size of the sampling range for
        /// the vector element to change.</param>
        /// <param name="probability">The probability for each dimension to be manipulated..</param>
        public static void Apply(IRandom random, IntegerVector vector, IntMatrix bounds, double probability)
        {
            if (bounds == null || bounds.Rows == 0 || bounds.Columns < 2)
            {
                throw new ArgumentException("UniformSomePositionsManipulator: Invalid bounds specified", "bounds");
            }
            bool atLeastOneManipulated = false;

            for (int index = 0; index < vector.Length; index++)
            {
                if (random.NextDouble() < probability)
                {
                    atLeastOneManipulated = true;
                    UniformOnePositionManipulator.Manipulate(random, vector, bounds, index);
                }
            }

            if (!atLeastOneManipulated)
            {
                UniformOnePositionManipulator.Manipulate(random, vector, bounds, random.Next(vector.Length));
            }
        }
        /// <summary>
        /// Performs the arithmetic crossover on some positions by taking either x = alpha * p1 + (1 - alpha) * p2 or x = p1 depending on the probability for a gene to be crossed.
        /// </summary>
        /// <param name="random">The random number generator.</param>
        /// <param name="parent1">The first parent vector.</param>
        /// <param name="parent2">The second parent vector.</param>
        /// <param name="bounds">The bounds and step size for each dimension (will be cycled in case there are less rows than elements in the parent vectors).</param>
        /// <param name="alpha">The alpha parameter (<see cref="AlphaParameter"/>).</param>
        /// <param name="probability">The probability parameter (<see cref="ProbabilityParameter"/>).</param>
        /// <returns>The vector resulting from the crossover.</returns>
        public static IntegerVector Apply(IRandom random, IntegerVector parent1, IntegerVector parent2, IntMatrix bounds, DoubleValue alpha, DoubleValue probability)
        {
            int length = parent1.Length;

            if (length != parent2.Length)
            {
                throw new ArgumentException("RoundedUniformArithmeticCrossover: The parent vectors are of different length.", "parent1");
            }
            if (alpha.Value < 0 || alpha.Value > 1)
            {
                throw new ArgumentException("RoundedUniformArithmeticCrossover: Parameter alpha must be in the range [0;1]", "alpha");
            }
            if (probability.Value < 0 || probability.Value > 1)
            {
                throw new ArgumentException("RoundedUniformArithmeticCrossover: Parameter probability must be in the range [0;1]", "probability");
            }

            var result = new IntegerVector(length);

            for (int i = 0; i < length; i++)
            {
                if (random.NextDouble() < probability.Value)
                {
                    int min = bounds[i % bounds.Rows, 0], max = bounds[i % bounds.Rows, 1], step = 1;
                    if (bounds.Columns > 2)
                    {
                        step = bounds[i % bounds.Rows, 2];
                    }
                    max = FloorFeasible(min, max, step, max - 1);
                    double value = alpha.Value * parent1[i] + (1 - alpha.Value) * parent2[i];
                    result[i] = RoundFeasible(min, max, step, value);
                }
                else
                {
                    result[i] = parent1[i];
                }
            }
            return(result);
        }
        /// <summary>
        /// Performs a single point crossover at a randomly chosen position of the two
        /// given parent integer vectors.
        /// </summary>
        /// <param name="random">A random number generator.</param>
        /// <param name="parent1">The first parent for crossover.</param>
        /// <param name="parent2">The second parent for crossover.</param>
        /// <returns>The newly created integer vector, resulting from the single point crossover.</returns>
        public static IntegerVector Apply(IRandom random, IntegerVector parent1, IntegerVector parent2)
        {
            if (parent1.Length != parent2.Length)
            {
                throw new ArgumentException("SinglePointCrossover: The parents are of different length.");
            }

            int length = parent1.Length;

            int[] result     = new int[length];
            int   breakPoint = random.Next(1, length);

            for (int i = 0; i < breakPoint; i++)
            {
                result[i] = parent1[i];
            }
            for (int i = breakPoint; i < length; i++)
            {
                result[i] = parent2[i];
            }

            return(new IntegerVector(result));
        }
    /// <summary>
    /// Performs an average crossover of the two given parent integer vectors.
    /// The average is rounded and mapped to the nearest valid value (e.g. if step size is > 1)
    /// </summary>
    /// <param name="random">A random number generator.</param>
    /// <param name="parents">The parents for crossover.</param>
    /// <param name="bounds">The bounds matrix that contains for each dimension one row with minimum (inclusive), maximum (exclusive), and step size columns.
    /// If the number of rows is smaller than the number of dimensions the matrix is cycled.</param>
    /// <returns>The newly created integer vector, resulting from the single point crossover.</returns>
    public static IntegerVector Apply(IRandom random, ItemArray<IntegerVector> parents, IntMatrix bounds) {
      int length = parents[0].Length, parentsCount = parents.Length;
      if (parents.Length < 2) throw new ArgumentException("RoundedAverageCrossover: The number of parents is less than 2.", "parents");
      if (bounds == null || bounds.Rows < 1 || bounds.Columns < 2) throw new ArgumentException("AverageCrossover: Invalid bounds specified.", "bounds");

      var result = new IntegerVector(length);
      try {
        double avg;
        for (int i = 0; i < length; i++) {
          avg = 0;
          for (int j = 0; j < parentsCount; j++)
            avg += parents[j][i];
          avg /= parentsCount;
          int min = bounds[i % bounds.Rows, 0], max = bounds[i % bounds.Rows, 1], step = 1;
          if (bounds.Columns > 2) step = bounds[i % bounds.Rows, 2];
          max = FloorFeasible(min, max, step, max - 1);
          result[i] = RoundFeasible(min, max, step, avg);
        }
      } catch (IndexOutOfRangeException) {
        throw new ArgumentException("RoundedAverageCrossover: The parents' vectors are of different length.", "parents");
      }

      return result;
    }
 protected IntegerVector(IntegerVector original, Cloner cloner) : base(original, cloner)
 {
 }
    /// <summary>
    /// Returns a randomly chosen child node for the given <paramref name="parentNode"/>.
    /// </summary>
    /// <param name="parentNode">parent node to find a child node randomly for</param>
    /// <param name="genotype">integer vector, which should be mapped to a tree</param>
    /// <param name="grammar">grammar used to define the allowed child symbols</param>
    /// <param name="genotypeIndex">index in the integer vector; can be greater than vector length</param>
    /// <param name="random">random number generator</param>
    /// <returns>randomly chosen child node or null, if no child node exits</returns>
    protected ISymbolicExpressionTreeNode GetNewChildNode(ISymbolicExpressionTreeNode parentNode,
                                                          IntegerVector genotype,
                                                          ISymbolicExpressionGrammar grammar,
                                                          int genotypeIndex,
                                                          IRandom random) {

      // only select specific symbols, which can be interpreted ...
      IEnumerable<ISymbol> symbolList = (from s in grammar.GetAllowedChildSymbols(parentNode.Symbol)
                                         where s.InitialFrequency > 0.0
                                         select s).ToList();

      int prodRuleCount = symbolList.Count();

      // no child node exists for the given parent node
      if (prodRuleCount < 1) return null;

      // genotypeIndex % genotype.Length, if wrapping is allowed
      int prodRuleIndex = genotype[genotypeIndex] % prodRuleCount;

      var newNode = symbolList.ElementAt(prodRuleIndex).CreateTreeNode();
      if (newNode.HasLocalParameters) newNode.ResetLocalParameters(random);
      return newNode;
    }
 protected abstract void ManipulateBounded(IRandom random, IntegerVector integerVector, IntMatrix bounds);
    /// <summary>
    /// Performs the rounded blend alpha beta crossover (BLX-a-b) on two parent vectors.
    /// </summary>
    /// <exception cref="ArgumentException">
    /// Thrown when either:<br/>
    /// <list type="bullet">
    /// <item><description>The length of <paramref name="betterParent"/> and <paramref name="worseParent"/> is not equal.</description></item>
    /// <item><description>The parameter <paramref name="alpha"/> is smaller than 0.</description></item>
    /// <item><description>The parameter <paramref name="beta"/> is smaller than 0.</description></item>
    /// </list>
    /// </exception>
    /// <param name="random">The random number generator to use.</param>
    /// <param name="betterParent">The better of the two parents with regard to their fitness.</param>
    /// <param name="worseParent">The worse of the two parents with regard to their fitness.</param>
    /// <param name="bounds">The bounds and step size for each dimension (will be cycled in case there are less rows than elements in the parent vectors).</param>
    /// <param name="alpha">The parameter alpha.</param>
    /// <param name="beta">The parameter beta.</param>
    /// <returns>The integer vector that results from the crossover.</returns>
    public static IntegerVector Apply(IRandom random, IntegerVector betterParent, IntegerVector worseParent, IntMatrix bounds, DoubleValue alpha, DoubleValue beta) {
      if (betterParent.Length != worseParent.Length) throw new ArgumentException("RoundedBlendAlphaBetaCrossover: The parents' vectors are of different length.", "betterParent");
      if (alpha.Value < 0) throw new ArgumentException("RoundedBlendAlphaBetaCrossover: Parameter alpha must be greater or equal to 0.", "alpha");
      if (beta.Value < 0) throw new ArgumentException("RoundedBlendAlphaBetaCrossover: Parameter beta must be greater or equal to 0.", "beta");
      if (bounds == null || bounds.Rows < 1 || bounds.Columns < 2) throw new ArgumentException("RoundedBlendAlphaBetaCrossover: Invalid bounds specified.", "bounds");

      int length = betterParent.Length;
      double min, max, d;
      var result = new IntegerVector(length);
      int minBound, maxBound, step = 1;
      for (int i = 0; i < length; i++) {
        minBound = bounds[i % bounds.Rows, 0];
        maxBound = bounds[i % bounds.Rows, 1];
        if (bounds.Columns > 2) step = bounds[i % bounds.Rows, 2];
        maxBound = FloorFeasible(minBound, maxBound, step, maxBound - 1);

        d = Math.Abs(betterParent[i] - worseParent[i]);
        if (betterParent[i] <= worseParent[i]) {
          min = FloorFeasible(minBound, maxBound, step, betterParent[i] - d * alpha.Value);
          max = CeilingFeasible(minBound, maxBound, step, worseParent[i] + d * beta.Value);
        } else {
          min = FloorFeasible(minBound, maxBound, step, worseParent[i] - d * beta.Value);
          max = CeilingFeasible(minBound, maxBound, step, betterParent[i] + d * alpha.Value);
        }
        result[i] = RoundFeasible(minBound, maxBound, step, min + random.NextDouble() * (max - min));
      }
      return result;
    }
 public abstract SymbolicExpressionTree Map(IRandom random, IntMatrix bounds, int length,
                                            ISymbolicExpressionGrammar grammar,
                                            IntegerVector genotype);
    /// <summary>
    /// Genotype-to-Phenotype mapper (iterative depth-first approach, by using a stack -> LIFO).
    /// </summary>
    /// <param name="startNode">first node of the tree with arity 1</param>
    /// <param name="genotype">integer vector, which should be mapped to a tree</param>
    /// <param name="grammar">grammar to determine the allowed child symbols for each node</param>
    /// <param name="maxSubtreeCount">maximum allowed subtrees (= number of used genomes)</param>
    /// <param name="random">random number generator</param>
    private void MapDepthFirstIteratively(ISymbolicExpressionTreeNode startNode,
                                          IntegerVector genotype,
                                          ISymbolicExpressionGrammar grammar,
                                          int maxSubtreeCount, IRandom random) {

      Stack<Tuple<ISymbolicExpressionTreeNode, int>> stack
        = new Stack<Tuple<ISymbolicExpressionTreeNode, int>>(); // tuples of <node, arity>

      int genotypeIndex = 0;
      stack.Push(new Tuple<ISymbolicExpressionTreeNode, int>(startNode, 1));

      while (stack.Count > 0) {

        // get next node from stack and re-push it, if this node still has unhandled subtrees ...
        Tuple<ISymbolicExpressionTreeNode, int> current = stack.Pop();
        if (current.Item2 > 1) {
          stack.Push(new Tuple<ISymbolicExpressionTreeNode, int>(current.Item1, current.Item2 - 1));
        }

        if (genotypeIndex >= maxSubtreeCount) {
          // if all genomes were used, only add terminal nodes to the remaining subtrees
          current.Item1.AddSubtree(GetRandomTerminalNode(current.Item1, grammar, random));
        } else {
          var newNode = GetNewChildNode(current.Item1, genotype, grammar, genotypeIndex, random);
          int arity = SampleArity(random, newNode, grammar);

          current.Item1.AddSubtree(newNode);
          genotypeIndex++;
          if (arity > 0) {
            // new node has subtrees so push it onto the stack 
            stack.Push(new Tuple<ISymbolicExpressionTreeNode, int>(newNode, arity));
          }
        }
      }
    }
Beispiel #37
0
 public static PWREncoding CreateTestPWR2() {
   PWREncoding result = new PWREncoding();
   IntegerVector pwr = new IntegerVector(new int[] { 0, 1, 1, 0, 2, 0, 1, 2, 2 });
   result.PermutationWithRepetition = pwr;
   return result;
 }
 protected sealed override void Manipulate(IRandom random, IntegerVector integerVector) {
   if (BoundsParameter.ActualValue == null) throw new InvalidOperationException("BoundedIntegerVectorManipulator: Parameter " + BoundsParameter.ActualName + " could not be found.");
   ManipulateBounded(random, integerVector, BoundsParameter.ActualValue);
 }
Beispiel #39
0
    /// <summary>
    /// Maps a genotype (an integer vector) to a phenotype (a symbolic expression tree).
    /// PIGE approach.
    /// </summary>
    /// <param name="random">random number generator</param>
    /// <param name="bounds">integer number range for genomes (codons) of the nont vector</param>
    /// <param name="length">length of the nont vector to create</param>
    /// <param name="grammar">grammar definition</param>
    /// <param name="genotype">integer vector, which should be mapped to a tree</param>
    /// <returns>phenotype (a symbolic expression tree)</returns>
    public override ISymbolicExpressionTree Map(IRandom random, IntMatrix bounds, int length,
                                               ISymbolicExpressionGrammar grammar,
                                               IntegerVector genotype) {

      SymbolicExpressionTree tree = new SymbolicExpressionTree();
      var rootNode = (SymbolicExpressionTreeTopLevelNode)grammar.ProgramRootSymbol.CreateTreeNode();
      var startNode = (SymbolicExpressionTreeTopLevelNode)grammar.StartSymbol.CreateTreeNode();
      rootNode.AddSubtree(startNode);
      tree.Root = rootNode;

      // Map can be called simultaniously on multiple threads
      lock (nontVectorLocker) {
        if (NontVector == null) {
          NontVector = GetNontVector(random, bounds, length);
        }
      }

      MapPIGEIteratively(startNode, genotype, grammar,
                         genotype.Length, random);

      return tree;
    }
 /// <summary>
 /// Retrieves the bounds and forwards the call to the static Apply method.
 /// </summary>
 /// <param name="random">The random number generator.</param>
 /// <param name="vector">The vector of integer values that is manipulated.</param>
 /// <param name="bounds">The bounds and step size for each dimension (will be cycled in case there are less rows than elements in the parent vectors).</param>
 protected override void ManipulateBounded(IRandom random, IntegerVector vector, IntMatrix bounds) {
   Apply(random, vector, bounds, SigmaParameter.Value);
 }
 protected abstract void ManipulateBounded(IRandom random, IntegerVector integerVector, IntMatrix bounds);
 protected abstract void Manipulate(IRandom random, IntegerVector integerVector);
Beispiel #43
0
 private static IntegerVector GetNontVector(IRandom random, IntMatrix bounds, int length) {
   IntegerVector v = new IntegerVector(length);
   v.Randomize(random, bounds);
   return v;
 }
Beispiel #44
0
    /// <summary>
    /// Genotype-to-Phenotype mapper (iterative 𝜋GE approach, using a list of not expanded nonTerminals).
    /// </summary>
    /// <param name="startNode">first node of the tree with arity 1</param>
    /// <param name="genotype">integer vector, which should be mapped to a tree</param>
    /// <param name="grammar">grammar to determine the allowed child symbols for each node</param>
    /// <param name="maxSubtreeCount">maximum allowed subtrees (= number of used genomes)</param>
    /// <param name="random">random number generator</param>
    private void MapPIGEIteratively(ISymbolicExpressionTreeNode startNode,
                                    IntegerVector genotype,
                                    ISymbolicExpressionGrammar grammar,
                                    int maxSubtreeCount, IRandom random) {

      List<ISymbolicExpressionTreeNode> nonTerminals = new List<ISymbolicExpressionTreeNode>();

      int genotypeIndex = 0;
      nonTerminals.Add(startNode);

      while (nonTerminals.Count > 0) {

        if (genotypeIndex >= maxSubtreeCount) {
          // if all genomes were used, only add terminal nodes to the remaining subtrees
          ISymbolicExpressionTreeNode current = nonTerminals[0];
          nonTerminals.RemoveAt(0);
          current.AddSubtree(GetRandomTerminalNode(current, grammar, random));
        } else {
          // Order:   NT   = nont % Num. NT
          int nt = NontVector[genotypeIndex] % nonTerminals.Count;
          ISymbolicExpressionTreeNode current = nonTerminals[nt];
          nonTerminals.RemoveAt(nt);

          // Content: Rule = rule % Num. Rules
          ISymbolicExpressionTreeNode newNode = GetNewChildNode(current, genotype, grammar, genotypeIndex, random);
          int arity = SampleArity(random, newNode, grammar);

          current.AddSubtree(newNode);
          genotypeIndex++;
          // new node has subtrees, so add "arity" number of copies of this node to the nonTerminals list
          for (int i = 0; i < arity; ++i) {
            nonTerminals.Add(newNode);
          }
        }
      }
    }
 /// <summary>
 /// Changes randomly several, but at least one, positions in the given integer <paramref name="vector"/>.
 /// </summary>
 /// <remarks>Calls <see cref="Apply"/>.</remarks>
 /// <param name="random">A random number generator.</param>
 /// <param name="vector">The integer vector to manipulate.</param>
 protected override void ManipulateBounded(IRandom random, IntegerVector vector, IntMatrix bounds) {
   Apply(random, vector, bounds, ProbabilityParameter.ActualValue.Value);
 }
 /// <summary>
 /// Retrieves the bounds and forwards the call to the static Apply method.
 /// </summary>
 /// <param name="random">The random number generator.</param>
 /// <param name="vector">The vector of integer values that is manipulated.</param>
 /// <param name="bounds">The bounds and step size for each dimension (will be cycled in case there are less rows than elements in the parent vectors).</param>
 protected override void ManipulateBounded(IRandom random, IntegerVector vector, IntMatrix bounds)
 {
     Apply(random, vector, bounds, SigmaParameter.Value);
 }
 /// <summary>
 /// Changes randomly a single position in the given integer <paramref name="vector"/>.
 /// </summary>
 /// <param name="random">A random number generator.</param>
 /// <param name="vector">The integer vector to manipulate.</param>
 /// <param name="min">The minimum value of the sampling range for
 /// the vector element to change (inclusive).</param>
 /// <param name="max">The maximum value of the sampling range for
 /// the vector element to change (exclusive).</param>
 /// <param name="bounds">The bounds and step size for each dimension (will be cycled in case there are less rows than elements in the parent vectors).</param>
 public static void Apply(IRandom random, IntegerVector vector, IntMatrix bounds)
 {
     Manipulate(random, vector, bounds, random.Next(vector.Length));
 }
 /// <summary>
 /// Changes randomly several, but at least one, positions in the given integer <paramref name="vector"/>.
 /// </summary>
 /// <remarks>Calls <see cref="Apply"/>.</remarks>
 /// <param name="random">A random number generator.</param>
 /// <param name="vector">The integer vector to manipulate.</param>
 protected override void ManipulateBounded(IRandom random, IntegerVector vector, IntMatrix bounds)
 {
     Apply(random, vector, bounds, ProbabilityParameter.ActualValue.Value);
 }
Beispiel #49
0
 public PRVEncoding(IntegerVector iv, IntValue nrOfRules)
   : base() {
   this.nrOfRules = (IntValue)nrOfRules.Clone();
   this.PriorityRulesVector = (IntegerVector)iv.Clone();
 }
Beispiel #50
0
    /// <summary>
    /// Genotype-to-Phenotype mapper (iterative random approach, where the next non-terminal
    /// symbol to expand is randomly determined).
    /// </summary>
    /// <param name="startNode">first node of the tree with arity 1</param>
    /// <param name="genotype">integer vector, which should be mapped to a tree</param>
    /// <param name="grammar">grammar to determine the allowed child symbols for each node</param>
    /// <param name="maxSubtreeCount">maximum allowed subtrees (= number of used genomes)</param>
    /// <param name="random">random number generator</param>
    private void MapRandomIteratively(ISymbolicExpressionTreeNode startNode,
                                     IntegerVector genotype,
                                     ISymbolicExpressionGrammar grammar,
                                     int maxSubtreeCount, IRandom random) {

      List<ISymbolicExpressionTreeNode> nonTerminals = new List<ISymbolicExpressionTreeNode>();

      int genotypeIndex = 0;
      nonTerminals.Add(startNode);

      while (nonTerminals.Count > 0) {
        if (genotypeIndex >= maxSubtreeCount) {
          // if all genomes were used, only add terminal nodes to the remaining subtrees
          ISymbolicExpressionTreeNode current = nonTerminals[0];
          nonTerminals.RemoveAt(0);
          current.AddSubtree(GetRandomTerminalNode(current, grammar, random));
        } else {
          // similar to PIGEMapper, but here the current node is determined randomly ...
          ISymbolicExpressionTreeNode current = nonTerminals.SampleRandom(random);
          nonTerminals.Remove(current);

          ISymbolicExpressionTreeNode newNode = GetNewChildNode(current, genotype, grammar, genotypeIndex, random);
          int arity = SampleArity(random, newNode, grammar);

          current.AddSubtree(newNode);
          genotypeIndex++;
          // new node has subtrees, so add "arity" number of copies of this node to the nonTerminals list
          for (int i = 0; i < arity; ++i) {
            nonTerminals.Add(newNode);
          }
        }
      }
    }
 protected IntegerVector(IntegerVector original, Cloner cloner) : base(original, cloner) { }
Beispiel #52
0
 protected abstract void Manipulate(IRandom random, IntegerVector integerVector);