001 /*
002 * Java Genetic Algorithm Library (jenetics-4.1.0).
003 * Copyright (c) 2007-2018 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 package io.jenetics;
021
022 import static java.lang.String.format;
023 import static java.util.Objects.requireNonNull;
024 import static io.jenetics.internal.util.Equality.eq;
025
026 import io.jenetics.internal.util.Equality;
027 import io.jenetics.internal.util.Hash;
028 import io.jenetics.util.ISeq;
029 import io.jenetics.util.IntRange;
030
031 /**
032 * @author <a href="mailto:franz.wilhelmstoetter@gmail.com">Franz Wilhelmstötter</a>
033 * @version 4.0
034 * @since 4.0
035 */
036 abstract class VariableChromosome<G extends Gene<?, G>>
037 extends AbstractChromosome<G>
038 {
039 private static final long serialVersionUID = 1L;
040
041 private final IntRange _lengthRange;
042
043 /**
044 * Create a new {@code VariableChromosome} from the given {@code genes}
045 * and the allowed length range of the chromosome.
046 *
047 * @param genes the genes that form the chromosome.
048 * @param lengthRange the allowed length range of the chromosome
049 * @throws NullPointerException if one of the arguments is {@code null}.
050 * @throws IllegalArgumentException if the length of the gene sequence is
051 * empty or doesn't match with the allowed length range.
052 * @throws IllegalArgumentException if the minimum or maximum of the range
053 * is smaller or equal zero
054 * @throws IllegalArgumentException if the given range size is zero
055 */
056 protected VariableChromosome(
057 final ISeq<? extends G> genes,
058 final IntRange lengthRange
059 ) {
060 super(genes);
061 _lengthRange = checkLengthRange(lengthRange, genes.size());
062 }
063
064 static IntRange checkLengthRange(final IntRange lengthRange, final int length) {
065 requireNonNull(lengthRange);
066 if (lengthRange.getMin() <= 0) {
067 throw new IllegalArgumentException(format(
068 "Minimum length must be positive: %d", lengthRange.getMin()
069 ));
070 }
071 if (lengthRange.getMax() <= 0) {
072 throw new IllegalArgumentException(format(
073 "Maximum length must be positive: %d", lengthRange.getMin()
074 ));
075 }
076 if (lengthRange.size() <= 0) {
077 throw new IllegalArgumentException(format(
078 "Maximal length must be positive: %d", lengthRange.size()
079 ));
080 }
081 if (length < lengthRange.getMin() ||
082 length >= lengthRange.getMax())
083 {
084 throw new IllegalArgumentException(format(
085 "Number of genes (%d) not within the allowed range: %s",
086 length,
087 lengthRange
088 ));
089 }
090
091 return lengthRange;
092 }
093
094 /**
095 * Return the allowed length range of the chromosome. The minimum value of
096 * the range is included and the maximum value is excluded.
097 *
098 * @return the allowed length range of the chromosome
099 */
100 public IntRange lengthRange() {
101 return _lengthRange;
102 }
103
104 @Override
105 public int hashCode() {
106 return Hash.of(getClass())
107 .and(super.hashCode())
108 .and(_lengthRange).value();
109 }
110
111 @Override
112 public boolean equals(final Object obj) {
113 return Equality.of(this, obj).test(cc ->
114 super.equals(obj) &&
115 eq(_lengthRange, cc._lengthRange)
116 );
117 }
118 }
|