From 10e63d46b5245ed0eb23a725e137482fac6b86ba Mon Sep 17 00:00:00 2001 From: Dave Hadka Date: Fri, 5 Apr 2024 19:05:20 -0600 Subject: [PATCH] Update to MOEAFramework 4.0 --- .classpath | 4 +- .github/workflows/ci.yml | 2 +- .github/workflows/stage.yml | 4 +- COPYING | 2 +- README.md | 4 +- pom.xml | 10 +-- .../java/org/moeaframework/gd/Example.java | 21 ++++++- .../java/org/moeaframework/gd/GDMOEAD.java | 63 ++++++++++--------- .../org/moeaframework/gd/GDMOEADProvider.java | 17 +++++ .../gd/GeneralizedDecomposition.java | 28 ++++----- .../moeaframework/gd/GDMOEADProviderTest.java | 17 +++++ 11 files changed, 110 insertions(+), 62 deletions(-) diff --git a/.classpath b/.classpath index 002ad57..7a9a105 100644 --- a/.classpath +++ b/.classpath @@ -9,6 +9,7 @@ + @@ -22,9 +23,10 @@ + - + diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f3028e7..4e70442 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -10,7 +10,7 @@ jobs: strategy: fail-fast: false matrix: - java: [ '8', '11', '16', '17', '18', '19', '20' ] + java: [ '17', '18', '19', '20', '21' ] steps: - uses: actions/checkout@v3 - name: Set up JDK ${{ matrix.java }} diff --git a/.github/workflows/stage.yml b/.github/workflows/stage.yml index 4d5c5cf..7ad75fc 100644 --- a/.github/workflows/stage.yml +++ b/.github/workflows/stage.yml @@ -25,10 +25,10 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - - name: Set up JDK 16 + - name: Set up JDK 17 uses: actions/setup-java@v3 with: - java-version: 16 + java-version: 17 distribution: temurin - name: Install required software run: | diff --git a/COPYING b/COPYING index 4469f22..024779c 100644 --- a/COPYING +++ b/COPYING @@ -1,4 +1,4 @@ -Copyright 2009-2022 David Hadka and other contributors. All rights reserved. +Copyright 2009-2024 David Hadka and other contributors. All rights reserved. The MOEA Framework is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by diff --git a/README.md b/README.md index 1346072..461c15c 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ Add the following dependency to your `pom.xml`: org.moeaframework gd - 1.2 + 2.0 ``` @@ -47,7 +47,7 @@ If unset, it will default to uniformly-spaced points generated using the Normal ## License -Copyright 2009-2022 David Hadka and other contributors. All rights reserved. +Copyright 2009-2024 David Hadka and other contributors. All rights reserved. The MOEA Framework is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by diff --git a/pom.xml b/pom.xml index c66c8ad..c0db6b8 100644 --- a/pom.xml +++ b/pom.xml @@ -31,15 +31,15 @@ UTF-8 - 8 - 8 + 17 + 17 org.moeaframework moeaframework - 3.2 + 4.0 provided @@ -58,13 +58,13 @@ commons-io commons-io - 2.11.0 + 2.15.1 provided org.apache.commons commons-lang3 - 3.12.0 + 3.14.0 provided diff --git a/src/main/java/org/moeaframework/gd/Example.java b/src/main/java/org/moeaframework/gd/Example.java index 08a86a0..8f29471 100644 --- a/src/main/java/org/moeaframework/gd/Example.java +++ b/src/main/java/org/moeaframework/gd/Example.java @@ -1,3 +1,20 @@ +/* Copyright 2009-2024 David Hadka + * + * This file is part of the MOEA Framework. + * + * The MOEA Framework 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. + * + * The MOEA Framework 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 the MOEA Framework. If not, see . + */ package org.moeaframework.gd; import org.moeaframework.Analyzer; @@ -21,8 +38,8 @@ public static void main(String[] args) { .withAlgorithm("MOEA/D") .runSeeds(50)); - // collect data for MOEA/D with Generalized Decomposition - by targeting the Pareto front - // points, we should get extremely close to the optimum + // collect data for MOEA/D with Generalized Decomposition - by targeting the Pareto front points, we should + // get extremely close to the optimum analyzer.addAll("GD-MOEA/D", executor .withAlgorithm("GD-MOEA/D") .withProperty("targets", "pf/DTLZ2.3D.pf") diff --git a/src/main/java/org/moeaframework/gd/GDMOEAD.java b/src/main/java/org/moeaframework/gd/GDMOEAD.java index e25e77a..a1218b1 100644 --- a/src/main/java/org/moeaframework/gd/GDMOEAD.java +++ b/src/main/java/org/moeaframework/gd/GDMOEAD.java @@ -1,22 +1,37 @@ +/* Copyright 2009-2024 David Hadka + * + * This file is part of the MOEA Framework. + * + * The MOEA Framework 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. + * + * The MOEA Framework 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 the MOEA Framework. If not, see . + */ package org.moeaframework.gd; import java.io.File; import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; import java.util.ArrayList; import java.util.List; import org.moeaframework.algorithm.MOEAD; import org.moeaframework.core.FrameworkException; import org.moeaframework.core.Population; -import org.moeaframework.core.PopulationIO; import org.moeaframework.core.Problem; import org.moeaframework.core.Solution; -import org.moeaframework.core.operator.RandomInitialization; +import org.moeaframework.core.initialization.RandomInitialization; import org.moeaframework.core.spi.OperatorFactory; import org.moeaframework.core.variable.RealVariable; -import org.moeaframework.util.io.CommentedLineReader; +import org.moeaframework.util.io.Resources; +import org.moeaframework.util.io.Resources.ResourceOption; import org.moeaframework.util.weights.NormalBoundaryDivisions; import org.moeaframework.util.weights.NormalBoundaryIntersectionGenerator; import org.moeaframework.util.weights.WeightGenerator; @@ -32,9 +47,8 @@ public GDMOEAD(Problem problem, String targets) { } public GDMOEAD(Problem problem, NormalBoundaryDivisions divisions) { - this(problem, - new GeneralizedDecomposition(new NormalBoundaryIntersectionGenerator( - problem.getNumberOfObjectives(), divisions))); + this(problem, new GeneralizedDecomposition(new NormalBoundaryIntersectionGenerator( + problem.getNumberOfObjectives(), divisions))); } public GDMOEAD(Problem problem, WeightGenerator weightGenerator) { @@ -50,35 +64,22 @@ public GDMOEAD(Problem problem, WeightGenerator weightGenerator) { } private static List loadTargets(String resource) { - Population population = null; - try { - File file = new File(resource); + File file = Resources.asFile(GDMOEAD.class, "/" + resource, ResourceOption.REQUIRED, + ResourceOption.TEMPORARY, ResourceOption.FILE); - if (file.exists()) { - population = PopulationIO.readObjectives(file); - } else { - try (InputStream input = GDMOEAD.class.getResourceAsStream("/" + resource)) { - if (input != null) { - population = PopulationIO.readObjectives(new CommentedLineReader(new InputStreamReader(input))); - } - } + Population population = Population.loadObjectives(file); + + List targets = new ArrayList(); + + for (Solution solution : population) { + targets.add(solution.getObjectives()); } + + return targets; } catch (IOException e) { throw new FrameworkException("failed to load " + resource, e); } - - if (population == null) { - throw new FrameworkException("could not find " + resource); - } - - List targets = new ArrayList(); - - for (Solution solution : population) { - targets.add(solution.getObjectives()); - } - - return targets; } } diff --git a/src/main/java/org/moeaframework/gd/GDMOEADProvider.java b/src/main/java/org/moeaframework/gd/GDMOEADProvider.java index c0f914f..7320cfd 100644 --- a/src/main/java/org/moeaframework/gd/GDMOEADProvider.java +++ b/src/main/java/org/moeaframework/gd/GDMOEADProvider.java @@ -1,3 +1,20 @@ +/* Copyright 2009-2024 David Hadka + * + * This file is part of the MOEA Framework. + * + * The MOEA Framework 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. + * + * The MOEA Framework 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 the MOEA Framework. If not, see . + */ package org.moeaframework.gd; import org.moeaframework.core.Algorithm; diff --git a/src/main/java/org/moeaframework/gd/GeneralizedDecomposition.java b/src/main/java/org/moeaframework/gd/GeneralizedDecomposition.java index 0140553..8a88ba0 100644 --- a/src/main/java/org/moeaframework/gd/GeneralizedDecomposition.java +++ b/src/main/java/org/moeaframework/gd/GeneralizedDecomposition.java @@ -1,4 +1,4 @@ -/* Copyright 2009-2022 David Hadka +/* Copyright 2009-2024 David Hadka * * This file is part of the MOEA Framework. * @@ -30,15 +30,13 @@ import com.joptimizer.optimizers.LPPrimalDualMethod; /** - * Generates weights used to find solutions near a given set of target points. - * Generalized decomposition determines the Chebychev scalarizing function - * weights that are used to attain solutions near the given target points. + * Generates weights used to find solutions near a given set of target points. Generalized decomposition determines + * the Chebychev scalarizing function weights that are used to attain solutions near the given target points. *

* References: *

    - *
  1. Giagkiozis, I., R. C. Purshouse, and P. J. Fleming (2013). - * "Generalized Decomposition." Evolutionary Multi-Criterion - * Optimization, 7th International Conference, pp. 428-442. + *
  2. Giagkiozis, I., R. C. Purshouse, and P. J. Fleming (2013). "Generalized Decomposition." Evolutionary + * Multi-Criterion Optimization, 7th International Conference, pp. 428-442. *
*/ public class GeneralizedDecomposition implements WeightGenerator { @@ -49,8 +47,7 @@ public class GeneralizedDecomposition implements WeightGenerator { private final List targets; /** - * Constructs a weight generator transforming the given weights into those - * defined by generalized decomposition. + * Constructs a weight generator transforming the given weights into those defined by generalized decomposition. * * @param generator the weight generator */ @@ -59,8 +56,8 @@ public GeneralizedDecomposition(WeightGenerator generator) { } /** - * Constructs a weight generator transforming the given target points into - * the required Chebychef scalaring function weights. + * Constructs a weight generator transforming the given target points into the required Chebychef scalarizing + * function weights. * * @param targets the target points normalized on the unit hypervolume */ @@ -86,8 +83,7 @@ public List generate() { } private static double[] solve_chebychev(double[] x) { - // This function uses JOptimizer to solve the following convex - // optimization problem: + // This function uses JOptimizer to solve the following convex optimization problem: // // minimize norm_inf(X*w) // subject to @@ -97,8 +93,7 @@ private static double[] solve_chebychev(double[] x) { // X is an n x n diagonal matrix // w is a n x 1 vector // - // norm_inf(X*w) is solved by introducing a slack variable, t, and - // adding constraints X*w <= t and X*w >= -t. + // norm_inf(X*w) is solved by introducing a slack variable, t, and adding constraints X*w <= t and X*w >= -t. // setup the standard form matrices for LP double[] c = new double[x.length + 1]; @@ -134,8 +129,7 @@ private static double[] solve_chebychev(double[] x) { } // use JOptimizer to solve the LP - ConvexMultivariateRealFunction[] inequalities = - new ConvexMultivariateRealFunction[4 * x.length]; + ConvexMultivariateRealFunction[] inequalities = new ConvexMultivariateRealFunction[4 * x.length]; for (int i = 0; i < 4 * x.length; i++) { inequalities[i] = new LinearMultivariateRealFunction(G[i], -h[i]); diff --git a/src/test/java/org/moeaframework/gd/GDMOEADProviderTest.java b/src/test/java/org/moeaframework/gd/GDMOEADProviderTest.java index 58c5905..0f2759d 100644 --- a/src/test/java/org/moeaframework/gd/GDMOEADProviderTest.java +++ b/src/test/java/org/moeaframework/gd/GDMOEADProviderTest.java @@ -1,3 +1,20 @@ +/* Copyright 2009-2024 David Hadka + * + * This file is part of the MOEA Framework. + * + * The MOEA Framework 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. + * + * The MOEA Framework 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 the MOEA Framework. If not, see . + */ package org.moeaframework.gd; import org.junit.Assert;