1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.commons.math.optimization;
19
20 import java.util.Arrays;
21 import java.util.Comparator;
22
23 import org.apache.commons.math.ConvergenceException;
24 import org.apache.commons.math.FunctionEvaluationException;
25 import org.apache.commons.math.MathRuntimeException;
26 import org.apache.commons.math.analysis.DifferentiableMultivariateRealFunction;
27 import org.apache.commons.math.random.RandomVectorGenerator;
28
29
30
31
32
33
34
35
36
37
38
39
40 public class MultiStartDifferentiableMultivariateRealOptimizer
41 implements DifferentiableMultivariateRealOptimizer {
42
43
44 private final DifferentiableMultivariateRealOptimizer optimizer;
45
46
47 private int maxIterations;
48
49
50 private int totalIterations;
51
52
53 private int maxEvaluations;
54
55
56 private int totalEvaluations;
57
58
59 private int totalGradientEvaluations;
60
61
62 private int starts;
63
64
65 private RandomVectorGenerator generator;
66
67
68 private RealPointValuePair[] optima;
69
70
71
72
73
74
75
76
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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119 public RealPointValuePair[] getOptima() throws IllegalStateException {
120 if (optima == null) {
121 throw MathRuntimeException.createIllegalStateException("no optimum computed yet");
122 }
123 return optima.clone();
124 }
125
126
127 public void setMaxIterations(int maxIterations) {
128 this.maxIterations = maxIterations;
129 }
130
131
132 public int getMaxIterations() {
133 return maxIterations;
134 }
135
136
137 public int getIterations() {
138 return totalIterations;
139 }
140
141
142 public void setMaxEvaluations(int maxEvaluations) {
143 this.maxEvaluations = maxEvaluations;
144 }
145
146
147 public int getMaxEvaluations() {
148 return maxEvaluations;
149 }
150
151
152 public int getEvaluations() {
153 return totalEvaluations;
154 }
155
156
157 public int getGradientEvaluations() {
158 return totalGradientEvaluations;
159 }
160
161
162 public void setConvergenceChecker(RealConvergenceChecker checker) {
163 optimizer.setConvergenceChecker(checker);
164 }
165
166
167 public RealConvergenceChecker getConvergenceChecker() {
168 return optimizer.getConvergenceChecker();
169 }
170
171
172 public RealPointValuePair optimize(final DifferentiableMultivariateRealFunction f,
173 final GoalType goalType,
174 double[] startPoint)
175 throws FunctionEvaluationException, OptimizationException {
176
177 optima = new RealPointValuePair[starts];
178 totalIterations = 0;
179 totalEvaluations = 0;
180 totalGradientEvaluations = 0;
181
182
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
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 "none of the {0} start points lead to convergence",
220 starts);
221 }
222
223
224 return optima[0];
225
226 }
227
228 }