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 }