    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    }