Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/ISSUE_TEMPLATE/bug_report.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ body:
id: version
attributes:
label: Unsga3 version / commit
placeholder: "0.1.2 or git SHA"
placeholder: "0.1.4 or git SHA"
validations:
required: true
- type: textarea
Expand Down
5 changes: 5 additions & 0 deletions .grok/skills/unsga3-oracle/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,11 @@ Repo root: Unsga3. Confirm `Unsga3.slnx` / `tools/OracleCompare` exist before ru
| Problem | Partitions | Pop | Gens | C# tournament |
|---------|------------|-----|------|----------------|
| zdt1 | 12 | 52 | 100 | default (`RankNicheDistance`) |
| zdt2 | 12 | 52 | **250** | `--pymoo-mode` (`PymooCompatible`) |
| dtlz2 | 12 | 92 | 150 | `--pymoo-mode` (`PymooCompatible`) |

ZDT2 **gens=100** is an early-stress snapshot (collapse on Bend, C#, and pymoo), not the quality bar. Quality protocol matches unsga3-bend A/B (gens=250, PymooCompatible). `RankNicheDistance` is an optional unpublished Wilcoxon ZDT2 mating mode — do not silently switch all ZDT defaults to it. ZDT1 and DTLZ2 unchanged.

IGD = **mean** nearest Euclidean distance (pymoo-compatible). Docs: `docs/EQUIVALENCE.md`, `docs/RESEARCH-STANDARDS.md`.

Requires: .NET 10 SDK; Python 3 + `pip install pymoo` for pymoo side / multi-seed.
Expand All @@ -31,8 +34,10 @@ Ask which mode if unclear; default **quick** when validating a small fix, **full
```powershell
dotnet build tools/OracleCompare -c Release
dotnet run --project tools/OracleCompare -c Release --no-build -- --problem zdt1 --partitions 12 --pop 52 --gens 100 --seed 1
dotnet run --project tools/OracleCompare -c Release --no-build -- --problem zdt2 --partitions 12 --pop 52 --seed 1 --pymoo-mode
dotnet run --project tools/OracleCompare -c Release --no-build -- --problem dtlz2 --partitions 12 --pop 92 --gens 150 --seed 1 --pymoo-mode
python tools/oracle/run_pymoo_oracle.py --problem zdt1 --partitions 12 --pop 52 --gens 100 --seed 1
python tools/oracle/run_pymoo_oracle.py --problem zdt2 --partitions 12 --pop 52 --seed 1
python tools/oracle/run_pymoo_oracle.py --problem dtlz2 --partitions 12 --pop 92 --gens 150 --seed 1
```

Expand Down
10 changes: 9 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/).

- Docs and XML comments describe `initialPopulation` and hybrid loops in generic terms (domain-adapter warm-start / grid-seed). No product-repo names.

## [0.1.4] — 2026-09-19

### Changed

- **ZDT2 oracle/smoke protocol:** quality bar is **gens=250** + `PymooCompatible` (docs and harness defaults). gens=100 is an early-stress snapshot (collapse on Bend, C#, and pymoo), not the quality bar. `RankNicheDistance` stays an optional unpublished Wilcoxon ZDT2 mating mode. ZDT1 (100) and DTLZ2 (150) unchanged. **No algorithm or public API change.** Matches [unsga3-bend](https://github.com/AppSprout-dev/unsga3-bend) A/B honesty.

## [0.1.3] — 2026-08-10

### Added
Expand Down Expand Up @@ -60,7 +66,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/).
- Benchmarks: ZDT1–4/6, DTLZ1–4/7, Sphere / Ackley / Rosenbrock
- Metrics: IGD, GD, 2-D HV; self-tests + GitHub Packages publish workflow

