source: src/main/java/agents/org/apache/commons/math/optimization/MultiStartDifferentiableMultivariateRealOptimizer.java

Last change on this file was 1, checked in by Wouter Pasman, 7 years ago

Initial import : Genius 9.0.0

File size: 8.8 KB
Line 
1/*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18package agents.org.apache.commons.math.optimization;
19
20import java.util.Arrays;
21import java.util.Comparator;
22
23import agents.org.apache.commons.math.FunctionEvaluationException;
24import agents.org.apache.commons.math.MathRuntimeException;
25import agents.org.apache.commons.math.analysis.DifferentiableMultivariateRealFunction;
26import agents.org.apache.commons.math.exception.util.LocalizedFormats;
27import agents.org.apache.commons.math.random.RandomVectorGenerator;
28
29/**
30 * Special implementation of the {@link DifferentiableMultivariateRealOptimizer} interface adding
31 * multi-start features to an existing optimizer.
32 * <p>
33 * This class wraps a classical optimizer to use it several times in
34 * turn with different starting points in order to avoid being trapped
35 * into a local extremum when looking for a global one.
36 * </p>
37 * @version $Revision: 1073158 $ $Date: 2011-02-21 22:46:52 +0100 (lun. 21 févr. 2011) $
38 * @since 2.0
39 */
40public class MultiStartDifferentiableMultivariateRealOptimizer
41 implements DifferentiableMultivariateRealOptimizer {
42
43 /** Underlying classical optimizer. */
44 private final DifferentiableMultivariateRealOptimizer optimizer;
45
46 /** Maximal number of iterations allowed. */
47 private int maxIterations;
48
49 /** Number of iterations already performed for all starts. */
50 private int totalIterations;
51
52 /** Maximal number of evaluations allowed. */
53 private int maxEvaluations;
54
55 /** Number of evaluations already performed for all starts. */
56 private int totalEvaluations;
57
58 /** Number of gradient evaluations already performed for all starts. */
59 private int totalGradientEvaluations;
60
61 /** Number of starts to go. */
62 private int starts;
63
64 /** Random generator for multi-start. */
65 private RandomVectorGenerator generator;
66
67 /** Found optima. */
68 private RealPointValuePair[] optima;
69
70 /**
71 * Create a multi-start optimizer from a single-start optimizer
72 * @param optimizer single-start optimizer to wrap
73 * @param starts number of starts to perform (including the
74 * first one), multi-start is disabled if value is less than or
75 * equal to 1
76 * @param generator random vector generator to use for restarts
77 */
78 public MultiStartDifferentiableMultivariateRealOptimizer(final DifferentiableMultivariateRealOptimizer optimizer,
79 final int starts,
80 final RandomVectorGenerator generator) {
81 this.optimizer = optimizer;
82 this.totalIterations = 0;
83 this.totalEvaluations = 0;
84 this.totalGradientEvaluations = 0;
85 this.starts = starts;
86 this.generator = generator;
87 this.optima = null;
88 setMaxIterations(Integer.MAX_VALUE);
89 setMaxEvaluations(Integer.MAX_VALUE);
90 }
91
92 /** Get all the optima found during the last call to {@link
93 * #optimize(DifferentiableMultivariateRealFunction, GoalType, double[])
94 * optimize}.
95 * <p>The optimizer stores all the optima found during a set of
96 * restarts. The {@link #optimize(DifferentiableMultivariateRealFunction,
97 * GoalType, double[]) optimize} method returns the best point only. This
98 * method returns all the points found at the end of each starts,
99 * including the best one already returned by the {@link
100 * #optimize(DifferentiableMultivariateRealFunction, GoalType, double[])
101 * optimize} method.
102 * </p>
103 * <p>
104 * The returned array as one element for each start as specified
105 * in the constructor. It is ordered with the results from the
106 * runs that did converge first, sorted from best to worst
107 * objective value (i.e in ascending order if minimizing and in
108 * descending order if maximizing), followed by and null elements
109 * corresponding to the runs that did not converge. This means all
110 * elements will be null if the {@link #optimize(DifferentiableMultivariateRealFunction,
111 * GoalType, double[]) optimize} method did throw a {@link
112 * agents.org.apache.commons.math.ConvergenceException ConvergenceException}).
113 * This also means that if the first element is non null, it is the best
114 * point found across all starts.</p>
115 * @return array containing the optima
116 * @exception IllegalStateException if {@link #optimize(DifferentiableMultivariateRealFunction,
117 * GoalType, double[]) optimize} has not been called
118 */
119 public RealPointValuePair[] getOptima() throws IllegalStateException {
120 if (optima == null) {
121 throw MathRuntimeException.createIllegalStateException(LocalizedFormats.NO_OPTIMUM_COMPUTED_YET);
122 }
123 return optima.clone();
124 }
125
126 /** {@inheritDoc} */
127 public void setMaxIterations(int maxIterations) {
128 this.maxIterations = maxIterations;
129 }
130
131 /** {@inheritDoc} */
132 public int getMaxIterations() {
133 return maxIterations;
134 }
135
136 /** {@inheritDoc} */
137 public int getIterations() {
138 return totalIterations;
139 }
140
141 /** {@inheritDoc} */
142 public void setMaxEvaluations(int maxEvaluations) {
143 this.maxEvaluations = maxEvaluations;
144 }
145
146 /** {@inheritDoc} */
147 public int getMaxEvaluations() {
148 return maxEvaluations;
149 }
150
151 /** {@inheritDoc} */
152 public int getEvaluations() {
153 return totalEvaluations;
154 }
155
156 /** {@inheritDoc} */
157 public int getGradientEvaluations() {
158 return totalGradientEvaluations;
159 }
160
161 /** {@inheritDoc} */
162 public void setConvergenceChecker(RealConvergenceChecker checker) {
163 optimizer.setConvergenceChecker(checker);
164 }
165
166 /** {@inheritDoc} */
167 public RealConvergenceChecker getConvergenceChecker() {
168 return optimizer.getConvergenceChecker();
169 }
170
171 /** {@inheritDoc} */
172 public RealPointValuePair optimize(final DifferentiableMultivariateRealFunction f,
173 final GoalType goalType,
174 double[] startPoint)
175 throws FunctionEvaluationException, OptimizationException, FunctionEvaluationException {
176
177 optima = new RealPointValuePair[starts];
178 totalIterations = 0;
179 totalEvaluations = 0;
180 totalGradientEvaluations = 0;
181
182 // multi-start loop
183 for (int i = 0; i < starts; ++i) {
184
185 try {
186 optimizer.setMaxIterations(maxIterations - totalIterations);
187 optimizer.setMaxEvaluations(maxEvaluations - totalEvaluations);
188 optima[i] = optimizer.optimize(f, goalType,
189 (i == 0) ? startPoint : generator.nextVector());
190 } catch (FunctionEvaluationException fee) {
191 optima[i] = null;
192 } catch (OptimizationException oe) {
193 optima[i] = null;
194 }
195
196 totalIterations += optimizer.getIterations();
197 totalEvaluations += optimizer.getEvaluations();
198 totalGradientEvaluations += optimizer.getGradientEvaluations();
199
200 }
201
202 // sort the optima from best to worst, followed by null elements
203 Arrays.sort(optima, new Comparator<RealPointValuePair>() {
204 public int compare(final RealPointValuePair o1, final RealPointValuePair o2) {
205 if (o1 == null) {
206 return (o2 == null) ? 0 : +1;
207 } else if (o2 == null) {
208 return -1;
209 }
210 final double v1 = o1.getValue();
211 final double v2 = o2.getValue();
212 return (goalType == GoalType.MINIMIZE) ?
213 Double.compare(v1, v2) : Double.compare(v2, v1);
214 }
215 });
216
217 if (optima[0] == null) {
218 throw new OptimizationException(
219 LocalizedFormats.NO_CONVERGENCE_WITH_ANY_START_POINT,
220 starts);
221 }
222
223 // return the found point given the best objective function value
224 return optima[0];
225
226 }
227
228}
Note: See TracBrowser for help on using the repository browser.