001 /*
002 * Java Genetic Algorithm Library (jenetics-3.5.0).
003 * Copyright (c) 2007-2016 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@gmx.at)
019 */
020 package org.jenetics;
021
022 import static java.lang.String.format;
023 import static org.jenetics.internal.util.Equality.eq;
024 import static org.jenetics.util.ISeq.toISeq;
025
026 import java.util.function.Function;
027 import java.util.stream.Collectors;
028 import java.util.stream.Stream;
029
030 import org.jenetics.internal.util.Hash;
031
032 import org.jenetics.util.ISeq;
033 import org.jenetics.util.Seq;
034
035 /**
036 * Combines several alterers to one.
037 *
038 * @author <a href="mailto:franz.wilhelmstoetter@gmx.at">Franz Wilhelmstötter</a>
039 * @since 1.0
040 * @version 3.0
041 */
042 final class CompositeAlterer<
043 G extends Gene<?, G>,
044 C extends Comparable<? super C>
045 >
046 extends AbstractAlterer<G, C>
047 {
048
049 private final ISeq<Alterer<G, C>> _alterers;
050
051 /**
052 * Combine the given alterers.
053 *
054 * @param alterers the alterers to combine.
055 * @throws NullPointerException if one of the alterers is {@code null}.
056 */
057 public CompositeAlterer(final Seq<Alterer<G, C>> alterers) {
058 super(1.0);
059 _alterers = normalize(alterers);
060 }
061
062 private static <G extends Gene<?, G>, C extends Comparable<? super C>>
063 ISeq<Alterer<G, C>> normalize(final Seq<Alterer<G, C>> alterers) {
064 final Function<Alterer<G, C>, Stream<Alterer<G, C>>> mapper =
065 a -> a instanceof CompositeAlterer<?, ?>
066 ? ((CompositeAlterer<G, C>)a).getAlterers().stream()
067 : Stream.of(a);
068
069 return alterers.stream()
070 .flatMap(mapper)
071 .collect(toISeq());
072 }
073
074 @Override
075 public int alter(final Population<G, C> population, final long generation) {
076 return _alterers.stream()
077 .mapToInt(a -> a.alter(population, generation))
078 .sum();
079 }
080
081 /**
082 * Return the alterers this alterer consists of. The returned array is sealed
083 * and cannot be changed.
084 *
085 * @return the alterers this alterer consists of.
086 */
087 public ISeq<Alterer<G, C>> getAlterers() {
088 return _alterers;
089 }
090
091 @Override
092 public int hashCode() {
093 return Hash.of(getClass()).and(_alterers).value();
094 }
095
096 @Override
097 public boolean equals(final Object obj) {
098 return obj instanceof CompositeAlterer &&
099 eq(((CompositeAlterer)obj)._alterers, _alterers);
100 }
101
102 @Override
103 public String toString() {
104 return format(
105 "%s:\n%s", getClass().getSimpleName(),
106 _alterers.stream()
107 .map(a -> " - " + a)
108 .collect(Collectors.joining("\n"))
109 );
110 }
111
112 /**
113 * Combine the given alterers.
114 *
115 * @param <G> the gene type
116 * @param <C> the fitness function result type
117 * @param alterers the alterers to combine.
118 * @return a new alterer which consists of the given one
119 * @throws NullPointerException if one of the alterers is {@code null}.
120 */
121 @SafeVarargs
122 public static <G extends Gene<?, G>, C extends Comparable<? super C>>
123 CompositeAlterer<G, C> of(final Alterer<G, C>... alterers) {
124 return new CompositeAlterer<>(ISeq.of(alterers));
125 }
126
127 /**
128 * Joins the given alterer and returns a new CompositeAlterer object. If one
129 * of the given alterers is a CompositeAlterer the sub alterers of it are
130 * unpacked and appended to the newly created CompositeAlterer.
131 *
132 * @param <T> the gene type of the alterers.
133 *
134 * @param <C> the fitness function result type
135 * @param a1 the first alterer.
136 * @param a2 the second alterer.
137 * @return a new CompositeAlterer object.
138 * @throws NullPointerException if one of the given alterer is {@code null}.
139 */
140 public static <T extends Gene<?, T>, C extends Comparable<? super C>>
141 CompositeAlterer<T, C> join(
142 final Alterer<T, C> a1,
143 final Alterer<T, C> a2
144 ) {
145 return CompositeAlterer.of(a1, a2);
146 }
147 }
|