1 | /* |
---|
2 | Copyright 2006 by Sean Luke and George Mason University |
---|
3 | Licensed under the Academic Free License version 3.0 |
---|
4 | See the file "LICENSE" for more information |
---|
5 | */ |
---|
6 | |
---|
7 | |
---|
8 | package ec.app.moosuite; |
---|
9 | |
---|
10 | import ec.util.*; |
---|
11 | import ec.*; |
---|
12 | import ec.multiobjective.MultiObjectiveFitness; |
---|
13 | import ec.simple.*; |
---|
14 | import ec.vector.*; |
---|
15 | |
---|
16 | /** |
---|
17 | Several standard Multi-objective benchmarks are implemented: |
---|
18 | <ul> |
---|
19 | <li>ZDT1: Zitzler, Deb & Thiele |
---|
20 | <li>ZDT2: Zitzler, Deb & Thiele |
---|
21 | <li>ZDT3: Zitzler, Deb & Thiele |
---|
22 | <li>ZDT4: Zitzler, Deb & Thiele |
---|
23 | <li>ZDT6: Zitzler, Deb & Thiele |
---|
24 | <li>SPHERE: ftp.tik.ee.ethz.ch/pub/people/zitzler/ZLT2001a.pdf |
---|
25 | <li>SCH: (Schaffer), (a.k.a. F1 in Srinivas & Deb); requires exactly 1 decision variables (genes) |
---|
26 | <li>F2: (Schaffer), (Srinivas & Deb), (Coello Coello & Cortes); requires exactly 1 decision variables (genes) |
---|
27 | <li>unconstrained F3: Schaffer, Srinivas & Deb (Chankong & Haimes); requires exactly 2 decision variables (genes) |
---|
28 | <li>QV: Quagliarella & Vicini |
---|
29 | <li>FON: Fonseca & Fleming; requires exactly 3 decision variables (genes) |
---|
30 | <li>POL: Poloni; requires exactly 2 decision variables (genes) |
---|
31 | <li>KUR: Kursawe from the Errata of Zitzler's TIK-Report 103: "SPEA2: Improving the Strength Pareto Evolutionary Algorithm" |
---|
32 | (note that many different versions are described in the literature). |
---|
33 | </ul> |
---|
34 | |
---|
35 | <p><b>Parameters</b><br> |
---|
36 | <table> |
---|
37 | <tr><td valign=top><i>base</i>.<tt>type</tt><br> |
---|
38 | <font size=-1>String, one of: zdt1, zdt2, zdt3, zdt4, zdt6, sphere, sch, fon, qv, pol, kur, f1, f2, unconstrained-f3</font></td> |
---|
39 | <td valign=top>The multi-objective optimization problem to test against. </td></tr> |
---|
40 | </table> |
---|
41 | @author Gabriel Catalin Balan |
---|
42 | */ |
---|
43 | |
---|
44 | public class MooSuite extends Problem implements SimpleProblemForm |
---|
45 | { |
---|
46 | /** |
---|
47 | * |
---|
48 | */ |
---|
49 | private static final long serialVersionUID = 1L; |
---|
50 | public static final String P_WHICH_PROBLEM = "type"; |
---|
51 | public static final String P_ZDT1 = "zdt1"; |
---|
52 | public static final String P_ZDT2 = "zdt2"; |
---|
53 | public static final String P_ZDT3 = "zdt3"; |
---|
54 | public static final String P_ZDT4 = "zdt4"; |
---|
55 | public static final String P_ZDT6 = "zdt6"; |
---|
56 | public static final String P_SPHERE = "sphere"; |
---|
57 | public static final String P_SCH = "sch"; |
---|
58 | public static final String P_FON = "fon"; |
---|
59 | public static final String P_QV = "qv"; |
---|
60 | public static final String P_POL = "pol"; |
---|
61 | public static final String P_KUR_NSGA2 = "kur-nsga2"; |
---|
62 | public static final String P_KUR_SPEA2 = "kur-spea2"; |
---|
63 | public static final String P_F1 = "f1"; |
---|
64 | public static final String P_F2 = "f2"; |
---|
65 | public static final String P_F3 = "unconstrained-f3"; |
---|
66 | |
---|
67 | //Some of the following problems requires an exact number of decision variables (genes). This is mentioned in comment preceding the problem. |
---|
68 | |
---|
69 | public static final int PROB_SPHERE = 0; |
---|
70 | public static final int PROB_ZDT1 = 1; |
---|
71 | public static final int PROB_ZDT2 = 2; |
---|
72 | public static final int PROB_ZDT3 = 3; |
---|
73 | public static final int PROB_ZDT4 = 4; |
---|
74 | public static final int PROB_ZDT6 = 6; |
---|
75 | public static final int PROB_FON = 7; |
---|
76 | public static final int PROB_POL = 8; |
---|
77 | public static final int PROB_KUR_NSGA2 = 9; |
---|
78 | public static final int PROB_KUR_SPEA2 = 10; |
---|
79 | public static final int PROB_QV = 11; |
---|
80 | public static final int PROB_SCH = 12; |
---|
81 | public static final int PROB_F2 = 13; |
---|
82 | public static final int PROB_F3 = 14; |
---|
83 | |
---|
84 | public int problemType = PROB_ZDT1; // defaults on zdt1 |
---|
85 | |
---|
86 | public void setup(final EvolutionState state, final Parameter base) |
---|
87 | { |
---|
88 | super.setup(state, base); |
---|
89 | String wp = state.parameters.getStringWithDefault( base.push( P_WHICH_PROBLEM ), null, "" ); |
---|
90 | if( wp.compareTo( P_ZDT1) == 0 ) |
---|
91 | problemType = PROB_ZDT1; |
---|
92 | else if ( wp.compareTo( P_ZDT2) == 0 ) |
---|
93 | problemType = PROB_ZDT2; |
---|
94 | else if ( wp.compareTo( P_ZDT3) == 0 ) |
---|
95 | problemType = PROB_ZDT3; |
---|
96 | else if ( wp.compareTo( P_ZDT4) == 0 ) |
---|
97 | problemType = PROB_ZDT4; |
---|
98 | else if ( wp.compareTo( P_ZDT6) == 0 ) |
---|
99 | problemType = PROB_ZDT6; |
---|
100 | else if ( wp.compareTo( P_FON) == 0 ) |
---|
101 | problemType = PROB_FON; |
---|
102 | else if ( wp.compareTo( P_POL) == 0 ) |
---|
103 | problemType = PROB_POL; |
---|
104 | else if ( wp.compareTo( P_QV) == 0 ) |
---|
105 | problemType = PROB_QV; |
---|
106 | else if ( wp.compareTo( P_KUR_NSGA2) == 0 ) |
---|
107 | problemType = PROB_KUR_NSGA2; |
---|
108 | else if ( wp.compareTo( P_KUR_SPEA2) == 0 ) |
---|
109 | problemType = PROB_KUR_SPEA2; |
---|
110 | else if( wp.compareTo( P_SPHERE) == 0) |
---|
111 | problemType = PROB_SPHERE; |
---|
112 | else if( wp.compareTo( P_F2) == 0) |
---|
113 | problemType = PROB_F2; |
---|
114 | else if( wp.compareTo( P_F3) == 0) |
---|
115 | problemType = PROB_F3; |
---|
116 | else if( wp.compareTo( P_SCH) == 0 || wp.compareTo( P_F1) == 0 ) |
---|
117 | problemType = PROB_SCH; |
---|
118 | else state.output.fatal( |
---|
119 | "Invalid value for parameter, or parameter not found.\n" + |
---|
120 | "Acceptable values are:\n" + |
---|
121 | " " + P_ZDT1 + "\n" + |
---|
122 | " " + P_ZDT2 + "\n" + |
---|
123 | " " + P_ZDT3 + "\n" + |
---|
124 | " " + P_ZDT4 + "\n" + |
---|
125 | " " + P_ZDT6 + "\n" + |
---|
126 | " " + P_POL + "\n" + |
---|
127 | " " + P_FON + "\n" + |
---|
128 | " " + P_KUR_NSGA2 + "\n" + |
---|
129 | " " + P_KUR_SPEA2 + "\n" + |
---|
130 | " " + P_SPHERE + "\n" + |
---|
131 | " " + P_SCH + "(or " + P_F1 + ")\n"+ |
---|
132 | " " + P_F2 + "\n", |
---|
133 | base.push( P_WHICH_PROBLEM ) ); |
---|
134 | } |
---|
135 | private static final double TWO_PI = Math.PI*2;//QV uses it. |
---|
136 | private static final double TEN_PI = Math.PI*10;//ZDT3 uses it. |
---|
137 | private static final double FOUR_PI = Math.PI*4;//ZDT4 uses it. |
---|
138 | private static final double SIX_PI = Math.PI*6;//ZDT6 uses it. |
---|
139 | private static final double ONE_OVER_SQRT_3 = 1d/Math.sqrt(3);//FON uses it. |
---|
140 | private static final double A1 = 0.5*Math.sin(1) - 2*Math.cos(1) + Math.sin(2)- 1.5*Math.cos(2);//POL uses it |
---|
141 | private static final double A2 = 1.5*Math.sin(1) - Math.cos(1) + 2* Math.sin(2)- 0.5*Math.cos(2);//POL uses it |
---|
142 | |
---|
143 | public void evaluate(final EvolutionState state, |
---|
144 | final Individual ind, |
---|
145 | final int subpopulation, |
---|
146 | final int threadnum) |
---|
147 | { |
---|
148 | if( !( ind instanceof DoubleVectorIndividual ) ) |
---|
149 | state.output.fatal( "The individuals for this problem should be DoubleVectorIndividuals." ); |
---|
150 | |
---|
151 | DoubleVectorIndividual temp = (DoubleVectorIndividual)ind; |
---|
152 | double[] genome = temp.genome; |
---|
153 | int numDecisionVars = genome.length; |
---|
154 | |
---|
155 | float[] objectives = ((MultiObjectiveFitness)ind.fitness).getObjectives(); |
---|
156 | |
---|
157 | double f, g, h, sum; |
---|
158 | |
---|
159 | switch(problemType) |
---|
160 | { |
---|
161 | case PROB_ZDT1: |
---|
162 | f = genome[0]; |
---|
163 | objectives[0] = (float)f; |
---|
164 | sum = 0; |
---|
165 | for(int i = 1; i< numDecisionVars; ++i) |
---|
166 | sum += genome[i]; |
---|
167 | g = 1d+9d*sum/(numDecisionVars-1); |
---|
168 | h = 1d-Math.sqrt(f/g); |
---|
169 | objectives[1] = (float)(g*h); |
---|
170 | break; |
---|
171 | |
---|
172 | case PROB_ZDT2: |
---|
173 | f = genome[0]; |
---|
174 | objectives[0] = (float)f; |
---|
175 | sum = 0; |
---|
176 | for(int i = 1; i< numDecisionVars; i++) |
---|
177 | sum += genome[i]; |
---|
178 | g = 1.0+9.0*sum/(float)(numDecisionVars-1); |
---|
179 | h = 1.0-(f/g)*(f/g); |
---|
180 | objectives[1] = (float)(g*h); |
---|
181 | break; |
---|
182 | |
---|
183 | case PROB_ZDT3: |
---|
184 | f = genome[0]; |
---|
185 | objectives[0] = (float)f; |
---|
186 | sum = 0; |
---|
187 | for(int i = 1; i< numDecisionVars; i++) |
---|
188 | sum += genome[i]; |
---|
189 | g = 1.0+9.0*sum/(numDecisionVars-1); |
---|
190 | double foverg = f/g; |
---|
191 | h = 1.0-Math.sqrt(foverg) - foverg * Math.sin(TEN_PI * f); |
---|
192 | objectives[1] = (float)(g*h); |
---|
193 | break; |
---|
194 | case PROB_ZDT4: |
---|
195 | f = genome[0]; |
---|
196 | objectives[0] = (float)f; |
---|
197 | sum = 0; |
---|
198 | for(int i = 1; i< numDecisionVars; ++i) |
---|
199 | sum += genome[i]*genome[i]- 10*Math.cos(FOUR_PI * genome[i]); |
---|
200 | |
---|
201 | g = 1+10*(numDecisionVars-1)+sum; |
---|
202 | h = 1-Math.sqrt(f/g); |
---|
203 | objectives[1] = (float)(g*h); |
---|
204 | break; |
---|
205 | case PROB_ZDT6: |
---|
206 | f = 1 - (Math.exp(-4 * genome[0]) * Math.pow(Math.sin(SIX_PI * genome[0]), 6)); |
---|
207 | objectives[0] = (float)f; |
---|
208 | sum = 0; |
---|
209 | for (int i = 1; i < numDecisionVars; ++i) |
---|
210 | sum += genome[i]; |
---|
211 | g = 1d + 9 * Math.pow(sum / (numDecisionVars - 1), 0.25); |
---|
212 | h = 1d - Math.pow(f / g, 2); |
---|
213 | objectives[1] = (float) (g * h); |
---|
214 | break; |
---|
215 | case PROB_SPHERE: |
---|
216 | int numObjectives = objectives.length; |
---|
217 | for(int j=0; j<numObjectives; ++j) |
---|
218 | { |
---|
219 | sum = (genome[j]-1)*(genome[j]-1); |
---|
220 | for(int i=0; i<numDecisionVars; ++i) |
---|
221 | if (i!=j) |
---|
222 | sum += genome[i]*genome[i]; |
---|
223 | objectives[j] = (float)sum; |
---|
224 | } |
---|
225 | break; |
---|
226 | case PROB_SCH: |
---|
227 | if(numDecisionVars!=1) throw new RuntimeException("SCH needs exactly 1 decision variable (gene)."); |
---|
228 | double x = genome[0]; |
---|
229 | objectives[0]=(float)(x*x); |
---|
230 | objectives[1]=(float)((x-2)*(x-2)); |
---|
231 | break; |
---|
232 | case PROB_F2: |
---|
233 | if(numDecisionVars!=1) throw new RuntimeException("F2 needs exactly 1 decision variable (gene)."); |
---|
234 | x = genome[0]; |
---|
235 | objectives[0]=(float)( x<=1? -x: (x<=3? x-2:(x<=4? 4-x: x-4))); |
---|
236 | objectives[1]=(float)((x-5)*(x-5)); |
---|
237 | break; |
---|
238 | case PROB_F3: |
---|
239 | if(numDecisionVars!=2) throw new RuntimeException("F3 needs exactly 2 decision variable (gene)."); |
---|
240 | double x1 = genome[0]; |
---|
241 | double x2 = genome[1]; |
---|
242 | objectives[0]=(float)((x1-2)*(x1-2)+(x2-1)*(x2-1)+2); |
---|
243 | objectives[1]=(float)(9*x1-(x2-1)*(x2-1)); |
---|
244 | break; |
---|
245 | case PROB_FON: |
---|
246 | if(numDecisionVars!=3) throw new RuntimeException("FON needs exactly 3 decision variables (genes)."); |
---|
247 | double sum1 = 0, sum2=0; |
---|
248 | for(int i = 0; i< numDecisionVars; i++) |
---|
249 | { |
---|
250 | double xi = genome[i]; |
---|
251 | double d = xi-ONE_OVER_SQRT_3; |
---|
252 | double s = xi+ONE_OVER_SQRT_3; |
---|
253 | sum1+=d*d; |
---|
254 | sum2+=s*s; |
---|
255 | } |
---|
256 | objectives[0] = 1 - (float)Math.exp(-sum1); |
---|
257 | objectives[1] = 1 - (float)Math.exp(-sum2); |
---|
258 | break; |
---|
259 | case PROB_POL: |
---|
260 | if(numDecisionVars!=2) throw new RuntimeException("POL needs exactly 2 decision variables (genes)."); |
---|
261 | x1= genome[0]; |
---|
262 | x2 = genome[1]; |
---|
263 | double b1 = 0.5*Math.sin(x1) - 2*Math.cos(x1) + Math.sin(x2)- 1.5*Math.cos(x2); |
---|
264 | double b2 = 1.5*Math.sin(x1) - Math.cos(x1) + 2* Math.sin(x2)- 0.5*Math.cos(x2); |
---|
265 | objectives[0] = (float)(1+(A1-b1)*(A1-b1)+(A2-b2)*(A2-b2)); |
---|
266 | objectives[1] = (float)((x1+3)*(x1+3)+(x2+1)*(x2+1)); |
---|
267 | break; |
---|
268 | case PROB_QV: |
---|
269 | sum=0; |
---|
270 | for(int i=0;i<numDecisionVars;i++) |
---|
271 | { |
---|
272 | double xi=genome[i]; |
---|
273 | sum+=xi*xi-10*Math.cos(TWO_PI*xi)+10; |
---|
274 | } |
---|
275 | objectives[0] = (float)Math.pow(sum/numDecisionVars, 0.25); |
---|
276 | sum=0; |
---|
277 | for(int i=0;i<numDecisionVars;i++) |
---|
278 | { |
---|
279 | double xi=genome[i]-1.5; |
---|
280 | sum+=xi*xi-10*Math.cos(TWO_PI*xi)+10; |
---|
281 | } |
---|
282 | objectives[1] = (float)Math.pow(sum/numDecisionVars, 0.25); |
---|
283 | break; |
---|
284 | case PROB_KUR_NSGA2: |
---|
285 | double nextSquared, thisSquared; |
---|
286 | thisSquared = genome[0]*genome[0]; |
---|
287 | sum=0; |
---|
288 | for(int i = 0; i< numDecisionVars-1; ++i) |
---|
289 | { |
---|
290 | nextSquared = genome[i+1]*genome[i+1]; |
---|
291 | //sum += 1d-Math.exp(-0.2*Math.sqrt(thisSquared + nextSquared)); |
---|
292 | sum += -10-Math.exp(-0.2*Math.sqrt(thisSquared + nextSquared)); |
---|
293 | thisSquared = nextSquared; |
---|
294 | } |
---|
295 | //objectives[1] = (float)sum; |
---|
296 | objectives[0] = (float)sum; |
---|
297 | sum= 0; |
---|
298 | for(int i = 0; i< numDecisionVars; ++i) |
---|
299 | { |
---|
300 | //double sin_xi = Math.sin(genome[i]); |
---|
301 | //double t1 = Math.pow(Math.abs(genome[i]), .8); |
---|
302 | //double t2 = 5*sin_xi*sin_xi*sin_xi; |
---|
303 | //sum +=t1+t2+ 3.5828; |
---|
304 | double xi3 = Math.pow(genome[i], 3); |
---|
305 | double t1 = Math.pow(Math.abs(genome[i]), .8); |
---|
306 | double t2 = 5*Math.sin(xi3); |
---|
307 | sum +=t1+t2; |
---|
308 | } |
---|
309 | //objectives[0] = (float)sum; |
---|
310 | objectives[1] = (float)sum; |
---|
311 | break; |
---|
312 | |
---|
313 | default: |
---|
314 | state.output.fatal( "ec.app.ecsuite.ECSuite has an invalid problem -- how on earth did that happen?" ); |
---|
315 | break; |
---|
316 | } |
---|
317 | |
---|
318 | ((MultiObjectiveFitness)ind.fitness).setObjectives(state, objectives); |
---|
319 | ind.evaluated = true; |
---|
320 | } |
---|
321 | } |
---|