001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  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    package org.apache.commons.math3.genetics;
018    
019    import java.util.concurrent.TimeUnit;
020    
021    import org.apache.commons.math3.exception.NumberIsTooSmallException;
022    
023    /**
024     * Stops after a fixed amount of time has elapsed.
025     * <p>
026     * The first time {@link #isSatisfied(Population)} is invoked, the end time of the evolution is determined based on the
027     * provided <code>maxTime</code> value. Once the elapsed time reaches the configured <code>maxTime</code> value,
028     * {@link #isSatisfied(Population)} returns true.
029     *
030     * @version $Id: FixedElapsedTime.java 1385297 2012-09-16 16:05:57Z tn $
031     * @since 3.1
032     */
033    public class FixedElapsedTime implements StoppingCondition {
034        /** Maximum allowed time period (in nanoseconds). */
035        private final long maxTimePeriod;
036    
037        /** The predetermined termination time (stopping condition). */
038        private long endTime = -1;
039    
040        /**
041         * Create a new {@link FixedElapsedTime} instance.
042         *
043         * @param maxTime maximum number of seconds generations are allowed to evolve
044         * @throws NumberIsTooSmallException if the provided time is &lt; 0
045         */
046        public FixedElapsedTime(final long maxTime) throws NumberIsTooSmallException {
047            this(maxTime, TimeUnit.SECONDS);
048        }
049    
050        /**
051         * Create a new {@link FixedElapsedTime} instance.
052         *
053         * @param maxTime maximum time generations are allowed to evolve
054         * @param unit {@link TimeUnit} of the maxTime argument
055         * @throws NumberIsTooSmallException if the provided time is &lt; 0
056         */
057        public FixedElapsedTime(final long maxTime, final TimeUnit unit) throws NumberIsTooSmallException {
058            if (maxTime < 0) {
059                throw new NumberIsTooSmallException(maxTime, 0, true);
060            }
061            maxTimePeriod = unit.toNanos(maxTime);
062        }
063    
064        /**
065         * Determine whether or not the maximum allowed time has passed.
066         * The termination time is determined after the first generation.
067         *
068         * @param population ignored (no impact on result)
069         * @return <code>true</code> IFF the maximum allowed time period has elapsed
070         */
071        public boolean isSatisfied(final Population population) {
072            if (endTime < 0) {
073                endTime = System.nanoTime() + maxTimePeriod;
074            }
075    
076            return System.nanoTime() >= endTime;
077        }
078    }