jMetal Variability: A Software Product Line Approach for the No-Code Configuration of Multi-Objective Metaheuristics
This repository provides an environment for managing, resolving variability, and evaluating the multi-objective optimization framework jMetal, integrated with Feature Models (in UVL format) through a derivation engine (variability engine).
- jMetal Variability: A Software Product Line Approach for the No-Code Configuration of Multi-Objective Metaheuristics
- Script Execution and Examples
- Implementation Best Practices to evolve the Feature Model and Jinja templates alongside the jMetal framework
jMetal Variability connects Software Product Line Engineering with multi-objective evolutionary algorithms such as NSGA-II. It enables:
- Defining variability using UVL (Universal Variability Language) feature models.
- Processing product configurations specified in JSON format.
- Automatically generating Java/Python source code from Jinja2 templates.
- Evaluating both the feature model and the templates.
- Java Development Kit (JDK): Version 22 or higher.
- Apache Maven: Version 3.8 or higher.
- Python: Version 3.10 or higher.
- Python packages:
flamapyuvengine
Clone and install the required version of jMetal into your local Maven repository (see below):
git clone https://github.com/jMetal/jMetal.git
cd jMetal
mvn clean install -Dgpg.skip=true -DskipTests=true
cd ..git clone https://github.com/jMetal/jmetal-variability.git
cd jmetal-variabilityEnsure that jmetal-var/pom.xml references the same jMetal version that you installed locally.
<dependency>
<groupId>org.uma.jmetal</groupId>
<artifactId>jmetal-core</artifactId>
<version>6.9.1</version>
</dependency>pip install flamapy uvenginejmetal-variability/
│
├── derivation_engine.py # Variability resolution engine
├── evaluation.py # Java source code analysis
├── evaluation_fm.py # Feature model analysis
│
├── uvengine_jMetal/ # UVEngine Python library
│
├── resources/
│ └── jmetal/
│ ├── fm_models/ # UVL feature models
│ ├── configurations/ # Product configurations (.uvl.json)
│ └── templates/ # Jinja2 templates
│
├── jmetal-var/ # Generated Java Maven project
│
└── diagrams/ # Architecture and class diagrams
| Component | Description |
|---|---|
derivation_engine.py |
Resolves a UVL configuration and generates Java/Python code from Jinja2 templates. |
evaluation.py |
Computes project metrics (files, classes, and LOC) for the jMetal framework. |
evaluation_fm.py |
Analyzes structural properties of the feature model using FlamaPy and Z3. |
uvengine_jMetal/ |
Python library implementing the variability resolution engine. |
resources/jmetal/fm_models/ |
UVL feature models. |
resources/jmetal/configurations/ |
Product configurations in JSON format. |
resources/jmetal/templates/ |
Jinja2 templates used during code generation. |
jmetal-var/ |
Maven project containing the generated algorithm variants. |
diagrams/ |
UML and architecture diagrams for documentation purpose. |
Resolves variability for a specific JSON configuration using a UVL feature model and generates the corresponding Java class.
python derivation_engine.py- Template:
resources/jmetal/templates/NSGAIIVar.java.jinja - UVL model:
resources/jmetal/fm_models/jMetal.uvl - Configuration:
resources/jmetal/configurations/NSGAIIDefaultConfiguration_Kursawe_scenario1.uvl.json
Computes project metrics, including the number of Java files, classes, and effective lines of code (excluding comments and blank lines).
python evaluation.py ./jmetal --exclude target testAnalyzes the UVL feature model using FlamaPy and Z3.
python evaluation_fm.pyCompile the generated project:
cd jmetal-var
mvn clean compileRun a generated algorithm:
mvn exec:java -Dexec.mainClass="com.example.AppExample"FUN.csv: Objective values of the non-dominated solutions.VAR.csv: Decision variable values.
Implementation Best Practices to evolve the Feature Model and Jinja templates alongside the jMetal framework
To facilitate variability management in jMetal operators:
All crossover / mutation operators should provide a constructor receiving the common parameter (e.g., crossoverProbability).
Additional parameters should preferably be configured through setter methods or optional overloaded constructors.
Whenever a parameter has a sensible default value (e.g., distributionIndex = 20.0), providing overloaded constructors is optional.