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    }