Skip to content

Commit a70f5fc

Browse files
committed
Add file AGENTS.md
1 parent ca94cf6 commit a70f5fc

9 files changed

Lines changed: 200 additions & 22 deletions

File tree

AGENTS.md

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# AGENTS
2+
3+
Guidance for humans and AI assistants collaborating on jMetalPy.
4+
5+
## Scope
6+
- Use agents for refactors, tests, docs, experiment scripts, and small utilities.
7+
- Avoid delegating API changes, licensing, or research conclusions without maintainer sign-off.
8+
- Keep changes scoped; prefer incremental PRs over broad rewrites.
9+
10+
## Safety and Privacy
11+
- Do not share credentials, private datasets, or unpublished results.
12+
- Assume no outbound network; request approval before downloads or package installs.
13+
- Avoid destructive commands (e.g., removing files, rewriting history). When in doubt, ask.
14+
- Work only inside the repository workspace.
15+
16+
## Coding Expectations
17+
- Follow `CODING_GUIDELINES.md` (typing, docstrings, Python 3.11+, testing).
18+
- English-only identifiers and comments; use ASCII unless the file already uses Unicode.
19+
- Prefer clarity over cleverness; keep functions small and focused.
20+
21+
## Tooling and Commands
22+
- Prefer `rg` for searches; summarize command output instead of dumping logs.
23+
- Run targeted `pytest`, `ruff`, and `mypy` for affected areas when feasible; note any tests not run.
24+
- Use `apply_patch` or minimal diffs; avoid auto-generated bulk changes unless requested.
25+
26+
## Interaction Style
27+
- Be concise, reference paths with backticks (e.g., `src/module.py:42`), and summarize results.
28+
- Explain rationale for non-obvious choices; add brief comments only when code needs context.
29+
- Never revert user changes unless explicitly asked.
30+
31+
## Pre-Submission Checklist
32+
- [ ] Changes comply with `CODING_GUIDELINES.md`.
33+
- [ ] Tests/lint/type checks run where relevant, with results noted.
34+
- [ ] No secrets or external data added; no destructive actions taken.
35+
- [ ] Summary of changes and affected files prepared for the reviewer.

