// LZ09.java // // Author: // Antonio J. Nebro <antonio@lcc.uma.es> // Juan J. Durillo <durillo@lcc.uma.es> // // Copyright (c) 2011 Antonio J. Nebro, Juan J. Durillo // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. package org.uma.jmetal.problem.multiobjective.lz09; import java.util.ArrayList; import java.util.List; /** * Base class to implement the problem of the lz09 benchmark, which is * defined in: * H. Li and Q. Zhang. Multiobjective optimization problem with complicated * pareto sets, MOEA/D and NSGA-II. IEEE Transactions on Evolutionary * Computation, 12(2):284-302, April 2009. */ public class LZ09 { int nvar; int nobj; int ltype; int dtype; int ptype; public LZ09(int nvar, int nobj, int ptype, int dtype, int ltype) { this.nvar = nvar; this.nobj = nobj; this.ltype = ltype; this.dtype = dtype; this.ptype = ptype; } // control the PF shape void alphaFunction(double alpha[], List<Double> x, int dim, int type) { if (dim == 2) { if (type == 21) { alpha[0] = x.get(0); alpha[1] = 1 - Math.sqrt(x.get(0)); } if (type == 22) { alpha[0] = x.get(0); alpha[1] = 1 - x.get(0) * x.get(0); } if (type == 23) { alpha[0] = x.get(0); alpha[1] = 1 - Math.sqrt(alpha[0]) - alpha[0] * Math.sin(10 * alpha[0] * alpha[0] * Math.PI); } if (type == 24) { alpha[0] = x.get(0); alpha[1] = 1 - x.get(0) - 0.05 * Math.sin(4 * Math.PI * x.get(0)); } } else { if (type == 31) { alpha[0] = Math.cos(x.get(0) * Math.PI / 2) * Math.cos(x.get(1) * Math.PI / 2); alpha[1] = Math.cos(x.get(0) * Math.PI / 2) * Math.sin(x.get(1) * Math.PI / 2); alpha[2] = Math.sin(x.get(0) * Math.PI / 2); } if (type == 32) { alpha[0] = 1 - Math.cos(x.get(0) * Math.PI / 2) * Math.cos(x.get(1) * Math.PI / 2); alpha[1] = 1 - Math.cos(x.get(0) * Math.PI / 2) * Math.sin(x.get(1) * Math.PI / 2); alpha[2] = 1 - Math.sin(x.get(0) * Math.PI / 2); } if (type == 33) { alpha[0] = x.get(0); alpha[1] = x.get(1); alpha[2] = 3 - (Math.sin(3 * Math.PI * x.get(0)) + Math.sin(3 * Math.PI * x.get(1))) - 2 * (x.get(0) + x.get(1)); } if (type == 34) { alpha[0] = x.get(0) * x.get(1); alpha[1] = x.get(0) * (1 - x.get(1)); alpha[2] = (1 - x.get(0)); } } } // control the distance double betaFunction(List<Double> x, int type) { double beta; beta = 0; int dim = x.size(); if (dim == 0) { beta = 0; } if (type == 1) { beta = 0; for (int i = 0; i < dim; i++) { beta += x.get(i) * x.get(i); } beta = 2.0 * beta / dim; } if (type == 2) { beta = 0; for (int i = 0; i < dim; i++) { beta += Math.sqrt(i + 1) * x.get(i) * x.get(i); } beta = 2.0 * beta / dim; } if (type == 3) { double sum = 0, xx; for (int i = 0; i < dim; i++) { xx = 2 * x.get(i); sum += (xx * xx - Math.cos(4 * Math.PI * xx) + 1); } beta = 2.0 * sum / dim; } if (type == 4) { double sum = 0, prod = 1, xx; for (int i = 0; i < dim; i++) { xx = 2 * x.get(i); sum += xx * xx; prod *= Math.cos(10 * Math.PI * xx / Math.sqrt(i + 1)); } beta = 2.0 * (sum - 2 * prod + 2) / dim; } return beta; } // control the PS shape of 2-d instances double psfunc2(double x, double t1, int dim, int type, int css) { // type: the type of curve // css: the class of index double beta; beta = 0.0; dim++; if (type == 21) { double xy = 2 * (x - 0.5); beta = xy - Math.pow(t1, 0.5 * (nvar + 3 * dim - 8) / (nvar - 2)); } if (type == 22) { double theta = 6 * Math.PI * t1 + dim * Math.PI / nvar; double xy = 2 * (x - 0.5); beta = xy - Math.sin(theta); } if (type == 23) { double theta = 6 * Math.PI * t1 + dim * Math.PI / nvar; double ra = 0.8 * t1; double xy = 2 * (x - 0.5); if (css == 1) { beta = xy - ra * Math.cos(theta); } else { beta = xy - ra * Math.sin(theta); } } if (type == 24) { double theta = 6 * Math.PI * t1 + dim * Math.PI / nvar; double xy = 2 * (x - 0.5); double ra = 0.8 * t1; if (css == 1) { beta = xy - ra * Math.cos(theta / 3); } else { beta = xy - ra * Math.sin(theta); } } if (type == 25) { double rho = 0.8; double phi = Math.PI * t1; double theta = 6 * Math.PI * t1 + dim * Math.PI / nvar; double xy = 2 * (x - 0.5); if (css == 1) { beta = xy - rho * Math.sin(phi) * Math.sin(theta); } else if (css == 2) { beta = xy - rho * Math.sin(phi) * Math.cos(theta); } else { beta = xy - rho * Math.cos(phi); } } if (type == 26) { double theta = 6 * Math.PI * t1 + dim * Math.PI / nvar; double ra = 0.3 * t1 * (t1 * Math.cos(4 * theta) + 2); double xy = 2 * (x - 0.5); if (css == 1) { beta = xy - ra * Math.cos(theta); } else { beta = xy - ra * Math.sin(theta); } } return beta; } // control the PS shapes of 3-D instances double psfunc3(double x, double t1, double t2, int dim, int type) { // type: the type of curve // css: the class of index double beta; beta = 0.0; dim++; if (type == 31) { double xy = 4 * (x - 0.5); double rate = 1.0 * dim / nvar; beta = xy - 4 * (t1 * t1 * rate + t2 * (1.0 - rate)) + 2; } if (type == 32) { double theta = 2 * Math.PI * t1 + dim * Math.PI / nvar; double xy = 4 * (x - 0.5); beta = xy - 2 * t2 * Math.sin(theta); } return beta; } void objective(List<Double> xVar, List<Double> yObj) { // 2-objective case if (nobj == 2) { if (ltype == 21 || ltype == 22 || ltype == 23 || ltype == 24 || ltype == 26) { double g = 0, h = 0, a, b; ArrayList<Double> aa = new ArrayList<Double>(); ArrayList<Double> bb = new ArrayList<Double>(); for (int n = 1; n < nvar; n++) { if (n % 2 == 0) { a = psfunc2(xVar.get(n), xVar.get(0), n, ltype, 1); // linkage aa.add(a); } else { b = psfunc2(xVar.get(n), xVar.get(0), n, ltype, 2); bb.add(b); } } g = betaFunction(aa, dtype); h = betaFunction(bb, dtype); double alpha[] = new double[2]; alphaFunction(alpha, xVar, 2, ptype); // shape function yObj.set(0, alpha[0] + h); yObj.set(1, alpha[1] + g); aa.clear(); bb.clear(); } if (ltype == 25) { double g = 0, h = 0, a, b; double /*e = 0,*/ c; ArrayList<Double> aa = new ArrayList<Double>(); ArrayList<Double> bb = new ArrayList<Double>(); for (int n = 1; n < nvar; n++) { if (n % 3 == 0) { a = psfunc2(xVar.get(n), xVar.get(0), n, ltype, 1); aa.add(a); } else if (n % 3 == 1) { b = psfunc2(xVar.get(n), xVar.get(0), n, ltype, 2); bb.add(b); } else { c = psfunc2(xVar.get(n), xVar.get(0), n, ltype, 3); if (n % 2 == 0) { aa.add(c); } else { bb.add(c); } } } g = betaFunction(aa, dtype); h = betaFunction(bb, dtype); double alpha[] = new double[2]; alphaFunction(alpha, xVar, 2, ptype); yObj.set(0, alpha[0] + h); yObj.set(1, alpha[1] + g); aa.clear(); bb.clear(); } } // 3-objective case if (nobj == 3) { if (ltype == 31 || ltype == 32) { double g = 0, h = 0, e = 0, a; ArrayList<Double> aa = new ArrayList<Double>(); ArrayList<Double> bb = new ArrayList<Double>(); ArrayList<Double> cc = new ArrayList<Double>(); for (int n = 2; n < nvar; n++) { a = psfunc3(xVar.get(n), xVar.get(0), xVar.get(1), n, ltype); if (n % 3 == 0) { aa.add(a); } else if (n % 3 == 1) { bb.add(a); } else { cc.add(a); } } g = betaFunction(aa, dtype); h = betaFunction(bb, dtype); e = betaFunction(cc, dtype); double alpha[] = new double[3]; alphaFunction(alpha, xVar, 3, ptype); yObj.set(0, alpha[0] + h); yObj.set(1, alpha[1] + g); yObj.set(2, alpha[2] + e); aa.clear(); bb.clear(); cc.clear(); } } } }