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 org.apache.commons.math.random.RandomGenerator;
019    
020    /**
021     * A configuration for a general evolutionary algorithm. Additionally to the
022     * components in {@link EaOptimizerConfigurationBase} it contains:
023     * <ul>
024     * <li>The {@link Recombiner} to
025     * {@link Recombiner#recombine(java.util.Collection) recombine} the selected
026     * pairings to new individuals.
027     * </ul>
028     * 
029     * @param <I>
030     *            the individuals' type
031     * 
032     * @author <a href="http://kumpe.de/christian/java">Christian Kumpe</a>
033     */
034    public class EaOptimizerConfiguration<I> extends
035                    EaOptimizerConfigurationBase<I> {
036            private static final long serialVersionUID = 1L;
037    
038            private Recombiner<I> recombiner;
039    
040            @Override
041            public EaOptimizerConfiguration<I> clone() {
042                    return (EaOptimizerConfiguration<I>) super.clone();
043            }
044    
045            /**
046             * {@inheritDoc}
047             * <p>
048             * Additionally calls
049             * {@link #injectRandomGenerator(Object, RandomGenerator)} on the given
050             * {@link #setRecombiner(Recombiner) recombiner}.
051             */
052            @Override
053            public void injectRandomGenerator(final RandomGenerator randomGenerator) {
054                    super.injectRandomGenerator(randomGenerator);
055    
056                    injectRandomGenerator(recombiner, randomGenerator);
057            }
058    
059            /**
060             * {@inheritDoc}
061             * <p>
062             * Additionally verifies that a {@link #setRecombiner(Recombiner)
063             * recombiner} has been set.
064             * 
065             * @throws IllegalStateException
066             *             {@inheritDoc}
067             */
068            @Override
069            public void validate() {
070                    super.validate();
071    
072                    if (null == recombiner) {
073                            throw new IllegalStateException(
074                                            "A Recombiner has to be set in the configuration.");
075                    }
076            }
077    
078            /**
079             * @return the configured {@link Recombiner}; <code>null</code> if none has
080             *         been set
081             */
082            public final Recombiner<I> getRecombiner() {
083                    return recombiner;
084            }
085    
086            /**
087             * @param recombiner
088             *            the {@link Recombiner} for this configuration
089             * 
090             * @throws NullPointerException
091             *             if {@code recombiner} is <code>null</code>
092             */
093            public final void setRecombiner(final Recombiner<I> recombiner) {
094                    if (null == recombiner) {
095                            throw new NullPointerException("recombiner may not be null.");
096                    }
097    
098                    this.recombiner = recombiner;
099            }
100    
101            @Override
102            public int hashCode() {
103                    final int prime = 31;
104                    int result = super.hashCode();
105                    result = prime * result
106                                    + (recombiner == null ? 0 : recombiner.hashCode());
107                    return result;
108            }
109    
110            @Override
111            public boolean equals(final Object obj) {
112                    if (this == obj) {
113                            return true;
114                    }
115                    if (!super.equals(obj)) {
116                            return false;
117                    }
118                    if (!(obj instanceof EaOptimizerConfiguration)) {
119                            return false;
120                    }
121                    final EaOptimizerConfiguration<?> other = (EaOptimizerConfiguration<?>) obj;
122                    if (recombiner == null) {
123                            if (other.recombiner != null) {
124                                    return false;
125                            }
126                    } else if (!recombiner.equals(other.recombiner)) {
127                            return false;
128                    }
129                    return true;
130            }
131    
132            @Override
133            public String toString() {
134                    return "EaOptimizerConfiguration [halter=" + getHalter()
135                                    + ", recombiner=" + recombiner + ", mutator=" + getMutator()
136                                    + ", evaluator=" + getEvaluator() + ", parents=" + getParents()
137                                    + ", preserveParents=" + isPreserveParents() + "]";
138            }
139    }