001/*
002 * Java Genetic Algorithm Library (jenetics-8.1.0).
003 * Copyright (c) 2007-2024 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 */
020package io.jenetics.ext;
021
022import static java.util.Objects.requireNonNull;
023
024import io.jenetics.ext.rewriting.TreeRewriter;
025import io.jenetics.ext.util.TreeNode;
026
027/**
028 * This alterer uses a {@link TreeRewriter} for altering the {@link TreeChromosome}.
029 *
030 * @see TreeRewriter
031 *
032 * @author <a href="mailto:franz.wilhelmstoetter@gmail.com">Franz Wilhelmstötter</a>
033 * @version 5.0
034 * @since 5.0
035 */
036public class TreeRewriteAlterer<
037        A,
038        G extends TreeGene<A, G>,
039        C extends Comparable<? super C>
040>
041        extends TreeMutator<A, G, C>
042{
043
044        private final TreeRewriter<A> _rewriter;
045        private final int _limit;
046
047        /**
048         * Create a new alterer with the given {@code rewriter} and given rewrite
049         * {@code limit}.
050         *
051         * @param rewriter the tree rewriter
052         * @param limit the rewriting limit
053         * @param probability the altering probability
054         * @throws NullPointerException if the {@code rewriter} is {@code null}
055         */
056        public TreeRewriteAlterer(
057                final TreeRewriter<A> rewriter,
058                final int limit,
059                final double probability
060        ) {
061                super(probability);
062                _rewriter = requireNonNull(rewriter);
063                _limit = limit;
064        }
065
066        /**
067         * Create a new alterer with the given {@code rewriter} and given rewrite
068         * {@code limit}.
069         *
070         * @param rewriter the tree rewriter
071         * @param limit the rewriting limit
072         * @throws NullPointerException if the {@code rewriter} is {@code null}
073         */
074        public TreeRewriteAlterer(final TreeRewriter<A> rewriter, final int limit) {
075                this(rewriter, limit, DEFAULT_ALTER_PROBABILITY);
076        }
077
078        /**
079         * Create a new alterer with the given {@code rewriter}.
080         *
081         * @param rewriter the tree rewriter
082         * @param probability the altering probability
083         * @throws NullPointerException if the {@code rewriter} is {@code null}
084         */
085        public TreeRewriteAlterer(
086                final TreeRewriter<A> rewriter,
087                final double probability
088        ) {
089                this(rewriter, Integer.MAX_VALUE, probability);
090        }
091
092        /**
093         * Create a new alterer with the given {@code rewriter}.
094         *
095         * @param rewriter the tree rewriter
096         * @throws NullPointerException if the {@code rewriter} is {@code null}
097         */
098        public TreeRewriteAlterer(final TreeRewriter<A> rewriter) {
099                this(rewriter, Integer.MAX_VALUE, DEFAULT_ALTER_PROBABILITY);
100        }
101
102        /**
103         * Performs the actual tree rewriting.
104         *
105         * @param tree the tree to rewrite
106         */
107        @Override
108        protected void mutate(final TreeNode<A> tree) {
109                _rewriter.rewrite(tree, _limit);
110        }
111
112}