001 /*
002 * Java Genetic Algorithm Library (jenetics-7.1.1).
003 * Copyright (c) 2007-2022 Franz Wilhelmstötter
004 *
005 * Licensed under the Apache License, Version 2.0 (the "License");
006 * you may not use this file except in compliance with the License.
007 * You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 *
017 * Author:
018 * Franz Wilhelmstötter (franz.wilhelmstoetter@gmail.com)
019 */
020
021 /**
022 * <h2>Operations</h2>
023 *
024 * When creating a new program tree, it is not necessary to implement own
025 * instance of the {@code ProgramGene} or {@code ProgramChromosome} class. The
026 * extension point for own programs is the {@code Op} interface.
027 *
028 * <pre>{@code
029 * public interface Op<T> {
030 * public String name();
031 * public int arity();
032 * public T apply(T[] args);
033 * }
034 * }</pre>
035 *
036 * <pre>{@code
037 * final Op<Double> myop = Op.of("myop", 3, v -> v[0]*v[1] + v[2]);
038 * }</pre>
039 *
040 * In the example above, a new operation with the "myop" and arity 3 is defined.
041 * Whenever the operation is evaluated, the function <em>f(x, y, z) = x*y + z</em>
042 * is executed.
043 * <p>
044 * <b>NOTE</b>: <em>The class {@link io.jenetics.prog.op.MathOp} in the
045 * defines a set of mathematical standard operations/functions.</em>
046 * </p>
047 *
048 * When creating a new {@link io.jenetics.prog.ProgramChromosome} we must
049 * distinguish two different kind of operations:
050 * <ol>
051 * <li><em>Non-terminal</em> operations have an arity greater than zero and
052 * form their own sub-tree</li>
053 * <li><em>Terminal</em> operations have an arity of zero and form the
054 * leaves of a program tree.</li>
055 * </ol>
056 *
057 * There are currently three different types of non-terminal operations
058 * implemented, {@link io.jenetics.prog.op.Var},
059 * {@link io.jenetics.prog.op.Const} and
060 * {@link io.jenetics.prog.op.EphemeralConst}.
061 *
062 * <h3>Var</h3>
063 *
064 * The {@code Var} operation defines a variable of a program, which are set
065 * from the program arguments.
066 *
067 * <pre>{@code
068 * final ISeq<Op<Double>> terminals = ISeq.of(
069 * Var.of("x", 0), Var.of("y", 1), Var.of("z", 2)
070 * );
071 * }</pre>
072 *
073 * The terminal operation list in the example code above will lead to a program
074 * which takes three input parameters, <em>x</em>, <em>y</em> and <em>z</em>,
075 * with the argument indices <em>0</em>, <em>1</em> and <em>2</em>.
076 *
077 * <h3>Const</h3>
078 *
079 * The {@code Const} operation will always return the same, constant, value
080 * when evaluated.
081 *
082 * <pre>{@code
083 * final Op<Double> one = Const.of(1.0);
084 * final Op<Double> pi = Const.of("π", Math.PI);
085 * }</pre>
086 *
087 * We can create a constant operation in to flavours, with a value only and with
088 * a dedicated name. If a constant has a name, the <em>symbolic</em> name is
089 * used, instead of the value, when the program tree is printing.
090 *
091 * <h3>EphemeralConst</h3>
092 *
093 * An ephemeral constant is a special constant, which is only constant within an
094 * tree. If a new tree is created, a new constant is created, by the `
095 * {@link java.util.function.Supplier} function the ephemeral constant is created
096 * with.
097 *
098 * <pre>{@code
099 * final Op<Double> rand1 = EphemeralConst.of(Math::random);
100 * final Op<Double> rand2 = EphemeralConst.of("R", Math::random);
101 * }</pre>
102 *
103 *
104 * @author <a href="mailto:franz.wilhelmstoetter@gmail.com">Franz Wilhelmstötter</a>
105 * @version 3.9
106 * @since 3.9
107 */
108 package io.jenetics.prog.op;
|