001 /*
002 * Copyright 2011 Christian Kumpe http://kumpe.de/christian/java
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016 package de.kumpe.hadooptimizer;
017
018 import java.io.Serializable;
019
020 /**
021 * A special type of an immutable individual for evolution strategies.
022 * <p>
023 * The actual individual is a vector of real numbers (<code>double[]</code>). It
024 * is combined with an increment (the standard deviation during the mutation of
025 * the vector), which is mutated by itself.
026 * <p>
027 * <i>Note: a instance is considered immutable, so you <b>should not modify</b>
028 * the contained individual. See {@link #getIndividual()} for additional
029 * hints.</i>
030 *
031 * @author <a href="http://kumpe.de/christian/java">Christian Kumpe</a>
032 */
033 public final class EsIndividual implements Serializable {
034 private static final long serialVersionUID = 1L;
035
036 private final double[] individual;
037 private final double increment;
038
039 /**
040 * Creates a new {@link EsIndividual} with the given single
041 * {@code individual}, which is converted to one-dimensional vector, and an
042 * increment of 1.
043 */
044 public EsIndividual(final double individual) {
045 this(new double[] { individual });
046 }
047
048 /**
049 * Creates a new {@link EsIndividual} with the given {@code individual} and
050 * an increment of 1.
051 *
052 * @throws NullPointerException
053 * if {@code individual} is <code>null</code>
054 * @throws IllegalArgumentException
055 * if {@code individual} is an empty array
056 */
057 public EsIndividual(final double[] individual) {
058 this(individual, 1d);
059 }
060
061 /**
062 * Creates a new {@link EsIndividual} with the given single
063 * {@code individual}, which is converted to one-dimensional vector, and the
064 * given {@code increment}.
065 */
066 public EsIndividual(final double individual, final double increment) {
067 this(new double[] { individual }, increment);
068 }
069
070 /**
071 * Creates a new {@link EsIndividual} with the given {@code individual} and
072 * {@code increment}.
073 *
074 * @throws NullPointerException
075 * if {@code individual} is <code>null</code>
076 * @throws IllegalArgumentException
077 * if {@code individual} is an empty array
078 */
079 public EsIndividual(final double[] individual, final double increment) {
080 if (null == individual) {
081 throw new NullPointerException("individual may not be null");
082 }
083 if (0 == individual.length) {
084 throw new IllegalArgumentException(
085 "individual may not be an empty array");
086 }
087
088 this.individual = individual;
089 this.increment = increment;
090 }
091
092 /**
093 * Return the contained actual individual.
094 * <p>
095 * <i>Note: An instance of {@link EsIndividual} is considered to be
096 * immutable, but for performance reasons the contained array is not copied.
097 * So <b>don't modify</b> the returned array.</i>
098 *
099 * @return the contained actual individual; cannot be <code>null</code>
100 */
101 public double[] getIndividual() {
102 assert null != individual;
103
104 return individual;
105 }
106
107 /**
108 * Returns the current increment.
109 *
110 * @return the current increment
111 */
112 public double getIncrement() {
113 return increment;
114 }
115
116 @Override
117 public int hashCode() {
118 assert null != individual;
119
120 final int prime = 31;
121 int result = 1;
122 long temp;
123 temp = Double.doubleToLongBits(increment);
124 result = prime * result + (int) (temp ^ temp >>> 32);
125 result = prime * result + individual.hashCode();
126 return result;
127 }
128
129 @Override
130 public boolean equals(final Object obj) {
131 assert null != individual;
132
133 if (this == obj) {
134 return true;
135 }
136 if (obj == null) {
137 return false;
138 }
139 if (!(obj instanceof EsIndividual)) {
140 return false;
141 }
142 final EsIndividual other = (EsIndividual) obj;
143 if (Double.doubleToLongBits(increment) != Double
144 .doubleToLongBits(other.increment)) {
145 return false;
146 }
147
148 return individual.equals(other.individual);
149 }
150
151 @Override
152 public String toString() {
153 return "EsIndividual [increment=" + increment + ", individual="
154 + individual + "]";
155 }
156 }