[Unreleased]: https://github.com/AppSprout-dev/Unsga3/compare/v0.1.2...HEAD
[Unreleased]: https://github.com/AppSprout-dev/Unsga3/compare/v0.1.4...HEAD
[0.1.4]: https://github.com/AppSprout-dev/Unsga3/compare/v0.1.3...v0.1.4
[0.1.3]: https://github.com/AppSprout-dev/Unsga3/compare/v0.1.2...v0.1.3
[0.1.2]: https://github.com/AppSprout-dev/Unsga3/compare/v0.1.1...v0.1.2
[0.1.1]: https://github.com/AppSprout-dev/Unsga3/compare/v0.1.0...v0.1.1
[0.1.0]: https://github.com/AppSprout-dev/Unsga3/releases/tag/v0.1.0
4 changes: 2 additions & 2 deletions CITATION.cff
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ keywords:
- C#
- .NET
license: MIT
version: 0.1.2
date-released: "2026-08-10"
version: 0.1.4
date-released: "2026-09-19"
references:
- type: article
authors:
Expand Down
3 changes: 3 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ dotnet run --project samples/BasicUsage -c Release
# single seed
dotnet run --project tools/OracleCompare -c Release -- --problem dtlz2 --partitions 12 --pop 92 --gens 150 --seed 1 --pymoo-mode
python tools/oracle/run_pymoo_oracle.py --problem dtlz2 --partitions 12 --pop 92 --gens 150 --seed 1
# ZDT2 quality protocol: omitted --gens is 250 + --pymoo-mode (matches unsga3-bend).
# --gens 100 is an early-stress snapshot. RankNicheDistance (omit --pymoo-mode) is optional.
dotnet run --project tools/OracleCompare -c Release -- --problem zdt2 --partitions 12 --pop 52 --seed 1 --pymoo-mode

# multi-seed Mann–Whitney / Wilcoxon (writes docs/WILCOXON-RESULTS.md)
python tools/oracle/run_multiseed_wilcoxon.py --problems zdt1 dtlz2 --seeds 15
Expand Down
2 changes: 1 addition & 1 deletion Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
<PackageProjectUrl>https://github.com/AppSprout-dev/Unsga3</PackageProjectUrl>
<RepositoryUrl>https://github.com/AppSprout-dev/Unsga3</RepositoryUrl>
<PackageTags>optimization;nsga;nsga3;unsga3;multi-objective;evolutionary;moea</PackageTags>
<Version>0.1.3</Version>
<Version>0.1.4</Version>
<PackageReadmeFile>README.md</PackageReadmeFile>

</PropertyGroup>
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

