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 */
017package org.apache.commons.math4.optim.linear;
018
019import java.util.Collection;
020import java.util.Collections;
021
022import org.apache.commons.math4.exception.TooManyIterationsException;
023import org.apache.commons.math4.optim.OptimizationData;
024import org.apache.commons.math4.optim.PointValuePair;
025import org.apache.commons.math4.optim.nonlinear.scalar.MultivariateOptimizer;
026
027/**
028 * Base class for implementing linear optimizers.
029 *
030 * @since 3.1
031 */
032public 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. In addition to those documented in
080     * {@link MultivariateOptimizer#parseOptimizationData(OptimizationData[])
081     * MultivariateOptimizer}, this method will register the following data:
082     * <ul>
083     *  <li>{@link LinearObjectiveFunction}</li>
084     *  <li>{@link LinearConstraintSet}</li>
085     *  <li>{@link NonNegativeConstraint}</li>
086     * </ul>
087     * @return {@inheritDoc}
088     * @throws TooManyIterationsException if the maximal number of
089     * iterations is exceeded.
090     */
091    @Override
092    public PointValuePair optimize(OptimizationData... optData)
093        throws TooManyIterationsException {
094        // Set up base class and perform computation.
095        return super.optimize(optData);
096    }
097
098    /**
099     * Scans the list of (required and optional) optimization data that
100     * characterize the problem.
101     *
102     * @param optData Optimization data.
103     * The following data will be looked for:
104     * <ul>
105     *  <li>{@link LinearObjectiveFunction}</li>
106     *  <li>{@link LinearConstraintSet}</li>
107     *  <li>{@link NonNegativeConstraint}</li>
108     * </ul>
109     */
110    @Override
111    protected void parseOptimizationData(OptimizationData... optData) {
112        // Allow base class to register its own data.
113        super.parseOptimizationData(optData);
114
115        // The existing values (as set by the previous call) are reused if
116        // not provided in the argument list.
117        for (OptimizationData data : optData) {
118            if (data instanceof LinearObjectiveFunction) {
119                function = (LinearObjectiveFunction) data;
120                continue;
121            }
122            if (data instanceof LinearConstraintSet) {
123                linearConstraints = ((LinearConstraintSet) data).getConstraints();
124                continue;
125            }
126            if  (data instanceof NonNegativeConstraint) {
127                nonNegative = ((NonNegativeConstraint) data).isRestrictedToNonNegative();
128                continue;
129            }
130        }
131    }
132}