    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.optim.linear;
    018
    019    import java.util.Collection;
    020    import java.util.Collections;
    021    import org.apache.commons.math3.exception.TooManyIterationsException;
    022    import org.apache.commons.math3.optim.OptimizationData;
    023    import org.apache.commons.math3.optim.PointValuePair;
    024    import org.apache.commons.math3.optim.nonlinear.scalar.MultivariateOptimizer;
    025
    026    /**
    027     * Base class for implementing linear optimizers.
    028     *
    029     * @version $Id: AbstractLinearOptimizer.java 1416643 2012-12-03 19:37:14Z tn $
    030     * @since 3.1
    031     */
    032    public abstract class LinearOptimizer
    033        extends MultivariateOptimizer {
    034        /**
    035         * Linear objective function.
    036         */
    037        private LinearObjectiveFunction function;
    038        /**
    039         * Linear constraints.
    040         */
    041        private Collection<LinearConstraint> linearConstraints;
    042        /**
    043         * Whether to restrict the variables to non-negative values.
    044         */
    045        private boolean nonNegative;
    046
    047        /**
    048         * Simple constructor with default settings.
    049         *
    050         */
    051        protected LinearOptimizer() {
    052            super(null); // No convergence checker.
    053        }
    054
    055        /**
    056         * @return {@code true} if the variables are restricted to non-negative values.
    057         */
    058        protected boolean isRestrictedToNonNegative() {
    059            return nonNegative;
    060        }
    061
    062        /**
    063         * @return the optimization type.
    064         */
    065        protected LinearObjectiveFunction getFunction() {
    066            return function;
    067        }
    068
    069        /**
    070         * @return the optimization type.
    071         */
    072        protected Collection<LinearConstraint> getConstraints() {
    073            return Collections.unmodifiableCollection(linearConstraints);
    074        }
    075
    076        /**
    077         * {@inheritDoc}
    078         *
    079         * @param optData Optimization data. The following data will be looked for:
    080         * <ul>
    081         *  <li>{@link org.apache.commons.math3.optim.MaxIter}</li>
    082         *  <li>{@link LinearObjectiveFunction}</li>
    083         *  <li>{@link LinearConstraintSet}</li>
    084         *  <li>{@link NonNegativeConstraint}</li>
    085         * </ul>
    086         * @return {@inheritDoc}
    087         * @throws TooManyIterationsException if the maximal number of
    088         * iterations is exceeded.
    089         */
    090        @Override
    091        public PointValuePair optimize(OptimizationData... optData)
    092            throws TooManyIterationsException {
    093             // Retrieve settings.
    094            parseOptimizationData(optData);
    095            // Set up base class and perform computation.
    096            return super.optimize(optData);
    097        }
    098
    099        /**
    100         * Scans the list of (required and optional) optimization data that
    101         * characterize the problem.
    102         *
    103         * @param optData Optimization data.
    104         * The following data will be looked for:
    105         * <ul>
    106         *  <li>{@link LinearObjectiveFunction}</li>
    107         *  <li>{@link LinearConstraintSet}</li>
    108         *  <li>{@link NonNegativeConstraint}</li>
    109         * </ul>
    110         */
    111        private void parseOptimizationData(OptimizationData... optData) {
    112            // The existing values (as set by the previous call) are reused if
    113            // not provided in the argument list.
    114            for (OptimizationData data : optData) {
    115                if (data instanceof LinearObjectiveFunction) {
    116                    function = (LinearObjectiveFunction) data;
    117                    continue;
    118                }
    119                if (data instanceof LinearConstraintSet) {
    120                    linearConstraints = ((LinearConstraintSet) data).getConstraints();
    121                    continue;
    122                }
    123                if  (data instanceof NonNegativeConstraint) {
    124                    nonNegative = ((NonNegativeConstraint) data).isRestrictedToNonNegative();
    125                    continue;
    126                }
    127            }
    128        }
    129    }