README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ A paper introducing jMetalPy is available at: https://doi.org/10.1016/j.swevo.20
1313
- [Installation](#installation)
1414
- [Usage](#hello-world-)
1515
- [Hyperparameter Tuning](#hyperparameter-tuning-)
16+
- [Agents](#agents)
1617
- [Features](#features)
1718
- [Changelog](#changelog)
1819
- [License](#license)
@@ -209,6 +210,10 @@ print(f"Best score: {result.best_score}")
209210
print(f"Best params: {result.best_params}")
210211
```
211212

213+
## Agents
214+
215+
If you use AI assistants (e.g., Copilot, Codex) while working on this project, please follow the guidelines in [AGENTS.md](AGENTS.md).
216+
212217
### Available Example Configurations
213218

214219
| File | Description |

examples/multiobjective/nsgaii/nsgaii_distance_based_archive_linf.py

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,11 @@
22
from jmetal.operator.crossover import SBXCrossover
33
from jmetal.operator.mutation import PolynomialMutation
44
from jmetal.problem import ZDT4
5+
from jmetal.problem.multiobjective.dtlz import DTLZ1
56
from jmetal.util.archive import DistanceBasedArchive
67
from jmetal.util.distance import DistanceMetric
78
from jmetal.util.evaluator import SequentialEvaluatorWithArchive
9+
from jmetal.util.plotting import save_plt_to_file
810
from jmetal.util.solution import (
911
print_function_values_to_file,
1012
print_variables_to_file, read_solutions,
@@ -20,8 +22,8 @@
2022

2123
problem.reference_front = read_solutions(filename="resources/reference_fronts/ZDT4.pf")
2224

23-
# Create distance-based archive with size 100 using L-infinity distance metric
24-
archive = DistanceBasedArchive(maximum_size=100, metric=DistanceMetric.LINF)
25+
# Create distance-based archive
26+
archive = DistanceBasedArchive(maximum_size=100, metric=DistanceMetric.L2_SQUARED)
2527
evaluator = SequentialEvaluatorWithArchive(archive)
2628

2729
max_evaluations = 25000
@@ -40,9 +42,14 @@
4042
# Get solutions from the archive instead of the algorithm result
4143
front = evaluator.get_archive().solution_list
4244

43-
# Save results to file with specific suffix
44-
print_function_values_to_file(front, "FUN." + algorithm.label + ".LINF")
45-
print_variables_to_file(front, "VAR." + algorithm.label + ".LINF")
45+
# Save results to file
46+
print_function_values_to_file(front, "FUN." + algorithm.label)
47+
print_variables_to_file(front, "VAR." + algorithm.label)
48+
49+
# Save a PNG visualization of the front (and optional HTML if Plotly available)
50+
png = save_plt_to_file(front, "FUN." + algorithm.label, out_dir='.', html_plotly=True)
51+
print(f"Saved front plot to: {png}")
52+
4653

4754
print(f"Algorithm: {algorithm.get_name()}")
4855
print(f"Problem: {problem.name()}")

examples/multiobjective/nsgaii/nsgaii_standard_settings_with_crowding_distance_archive.py

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,11 +44,8 @@
4444
print_variables_to_file(front, "VAR." + algorithm.label)
4545

4646
# Save a PNG visualization of the front (and optional HTML if Plotly available)
47-
try:
48-
png = save_plt_to_file(front, "FUN." + algorithm.label, out_dir='.', html_plotly=True)
49-
print(f"Saved front plot to: {png}")
50-
except Exception as e:
51-
print(f"Warning: could not generate front plot: {e}")
47+
png = save_plt_to_file(front, "FUN." + algorithm.label, out_dir='.', html_plotly=True)
48+
print(f"Saved front plot to: {png}")
5249

5350
print(f"Algorithm: {algorithm.get_name()}")
5451
print(f"Problem: {problem.name()}")

examples/multiobjective/nsgaii/nsgaii_standard_settings_with_distance_based_archive.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,11 @@
6262
except Exception as e:
6363
print(f"Warning: could not generate front plot: {e}")
6464

65+
# Save a PNG visualization of the front (and optional HTML if Plotly available)
66+
png = save_plt_to_file(front, "FUN." + algorithm.label, out_dir='.', html_plotly=True)
67+
print(f"Saved front plot to: {png}")
68+
69+
6570
print(f"Algorithm: {algorithm.get_name()}")
6671
print(f"Problem: {problem.name()}")
6772
print(f"Archive size: {len(front)} solutions")

src/jmetal/tuning/cli/parallel.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -194,8 +194,6 @@ def main():
194194
seed = args.seed if args.seed is not None else config.seed
195195
population_size = args.population_size if args.population_size is not None else config.population_size
196196

197-
args = parser.parse_args()
198-
199197
# Build extra arguments to pass to workers
200198
extra_args = [
201199
"--trials", str(n_trials),

src/jmetal/tuning/tuning_parallel.py

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -385,12 +385,21 @@ def main():
385385
problems = None
386386

387387
# Apply config values with CLI overrides
388-
algorithm = args.algorithm if args.algorithm != "NSGAII" or config is None else config.algorithm
389-
total_trials = args.trials if config is None else config.n_trials
390-
max_evaluations = args.evaluations if config is None else config.n_evaluations
391-
sampler = args.sampler if config is None else config.sampler
392-
seed = args.seed if config is None else config.seed
393-
population_size = args.population_size if config is None else config.population_size
388+
# CLI arguments take precedence over config file
389+
if config is not None:
390+
algorithm = args.algorithm if args.algorithm != "NSGAII" else config.algorithm
391+
total_trials = args.trials if args.trials != NUMBER_OF_TRIALS else config.n_trials
392+
max_evaluations = args.evaluations if args.evaluations != TRAINING_EVALUATIONS else config.n_evaluations
393+
sampler = args.sampler if args.sampler != "tpe" else config.sampler
394+
seed = args.seed if args.seed != SEED else config.seed
395+
population_size = args.population_size if args.population_size != POPULATION_SIZE else config.population_size
396+
else:
397+
algorithm = args.algorithm
398+
total_trials = args.trials
399+
max_evaluations = args.evaluations
400+
sampler = args.sampler
401+
seed = args.seed
402+
population_size = args.population_size
394403

395404
# Create observers based on argument
396405
# Note: plot observer only enabled on worker 0 to show global progress

src/jmetalpy.egg-info/PKG-INFO

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,8 @@ A paper introducing jMetalPy is available at: https://doi.org/10.1016/j.swevo.20
105105
### Table of Contents
106106
- [Installation](#installation)
107107
- [Usage](#hello-world-)
108+
- [Hyperparameter Tuning](#hyperparameter-tuning-)
109+
- [Agents](#agents)
108110
- [Features](#features)
109111
- [Changelog](#changelog)
110112
- [License](#license)
@@ -193,6 +195,128 @@ plot_front.plot(front, label='NSGAII-ZDT1', filename='NSGAII-ZDT1', format='png'
193195

194196
<img src=docs/source/_static/NSGAII-ZDT1.png width=450 alt="Pareto front approximation">
195197

198+
## Hyperparameter Tuning 🎛️
199+
200+
jMetalPy includes an Optuna-based hyperparameter tuning system that allows you to automatically find optimal algorithm configurations.
201+
202+
### Quick Start
203+
204+
```python
205+
from jmetal.tuning import tune
206+
207+
# Basic tuning with default settings
208+
result = tune("NSGAII", n_trials=50)
209+
print(f"Best parameters: {result.best_params}")
210+
```
211+
212+
### Using YAML Configuration Files
213+
214+
The recommended way to configure tuning experiments is through YAML files:
215+
216+
```bash
217+
# Run with a configuration file
218+
python -m jmetal.tuning.cli.sequential --config examples/tuning/configs/default.yaml
219+
220+
# Override specific settings via CLI
221+
python -m jmetal.tuning.cli.sequential --config examples/tuning/configs/quick_demo.yaml --trials 30
222+
```
223+
224+
### Example YAML Configurations
225+
226+
**Quick Demo** (`examples/tuning/configs/quick_demo.yaml`):
227+
```yaml
228+
algorithm: NSGAII
229+
n_trials: 20
230+
n_evaluations: 5000
231+
232+
problems:
233+
- name: ZDT1
234+
reference_front: ZDT1.pf
235+
- name: ZDT2
236+
reference_front: ZDT2.pf
237+
```
238+
239+
**SBX-Only Configuration** (`examples/tuning/configs/sbx_only.yaml`):
240+
```yaml
241+
algorithm: NSGAII
242+
n_trials: 100
243+
n_evaluations: 10000
244+
245+
parameter_space:
246+
offspring_population_size:
247+
values: [50, 100, 150, 200]
248+
249+
crossover:
250+
type: sbx # Only explore SBX crossover
251+
probability: {min: 0.8, max: 1.0}
252+
distribution_index: {min: 5.0, max: 100.0}
253+
254+
mutation:
255+
type: polynomial # Only explore polynomial mutation
256+
probability_factor: {min: 0.5, max: 2.0}
257+
distribution_index: {min: 5.0, max: 100.0}
258+
```
259+
260+
**Narrow Search Space** (`examples/tuning/configs/narrow_search.yaml`):
261+
```yaml
262+
algorithm: NSGAII
263+
n_trials: 50
264+
265+
parameter_space:
266+
crossover:
267+
probability: {min: 0.9, max: 1.0}
268+
distribution_index: {min: 10.0, max: 30.0}
269+
mutation:
270+
probability_factor: {min: 0.8, max: 1.2}
271+
```
272+
273+
### Parallel Tuning
274+
275+
For large-scale tuning experiments, use parallel execution with PostgreSQL:
276+
277+
```bash
278+
# Launch 4 parallel workers
279+
python -m jmetal.tuning.cli.parallel --config examples/tuning/configs/default.yaml --workers 4
280+
281+
# With progress observer
282+
python -m jmetal.tuning.cli.parallel --config my_config.yaml --workers 8 --observer progress
283+
```
284+
285+
### Programmatic Usage with Custom Config
286+
287+
```python
288+
from jmetal.tuning import tune, TuningConfig
289+
290+
# Load configuration from YAML
291+
config = TuningConfig.from_yaml("my_config.yaml")
292+
293+
# Run tuning with config
294+
result = tune(
295+
algorithm=config.algorithm,
296+
problems=config.get_problems_as_tuples(),
297+
n_trials=config.n_trials,
298+
n_evaluations=config.n_evaluations,
299+
parameter_space=config.parameter_space,
300+
)
301+
302+
print(f"Best score: {result.best_score}")
303+
print(f"Best params: {result.best_params}")
304+
```
305+
306+
## Agents
307+
308+
If you use AI assistants (e.g., Copilot, Codex) while working on this project, please follow the guidelines in [AGENTS.md](AGENTS.md).
309+
310+
### Available Example Configurations
311+
312+
| File | Description |
313+
|------|-------------|
314+
| `default.yaml` | Standard ZDT benchmark with 100 trials |
315+
| `quick_demo.yaml` | Fast demo with 20 trials, 2 problems |
316+
| `sbx_only.yaml` | SBX crossover + polynomial mutation only |
317+
| `narrow_search.yaml` | Narrow parameter ranges for fine-tuning |
318+
| `dtlz_3obj.yaml` | DTLZ problems with 3 objectives |
319+
196320
## Features
197321
The current release of jMetalPy (v1.9.0) contains the following components:
198322

src/jmetalpy.egg-info/SOURCES.txt

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,9 @@ src/jmetal/problem/singleobjective/knapsack.py
6868
src/jmetal/problem/singleobjective/tsp.py
6969
src/jmetal/problem/singleobjective/unconstrained.py
7070
src/jmetal/tuning/__init__.py
71+
src/jmetal/tuning/config.py
7172
src/jmetal/tuning/tuning.py
73+
src/jmetal/tuning/tuning_config.py
7274
src/jmetal/tuning/tuning_parallel.py
7375
src/jmetal/tuning/_legacy/__init__.py
7476
src/jmetal/tuning/_legacy/nsgaii_optuna_tuning.py
@@ -84,10 +86,6 @@ src/jmetal/tuning/algorithms/nsgaii.py
8486
src/jmetal/tuning/cli/__init__.py
8587
src/jmetal/tuning/cli/parallel.py
8688
src/jmetal/tuning/cli/sequential.py
87-
src/jmetal/tuning/config/__init__.py
88-
src/jmetal/tuning/config/defaults.py
89-
src/jmetal/tuning/config/paths.py
90-
src/jmetal/tuning/config/problems.py
9189
src/jmetal/tuning/metrics/__init__.py
9290
src/jmetal/tuning/metrics/indicators.py
9391
src/jmetal/tuning/metrics/reference_fronts.py

0 commit comments

Comments
 (0)