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)