diff --git a/.github/workflows/check_python_package.yaml b/.github/workflows/check_python_package.yaml
index 5bd82ab..33262cb 100644
--- a/.github/workflows/check_python_package.yaml
+++ b/.github/workflows/check_python_package.yaml
@@ -14,7 +14,7 @@ jobs:
python-version: ["3.10", "3.11", "3.12", "3.13"]
runs-on: ${{matrix.runs-on}}
steps:
- - uses: actions/checkout@v6
+ - uses: actions/checkout@v7
with:
fetch-depth: 0
diff --git a/.github/workflows/new_problem_check.yml b/.github/workflows/new_problem_check.yml
index 88b198c..12773e1 100644
--- a/.github/workflows/new_problem_check.yml
+++ b/.github/workflows/new_problem_check.yml
@@ -13,10 +13,10 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
- uses: actions/checkout@v5
+ uses: actions/checkout@v7
- name: Set up Python
- uses: actions/setup-python@v4
+ uses: actions/setup-python@v6
with:
python-version: '3.x'
@@ -27,5 +27,5 @@ jobs:
- name: Run New Problem Check
run: |
- python utils/validate_yaml.py problems.yaml
+ uv run utils/validate_yaml.py problems.yaml
diff --git a/.github/workflows/run_to_html.yml b/.github/workflows/run_to_html.yml
index 2d28e87..cf449e1 100644
--- a/.github/workflows/run_to_html.yml
+++ b/.github/workflows/run_to_html.yml
@@ -13,7 +13,7 @@ jobs:
contents: write
steps:
- name: Checkout repository
- uses: actions/checkout@v5
+ uses: actions/checkout@v7
with:
ref: ${{ github.event.pull_request.head.ref }}
persist-credentials: true
diff --git a/OPL_form.csv b/OPL_form.csv
deleted file mode 100644
index 841b7d7..0000000
--- a/OPL_form.csv
+++ /dev/null
@@ -1,3 +0,0 @@
-Timestamp,Submitter Name,Submitter Email,Short name of Suite / Problem / Generator,Type,Types of input variables,Number of Input variables (number or range or 'scalable'),Number of Objectives (number or range or 'scalable'),Problem Characteristics [Constrained],Problem Characteristics [Dynamic],Problem Characteristics [Noisy],Problem Characteristics [Multi-modal],Problem Characteristics [Partial evaluations possible],Problem Characteristics [Multiple fidelities],Problem Source,Reference,Short description of problem(s),Do you wish to provide some more detailed information about the proposed problems?,Full name of suite,Constraint Properties,Number of constraints,Type of Dynamicism,Form of noise model,Type of noise space,Other noise properties,Description of multimodality,Citation / reference,Key challenges / characteristics,Scientific motivation for the proposed suite / problem / generator,Limitations of the proposed suite / problem / generator,Implemenation languages,Approximate time to evaluate a single solution (or times if e.g. multi-fidelity),Links to examples of usage of the proposed suite / problem / generator,Other relevant information,Feedback about the form
-16/10/2025 11:17:36,,,test,Single Problem,Continuous,1,1,Multi-modal,,,,,,Real-World Application,test,test,Yes (go to detailed information),,,,,,,,,,,,,,,,,
-26/11/2025 12:05:57,Anonymized,Anonymized,MECHBench,Problem Suite,Continuous,scalable',1,Present,Not Present,Not Present,Present,Not Present,Not Present,Real-World Application,https://github.com/BayesOptApp/MECHBench,"This is a set of problems with inspiration from Structural Mechanics Design Optimization. The suite comprises three physical models, from which the user may define different kind of problems which impact the final design output.",Yes (go to detailed information),MECHBench,Hard Constraints,1 or 2,None,None,None,None,Unstructured or non isotropic multimodality,https://arxiv.org/abs/2511.10821,Embeds physical simulations and is flexible and modular,Bridge the black-box optimization techniques to a Mechanical Design Problem which require these kinds of algorithms,"The models do not include fracture or damage mechanics, just plasticity.",Python,Times -> from 1 minute to 7 minutes,,,
\ No newline at end of file
diff --git a/docs/index.html b/docs/index.html
index 38384f7..e4b4df0 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -101,7 +101,7 @@
OPL – Optimisation problem library
|
Parameters of the modules of the Automatic Train Operation are optimized; Parameters for the trajectory planning (first module) are maximum velocity (v_max), weighting of objectives (energy, time, comfort) in planning (lambda_e, lambda_s, lambda_t), step width (ds), maximum lateral acceleration (aq_max); as control module a PID controller is implemented, where the ki and kp parameters are optimized. The objectives are minimizing travel time and energy consumption. The evaluation takes several minutes, because the pipeline includes also a simulation. |
|
- Carolin Mensendiek; Henrik Zeipel; Oliver Ludger Preuß; Moritz Vinzent Seiler; Walter Sextro; Heike Trautmann, https://doi.org/10.1145/3795101.3805368 | Multi-Objective Pipeline Optimisation and Configuration of Automatic Train Operation Trajectories |
+ Multi-Objective Pipeline Optimisation and Configuration of Automatic Train Operation Trajectories, Carolin Mensendiek; Henrik Zeipel; Oliver Ludger Preuß; Moritz Vinzent Seiler; Walter Sextro; Heike Trautmann, https://doi.org/10.1145/3795101.3805368 |
|
unimodal |
|
@@ -132,7 +132,7 @@ OPL – Optimisation problem library
>=2 |
2 |
|
- unknown | box |
+ box | unknown |
>=2 |
|
|
@@ -154,7 +154,7 @@ OPL – Optimisation problem library
|
BSO-toolbox |
C++ |
- {'1 second', '40 seconds'} |
+ {'40 seconds', '1 second'} |
https://github.com/TUe-excellent-buildings/BSO-toolbox |
Building Spatial Design toolbox (TU/e) |
|
@@ -214,7 +214,7 @@ OPL – Optimisation problem library
26 |
1 |
noisy |
- unknown | box |
+ box | unknown |
>=14 |
|
noisy |
@@ -661,7 +661,7 @@ OPL – Optimisation problem library
gen_ealain |
Ealain |
Generator |
- binary | integer | continuous |
+ binary | continuous | integer |
>=3 |
[1, 10, 2, 3, 4, 5, 6, 7, 8, 9] |
dynamic | multi-fidelity |
@@ -890,11 +890,11 @@ OPL – Optimisation problem library
|
>=1 |
|
- IOHexperimenter | MA-BBOB (IOHexperimenter) |
+ MA-BBOB (IOHexperimenter) | IOHexperimenter |
C++/Python |
|
- https://github.com/IOHprofiler/IOHexperimenter | https://github.com/IOHprofiler/IOHexperimenter/blob/master/example/Competitions/MA-BBOB/Example_MABBOB.ipynb |
- IOHprofiler experimenter framework | Example notebook for MA-BBOB in IOHexperimenter |
+ https://github.com/IOHprofiler/IOHexperimenter/blob/master/example/Competitions/MA-BBOB/Example_MABBOB.ipynb | https://github.com/IOHprofiler/IOHexperimenter |
+ Example notebook for MA-BBOB in IOHexperimenter | IOHprofiler experimenter framework |
|
|
|
@@ -1030,7 +1030,7 @@ OPL – Optimisation problem library
gen_randoptgen |
RandOptGen |
Generator |
- binary | integer | continuous |
+ binary | continuous | integer |
>=3 |
[1, 10, 2, 3, 4, 5, 6, 7, 8, 9] |
|
@@ -1194,7 +1194,7 @@ OPL – Optimisation problem library
suite_amvop |
AMVOP |
Suite |
- categorical | integer | continuous |
+ categorical | continuous | integer |
>=3 |
1 |
|
@@ -1525,7 +1525,7 @@ OPL – Optimisation problem library
continuous |
>=1 |
[10, 2, 3, 4, 5, 6, 7, 8, 9] |
- noisy |
+ |
|
|
|
@@ -1648,7 +1648,7 @@ OPL – Optimisation problem library
continuous |
>=1 |
[10, 2, 3, 4, 5, 6, 7, 8, 9] |
- dynamic | noisy |
+ |
unknown |
>=1 |
unknown |
@@ -1710,11 +1710,11 @@ OPL – Optimisation problem library
|
>=1 |
|
- IOHexperimenter | CEC2013 reference code |
+ CEC2013 reference code | IOHexperimenter |
C++/Python |
|
- https://github.com/IOHprofiler/IOHexperimenter | https://github.com/P-N-Suganthan/CEC2013 |
- IOHprofiler experimenter framework | Suganthan's reference implementation |
+ https://github.com/P-N-Suganthan/CEC2013 | https://github.com/IOHprofiler/IOHexperimenter |
+ Suganthan's reference implementation | IOHprofiler experimenter framework |
|
|
|
@@ -1833,11 +1833,11 @@ OPL – Optimisation problem library
|
>=1 |
|
- IOHexperimenter | CEC2022 reference code |
+ CEC2022 reference code | IOHexperimenter |
C++/Python |
|
- https://github.com/IOHprofiler/IOHexperimenter | https://github.com/P-N-Suganthan/2022-SO-BO |
- IOHprofiler experimenter framework | Suganthan's reference implementation |
+ https://github.com/P-N-Suganthan/2022-SO-BO | https://github.com/IOHprofiler/IOHexperimenter |
+ Suganthan's reference implementation | IOHprofiler experimenter framework |
|
|
|
@@ -1876,7 +1876,7 @@ OPL – Optimisation problem library
|
CFD test problem suite |
|
- {'15m', '30s'} |
+ {'30s', '15m'} |
https://bitbucket.org/arahat/cfd-test-problem-suite |
Expensive real-world CFD-based test problems |
|
@@ -1932,7 +1932,7 @@ OPL – Optimisation problem library
suite_cuter |
CUTEr |
Suite |
- binary | integer | continuous |
+ binary | continuous | integer |
>=3 |
1 |
|
@@ -1973,11 +1973,11 @@ OPL – Optimisation problem library
suite_cutest |
CUTEst |
Suite |
- binary | integer | continuous |
+ binary | continuous | integer |
>=3 |
1 |
|
- unknown | box |
+ box | unknown |
>=2 |
|
|
@@ -2178,11 +2178,11 @@ OPL – Optimisation problem library
suite_expobench |
EXPObench |
Suite |
- continuous | integer | categorical |
+ categorical | continuous | integer |
30-405 |
1 |
noisy |
- unknown | box |
+ box | unknown |
>=2 |
|
["observational", "real-life"] |
@@ -2204,7 +2204,7 @@ OPL – Optimisation problem library
10-135 |
EXPObench |
Python |
- {'80 seconds', '2 seconds'} |
+ {'2 seconds', '80 seconds'} |
https://github.com/AlgTUDelft/ExpensiveOptimBenchmark |
EXPensive Optimization benchmark library (wind farm layout, gas filter design, pipe shape, hyperparameter tuning, hospital simulation) |
|
@@ -2632,7 +2632,7 @@ OPL – Optimisation problem library
continuous |
>=1 |
[10, 2, 3, 4, 5, 6, 7, 8, 9] |
- noisy |
+ |
|
|
|
@@ -2696,7 +2696,7 @@ OPL – Optimisation problem library
|
MECHBench |
Python |
- {'1 minute', '7 minutes'} |
+ {'7 minutes', '1 minute'} |
https://github.com/BayesOptApp/MECHBench |
Structural mechanics design optimization benchmark |
|
@@ -2919,7 +2919,7 @@ OPL – Optimisation problem library
unknown |
0 |
2 |
- dynamic | noisy |
+ |
unknown |
>=1 |
unknown |
@@ -3039,7 +3039,7 @@ OPL – Optimisation problem library
suite_re |
RE |
Suite |
- integer | continuous |
+ continuous | integer |
4-14 |
[2, 3, 4, 5, 6, 7, 8, 9] |
|
@@ -3080,7 +3080,7 @@ OPL – Optimisation problem library
suite_rwmvop |
RWMVOP |
Suite |
- categorical | integer | continuous |
+ categorical | continuous | integer |
>=3 |
1 |
|
@@ -3165,7 +3165,7 @@ OPL – Optimisation problem library
continuous |
>=1 |
[10, 2, 3, 4, 5, 6, 7, 8, 9] |
- dynamic | noisy |
+ dynamic |
|
|
dynamic |
@@ -3247,7 +3247,7 @@ OPL – Optimisation problem library
continuous |
>=1 |
1 |
- noisy | multi-fidelity |
+ multi-fidelity | noisy |
unknown |
>=2 |
|
@@ -3270,7 +3270,7 @@ OPL – Optimisation problem library
|
TulipaEnergyModel.jl |
Julia / JuMP |
- {'minutes', 'hours'} |
+ {'hours', 'minutes'} |
https://tulipaenergy.github.io/TulipaEnergyModel.jl/stable/ | https://github.com/TulipaEnergy/Tulipa-OBZ-CaseStudy |
Large linear program for optimal investment and operation of energy systems |
|
diff --git a/docs/problems.html b/docs/problems.html
index fce6ed5..92dc2f8 100644
--- a/docs/problems.html
+++ b/docs/problems.html
@@ -75,7 +75,7 @@
|
Parameters of the modules of the Automatic Train Operation are optimized; Parameters for the trajectory planning (first module) are maximum velocity (v_max), weighting of objectives (energy, time, comfort) in planning (lambda_e, lambda_s, lambda_t), step width (ds), maximum lateral acceleration (aq_max); as control module a PID controller is implemented, where the ki and kp parameters are optimized. The objectives are minimizing travel time and energy consumption. The evaluation takes several minutes, because the pipeline includes also a simulation. |
|
- Carolin Mensendiek; Henrik Zeipel; Oliver Ludger Preuß; Moritz Vinzent Seiler; Walter Sextro; Heike Trautmann, https://doi.org/10.1145/3795101.3805368 | Multi-Objective Pipeline Optimisation and Configuration of Automatic Train Operation Trajectories |
+ Multi-Objective Pipeline Optimisation and Configuration of Automatic Train Operation Trajectories, Carolin Mensendiek; Henrik Zeipel; Oliver Ludger Preuß; Moritz Vinzent Seiler; Walter Sextro; Heike Trautmann, https://doi.org/10.1145/3795101.3805368 |
|
unimodal |
|
@@ -106,7 +106,7 @@
>=2 |
2 |
|
- unknown | box |
+ box | unknown |
>=2 |
|
|
@@ -128,7 +128,7 @@
|
BSO-toolbox |
C++ |
- {'1 second', '40 seconds'} |
+ {'40 seconds', '1 second'} |
https://github.com/TUe-excellent-buildings/BSO-toolbox |
Building Spatial Design toolbox (TU/e) |
|
@@ -188,7 +188,7 @@
26 |
1 |
noisy |
- unknown | box |
+ box | unknown |
>=14 |
|
noisy |
@@ -635,7 +635,7 @@
gen_ealain |
Ealain |
Generator |
- binary | integer | continuous |
+ binary | continuous | integer |
>=3 |
[1, 10, 2, 3, 4, 5, 6, 7, 8, 9] |
dynamic | multi-fidelity |
@@ -864,11 +864,11 @@
|
>=1 |
|
- IOHexperimenter | MA-BBOB (IOHexperimenter) |
+ MA-BBOB (IOHexperimenter) | IOHexperimenter |
C++/Python |
|
- https://github.com/IOHprofiler/IOHexperimenter | https://github.com/IOHprofiler/IOHexperimenter/blob/master/example/Competitions/MA-BBOB/Example_MABBOB.ipynb |
- IOHprofiler experimenter framework | Example notebook for MA-BBOB in IOHexperimenter |
+ https://github.com/IOHprofiler/IOHexperimenter/blob/master/example/Competitions/MA-BBOB/Example_MABBOB.ipynb | https://github.com/IOHprofiler/IOHexperimenter |
+ Example notebook for MA-BBOB in IOHexperimenter | IOHprofiler experimenter framework |
|
|
|
@@ -1004,7 +1004,7 @@
gen_randoptgen |
RandOptGen |
Generator |
- binary | integer | continuous |
+ binary | continuous | integer |
>=3 |
[1, 10, 2, 3, 4, 5, 6, 7, 8, 9] |
|
@@ -1168,7 +1168,7 @@
suite_amvop |
AMVOP |
Suite |
- categorical | integer | continuous |
+ categorical | continuous | integer |
>=3 |
1 |
|
@@ -1499,7 +1499,7 @@
continuous |
>=1 |
[10, 2, 3, 4, 5, 6, 7, 8, 9] |
- noisy |
+ |
|
|
|
@@ -1622,7 +1622,7 @@
continuous |
>=1 |
[10, 2, 3, 4, 5, 6, 7, 8, 9] |
- dynamic | noisy |
+ |
unknown |
>=1 |
unknown |
@@ -1684,11 +1684,11 @@
|
>=1 |
|
- IOHexperimenter | CEC2013 reference code |
+ CEC2013 reference code | IOHexperimenter |
C++/Python |
|
- https://github.com/IOHprofiler/IOHexperimenter | https://github.com/P-N-Suganthan/CEC2013 |
- IOHprofiler experimenter framework | Suganthan's reference implementation |
+ https://github.com/P-N-Suganthan/CEC2013 | https://github.com/IOHprofiler/IOHexperimenter |
+ Suganthan's reference implementation | IOHprofiler experimenter framework |
|
|
|
@@ -1807,11 +1807,11 @@
|
>=1 |
|
- IOHexperimenter | CEC2022 reference code |
+ CEC2022 reference code | IOHexperimenter |
C++/Python |
|
- https://github.com/IOHprofiler/IOHexperimenter | https://github.com/P-N-Suganthan/2022-SO-BO |
- IOHprofiler experimenter framework | Suganthan's reference implementation |
+ https://github.com/P-N-Suganthan/2022-SO-BO | https://github.com/IOHprofiler/IOHexperimenter |
+ Suganthan's reference implementation | IOHprofiler experimenter framework |
|
|
|
@@ -1850,7 +1850,7 @@
|
CFD test problem suite |
|
- {'15m', '30s'} |
+ {'30s', '15m'} |
https://bitbucket.org/arahat/cfd-test-problem-suite |
Expensive real-world CFD-based test problems |
|
@@ -1906,7 +1906,7 @@
suite_cuter |
CUTEr |
Suite |
- binary | integer | continuous |
+ binary | continuous | integer |
>=3 |
1 |
|
@@ -1947,11 +1947,11 @@
suite_cutest |
CUTEst |
Suite |
- binary | integer | continuous |
+ binary | continuous | integer |
>=3 |
1 |
|
- unknown | box |
+ box | unknown |
>=2 |
|
|
@@ -2152,11 +2152,11 @@
suite_expobench |
EXPObench |
Suite |
- continuous | integer | categorical |
+ categorical | continuous | integer |
30-405 |
1 |
noisy |
- unknown | box |
+ box | unknown |
>=2 |
|
["observational", "real-life"] |
@@ -2178,7 +2178,7 @@
10-135 |
EXPObench |
Python |
- {'80 seconds', '2 seconds'} |
+ {'2 seconds', '80 seconds'} |
https://github.com/AlgTUDelft/ExpensiveOptimBenchmark |
EXPensive Optimization benchmark library (wind farm layout, gas filter design, pipe shape, hyperparameter tuning, hospital simulation) |
|
@@ -2606,7 +2606,7 @@
continuous |
>=1 |
[10, 2, 3, 4, 5, 6, 7, 8, 9] |
- noisy |
+ |
|
|
|
@@ -2670,7 +2670,7 @@
|
MECHBench |
Python |
- {'1 minute', '7 minutes'} |
+ {'7 minutes', '1 minute'} |
https://github.com/BayesOptApp/MECHBench |
Structural mechanics design optimization benchmark |
|
@@ -2893,7 +2893,7 @@
unknown |
0 |
2 |
- dynamic | noisy |
+ |
unknown |
>=1 |
unknown |
@@ -3013,7 +3013,7 @@
suite_re |
RE |
Suite |
- integer | continuous |
+ continuous | integer |
4-14 |
[2, 3, 4, 5, 6, 7, 8, 9] |
|
@@ -3054,7 +3054,7 @@
suite_rwmvop |
RWMVOP |
Suite |
- categorical | integer | continuous |
+ categorical | continuous | integer |
>=3 |
1 |
|
@@ -3139,7 +3139,7 @@
continuous |
>=1 |
[10, 2, 3, 4, 5, 6, 7, 8, 9] |
- dynamic | noisy |
+ dynamic |
|
|
dynamic |
@@ -3221,7 +3221,7 @@
continuous |
>=1 |
1 |
- noisy | multi-fidelity |
+ multi-fidelity | noisy |
unknown |
>=2 |
|
@@ -3244,7 +3244,7 @@
|
TulipaEnergyModel.jl |
Julia / JuMP |
- {'minutes', 'hours'} |
+ {'hours', 'minutes'} |
https://tulipaenergy.github.io/TulipaEnergyModel.jl/stable/ | https://github.com/TulipaEnergy/Tulipa-OBZ-CaseStudy |
Large linear program for optimal investment and operation of energy systems |
|
diff --git a/form_processing/OPL_form.csv b/form_processing/OPL_form.csv
new file mode 100644
index 0000000..7dc00a8
--- /dev/null
+++ b/form_processing/OPL_form.csv
@@ -0,0 +1,3 @@
+Timestamp,Submitter Name,Submitter Email,Short name of Suite / Problem / Generator,Type,Types of input variables,Number of Input variables (number(s) or range or 'scalable'),Number of Objectives (number(s) or range or 'scalable'),Problem Characteristics [Constrained],Problem Characteristics [Dynamic],Problem Characteristics [Noisy],Problem Characteristics [Multi-modal],Problem Characteristics [Partial evaluations possible],Problem Characteristics [Multiple fidelities],Problem Source,Link to Implementation,Short description of problem(s),Do you wish to provide some more detailed information about the proposed problems?,Full name of suite,Constraint Properties,Number of constraints,Type of Dynamicism,Form of noise model,Type of noise space,Other noise properties,Description of multimodality,Citation / reference,Key challenges / characteristics,Scientific motivation for the proposed suite / problem / generator,Limitations of the proposed suite / problem / generator,Implemenation languages,Links to implementations,Approximate time to evaluate a single solution (or times if e.g. multi-fidelity),Links to examples of usage of the proposed suite / problem / generator,Other relevant information,Feedback about the form,Code example / instructions,Problem Characteristics [Objectives evaluated independently], [Row 1]
+x,,,test,Single Problem,Continuous,1,1,Multi-modal,,,,,,Real-World Application,test,test,Yes (go to detailed information),,,,,,,,,,,,,,,,,,,,,
+x,Anonymized,Anonymized,MECHBench,Problem Suite,Continuous,scalable',1,Present,Not Present,Not Present,Present,Not Present,Not Present,Real-World Application,https://github.com/BayesOptApp/MECHBench,"This is a set of problems with inspiration from Structural Mechanics Design Optimization. The suite comprises three physical models, from which the user may define different kind of problems which impact the final design output.",Yes (go to detailed information),MECHBench,Hard Constraints,1 or 2,None,None,None,None,Unstructured or non isotropic multimodality,https://arxiv.org/abs/2511.10821,Embeds physical simulations and is flexible and modular,Bridge the black-box optimization techniques to a Mechanical Design Problem which require these kinds of algorithms,"The models do not include fracture or damage mechanics, just plasticity.",Python,https://github.com/BayesOptApp/MECHBench,Times -> from 1 minute to 7 minutes,,,,,,
diff --git a/form_processing/Readme.md b/form_processing/Readme.md
new file mode 100644
index 0000000..8ec7eb3
--- /dev/null
+++ b/form_processing/Readme.md
@@ -0,0 +1,38 @@
+# CSV to YAML import
+
+This folder contains a small Python script that merges the content of the form-response CSV into the main OPL YAML file.
+
+## What it does
+
+- reads `OPL_form.csv`
+- converts each row into OPL schema objects
+- merges new entries into `../problems.yaml`
+- skips duplicate names and empty rows
+- validates the merged YAML before writing
+
+## Usage
+
+Run the script from the repository root or from this folder:
+
+```bash
+python form_processing/formresponse_to_yaml.py --csv form_processing/OPL_form.csv --existing-yaml problems.yaml --output-yaml problems.yaml
+```
+
+If you run it from inside `form_processing`, the defaults also work:
+
+```bash
+python formresponse_to_yaml.py
+```
+
+## Dry run
+
+Use dry-run mode to check the import without changing any files:
+
+```bash
+python form_processing/formresponse_to_yaml.py --dry-run
+```
+
+## Notes
+
+- The script keeps existing entries and only adds new ones.
+- It prints how many entries were added, how many implementations were added, and how many rows were skipped.
diff --git a/form_processing/formresponse_to_yaml.py b/form_processing/formresponse_to_yaml.py
new file mode 100644
index 0000000..83e51fd
--- /dev/null
+++ b/form_processing/formresponse_to_yaml.py
@@ -0,0 +1,681 @@
+from __future__ import annotations
+
+import argparse
+import re
+import unicodedata
+from pathlib import Path
+from types import UnionType
+from typing import Any, get_args, get_origin
+
+import pandas as pd
+import yaml
+
+from opltools.schema import (
+ Constraint,
+ ConstraintType,
+ Generator,
+ Implementation,
+ Library,
+ Link,
+ OPLType,
+ Problem,
+ Reference,
+ Suite,
+ ValueRange,
+ Variable,
+ VariableType,
+ YesNoSome,
+)
+
+
+COL_NAME = "Short name of Suite / Problem / Generator"
+COL_TYPE = "Type"
+COL_VARIABLE_TYPES = "Types of input variables"
+COL_DIM = "Number of Input variables (number or range or 'scalable')"
+COL_OBJECTIVES = "Number of Objectives (number or range or 'scalable')"
+COL_CONSTRAINED = "Problem Characteristics [Constrained]"
+COL_DYNAMIC = "Problem Characteristics [Dynamic]"
+COL_NOISY = "Problem Characteristics [Noisy]"
+COL_MULTIMODAL = "Problem Characteristics [Multi-modal]"
+COL_PARTIAL_EVAL = "Problem Characteristics [Partial evaluations possible]"
+COL_MULTI_FIDELITY = "Problem Characteristics [Multiple fidelities]"
+COL_OBJECTIVES_INDEPENDENT = "Problem Characteristics [Objectives evaluated independently]"
+COL_SOURCE = "Problem Source"
+COL_IMPL_LINK = "Link to Implementation"
+COL_DESCRIPTION = "Short description of problem(s)"
+COL_REFERENCE = "Citation / reference"
+COL_FULL_NAME = "Full name of suite"
+COL_CONSTRAINT_PROPERTIES = "Constraint Properties"
+COL_CONSTRAINT_COUNT = "Number of constraints"
+COL_DYNAMIC_TYPE = "Type of Dynamicism"
+COL_NOISE_MODEL = "Form of noise model"
+COL_NOISE_SPACE = "Type of noise space"
+COL_NOISE_OTHER = "Other noise properties"
+COL_MULTIMODAL_DESC = "Description of multimodality"
+COL_IMPL_LANG = "Implemenation languages"
+COL_IMPL_LINKS = "Links to implementations"
+COL_EVAL_TIME = "Approximate time to evaluate a single solution (or times if e.g. multi-fidelity)"
+COL_OTHER = "Other relevant information"
+
+NO_VALUE_MARKERS = {
+ "",
+ "-",
+ "n/a",
+ "na",
+ "none",
+ "not found",
+ "unknown",
+ "not public",
+ "implementation not freely available",
+}
+
+
+def normalize_text(value: Any) -> str:
+ if value is None:
+ return ""
+ if isinstance(value, float) and pd.isna(value):
+ return ""
+ return str(value).strip()
+
+
+def is_meaningful(value: Any) -> bool:
+ text = normalize_text(value)
+ return bool(text) and text.lower() not in NO_VALUE_MARKERS
+
+
+def split_values(value: Any) -> list[str]:
+ text = normalize_text(value)
+ if not text:
+ return []
+ parts = re.split(r"[,;\n|]+", text)
+ return [p.strip() for p in parts if p.strip()]
+
+
+def extract_urls(value: Any) -> list[str]:
+ text = normalize_text(value)
+ if not text:
+ return []
+ return re.findall(r"https?://[^\s,\])\"']+", text)
+
+
+def slugify(value: str) -> str:
+ normalized = unicodedata.normalize("NFKD", value).encode("ascii", "ignore").decode("ascii")
+ normalized = normalized.lower()
+ normalized = re.sub(r"[^a-z0-9]+", "_", normalized)
+ return normalized.strip("_") or "entry"
+
+
+def unique_id(prefix: str, name: str, used_ids: set[str]) -> str:
+ base = f"{prefix}{slugify(name)}"
+ if base not in used_ids:
+ used_ids.add(base)
+ return base
+
+ suffix = 2
+ while True:
+ candidate = f"{base}_{suffix}"
+ if candidate not in used_ids:
+ used_ids.add(candidate)
+ return candidate
+ suffix += 1
+
+
+def parse_yes_no_some(value: Any) -> YesNoSome | None:
+ text = normalize_text(value).lower()
+ if not text:
+ return None
+
+ # Normalize common punctuation variants to make matching robust.
+ text = re.sub(r"\s+", " ", text.replace("_", " ").replace("-", " ")).strip().lower()
+
+ if text in {"not present", "not available", "absent", "no", "n", "false", "none"}:
+ return YesNoSome.no
+ if text in {"present", "available", "yes", "y", "true"}:
+ return YesNoSome.yes
+ if text in {"some", "partial", "mixed", "depends"}:
+ return YesNoSome.some
+ if text in {"unknown", "?"}:
+ return YesNoSome.unknown
+
+ return None
+
+
+def parse_type(value: Any) -> OPLType:
+ text = normalize_text(value).lower()
+ if "suite" in text:
+ return OPLType.suite
+ if "generator" in text:
+ return OPLType.generator
+ return OPLType.problem
+
+
+def parse_scalar_set_or_range(value: Any) -> int | set[int] | ValueRange | None:
+ text = normalize_text(value)
+ if not text:
+ return None
+
+ lowered = text.lower()
+ numbers = [int(n) for n in re.findall(r"\d+", text)]
+
+ if "scalable" in lowered:
+ if len(numbers) >= 2:
+ return ValueRange(min=min(numbers), max=max(numbers))
+ if len(numbers) == 1:
+ return ValueRange(min=numbers[0], max=None)
+ return ValueRange(min=1, max=None)
+
+ if (" to " in lowered or "-" in lowered) and len(numbers) >= 2:
+ return ValueRange(min=min(numbers), max=max(numbers))
+
+ if " or " in lowered and numbers:
+ vals = set(numbers)
+ return next(iter(vals)) if len(vals) == 1 else vals
+
+ if len(numbers) == 1:
+ return numbers[0]
+ if len(numbers) > 1:
+ vals = set(numbers)
+ return next(iter(vals)) if len(vals) == 1 else vals
+ return None
+
+
+def parse_objectives(value: Any) -> set[int] | None:
+ text = normalize_text(value)
+ if not text:
+ return None
+ numbers = {int(n) for n in re.findall(r"\d+", text)}
+ return numbers or None
+
+
+def parse_variable_type(token: str) -> VariableType:
+ lowered = token.strip().lower()
+ if any(t in lowered for t in ["continuous", "real"]):
+ return VariableType.continuous
+ if any(t in lowered for t in ["integer", "ordinal", "int"]):
+ return VariableType.integer
+ if any(t in lowered for t in ["boolean", "binary", "bool"]):
+ return VariableType.binary
+ if any(t in lowered for t in ["categorical", "nominal", "category"]):
+ return VariableType.categorical
+ return VariableType.unknown
+
+
+def parse_variables(var_types_value: Any, dim_value: Any) -> set[Variable] | None:
+ type_tokens = split_values(var_types_value)
+ dim = parse_scalar_set_or_range(dim_value)
+
+ if not type_tokens:
+ return None
+
+ variables: set[Variable] = set()
+ for token in type_tokens:
+ variables.add(Variable(type=parse_variable_type(token), dim=dim))
+ return variables or None
+
+
+def parse_constraint_type(token: str) -> ConstraintType:
+ lowered = token.lower()
+ if "box" in lowered:
+ return ConstraintType.box
+ if "linear" in lowered:
+ return ConstraintType.linear
+ if "function" in lowered or "nonlinear" in lowered:
+ return ConstraintType.function
+ return ConstraintType.unknown
+
+
+def parse_constraint_yesnosome_from_properties(
+ property_tokens: list[str],
+ positive_terms: tuple[str, ...],
+ negative_terms: tuple[str, ...],
+) -> YesNoSome | None:
+ if not property_tokens:
+ return None
+
+ lowered = [token.lower() for token in property_tokens]
+
+ def _matches_term(token: str, term: str) -> bool:
+ # Non-word terms (like <=) are matched as substrings; words use boundaries.
+ if not re.search(r"\w", term):
+ return term in token
+ pattern = rf"\b{re.escape(term.strip())}\b"
+ return re.search(pattern, token) is not None
+
+ has_positive = any(any(_matches_term(token, term) for term in positive_terms) for token in lowered)
+ has_negative = any(any(_matches_term(token, term) for term in negative_terms) for token in lowered)
+
+ if has_positive and has_negative:
+ return YesNoSome.some
+ if has_positive:
+ return YesNoSome.yes
+ if has_negative:
+ return YesNoSome.no
+ return None
+
+
+def parse_constraints(row: dict[str, Any]) -> set[Constraint] | None:
+ constrained = parse_yes_no_some(row.get(COL_CONSTRAINED))
+ if constrained == YesNoSome.no:
+ # Explicitly encode unconstrained problems as an empty set.
+ return set()
+ if constrained is None:
+ return None
+
+ number = parse_scalar_set_or_range(row.get(COL_CONSTRAINT_COUNT))
+ property_tokens = split_values(row.get(COL_CONSTRAINT_PROPERTIES))
+
+ hard = parse_constraint_yesnosome_from_properties(
+ property_tokens=property_tokens,
+ positive_terms=("hard",),
+ negative_terms=("soft",),
+ )
+ equality = parse_constraint_yesnosome_from_properties(
+ property_tokens=property_tokens,
+ positive_terms=("equality", "equal", "==", "eq"),
+ negative_terms=("inequality", "inequal", "<", ">", "<=", ">="),
+ )
+
+ types = {parse_constraint_type(t) for t in property_tokens if t.strip()}
+ if not types:
+ types = {ConstraintType.unknown}
+
+ constraints: set[Constraint] = set()
+ for ctype in types:
+ constraints.add(Constraint(type=ctype, hard=hard, equality=equality, number=number))
+ return constraints
+
+
+def parse_source(value: Any) -> set[str] | None:
+ text = normalize_text(value).lower()
+ if not text:
+ return None
+ if "real" in text:
+ return {"real-world"}
+ if "artificial" in text:
+ return {"artificial"}
+ return {normalize_text(value)}
+
+
+def parse_modality(simple_value: Any, detail_value: Any) -> set[str] | None:
+ flag = parse_yes_no_some(simple_value)
+ if flag == YesNoSome.yes:
+ detailed = split_values(detail_value)
+ return {d.lower() for d in detailed} or {"multimodal"}
+ if flag == YesNoSome.no:
+ return {"unimodal"}
+ return None
+
+
+def parse_dynamic_type(simple_value: Any, detail_value: Any) -> set[str] | None:
+ flag = parse_yes_no_some(simple_value)
+ if flag == YesNoSome.no:
+ return {"none"}
+ if flag == YesNoSome.yes:
+ detailed = split_values(detail_value)
+ return {d.lower() for d in detailed} or {"dynamic"}
+ return None
+
+
+def parse_noise_type(simple_value: Any, model_value: Any, space_value: Any, other_value: Any) -> set[str] | None:
+ flag = parse_yes_no_some(simple_value)
+ if flag == YesNoSome.no:
+ return {"none"}
+ if flag != YesNoSome.yes:
+ return None
+
+ vals = split_values(model_value) + split_values(space_value) + split_values(other_value)
+ return {v.lower() for v in vals} or {"noisy"}
+
+
+def parse_fidelity_levels(value: Any) -> set[int] | None:
+ flag = parse_yes_no_some(value)
+ if flag == YesNoSome.yes:
+ return {1, 2}
+ if flag == YesNoSome.no:
+ return {1}
+ return None
+
+
+def parse_reference(value: Any, fallback_title: str) -> set[Reference] | None:
+ text = normalize_text(value)
+ if not is_meaningful(text):
+ return None
+
+ urls = extract_urls(text)
+ if urls:
+ return {Reference(title=fallback_title, authors=[], link=Link(url=urls[0]))}
+
+ return {Reference(title=text, authors=[])}
+
+
+def _union_contains_type(annotation: Any, target: type) -> bool:
+ origin = get_origin(annotation)
+ if origin in (UnionType,):
+ return any(_union_contains_type(arg, target) for arg in get_args(annotation))
+ # typing.Union may still appear depending on runtime typing machinery.
+ if str(origin) == "typing.Union":
+ return any(_union_contains_type(arg, target) for arg in get_args(annotation))
+ return annotation is target
+
+
+def _field_allows_set_of_str(model_cls: type, field_name: str) -> bool:
+ field = model_cls.model_fields.get(field_name)
+ if field is None:
+ return True
+
+ annotation = field.annotation
+ if _union_contains_type(annotation, set):
+ return True
+
+ origin = get_origin(annotation)
+ if origin is set:
+ args = get_args(annotation)
+ return not args or args == (str,)
+
+ for arg in get_args(annotation):
+ if get_origin(arg) is set:
+ sub_args = get_args(arg)
+ if not sub_args or sub_args == (str,):
+ return True
+
+ return False
+
+
+def parse_eval_time(value: Any, model_cls: type) -> set[str] | str | None:
+ parts = split_values(value)
+ cleaned = {p.strip() for p in parts if p.strip()}
+ if not cleaned:
+ return None
+
+ if _field_allows_set_of_str(model_cls, "evaluation_time"):
+ return cleaned
+
+ # Backward compatibility for schema variants where evaluation_time is a string.
+ return "; ".join(sorted(cleaned))
+
+
+def parse_implementation_requirements(primary_link_value: Any) -> str | None:
+ text = normalize_text(primary_link_value)
+ if not text:
+ return None
+ if extract_urls(text):
+ return None
+ if text.lower() in NO_VALUE_MARKERS:
+ return None
+ return text
+
+
+def make_implementation(row: dict[str, Any], thing_name: str, used_ids: set[str]) -> tuple[str, Implementation] | None:
+ impl_links = extract_urls(row.get(COL_IMPL_LINK)) + extract_urls(row.get(COL_IMPL_LINKS))
+ impl_links = list(dict.fromkeys(impl_links))
+
+ links = [Link(type="repository", url=url) for url in impl_links] or None
+ language = normalize_text(row.get(COL_IMPL_LANG)) or None
+ eval_time = parse_eval_time(row.get(COL_EVAL_TIME), Implementation)
+ requirements = parse_implementation_requirements(row.get(COL_IMPL_LINK))
+
+ has_info = any([links, language, eval_time, requirements])
+ if not has_info:
+ return None
+
+ impl_name = thing_name
+ impl_description = normalize_text(row.get(COL_DESCRIPTION)) or f"Implementation for {thing_name}"
+
+ impl = Implementation(
+ name=impl_name,
+ description=impl_description,
+ links=links,
+ language=language,
+ evaluation_time=eval_time,
+ requirements=requirements,
+ )
+ impl_id = unique_id("impl_", thing_name, used_ids)
+ return impl_id, impl
+
+
+def make_thing(row: dict[str, Any], used_ids: set[str]) -> tuple[str, Problem | Suite | Generator, tuple[str, Implementation] | None] | None:
+ name = normalize_text(row.get(COL_NAME))
+ if not name:
+ return None
+
+ opl_type = parse_type(row.get(COL_TYPE))
+ obj = parse_objectives(row.get(COL_OBJECTIVES))
+ variables = parse_variables(row.get(COL_VARIABLE_TYPES), row.get(COL_DIM))
+ constraints = parse_constraints(row)
+ source = parse_source(row.get(COL_SOURCE))
+ modality = parse_modality(row.get(COL_MULTIMODAL), row.get(COL_MULTIMODAL_DESC))
+ dynamic_type = parse_dynamic_type(row.get(COL_DYNAMIC), row.get(COL_DYNAMIC_TYPE))
+ noise_type = parse_noise_type(
+ row.get(COL_NOISY), row.get(COL_NOISE_MODEL), row.get(COL_NOISE_SPACE), row.get(COL_NOISE_OTHER)
+ )
+ partial = parse_yes_no_some(row.get(COL_PARTIAL_EVAL))
+ objectives_independent = parse_yes_no_some(row.get(COL_OBJECTIVES_INDEPENDENT))
+ fidelity_levels = parse_fidelity_levels(row.get(COL_MULTI_FIDELITY))
+ references = parse_reference(row.get(COL_REFERENCE), fallback_title=name)
+
+ long_name = normalize_text(row.get(COL_FULL_NAME)) or None
+ description = normalize_text(row.get(COL_DESCRIPTION)) or None
+
+ impl_data = make_implementation(row, name, used_ids)
+ implementations = {impl_data[0]} if impl_data else None
+
+ common_kwargs = dict(
+ name=name,
+ long_name=long_name,
+ description=description,
+ references=references,
+ implementations=implementations,
+ objectives=obj,
+ variables=variables,
+ constraints=constraints,
+ dynamic_type=dynamic_type,
+ noise_type=noise_type,
+ allows_partial_evaluation=partial,
+ can_evaluate_objectives_independently=objectives_independent,
+ modality=modality,
+ fidelity_levels=fidelity_levels,
+ evaluation_time=parse_eval_time(row.get(COL_EVAL_TIME), Problem),
+ source=source,
+ )
+
+ if is_meaningful(row.get(COL_OTHER)):
+ common_kwargs["tags"] = {"form-submission"}
+
+ if opl_type == OPLType.problem:
+ thing = Problem(**common_kwargs)
+ thing_id = unique_id("fn_", name, used_ids)
+ elif opl_type == OPLType.suite:
+ thing = Suite(**common_kwargs)
+ thing_id = unique_id("suite_", name, used_ids)
+ else:
+ thing = Generator(**common_kwargs)
+ thing_id = unique_id("gen_", name, used_ids)
+
+ return thing_id, thing, impl_data
+
+
+def load_existing_library(path: Path) -> dict[str, Problem | Suite | Generator | Implementation]:
+ if not path.exists():
+ return {}
+
+ with path.open("r", encoding="utf-8") as in_file:
+ raw = yaml.safe_load(in_file) or {}
+
+ # PyYAML interprets bare `yes` / `no` as booleans. Also, historical files may
+ # encode unknown as either `unknown` or `?` depending on schema version.
+ # Normalize values for fields that are modeled as YesNoSome enums.
+ yes_no_some_fields = {
+ "hard",
+ "equality",
+ "allows_partial_evaluation",
+ "can_evaluate_objectives_independently",
+ }
+
+ enum_values = {str(member.value).lower(): str(member.value) for member in YesNoSome}
+ unknown_target = enum_values.get("unknown") or enum_values.get("?")
+
+ def _normalize_yes_no_some_value(value: Any) -> Any:
+ if isinstance(value, bool):
+ return enum_values.get("yes") if value else enum_values.get("no")
+
+ if isinstance(value, str):
+ lowered = value.strip().lower()
+ if lowered in {"yes", "y", "true", "1", "present"}:
+ return enum_values.get("yes")
+ if lowered in {"no", "n", "false", "0", "not present"}:
+ return enum_values.get("no")
+ if lowered in {"some", "partial", "mixed", "depends"}:
+ return enum_values.get("some")
+ if lowered in {"unknown", "?"} and unknown_target is not None:
+ return unknown_target
+
+ return value
+
+ def _normalize_yes_no_some_bools(value: Any, key: str | None = None) -> Any:
+ if isinstance(value, dict):
+ return {k: _normalize_yes_no_some_bools(v, k) for k, v in value.items()}
+ if isinstance(value, list):
+ return [_normalize_yes_no_some_bools(v, key) for v in value]
+ if key in yes_no_some_fields:
+ normalized = _normalize_yes_no_some_value(value)
+ if normalized is not None:
+ return normalized
+ return value
+
+ raw = _normalize_yes_no_some_bools(raw)
+
+ library = Library.model_validate(raw)
+ return dict(library.root)
+
+
+def dump_library(path: Path, root: dict[str, Problem | Suite | Generator | Implementation]) -> None:
+ # model_dump(mode="json") converts enums and nested pydantic models to plain YAML-safe values.
+ serializable = {key: value.model_dump(mode="json") for key, value in root.items()}
+ with path.open("w", encoding="utf-8") as out_file:
+ yaml.safe_dump(serializable, out_file, sort_keys=True, allow_unicode=True)
+
+
+def convert(
+ csv_path: Path,
+ existing_yaml_path: Path,
+ output_yaml_path: Path,
+ dry_run: bool,
+ override: bool,
+) -> tuple[int, int, int]:
+ df = pd.read_csv(csv_path).fillna("")
+ existing_root = load_existing_library(existing_yaml_path)
+
+ used_ids = set(existing_root)
+ existing_names_to_ids: dict[str, set[str]] = {}
+ for existing_id, existing_thing in existing_root.items():
+ existing_names_to_ids.setdefault(existing_thing.name.casefold(), set()).add(existing_id)
+ new_names: set[str] = set()
+
+ added_things = 0
+ added_impls = 0
+ skipped_rows = 0
+
+ for row in df.to_dict(orient="records"):
+ name = normalize_text(row.get(COL_NAME))
+ if not name:
+ skipped_rows += 1
+ continue
+
+ if name.casefold() == "test":
+ skipped_rows += 1
+ continue
+
+ key_name = name.casefold()
+ if key_name in existing_names_to_ids:
+ if not override:
+ skipped_rows += 1
+ continue
+
+ # Remove previously stored entries with the same name so this row can replace them.
+ ids_to_remove = list(existing_names_to_ids[key_name])
+ for existing_id in ids_to_remove:
+ existing_thing = existing_root.pop(existing_id, None)
+ used_ids.discard(existing_id)
+ if existing_thing is None:
+ continue
+
+ # Remove old linked implementations so references stay clean when replacing.
+ implementations = getattr(existing_thing, "implementations", None)
+ if implementations:
+ for impl_id in list(implementations):
+ existing_root.pop(impl_id, None)
+ used_ids.discard(impl_id)
+
+ existing_names_to_ids.pop(key_name, None)
+ new_names.discard(key_name)
+ elif key_name in new_names:
+ skipped_rows += 1
+ continue
+
+ result = make_thing(row, used_ids)
+ if result is None:
+ skipped_rows += 1
+ continue
+
+ thing_id, thing, impl_data = result
+ existing_root[thing_id] = thing
+ existing_names_to_ids.setdefault(key_name, set()).add(thing_id)
+ added_things += 1
+ new_names.add(key_name)
+
+ if impl_data:
+ impl_id, impl = impl_data
+ existing_root[impl_id] = impl
+ existing_names_to_ids.setdefault(key_name, set()).add(impl_id)
+ added_impls += 1
+
+ # Validate merged result before writing.
+ Library(root=existing_root)
+
+ if not dry_run:
+ dump_library(output_yaml_path, existing_root)
+
+ return added_things, added_impls, skipped_rows
+
+
+def main() -> int:
+ parser = argparse.ArgumentParser(
+ description="Convert OPL form CSV rows into schema objects and merge into a YAML library."
+ )
+ parser.add_argument("--csv", default="OPL_form.csv", help="Input CSV file")
+ parser.add_argument(
+ "--existing-yaml",
+ default="../problems.yaml",
+ help="Existing OPL library YAML to merge into",
+ )
+ parser.add_argument(
+ "--output-yaml",
+ default="../problems.yaml",
+ help="Output YAML path (defaults to updating existing file)",
+ )
+ parser.add_argument(
+ "--override",
+ action="store_true",
+ help="Override existing YAML entries with same name using form data rows",
+ )
+ parser.add_argument("--dry-run", action="store_true", help="Validate conversion without writing")
+ args = parser.parse_args()
+
+ added_things, added_impls, skipped = convert(
+ csv_path=Path(args.csv),
+ existing_yaml_path=Path(args.existing_yaml),
+ output_yaml_path=Path(args.output_yaml),
+ dry_run=args.dry_run,
+ override=args.override,
+ )
+
+ print(f"Added entities: {added_things}")
+ print(f"Added implementations: {added_impls}")
+ print(f"Skipped rows: {skipped}")
+ if args.dry_run:
+ print("Dry-run mode: output file was not written.")
+ return 0
+
+
+if __name__ == "__main__":
+ raise SystemExit(main())
\ No newline at end of file
diff --git a/formresponse_to_yaml.py b/formresponse_to_yaml.py
deleted file mode 100644
index a9f8aef..0000000
--- a/formresponse_to_yaml.py
+++ /dev/null
@@ -1,99 +0,0 @@
-import pandas as pd
-import yaml
-
-csv_file = "responses_OPL.csv"
-yaml_file = "problems.yaml"
-
-
-translations = {
- # "Timestamp",
- # "Submitter Name",
- # "Submitter Email",
- "Short name of Suite / Problem / Generator" : "name",
- "Type" : "suite/generator/single",
- "Types of input variables" : "variable type",
- "Number of Input variables (number or range or 'scalable')" : "dimensionality",
- "Number of Objectives (number or range or 'scalable')" : "objectives",
- "Problem Characteristics [Constrained]":"constraints",
- "Problem Characteristics [Dynamic]":"dynamic",
- "Problem Characteristics [Noisy]":"noise",
- "Problem Characteristics [Multi-modal]":"multimodal",
- "Problem Characteristics [Multiple fidelities]":"multi-fidelity",
- "Problem Source":"source (real-world/artificial)",
- "Link to Implementation" :"implementation",
- "Short description of problem(s)":"textual description",
- "Citation / reference": "reference",
-}
-
-translations_other = {
- "Short name of Suite / Problem / Generator" : "name",
- "Other relevant information": "general",
- "Problem Characteristics [Partial evaluations possible]" :"partial evaluations",
- "Full name of suite" : "full name",
- "Constraint Properties" : "constraint properties",
- "Number of constraints" : "number of constraints",
- "Type of Dynamicism" : "type of dynamicism",
- "Form of noise model" : "form of noise model",
- "Type of noise space" : "type of noise space",
- "Other noise properties" : "other noise properties",
- "Description of multimodality" : "description of multimodality",
- "Key challenges / characteristics" : "key challenges / characteristics",
- "Scientific motivation for the proposed suite / problem / generator" : "scientific motivation",
- "Limitations of the proposed suite / problem / generator" : "limitations",
- "Implemenation languages" : "implementation languages",
- "Approximate time to evaluate a single solution (or times if e.g. multi-fidelity)" : "approximate evaluation time",
- "Links to examples of usage of the proposed suite / problem / generator" : "links to usage examples",
-}
-
-# Read the csv file
-data = pd.read_csv(csv_file)
-
-# Handle empty cells being read as 'NaN', by emptying them again
-data = data.fillna("")
-data_main = data.rename(columns=translations)
-data_main.drop(columns=[col for col in data_main.columns if col not in translations.values()], inplace=True)
-data_other = data.rename(columns=translations_other)
-data_other.drop(columns=[col for col in data_other.columns if col not in translations_other.values()], inplace=True)
-
-dict_main = data_main.to_dict(orient="records")
-dict_other = data_other.to_dict(orient="records")
-for dict_m, dict_o in zip(dict_main, dict_other):
- for k in list(dict_o.keys()):
- if dict_o[k] is None or dict_o[k] == "":
- dict_o.pop(k)
- elif dict_o[k] == "Present":
- dict_o[k] = 'yes'
- elif dict_o[k] == "Not Present":
- dict_o[k] = 'no'
- dict_o.pop("name") # Remove duplicate name entry
- for k in list(dict_m.keys()):
- if dict_m[k] is None or dict_m[k] == "":
- dict_m.pop(k)
- elif dict_m[k] == "Present":
- dict_m[k] = 'yes'
- elif dict_m[k] == "Not Present":
- dict_m[k] = 'no'
- dict_m['other info'] = dict_o
-
-with open(yaml_file) as in_file:
- data = pd.json_normalize(yaml.safe_load(in_file))
-# print(data['name'].tolist())
-existing_names = data['name'].tolist() + ['test']
-
-#Filter out entries already in the yaml file
-dict_new = []
-for d in dict_main:
- name = d['name']
- if name not in existing_names:
- dict_new.append(d)
-
-if len(dict_new) > 0:
-
- print(f"Number of new entries to add: {len(dict_new)}")
-
- # Write the yaml file
- with open(yaml_file, "a") as out_file:
- yaml.dump(dict_new, out_file,
- sort_keys=False) # Prevent columns being reordered alphabetically
-else:
- print("No new entries to add.")
\ No newline at end of file
diff --git a/problems.yaml b/problems.yaml
index fcc539c..c32939e 100644
--- a/problems.yaml
+++ b/problems.yaml
@@ -1,14 +1,21 @@
fn_ato:
- allows_partial_evaluation: no
+ allows_partial_evaluation: 'no'
can_evaluate_objectives_independently: null
code_examples: null
constraints:
- equality: null
- hard: yes
+ hard: 'yes'
number: null
type: box
- description: 'Parameters of the modules of the Automatic Train Operation are optimized; Parameters for the trajectory planning (first module) are maximum velocity (v_max), weighting of objectives (energy, time, comfort) in planning (lambda_e, lambda_s, lambda_t), step width (ds), maximum lateral acceleration (aq_max); as control module a PID controller is implemented, where the ki and kp parameters are optimized. The objectives are minimizing travel time and energy consumption. The evaluation takes several minutes, because the pipeline includes also a simulation.'
+ description: Parameters of the modules of the Automatic Train Operation are optimized;
+ Parameters for the trajectory planning (first module) are maximum velocity (v_max),
+ weighting of objectives (energy, time, comfort) in planning (lambda_e, lambda_s,
+ lambda_t), step width (ds), maximum lateral acceleration (aq_max); as control
+ module a PID controller is implemented, where the ki and kp parameters are optimized.
+ The objectives are minimizing travel time and energy consumption. The evaluation
+ takes several minutes, because the pipeline includes also a simulation.
dynamic_type: null
+ evaluation_time: null
fidelity_levels: null
implementations: null
instances: null
@@ -20,11 +27,18 @@ fn_ato:
objectives:
- 2
references:
- - authors: ["Carolin Mensendiek", "Henrik Zeipel", "Oliver Ludger Preuß", "Moritz Vinzent Seiler", "Walter Sextro", "Heike Trautmann"]
+ - authors:
+ - Carolin Mensendiek
+ - Henrik Zeipel
+ - Oliver Ludger Preuß
+ - Moritz Vinzent Seiler
+ - Walter Sextro
+ - Heike Trautmann
link:
type: null
url: https://doi.org/10.1145/3795101.3805368
- - title: "Multi-Objective Pipeline Optimisation and Configuration of Automatic Train Operation Trajectories"
+ title: Multi-Objective Pipeline Optimisation and Configuration of Automatic Train Operation Trajectories
+ type: null
source:
- real-world
tags: null
@@ -33,26 +47,25 @@ fn_ato:
- dim: 10
type: continuous
fn_building_spatial:
- allows_partial_evaluation: no
+ allows_partial_evaluation: 'no'
can_evaluate_objectives_independently: null
code_examples: null
constraints:
- equality: null
- hard: yes
+ hard: 'yes'
number: null
- type: box
+ type: unknown
- equality: null
- hard: yes
+ hard: 'yes'
number: null
- type: unknown
- description: Optimise the spatial layout of a building to minimise energy
- consumption for climate control and minimise the strain on the structure.
- Many hard constraints; mixed-variable (continuous+binary); expensive
- evaluations.
+ type: box
+ description: Optimise the spatial layout of a building to minimise energy consumption
+ for climate control and minimise the strain on the structure. Many hard constraints;
+ mixed-variable (continuous+binary); expensive evaluations.
dynamic_type: null
evaluation_time:
- - 40 seconds
- 1 second
+ - 40 seconds
fidelity_levels: null
implementations:
- impl_bso_toolbox
@@ -124,28 +137,44 @@ fn_convex_dtlz2:
min: 1
type: continuous
fn_emdo:
- allows_partial_evaluation: no
+ allows_partial_evaluation: 'no'
can_evaluate_objectives_independently: null
code_examples: null
constraints:
- equality: null
- hard: yes
- number: 12
- type: unknown
+ hard: 'yes'
+ number: null
+ type: box
- equality: null
hard: some
number: null
type: unknown
- equality: null
- hard: yes
- number: null
- type: box
- description: "# Goal\nFind a design of a synchronous electric motor for power steering
- systems that minimizes costs and satisfies all constraints.\n\n# Motivation\n\
- Challenging to find good solutions in a limited time.\n\n# Key Challenges\n* Time-consuming
- solution evaluation\n* Highly-constrained problem\n* Constraints are multimodal\n\
- \nThis is not an available problem, but could be interesting to show to researchers
- which difficulties appear in real-world problems."
+ hard: 'yes'
+ number: 12
+ type: unknown
+ description: '# Goal
+
+ Find a design of a synchronous electric motor for power steering systems that
+ minimizes costs and satisfies all constraints.
+
+
+ # Motivation
+
+ Challenging to find good solutions in a limited time.
+
+
+ # Key Challenges
+
+ * Time-consuming solution evaluation
+
+ * Highly-constrained problem
+
+ * Constraints are multimodal
+
+
+ This is not an available problem, but could be interesting to show to researchers
+ which difficulties appear in real-world problems.'
dynamic_type: null
evaluation_time:
- 8 minutes
@@ -176,17 +205,17 @@ fn_emdo:
tags: null
type: problem
variables:
- - dim: 13
- type: integer
- dim: 13
type: continuous
+ - dim: 13
+ type: integer
fn_fleetopt:
- allows_partial_evaluation: yes
+ allows_partial_evaluation: 'yes'
can_evaluate_objectives_independently: null
code_examples: null
constraints:
- equality: null
- hard: yes
+ hard: 'yes'
number: null
type: unknown
description: 'UK healthcare organisation fleet optimisation: reduce the fleet of
@@ -225,14 +254,14 @@ fn_gasoline:
code_examples: null
constraints:
- equality: null
- hard: yes
+ hard: 'yes'
number: 5
type: unknown
- description: Multi-objective optimization to minimize fuel consumption and NOx
- emissions over a two-minute dynamic duty cycle, subject to five constraints
- (turbine inlet temperature, knock occurrences, peak cylinder pressure, peak
- cylinder pressure rise, total work). Seven decision variables cover hardware
- choices and engine control parameters.
+ description: Multi-objective optimization to minimize fuel consumption and NOx emissions
+ over a two-minute dynamic duty cycle, subject to five constraints (turbine inlet
+ temperature, knock occurrences, peak cylinder pressure, peak cylinder pressure
+ rise, total work). Seven decision variables cover hardware choices and engine
+ control parameters.
dynamic_type: null
evaluation_time: []
fidelity_levels:
@@ -259,10 +288,10 @@ fn_gasoline:
tags: null
type: problem
variables:
- - dim: 7
- type: integer
- dim: 7
type: continuous
+ - dim: 7
+ type: integer
fn_invdeceptive_deceptive_rotell:
allows_partial_evaluation: null
can_evaluate_objectives_independently: null
@@ -346,7 +375,7 @@ fn_jsec2019:
code_examples: null
constraints:
- equality: null
- hard: yes
+ hard: 'yes'
number: 22
type: unknown
description: expensive evaluations 3s; 22 constraints
@@ -371,8 +400,7 @@ fn_jsec2019:
- authors: []
link:
type: null
- url:
- http://www.jpnsec.org/files/competition2019/EC-Symposium-2019-Competition-English.html
+ url: http://www.jpnsec.org/files/competition2019/EC-Symposium-2019-Competition-English.html
title: JPNSEC EC-Symposium 2019 competition
type: null
source:
@@ -462,7 +490,7 @@ fn_radar_waveform:
code_examples: null
constraints:
- equality: null
- hard: yes
+ hard: 'yes'
number: null
type: unknown
description: null
@@ -495,24 +523,25 @@ fn_radar_waveform:
min: 4
type: integer
gen_beacon:
- allows_partial_evaluation: no
+ allows_partial_evaluation: 'no'
can_evaluate_objectives_independently: null
code_examples: null
constraints:
- equality: null
- hard: yes
+ hard: 'yes'
number: 0
type: box
- description: Generator for bi-objective benchmark problems with explicitly
- controlled correlations in continuous spaces. Multimodal with random
- structure.
+ description: Generator for bi-objective benchmark problems with explicitly controlled
+ correlations in continuous spaces. Multimodal with random structure.
dynamic_type: null
- evaluation_time: null
+ evaluation_time:
+ - negligible
fidelity_levels: null
implementations:
- impl_beacon
- long_name: Continuous Bi-objective Benchmark problems with Explicit Adjustable
- COrrelatioN control
+ instances: null
+ long_name: Continuous Bi-objective Benchmark problems with Explicit Adjustable COrrelatioN
+ control
modality:
- multimodal
name: BEACON
@@ -536,23 +565,23 @@ gen_beacon:
min: 1
type: continuous
gen_bono_bench:
- allows_partial_evaluation: no
+ allows_partial_evaluation: 'no'
can_evaluate_objectives_independently: null
code_examples: null
constraints:
- equality: null
- hard: yes
+ hard: 'yes'
number: null
type: box
- description: Bi-objective problem generator and suite with scalable continuous
- decision space. Features complex problem properties and Pareto front
- approximations with error guarantees for the hypervolume and exact R2
- indicators.
+ description: Bi-objective problem generator and suite with scalable continuous decision
+ space. Features complex problem properties and Pareto front approximations with
+ error guarantees for the hypervolume and exact R2 indicators.
dynamic_type: null
- evaluation_time: null
+ evaluation_time: []
fidelity_levels: null
implementations:
- impl_bonobench
+ instances: null
long_name: Bi-objective Numerical Optimization Benchmark
modality:
- multimodal
@@ -582,12 +611,13 @@ gen_ealain:
description: Real-world-like, easily extensible to increase complexity
dynamic_type:
- optional
- evaluation_time: null
+ evaluation_time: []
fidelity_levels:
- 1
- 2
implementations:
- impl_ealain
+ instances: null
long_name: null
modality: null
name: Ealain
@@ -622,11 +652,11 @@ gen_ealain:
- dim:
max: null
min: 1
- type: binary
+ type: integer
- dim:
max: null
min: 1
- type: integer
+ type: binary
gen_gnbg:
allows_partial_evaluation: null
can_evaluate_objectives_independently: null
@@ -634,10 +664,11 @@ gen_gnbg:
constraints: null
description: Generator counterpart of GNBG.
dynamic_type: null
- evaluation_time: null
+ evaluation_time: []
fidelity_levels: null
implementations:
- impl_gnbg
+ instances: null
long_name: null
modality: null
name: GNBG
@@ -667,11 +698,12 @@ gen_gnbg_ii:
constraints: null
description: Generator counterpart of GNBG-II.
dynamic_type: null
- evaluation_time: null
+ evaluation_time: []
fidelity_levels: null
implementations:
- - impl_gnbg_ii
- impl_iohgnbg
+ - impl_gnbg_ii
+ instances: null
long_name: null
modality: null
name: GNBG-II
@@ -708,6 +740,7 @@ gen_gpd:
evaluation_time: null
fidelity_levels: null
implementations: null
+ instances: null
long_name: null
modality: null
name: GPD
@@ -745,10 +778,11 @@ gen_iohclustering:
constraints: null
description: Generator counterpart of the IOHClustering suite.
dynamic_type: null
- evaluation_time: null
+ evaluation_time: []
fidelity_levels: null
implementations:
- impl_iohclustering
+ instances: null
long_name: null
modality:
- multimodal
@@ -779,11 +813,12 @@ gen_ma_bbob:
constraints: null
description: Generator that creates affine combinations of BBOB functions
dynamic_type: null
- evaluation_time: null
+ evaluation_time: []
fidelity_levels: null
implementations:
- - impl_iohexperimenter
- impl_ma_bbob
+ - impl_iohexperimenter
+ instances: null
long_name: null
modality:
- multimodal
@@ -812,13 +847,14 @@ gen_mpm2:
can_evaluate_objectives_independently: null
code_examples: null
constraints: null
- description: nonlinear nonseparable nonsymmetric; scalable in terms of time to
- evaluate the objective function
+ description: nonlinear nonseparable nonsymmetric; scalable in terms of time to evaluate
+ the objective function
dynamic_type: null
- evaluation_time: null
+ evaluation_time: []
fidelity_levels: null
implementations:
- impl_mpm2
+ instances: null
long_name: null
modality:
- multimodal
@@ -846,13 +882,14 @@ gen_mubqp:
can_evaluate_objectives_independently: null
code_examples: null
constraints: null
- description: tunable variable and objective dimensions; tunable density and
- correlation between objectives
+ description: tunable variable and objective dimensions; tunable density and correlation
+ between objectives
dynamic_type: null
- evaluation_time: null
+ evaluation_time: []
fidelity_levels: null
implementations:
- impl_mocobench
+ instances: null
long_name: null
modality:
- quadratic
@@ -886,19 +923,19 @@ gen_mubqp:
min: 1
type: binary
gen_puboi:
- allows_partial_evaluation: no
+ allows_partial_evaluation: 'no'
can_evaluate_objectives_independently: null
code_examples: null
constraints: null
- description: A benchmark in which variable importance is tunable, based on the
- Walsh function.
+ description: A benchmark in which variable importance is tunable, based on the Walsh
+ function.
dynamic_type: null
- evaluation_time: null
+ evaluation_time: []
fidelity_levels: null
implementations:
- impl_puboi
- long_name: Polynomial Unconstrained Binary Optimization with tunable
- importance
+ instances: null
+ long_name: Polynomial Unconstrained Binary Optimization with tunable importance
modality: null
name: PUBOi
noise_type: null
@@ -921,17 +958,19 @@ gen_puboi:
min: 1
type: binary
gen_randoptgen:
- allows_partial_evaluation: no
+ allows_partial_evaluation: 'no'
can_evaluate_objectives_independently: null
code_examples: null
constraints: null
- description: A Unified Random Problem Generator for Single- and
- Multi-Objective Optimization Problems with Mixed-Variable Input Spaces.
+ description: A Unified Random Problem Generator for Single- and Multi-Objective
+ Optimization Problems with Mixed-Variable Input Spaces.
dynamic_type: null
- evaluation_time: null
+ evaluation_time:
+ - milliseconds
fidelity_levels: null
implementations:
- impl_randoptgen
+ instances: null
long_name: RandOptGen
modality:
- multimodal
@@ -961,23 +1000,24 @@ gen_randoptgen:
- dim:
max: null
min: 1
- type: binary
+ type: integer
- dim:
max: null
min: 1
- type: integer
+ type: binary
gen_rho_mnk_landscapes:
allows_partial_evaluation: null
can_evaluate_objectives_independently: null
code_examples: null
constraints: null
- description: tunable variable and objective dimensions; tunable multimodality
- and correlation between objectives
+ description: tunable variable and objective dimensions; tunable multimodality and
+ correlation between objectives
dynamic_type: null
- evaluation_time: null
+ evaluation_time: []
fidelity_levels: null
implementations:
- impl_mocobench
+ instances: null
long_name: null
modality:
- multimodal
@@ -999,8 +1039,7 @@ gen_rho_mnk_landscapes:
link:
type: null
url: https://doi.org/10.1016/j.ejor.2012.12.019
- title: On the design of multi-objective evolutionary algorithms based on
- NK-landscapes
+ title: On the design of multi-objective evolutionary algorithms based on NK-landscapes
type: null
source: null
tags: null
@@ -1015,13 +1054,14 @@ gen_rho_mtsp:
can_evaluate_objectives_independently: null
code_examples: null
constraints: null
- description: tunable variable and objective dimensions; tunable instance type
- (euclidean/random); tunable correlation between objectives
+ description: tunable variable and objective dimensions; tunable instance type (euclidean/random);
+ tunable correlation between objectives
dynamic_type: null
- evaluation_time: null
+ evaluation_time: []
fidelity_levels: null
implementations:
- impl_mocobench
+ instances: null
long_name: null
modality:
- quadratic
@@ -1059,13 +1099,14 @@ gen_wmodel:
can_evaluate_objectives_independently: null
code_examples: null
constraints: null
- description: Tunable generator for binary optimization based on several
- difficulty features
+ description: Tunable generator for binary optimization based on several difficulty
+ features
dynamic_type: null
- evaluation_time: null
+ evaluation_time: []
fidelity_levels: null
implementations:
- impl_wmodel
+ instances: null
long_name: null
modality: null
name: W-model
@@ -1091,13 +1132,15 @@ gen_wmodel:
impl_ato:
description: Non-public implementation
evaluation_time:
- - "several minutes"
+ - several minutes
language: Python
+ links: null
name: Automatic Train Operation Pipeline
+ requirements: null
type: implementation
impl_beacon:
- description: Continuous Bi-objective Benchmark with Explicit Adjustable
- COrrelatioN control
+ description: Continuous Bi-objective Benchmark with Explicit Adjustable COrrelatioN
+ control
evaluation_time:
- negligible
language: Python
@@ -1120,8 +1163,8 @@ impl_bonobench:
impl_bso_toolbox:
description: Building Spatial Design toolbox (TU/e)
evaluation_time:
- - 40 seconds
- 1 second
+ - 40 seconds
language: C++
links:
- type: repository
@@ -1188,8 +1231,7 @@ impl_coco_legacy:
language: C/Python
links:
- type: archive
- url:
- https://web.archive.org/web/20210416065610/https://coco.gforge.inria.fr/doku.php?id=downloads
+ url: https://web.archive.org/web/20210416065610/https://coco.gforge.inria.fr/doku.php?id=downloads
name: COCO legacy (bbob-noisy)
requirements: null
type: implementation
@@ -1218,8 +1260,7 @@ impl_emo2017:
language: null
links:
- type: download
- url:
- https://www.ini.rub.de/PEOPLE/glasmtbl/projects/bbcomp/downloads/realworld-problems-bbcomp-EMO-2017.zip
+ url: https://www.ini.rub.de/PEOPLE/glasmtbl/projects/bbcomp/downloads/realworld-problems-bbcomp-EMO-2017.zip
name: EMO 2017 real-world problems
requirements: null
type: implementation
@@ -1234,8 +1275,8 @@ impl_etmof:
requirements: null
type: implementation
impl_expobench:
- description: EXPensive Optimization benchmark library (wind farm layout, gas
- filter design, pipe shape, hyperparameter tuning, hospital simulation)
+ description: EXPensive Optimization benchmark library (wind farm layout, gas filter
+ design, pipe shape, hyperparameter tuning, hospital simulation)
evaluation_time:
- 2 seconds
- 80 seconds
@@ -1259,8 +1300,8 @@ impl_gasoline:
impl_gbea:
description: Game-Benchmark for Evolutionary Algorithms (COCO fork)
evaluation_time:
- - 5 seconds
- 34 seconds
+ - 5 seconds
language: null
links:
- type: repository
@@ -1325,8 +1366,7 @@ impl_jsec2019:
language: null
links:
- type: website
- url:
- http://www.jpnsec.org/files/competition2019/EC-Symposium-2019-Competition-English.html
+ url: http://www.jpnsec.org/files/competition2019/EC-Symposium-2019-Competition-English.html
name: JSEC 2019 competition
requirements: null
type: implementation
@@ -1336,8 +1376,7 @@ impl_ma_bbob:
language: null
links:
- type: example
- url:
- https://github.com/IOHprofiler/IOHexperimenter/blob/master/example/Competitions/MA-BBOB/Example_MABBOB.ipynb
+ url: https://github.com/IOHprofiler/IOHexperimenter/blob/master/example/Competitions/MA-BBOB/Example_MABBOB.ipynb
name: MA-BBOB (IOHexperimenter)
requirements: null
type: implementation
@@ -1415,8 +1454,8 @@ impl_mpm2:
requirements: null
type: implementation
impl_puboi:
- description: A benchmark in which variable importance is tunable, based on the
- Walsh function
+ description: A benchmark in which variable importance is tunable, based on the Walsh
+ function
evaluation_time: null
language: Python / C++
links:
@@ -1456,8 +1495,8 @@ impl_radar_waveform:
requirements: null
type: implementation
impl_randoptgen:
- description: Unified Random Problem Generator for Single- and Multi-Objective
- Optimization with Mixed-Variable Input Spaces
+ description: Unified Random Problem Generator for Single- and Multi-Objective Optimization
+ with Mixed-Variable Input Spaces
evaluation_time:
- milliseconds
language: Python
@@ -1480,8 +1519,7 @@ impl_reproblems:
requirements: null
type: implementation
impl_transfer_rf_bbob_rw:
- description: Real-world BBOB-like problem implementations (Porkchop,
- KinematicsRobotArm)
+ description: Real-world BBOB-like problem implementations (Porkchop, KinematicsRobotArm)
evaluation_time: null
language: null
links:
@@ -1491,11 +1529,11 @@ impl_transfer_rf_bbob_rw:
requirements: null
type: implementation
impl_tulipa:
- description: Large linear program for optimal investment and operation of
- energy systems
+ description: Large linear program for optimal investment and operation of energy
+ systems
evaluation_time:
- - hours
- minutes
+ - hours
language: Julia / JuMP
links:
- type: website
@@ -1561,11 +1599,11 @@ suite_amvop:
- dim:
max: null
min: 1
- type: categorical
+ type: integer
- dim:
max: null
min: 1
- type: integer
+ type: categorical
suite_bbob:
allows_partial_evaluation: null
can_evaluate_objectives_independently: null
@@ -1678,7 +1716,7 @@ suite_bbob_constrained:
code_examples: null
constraints:
- equality: null
- hard: yes
+ hard: 'yes'
number: null
type: unknown
description: null
@@ -1859,18 +1897,18 @@ suite_bp:
min: 1
type: continuous
suite_brachytherapy:
- allows_partial_evaluation: yes
+ allows_partial_evaluation: 'yes'
can_evaluate_objectives_independently: null
code_examples: null
constraints:
- equality: null
- hard: yes
+ hard: 'yes'
number:
max: null
min: 1
type: unknown
- description: Treatment planning for internal radiation therapy.
- Multi-objective with aggregated objectives; no public source code.
+ description: Treatment planning for internal radiation therapy. Multi-objective
+ with aggregated objectives; no public source code.
dynamic_type: null
evaluation_time: null
fidelity_levels:
@@ -1908,7 +1946,7 @@ suite_car_structure:
code_examples: null
constraints:
- equality: null
- hard: yes
+ hard: 'yes'
number: 54
type: unknown
description: 54 constraints
@@ -1946,7 +1984,7 @@ suite_cdmp:
code_examples: null
constraints:
- equality: null
- hard: yes
+ hard: 'yes'
number: null
type: unknown
description: null
@@ -1996,8 +2034,8 @@ suite_cec2013:
evaluation_time: null
fidelity_levels: null
implementations:
- - impl_iohexperimenter
- impl_cec2013
+ - impl_iohexperimenter
long_name: null
modality: null
name: CEC2013
@@ -2047,8 +2085,8 @@ suite_cec2015_dmoo:
references:
- authors: []
link: null
- title: Benchmark Functions for CEC 2015 Special Session and Competition on
- Dynamic Multi-objective Optimization
+ title: Benchmark Functions for CEC 2015 Special Session and Competition on Dynamic
+ Multi-objective Optimization
type: null
source: null
tags: null
@@ -2082,8 +2120,7 @@ suite_cec2018_dt:
- authors: []
link:
type: null
- url:
- https://www.academia.edu/download/94499025/TR-CEC2018-DMOP-Competition.pdf
+ url: https://www.academia.edu/download/94499025/TR-CEC2018-DMOP-Competition.pdf
title: CEC2018 DMOP Competition TR
type: null
source:
@@ -2105,8 +2142,8 @@ suite_cec2022:
evaluation_time: null
fidelity_levels: null
implementations:
- - impl_iohexperimenter
- impl_cec2022
+ - impl_iohexperimenter
long_name: null
modality: null
name: CEC2022
@@ -2118,8 +2155,7 @@ suite_cec2022:
- authors: []
link:
type: null
- url:
- https://github.com/P-N-Suganthan/2022-SO-BO/blob/main/CEC2022%20TR.pdf
+ url: https://github.com/P-N-Suganthan/2022-SO-BO/blob/main/CEC2022%20TR.pdf
title: CEC2022 TR
type: null
source:
@@ -2137,7 +2173,7 @@ suite_cfd:
code_examples: null
constraints:
- equality: null
- hard: yes
+ hard: 'yes'
number: null
type: unknown
description: expensive evaluations 30s-15m
@@ -2176,7 +2212,7 @@ suite_cre:
code_examples: null
constraints:
- equality: null
- hard: yes
+ hard: 'yes'
number: null
type: unknown
description: null
@@ -2218,12 +2254,12 @@ suite_cre:
min: 3
type: integer
suite_cuter:
- allows_partial_evaluation: no
+ allows_partial_evaluation: 'no'
can_evaluate_objectives_independently: null
code_examples: null
constraints:
- equality: null
- hard: yes
+ hard: 'yes'
number: null
type: unknown
description: A constrained and unconstrained testing environment.
@@ -2257,18 +2293,18 @@ suite_cuter:
- dim:
max: null
min: 1
- type: binary
+ type: integer
- dim:
max: null
min: 1
- type: integer
+ type: binary
suite_cutest:
- allows_partial_evaluation: no
+ allows_partial_evaluation: 'no'
can_evaluate_objectives_independently: null
code_examples: null
constraints:
- equality: null
- hard: yes
+ hard: 'yes'
number: null
type: box
- equality: null
@@ -2310,11 +2346,11 @@ suite_cutest:
- dim:
max: null
min: 1
- type: binary
+ type: integer
- dim:
max: null
min: 1
- type: integer
+ type: binary
suite_dtlz:
allows_partial_evaluation: null
can_evaluate_objectives_independently: null
@@ -2512,20 +2548,20 @@ suite_etmof:
min: 25
type: continuous
suite_expobench:
- allows_partial_evaluation: no
+ allows_partial_evaluation: 'no'
can_evaluate_objectives_independently: null
code_examples: null
constraints:
- equality: null
- hard: some
+ hard: 'yes'
number: null
- type: unknown
+ type: box
- equality: null
- hard: yes
+ hard: some
number: null
- type: box
- description: Wind farm layout optimization, gas filter design, pipe shape
- optimization, hyperparameter tuning, and hospital simulation
+ type: unknown
+ description: Wind farm layout optimization, gas filter design, pipe shape optimization,
+ hyperparameter tuning, and hospital simulation
dynamic_type: null
evaluation_time: null
fidelity_levels: null
@@ -2535,8 +2571,8 @@ suite_expobench:
modality: null
name: EXPObench
noise_type:
- - observational
- real-life
+ - observational
objectives:
- 1
problems: null
@@ -2559,18 +2595,18 @@ suite_expobench:
- dim:
max: 135
min: 10
- type: continuous
+ type: categorical
- dim:
max: 135
min: 10
- type: categorical
+ type: continuous
suite_gbea:
allows_partial_evaluation: null
can_evaluate_objectives_independently: null
code_examples: null
constraints: null
- description: expensive evaluations 5s-35s, RW-GAN-Mario and TopTrumps are part
- of GBEA
+ description: expensive evaluations 5s-35s, RW-GAN-Mario and TopTrumps are part of
+ GBEA
dynamic_type: null
evaluation_time: null
fidelity_levels: null
@@ -2641,14 +2677,14 @@ suite_gnbg_ii:
can_evaluate_objectives_independently: null
code_examples: null
constraints: null
- description: Generalized Numerical Benchmark Generator (version 2). Also
- available in IOH.
+ description: Generalized Numerical Benchmark Generator (version 2). Also available
+ in IOH.
dynamic_type: null
evaluation_time: null
fidelity_levels: null
implementations:
- - impl_gnbg_ii
- impl_iohgnbg
+ - impl_gnbg_ii
long_name: null
modality: null
name: GNBG-II
@@ -2971,19 +3007,19 @@ suite_maop:
min: 1
type: continuous
suite_mechbench:
- allows_partial_evaluation: no
+ allows_partial_evaluation: 'no'
can_evaluate_objectives_independently: null
code_examples: null
constraints:
- equality: null
- hard: yes
+ hard: 'yes'
number:
- 1
- 2
type: unknown
- description: Set of problems inspired by Structural Mechanics Design
- Optimization. Embeds physical simulations (plasticity only, no
- fracture/damage). Unstructured/non-isotropic multimodality.
+ description: Set of problems inspired by Structural Mechanics Design Optimization.
+ Embeds physical simulations (plasticity only, no fracture/damage). Unstructured/non-isotropic
+ multimodality.
dynamic_type: null
evaluation_time: null
fidelity_levels: null
@@ -3053,8 +3089,7 @@ suite_minus_dtlz:
can_evaluate_objectives_independently: null
code_examples: null
constraints: null
- description: Variant of DTLZ that minimises the inverse of the base DTLZ
- functions
+ description: Variant of DTLZ that minimises the inverse of the base DTLZ functions
dynamic_type: null
evaluation_time: null
fidelity_levels: null
@@ -3094,8 +3129,7 @@ suite_minus_wfg:
can_evaluate_objectives_independently: null
code_examples: null
constraints: null
- description: Variant of WFG that minimises the inverse of the base WFG
- functions
+ description: Variant of WFG that minimises the inverse of the base WFG functions
dynamic_type: null
evaluation_time: null
fidelity_levels: null
@@ -3136,7 +3170,7 @@ suite_mmopp:
code_examples: null
constraints:
- equality: null
- hard: yes
+ hard: 'yes'
number: null
type: unknown
description: null
@@ -3162,8 +3196,7 @@ suite_mmopp:
- authors: []
link:
type: null
- url:
- http://www5.zzu.edu.cn/system/_content/download.jsp?urltype=news.DownloadAttachUrl&owner=1327567121&wbfileid=4764412
+ url: http://www5.zzu.edu.cn/system/_content/download.jsp?urltype=news.DownloadAttachUrl&owner=1327567121&wbfileid=4764412
title: MMOPP technical report
type: null
source: null
@@ -3178,11 +3211,11 @@ suite_modact:
code_examples: null
constraints:
- equality: null
- hard: yes
+ hard: 'yes'
number: null
type: unknown
- description: Realistic Constrained Multi-Objective Optimization Benchmark
- Problems from Design.
+ description: Realistic Constrained Multi-Objective Optimization Benchmark Problems
+ from Design.
dynamic_type: null
evaluation_time: null
fidelity_levels: null
@@ -3355,18 +3388,18 @@ suite_re:
- dim:
max: 7
min: 2
- type: continuous
+ type: integer
- dim:
max: 7
min: 2
- type: integer
+ type: continuous
suite_rwmvop:
allows_partial_evaluation: null
can_evaluate_objectives_independently: null
code_examples: null
constraints:
- equality: null
- hard: yes
+ hard: 'yes'
number: null
type: unknown
description: null
@@ -3400,18 +3433,18 @@ suite_rwmvop:
- dim:
max: null
min: 1
- type: categorical
+ type: integer
- dim:
max: null
min: 1
- type: integer
+ type: categorical
suite_sbox_cost:
allows_partial_evaluation: null
can_evaluate_objectives_independently: null
code_examples: null
constraints: null
- description: problems from BBOB but allows instances with the optimum close to
- the boundary
+ description: problems from BBOB but allows instances with the optimum close to the
+ boundary
dynamic_type: null
evaluation_time: null
fidelity_levels: null
@@ -3487,8 +3520,8 @@ suite_submodular:
can_evaluate_objectives_independently: null
code_examples: null
constraints: null
- description: set of graph-based submodular optimization problems from 4
- problem types
+ description: set of graph-based submodular optimization problems from 4 problem
+ types
dynamic_type: null
evaluation_time: null
fidelity_levels: null
@@ -3523,17 +3556,17 @@ suite_tulipa_energy:
code_examples: null
constraints:
- equality: null
- hard: some
+ hard: 'yes'
number: null
type: unknown
- equality: null
- hard: yes
+ hard: some
number: null
type: unknown
- description: Determine the optimal investment and operation decisions for
- different assets in the energy system (production, consumption, conversion,
- storage, transport) while minimizing loss of load. Modelled as a potentially
- very large linear program with multiple fidelity levels.
+ description: Determine the optimal investment and operation decisions for different
+ assets in the energy system (production, consumption, conversion, storage, transport)
+ while minimizing loss of load. Modelled as a potentially very large linear program
+ with multiple fidelity levels.
dynamic_type: null
evaluation_time: null
fidelity_levels:
@@ -3554,8 +3587,7 @@ suite_tulipa_energy:
- authors: []
link:
type: null
- url:
- https://tulipaenergy.github.io/TulipaEnergyModel.jl/stable/40-scientific-foundation/45-scientific-references
+ url: https://tulipaenergy.github.io/TulipaEnergyModel.jl/stable/40-scientific-foundation/45-scientific-references
title: TulipaEnergyModel.jl scientific references
type: null
source:
@@ -3635,8 +3667,7 @@ suite_wfg:
link:
type: null
url: https://doi.org/10.1109/TEVC.2005.861417
- title: A review of multiobjective test problems and a scalable test problem
- toolkit
+ title: A review of multiobjective test problems and a scalable test problem toolkit
type: null
source: null
tags: null
diff --git a/requirements.txt b/requirements.txt
index b052e87..8f46f2f 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,2 +1,3 @@
pandas
pyyaml
+pydantic_yaml
diff --git a/utils/requirements.txt b/utils/requirements.txt
index 6a17fcc..8993e34 100644
--- a/utils/requirements.txt
+++ b/utils/requirements.txt
@@ -1,2 +1,3 @@
pyyaml
pandas
+pydantic_yaml
diff --git a/utils/validate_yaml.py b/utils/validate_yaml.py
index 79f4238..3249e0e 100644
--- a/utils/validate_yaml.py
+++ b/utils/validate_yaml.py
@@ -9,7 +9,7 @@
sys.path.insert(0, str(parent))
# Now you can import normally
-from yaml_to_html import default_columns as REQUIRED_FIELDS
+from yaml_to_html import DEFAULT_VISIBLE_COLUMNS as REQUIRED_FIELDS
OPTIONAL_FIELDS = ["multimodal"]
UNIQUE_FIELDS = ["name"]
diff --git a/yaml_to_html.py b/yaml_to_html.py
index 7ee5a6e..dbfbfe4 100755
--- a/yaml_to_html.py
+++ b/yaml_to_html.py
@@ -320,8 +320,8 @@ def format_variables_by_type(variables):
if domain is not None:
domains.append(domain)
- for variable_type in values:
- values[variable_type] = " | ".join(values[variable_type])
+ for variable_type in sorted(list(values.keys())):
+ values[variable_type] = " | ".join(sorted(values[variable_type]))
return values, combine_domains_for_total(domains)
@@ -356,7 +356,7 @@ def list_variable_types(variables):
types = [v for v in unique_preserve_order(types) if v]
if not types:
return ""
- return " | ".join(types)
+ return " | ".join(sorted(types))
def list_constraint_types(constraints):
@@ -373,7 +373,7 @@ def list_constraint_types(constraints):
types = [c for c in unique_preserve_order(types) if c]
if not types:
return ""
- return " | ".join(types)
+ return " | ".join(sorted(types))
def has_nonzero_info(value, yes_only=False):
@@ -381,7 +381,10 @@ def has_nonzero_info(value, yes_only=False):
return False
if isinstance(value, (set, list, tuple, dict)):
- return len(value) > 0
+ if len(value) == 1:
+ return has_nonzero_info(next(iter(value)), yes_only=yes_only)
+ else:
+ return len(value) > 0
text = str(value).strip().lower()
if not text:
@@ -404,10 +407,11 @@ def build_properties(item):
if has_nonzero_info(getattr(item, "can_evaluate_objectives_independently", None), yes_only=True):
properties.append("independent objective evaluations")
if has_nonzero_info(getattr(item, "fidelity_levels", None)):
- properties.append("multi-fidelity")
+ if getattr(item, "fidelity_levels", None) != {1}:
+ properties.append("multi-fidelity")
if not properties:
return ""
- return " | ".join(properties)
+ return " | ".join(sorted(properties))
def format_implementation_links(links):
@@ -552,8 +556,8 @@ def format_constraints_by_type(constraints, constraint_types):
soft_domains.append(count_domain)
for constraint_type in constraint_types:
- hard_values[constraint_type] = " | ".join(hard_values[constraint_type])
- soft_values[constraint_type] = " | ".join(soft_values[constraint_type])
+ hard_values[constraint_type] = " | ".join(sorted(hard_values[constraint_type]))
+ soft_values[constraint_type] = " | ".join(sorted(soft_values[constraint_type]))
hard_total = combine_domains_for_total(hard_domains)
soft_total = combine_domains_for_total(soft_domains)