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.MultivariateRealFunction;
27 import org.apache.commons.math.random.RandomVectorGenerator;
28
29
30
31
32
33
34
35
36
37
38
39
40 public class MultiStartMultivariateRealOptimizer
41 implements MultivariateRealOptimizer {
42
43
44 private final MultivariateRealOptimizer optimizer;
45
46
47 private int maxIterations;
48
49
50 private int maxEvaluations;
51
52
53 private int totalIterations;
54
55
56 private int totalEvaluations;
57
58
59 private int starts;
60
61
62 private RandomVectorGenerator generator;
63
64
65 private RealPointValuePair[] optima;
66
67
68
69
70
71
72
73
74
75 public MultiStartMultivariateRealOptimizer(final MultivariateRealOptimizer optimizer,
76 final int starts,
77 final RandomVectorGenerator generator) {
78 this.optimizer = optimizer;
79 this.totalIterations = 0;
80 this.totalEvaluations = 0;
81 this.starts = starts;
82 this.generator = generator;
83 this.optima = null;
84 setMaxIterations(Integer.MAX_VALUE);
85 setMaxEvaluations(Integer.MAX_VALUE);
86 }
87
88
89
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 public RealPointValuePair[] getOptima() throws IllegalStateException {
115 if (optima == null) {
116 throw MathRuntimeException.createIllegalStateException("no optimum computed yet");
117 }
118 return optima.clone();
119 }
120
121
122 public void setMaxIterations(int maxIterations) {
123 this.maxIterations = maxIterations;
124 }
125
126
127 public int getMaxIterations() {
128 return maxIterations;
129 }
130
131
132 public void setMaxEvaluations(int maxEvaluations) {
133 this.maxEvaluations = maxEvaluations;
134 }
135
136
137 public int getMaxEvaluations() {
138 return maxEvaluations;
139 }
140
141
142 public int getIterations() {
143 return totalIterations;
144 }
145
146
147 public int getEvaluations() {
148 return totalEvaluations;
149 }
150
151
152 public void setConvergenceChecker(RealConvergenceChecker checker) {
153 optimizer.setConvergenceChecker(checker);
154 }
155
156
157 public RealConvergenceChecker getConvergenceChecker() {
158 return optimizer.getConvergenceChecker();
159 }
160
161
162 public RealPointValuePair optimize(final MultivariateRealFunction f,
163 final GoalType goalType,
164 double[] startPoint)
165 throws FunctionEvaluationException, OptimizationException {
166
167 optima = new RealPointValuePair[starts];
168 totalIterations = 0;
169 totalEvaluations = 0;
170
171
172 for (int i = 0; i < starts; ++i) {
173
174 try {
175 optimizer.setMaxIterations(maxIterations - totalIterations);
176 optimizer.setMaxEvaluations(maxEvaluations - totalEvaluations);
177 optima[i] = optimizer.optimize(f, goalType,
178 (i == 0) ? startPoint : generator.nextVector());
179 } catch (FunctionEvaluationException fee) {
180 optima[i] = null;
181 } catch (OptimizationException oe) {
182 optima[i] = null;
183 }
184
185 totalIterations += optimizer.getIterations();
186 totalEvaluations += optimizer.getEvaluations();
187
188 }
189
190
191 Arrays.sort(optima, new Comparator<RealPointValuePair>() {
192 public int compare(final RealPointValuePair o1, final RealPointValuePair o2) {
193 if (o1 == null) {
194 return (o2 == null) ? 0 : +1;
195 } else if (o2 == null) {
196 return -1;
197 }
198 final double v1 = o1.getValue();
199 final double v2 = o2.getValue();
200 return (goalType == GoalType.MINIMIZE) ?
201 Double.compare(v1, v2) : Double.compare(v2, v1);
202 }
203 });
204
205 if (optima[0] == null) {
206 throw new OptimizationException(
207 "none of the {0} start points lead to convergence",
208 starts);
209 }
210
211
212 return optima[0];
213
214 }
215
216 }