**U-NSGA-III** (Unified NSGA-III) for .NET — single-, multi-, and many-objective evolutionary optimization with Das–Dennis reference directions, SBX crossover, polynomial mutation, and **niching-based tournament selection** ([Seada & Deb, 2016](https://ieeexplore.ieee.org/document/7271063)).

> **v0.1.2** — production-usable core with pymoo-aligned normalization.
> **v0.1.4** — production-usable core with pymoo-aligned normalization. ZDT2 quality protocol is gens=250 (docs/defaults; no algorithm/API change).
> **15-seed IGD vs pymoo `UNSGA3`:** ZDT1 **median 0.053 vs 0.070** (we win; MWU *p*≈0.05); DTLZ2 **median 0.0045 vs 0.0028** (~1.6×, same order; pymoo still ahead).
> Details: [`docs/WILCOXON-RESULTS.md`](docs/WILCOXON-RESULTS.md) · single-seed notes: [`docs/ORACLE-RESULTS.md`](docs/ORACLE-RESULTS.md)

Expand Down Expand Up @@ -121,7 +121,7 @@ API docs used: [HTTP](https://docs.typesafe.ai/api.md) · [Python SDK](https://d
|-----|----------|
| [docs/ORACLE-RESULTS.md](docs/ORACLE-RESULTS.md) | Single-seed C# vs pymoo |
| [docs/WILCOXON-RESULTS.md](docs/WILCOXON-RESULTS.md) | Multi-seed Mann–Whitney / Wilcoxon |
| [docs/EQUIVALENCE.md](docs/EQUIVALENCE.md) | Protocol & intentional deltas |
| [docs/EQUIVALENCE.md](docs/EQUIVALENCE.md) | Protocol & intentional deltas (ZDT2 quality A/B = gens=250, `PymooCompatible`; matches unsga3-bend) |
| [docs/RESEARCH-STANDARDS.md](docs/RESEARCH-STANDARDS.md) | Literature + indicator standards |
| [docs/NOTICE.md](docs/NOTICE.md) | Attribution (papers + validation tools) |
| [docs/ROADMAP.md](docs/ROADMAP.md) | Near / medium term plan |
Expand Down
10 changes: 10 additions & 0 deletions docs/EQUIVALENCE.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,16 @@ See also **[RESEARCH-STANDARDS.md](RESEARCH-STANDARDS.md)** for the literature +
5. **Tolerance:** median IGD within ~1–2× of pymoo on ZDT/DTLZ is the practical bar.
15-seed: ZDT1 median **better** than pymoo (ratio 0.76, MWU n.s.); DTLZ2 median ~**1.6×** (pymoo still ahead).

Published A/B budgets (ZDT1 / DTLZ2 unchanged; ZDT2 matches unsga3-bend protocol honesty):

| Problem | Pop | Gens | Partitions | C# tournament (quality) |
|---------|-----|------|------------|-------------------------|
| ZDT1 | 52 | 100 | 12 | `RankNicheDistance` (published Wilcoxon) |
| ZDT2 | 52 | **250** | 12 | `PymooCompatible` (A/B quality) |
| DTLZ2 | 92 | 150 | 12 | `PymooCompatible` |

ZDT2 **gens=100** is an early-stress snapshot (collapse on Bend, C#, and pymoo), not the quality bar. `RankNicheDistance` on ZDT2 is an optional unpublished Wilcoxon mating mode — do not silently switch all ZDT defaults to it. C# has no published ZDT2 IGD / Wilcoxon table; do not invent one.

## Problems (must-pass)

| Class | Problems | M | In library |
Expand Down
11 changes: 11 additions & 0 deletions docs/ORACLE-RESULTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,21 @@ Reproduce:
# Python
pip install pymoo
python tools/oracle/run_pymoo_oracle.py --problem zdt1 --partitions 12 --pop 52 --gens 100 --seed 1
python tools/oracle/run_pymoo_oracle.py --problem zdt2 --partitions 12 --pop 52 --seed 1
python tools/oracle/run_pymoo_oracle.py --problem dtlz2 --partitions 12 --pop 92 --gens 150 --seed 1

# C#
dotnet run --project tools/OracleCompare -c Release -- --problem zdt1 --partitions 12 --pop 52 --gens 100 --seed 1
dotnet run --project tools/OracleCompare -c Release -- --problem zdt2 --partitions 12 --pop 52 --seed 1 --pymoo-mode
dotnet run --project tools/OracleCompare -c Release -- --problem dtlz2 --partitions 12 --pop 92 --gens 150 --seed 1 --pymoo-mode
```

Omitted `--gens` on `--problem zdt2` is **250** (quality protocol). `--gens 100` is an early-stress snapshot. ZDT1 stays 100; DTLZ2 stays 150.

### ZDT2 protocol honesty (matches unsga3-bend)

C# never published a hard ZDT2 oracle / Wilcoxon table. The unpublished Wilcoxon harness used **gens=100** and **`RankNicheDistance`**. That budget collapses on Bend, C#, and pymoo (axis pile near `f1≈0`). **gens=250 + `PymooCompatible`** is the quality A/B bar (15-seed: 0/15 collapse on both stacks; see [unsga3-bend PR #17](https://github.com/AppSprout-dev/unsga3-bend/pull/17) / `docs/ZDT2_COLLAPSE.md`). `RankNicheDistance` remains an **optional** Wilcoxon mating mode — do not silently switch all ZDT defaults to it. This repo does not invent a ZDT2 IGD table here.

## Results (seed=1)

| Problem | Settings | pymoo IGD | C# default IGD | C# `PymooCompatible` IGD | Verdict |
Expand Down Expand Up @@ -69,9 +77,12 @@ Deep-dive vs pymoo `HyperplaneNormalization` / `ReferenceDirectionSurvival` (pym
| Test | Bar |
|------|-----|
| ZDT1 seed=1, 100 gen, default tournament | IGD ≤ 1.5 × 0.0629 |
| ZDT2 seed=2, 250 gen, default `RankNicheDistance` | IGD &lt; 0.75 (loose CI smoke, not oracle parity) |
| DTLZ2 seed=1, 150 gen, pymoo-mode | IGD ≤ 3 × 0.00350 (currently ~1.15×) |
| DTLZ2 short smoke (80 gen) | IGD &lt; 0.15 |

ZDT2 quality A/B is gens=250 + `PymooCompatible` (not the loose smoke bar). ZDT1 / DTLZ2 shipping bars are unchanged.

## Known remaining deltas (intentional / minor)

| Item | Status |
Expand Down
5 changes: 4 additions & 1 deletion docs/RESEARCH-STANDARDS.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,12 @@ Typical ZDT: r = (1.1, 1.1). Always document r; never compare HV across differen
1. Same problem definition (bounds, n, evaluate)
2. Same Das–Dennis partitions → identical ref set size
3. Same pop, gens, SBX/PM η, p_m = 1/n
- ZDT1: pop=52, **gens=100**
- ZDT2 quality A/B: pop=52, **gens=250**, `PymooCompatible` (matches unsga3-bend). gens=100 is an early-stress snapshot, not the quality bar. `RankNicheDistance` is optional, not the ZDT2 default.
- DTLZ2: pop=92, **gens=150**, `PymooCompatible`
4. Fixed seed **or** 15–31 seeds → median + IQR IGD
5. Compare IGD (and HV for M=2) to pymoo `UNSGA3`
6. Shipping bar: median IGD within ~1–2% of pymoo on ZDT1/DTLZ2 (or non-inferior Wilcoxon)
6. Shipping bar: median IGD within ~1–2% of pymoo on ZDT1/DTLZ2 (or non-inferior Wilcoxon). ZDT2 has no published C# Wilcoxon table; quality budget is 250 gens.

Export path: dump final `F` as CSV from both sides; compute IGD in this library.

Expand Down
3 changes: 3 additions & 0 deletions docs/WILCOXON-RESULTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,11 @@ Generated by `tools/oracle/run_multiseed_wilcoxon.py`. IGD = mean nearest Euclid
| Problem | Pop | Gens | Partitions | C# tournament | Seeds |
|---------|-----|------|------------|---------------|-------|
| zdt1 | 52 | 100 | 12 | RankNicheDistance | 15 |
| zdt2 (quality A/B; not in this table) | 52 | **250** | 12 | PymooCompatible | — |
| dtlz2 | 92 | 150 | 12 | PymooCompatible | 15 |

ZDT2 **gens=100** is an early-stress snapshot, not the quality bar. C# never published a hard ZDT2 Wilcoxon table; the unpublished harness used gens=100 + `RankNicheDistance` (optional mating mode — do not silently switch all ZDT defaults to it). Quality protocol matches [unsga3-bend](https://github.com/AppSprout-dev/unsga3-bend) A/B honesty: gens=250 + `PymooCompatible`. ZDT1 and DTLZ2 numbers below are unchanged. Do not invent a ZDT2 IGD table here.

Hypothesis tests (α = 0.05, two-sided):

- **Mann–Whitney U** (Wilcoxon rank-sum): independent samples, H₀: same IGD distribution.
Expand Down
10 changes: 8 additions & 2 deletions tests/Unsga3.Tests/Benchmarks/IgdSmokeTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ namespace Unsga3.Tests.Benchmarks;
/// <summary>
/// Fixed-seed IGD smoke bars — not full pymoo equivalence (see docs/EQUIVALENCE.md).
/// Bounds are intentionally loose; tighten after oracle harness lands.
/// ZDT2 quality A/B is gens=250 + <see cref="TournamentMode.PymooCompatible"/>
/// (matches unsga3-bend). The ZDT2 smoke below keeps ctor-default
/// <see cref="TournamentMode.RankNicheDistance"/> and a loose IGD bar.
/// </summary>
public class IgdSmokeTests
{
Expand Down Expand Up @@ -40,10 +43,13 @@ public void Zdt2_runs_with_measurable_igd()
var problem = new Zdt2Problem();
var dirs = ReferenceDirections.DasDennis(2, 12);
var algo = new Unsga3Algorithm(dirs, populationSize: 52, seed: 2);
var result = algo.Run(problem, maxGenerations: 150);
var result = algo.Run(problem, maxGenerations: 250);
var obtained = result.NonDominatedSolutions.Select(i => i.Objectives).ToArray();
double igd = PerformanceIndicators.InvertedGenerationalDistance(obtained, ParetoFronts.Zdt2());
// ZDT2 non-convex; mean-IGD smoke bar (not oracle parity).
// Loose CI smoke, not oracle parity. Quality A/B is gens=250 + PymooCompatible
// (matches unsga3-bend). gens=100 is an early-stress snapshot (collapse on
// Bend, C#, and pymoo). This test keeps the ctor default RankNicheDistance
// (optional unpublished Wilcoxon ZDT2 mating mode) and IGD < 0.75.
Assert.True(igd < 0.75, $"ZDT2 IGD={igd}");
}

Expand Down
15 changes: 14 additions & 1 deletion tools/OracleCompare/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,16 @@
// Fixed-protocol C# side of the pymoo oracle (see tools/oracle/run_pymoo_oracle.py).
//
// dotnet run --project tools/OracleCompare -- --problem zdt1 --partitions 12 --pop 52 --gens 100 --seed 1 --pymoo-mode
// # ZDT2 quality protocol (matches unsga3-bend A/B): gens=250 + --pymoo-mode.
// # Omitted --gens on --problem zdt2 is 250. gens=100 is an early-stress snapshot.
// # RankNicheDistance (omit --pymoo-mode) is optional, not the ZDT2 A/B default.
// dotnet run --project tools/OracleCompare -- --problem zdt2 --partitions 12 --pop 52 --seed 1 --pymoo-mode

string problemName = "zdt1";
int partitions = 12;
int? pop = null;
int gens = 100;
bool gensExplicit = false;
int seed = 1;
bool pymooMode = false;
string? outDir = null;
Expand All @@ -26,13 +31,21 @@
case "--problem": problemName = args[++i]; break;
case "--partitions": partitions = int.Parse(args[++i], CultureInfo.InvariantCulture); break;
case "--pop": pop = int.Parse(args[++i], CultureInfo.InvariantCulture); break;
case "--gens": gens = int.Parse(args[++i], CultureInfo.InvariantCulture); break;
case "--gens":
gens = int.Parse(args[++i], CultureInfo.InvariantCulture);
gensExplicit = true;
break;
case "--seed": seed = int.Parse(args[++i], CultureInfo.InvariantCulture); break;
case "--pymoo-mode": pymooMode = true; break;
case "--out-dir": outDir = args[++i]; break;
}
}

// Quality protocol: ZDT2 A/B default is gens=250 (unsga3-bend honesty).
// ZDT1 stays 100; DTLZ2 callers still pass --gens 150. Explicit --gens always wins.
if (!gensExplicit && problemName.Equals("zdt2", StringComparison.OrdinalIgnoreCase))
gens = 250;

IProblem problem;
int m;
double[][] pf;
Expand Down
10 changes: 9 additions & 1 deletion tools/oracle/run_multiseed_wilcoxon.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@
Protocol matches docs/EQUIVALENCE.md and docs/RESEARCH-STANDARDS.md:
15 independent seeds (default), fixed SBX/PM/Das–Dennis settings.

ZDT2 quality protocol is gens=250 + PymooCompatible (matches unsga3-bend A/B).
gens=100 is an early-stress snapshot. RankNicheDistance (csharp_pymoo_mode=False)
is an optional unpublished Wilcoxon mating mode — not the ZDT2 A/B default.
ZDT1 and DTLZ2 budgets are unchanged.

Usage:
python tools/oracle/run_multiseed_wilcoxon.py
python tools/oracle/run_multiseed_wilcoxon.py --problems zdt1 dtlz2 --seeds 15 --skip-pymoo
Expand Down Expand Up @@ -38,7 +43,10 @@ class Protocol:

PROTOCOLS: dict[str, Protocol] = {
"zdt1": Protocol("zdt1", partitions=12, pop=52, gens=100, n_obj=2, csharp_pymoo_mode=False),
"zdt2": Protocol("zdt2", partitions=12, pop=52, gens=100, n_obj=2, csharp_pymoo_mode=False),
# Quality A/B (unsga3-bend honesty): 250 gens, PymooCompatible.
# Optional: csharp_pymoo_mode=False (RankNicheDistance) + gens=100 is the
# unpublished Wilcoxon ZDT2 mating snapshot — do not treat it as the default.
"zdt2": Protocol("zdt2", partitions=12, pop=52, gens=250, n_obj=2, csharp_pymoo_mode=True),
"dtlz2": Protocol("dtlz2", partitions=12, pop=92, gens=150, n_obj=3, csharp_pymoo_mode=True),
}

Expand Down
31 changes: 26 additions & 5 deletions tools/oracle/run_pymoo_oracle.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@
Usage:
python run_pymoo_oracle.py
python run_pymoo_oracle.py --problem zdt1 --partitions 12 --pop 52 --gens 100 --seed 1
python run_pymoo_oracle.py --problem zdt2 --partitions 12 --pop 52 --seed 1
# omitted --gens on zdt2 is 250 (quality protocol; matches unsga3-bend A/B).
# --gens 100 is an early-stress snapshot, not the quality bar.
"""
from __future__ import annotations

Expand All @@ -20,15 +23,33 @@
import numpy as np


def default_gens(problem: str) -> int:
"""Quality-protocol generations when --gens is omitted.

ZDT2 A/B default is 250 (unsga3-bend honesty). ZDT1 stays 100.
DTLZ2 stays 100 here so existing callers that omit --gens are unchanged;
the published DTLZ2 oracle still passes --gens 150.
"""
if problem == "zdt2":
return 250
return 100


def main() -> int:
p = argparse.ArgumentParser()
p.add_argument("--problem", default="zdt1", choices=["zdt1", "zdt2", "dtlz2"])
p.add_argument("--partitions", type=int, default=12)
p.add_argument("--pop", type=int, default=None, help="default = n_ref_dirs")
p.add_argument("--gens", type=int, default=100)
p.add_argument(
"--gens",
type=int,
default=None,
help="generations (default: zdt2=250, else 100; explicit value always wins)",
)
p.add_argument("--seed", type=int, default=1)
p.add_argument("--out-dir", type=Path, default=Path(__file__).resolve().parent / "out")
args = p.parse_args()
gens = args.gens if args.gens is not None else default_gens(args.problem)

try:
from pymoo.algorithms.moo.unsga3 import UNSGA3
Expand Down Expand Up @@ -56,12 +77,12 @@ def main() -> int:
algo = UNSGA3(ref_dirs, pop_size=pop)

print(f"pymoo UNSGA3 | problem={args.problem} M={n_obj} refs={len(ref_dirs)} "
f"pop={pop} gens={args.gens} seed={args.seed}")
f"pop={pop} gens={gens} seed={args.seed}")

res = minimize(
problem,
algo,
("n_gen", args.gens),
("n_gen", gens),
seed=args.seed,
verbose=False,
save_history=False,
Expand All @@ -71,7 +92,7 @@ def main() -> int:
igd = float(IGD(pf)(F))

args.out_dir.mkdir(parents=True, exist_ok=True)
stem = f"pymoo_{args.problem}_p{args.partitions}_pop{pop}_g{args.gens}_s{args.seed}"
stem = f"pymoo_{args.problem}_p{args.partitions}_pop{pop}_g{gens}_s{args.seed}"
f_path = args.out_dir / f"{stem}_F.csv"
meta_path = args.out_dir / f"{stem}_meta.json"
np.savetxt(f_path, F, delimiter=",")
Expand All @@ -83,7 +104,7 @@ def main() -> int:
"partitions": args.partitions,
"n_ref_dirs": int(len(ref_dirs)),
"pop_size": pop,
"n_gen": args.gens,
"n_gen": gens,
"seed": args.seed,
"n_solutions": int(F.shape[0]),
"igd": igd,
Expand Down
Loading