diff --git a/.flake8 b/.flake8 deleted file mode 100644 index 5b92ae3..0000000 --- a/.flake8 +++ /dev/null @@ -1,18 +0,0 @@ -[flake8] -extend-select = B9 -extend-ignore = E203, E231, E501, E722, W503, B950, B014, W504, E123, E126, E226, E121, B905, SIM113 -per-file-ignores = __init__.py:F401 -max-line-length = 120 -show-source = true -exclude = - .git, - .idea, - .eggs, - __pycache__, - .tox, - docs/source/conf.py, - build, - .nox, - venv, - .venv -application-import-names = mqt.qao diff --git a/.github/codecov.yml b/.github/codecov.yml index 2b41601..897f822 100644 --- a/.github/codecov.yml +++ b/.github/codecov.yml @@ -11,6 +11,3 @@ coverage: patch: default: threshold: 1% -codecov: - notify: - after_n_builds: 8 diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..6b89cc9 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,25 @@ +version: 2 +updates: + - package-ecosystem: "github-actions" + directory: "/" + groups: + github-actions: + patterns: + - "*" + schedule: + interval: "weekly" + day: "wednesday" + time: "06:00" + timezone: "Europe/Vienna" + + - package-ecosystem: "pip" + directory: "/" + groups: + python-dependencies: + patterns: + - "*" + schedule: + interval: "weekly" + day: "friday" + time: "06:00" + timezone: "Europe/Vienna" diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml index 36a7013..2f63168 100644 --- a/.github/workflows/cd.yml +++ b/.github/workflows/cd.yml @@ -7,7 +7,7 @@ on: jobs: python-packaging: name: 🐍 Packaging - uses: cda-tum/mqt-workflows/.github/workflows/reusable-python-packaging.yml@v1.0.0 + uses: cda-tum/mqt-workflows/.github/workflows/reusable-python-packaging.yml@v1.0.1 with: pure-python: true diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7126586..f0e32ce 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -14,21 +14,19 @@ concurrency: jobs: change-detection: name: πŸ” Change - uses: cda-tum/mqt-workflows/.github/workflows/reusable-change-detection.yml@v1.0.0 + uses: cda-tum/mqt-workflows/.github/workflows/reusable-change-detection.yml@v1.0.1 python-tests: name: 🐍 Test needs: change-detection if: fromJSON(needs.change-detection.outputs.run-python-tests) - uses: cda-tum/mqt-workflows/.github/workflows/reusable-python-ci.yml@v1.0.0 - secrets: - token: ${{ secrets.CODECOV_TOKEN }} + uses: cda-tum/mqt-workflows/.github/workflows/reusable-python-ci.yml@v1.0.1 code-ql: name: πŸ“ CodeQL needs: change-detection if: fromJSON(needs.change-detection.outputs.run-code-ql) - uses: cda-tum/mqt-workflows/.github/workflows/reusable-code-ql-python.yml@v1.0.0 + uses: cda-tum/mqt-workflows/.github/workflows/reusable-code-ql-python.yml@v1.0.1 required-checks-pass: # This job does nothing and is only used for branch protection name: 🚦 Check diff --git a/.github/workflows/mypy.yml b/.github/workflows/mypy.yml deleted file mode 100644 index d2984e8..0000000 --- a/.github/workflows/mypy.yml +++ /dev/null @@ -1,25 +0,0 @@ -name: mypy - -on: - pull_request: - push: - branches: - - main - workflow_dispatch: - -concurrency: - group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} - cancel-in-progress: true - -jobs: - lint: - runs-on: ubuntu-latest - name: Run my[py] linter - steps: - - uses: actions/checkout@v4 - - uses: actions/setup-python@v4 - with: - python-version: "3.10" - - uses: pre-commit/action@v3.0.0 - with: - extra_args: mypy --all-files diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 5a0b456..33a1cc4 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -15,22 +15,35 @@ ci: repos: # Standard hooks - repo: https://github.com/pre-commit/pre-commit-hooks - rev: "v4.5.0" + rev: v4.6.0 hooks: - id: check-added-large-files - id: check-case-conflict - id: check-docstring-first - id: check-merge-conflict + - id: check-symlinks - id: check-toml - id: check-yaml - id: debug-statements - id: end-of-file-fixer - id: mixed-line-ending + - id: requirements-txt-fixer - id: trailing-whitespace + # Clean jupyter notebooks + - repo: https://github.com/srstevenson/nb-clean + rev: 3.2.0 + hooks: + - id: nb-clean + args: + - --remove-empty-cells + - --preserve-cell-metadata + - raw_mimetype + - -- + # Handling unwanted unicode characters - repo: https://github.com/sirosen/texthooks - rev: "0.6.2" + rev: 0.6.6 hooks: - id: fix-ligatures - id: fix-smartquotes @@ -43,28 +56,9 @@ repos: - id: rst-directive-colons - id: rst-inline-touching-normal - # Clean jupyter notebooks - - repo: https://github.com/srstevenson/nb-clean - rev: "3.1.0" - hooks: - - id: nb-clean - # Check for spelling - - repo: https://github.com/codespell-project/codespell - rev: "v2.2.6" - hooks: - - id: codespell - args: ["-L", "wille,linz,fro"] - exclude: "mqt/benchviewer/templates/legal.html" - - # Format configuration files with prettier - - repo: https://github.com/pre-commit/mirrors-prettier - rev: "v3.0.3" - hooks: - - id: prettier - types_or: [yaml, markdown, html, css, javascript, json] - + # Python linting using ruff - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.1.4 + rev: v0.4.7 hooks: - id: ruff args: ["--fix", "--show-fixes"] @@ -72,38 +66,37 @@ repos: - id: ruff-format types_or: [python, pyi, jupyter] + # Static type checking using mypy + - repo: https://github.com/pre-commit/mirrors-mypy + rev: v1.10.0 + hooks: + - id: mypy + files: ^(src/mqt|tests) + args: [] + additional_dependencies: + - pytest + - numpy + # Also run Black on examples in the documentation - repo: https://github.com/adamchainz/blacken-docs rev: 1.16.0 hooks: - id: blacken-docs - additional_dependencies: [black==23.*] + additional_dependencies: [black==24.*] - - repo: https://github.com/pre-commit/mirrors-mypy - rev: v1.6.1 + # Format configuration files with prettier + - repo: https://github.com/pre-commit/mirrors-prettier + rev: v4.0.0-alpha.8 hooks: - - id: mypy - files: ^(src|tests) - args: [] - additional_dependencies: - - importlib_resources - - qubovert - - pytest==7.4.0 - - types-setuptools - - setuptools<=65.6.3 - - sympy==1.12 - - numpy==1.23.5 - - dwave-samplers - - dwave.system - - docplex==2.25.236 - - qiskit==0.45.3 - - qiskit_optimization==0.4.0 - - qiskit-algorithms==0.2.1 - - qiskit_ibm_runtime==0.14.0 - - matplotlib - - pandas - - PyPortfolioOpt - - scikit-learn + - id: prettier + types_or: [yaml, markdown, html, css, scss, javascript, json] + + # Check for spelling + - repo: https://github.com/codespell-project/codespell + rev: v2.3.0 + hooks: + - id: codespell + args: ["-L", "wille,linz", "--skip", "*.ipynb"] # Catch common capitalization mistakes - repo: local @@ -112,7 +105,7 @@ repos: name: Disallow improper capitalization language: pygrep entry: PyBind|Numpy|Cmake|CCache|Github|PyTest|Mqt|Tum - exclude: (.joblib|.pre-commit-config.yaml) + exclude: .pre-commit-config.yaml # Check best practices for scientific Python code - repo: https://github.com/scientific-python/cookie diff --git a/.readthedocs.yaml b/.readthedocs.yaml new file mode 100644 index 0000000..20ae190 --- /dev/null +++ b/.readthedocs.yaml @@ -0,0 +1,30 @@ +version: 2 + +submodules: + include: all + recursive: true + +build: + os: ubuntu-22.04 + tools: + python: "3.11" + jobs: + post_checkout: + # Skip docs build if the commit message contains "skip ci" + - (git --no-pager log --pretty="tformat:%s -- %b" -1 | grep -viq "skip ci") || exit 183 + # Skip docs build if there are no changes related to docs + - | + if [ "$READTHEDOCS_VERSION_TYPE" = "external" ] && git diff --quiet origin/main -- docs/ .readthedocs.yaml src/mqt/ .github/contributing* .github/support*; + then + exit 183; + fi + +sphinx: + configuration: docs/conf.py + +python: + install: + - method: pip + path: . + extra_requirements: + - docs diff --git a/CITATION.bib b/CITATION.bib index 306c981..42f9a00 100644 --- a/CITATION.bib +++ b/CITATION.bib @@ -1,7 +1,6 @@ -@MISC{volpe2024towards, +@INPROCEEDINGS{volpe2024towards, AUTHOR = {D.Volpe and N. Quetschlich and M. Graziano and G. Turvani and R. Wille}, TITLE = {{Towards an Automatic Framework for Solving Optimization Problems with Quantum Computers}}, YEAR = {2024}, - EPRINT = {}, - EPRINTTYPE = {}, + BOOKTITLE = {IEEE International Conference on Quantum Software (QSW)}, } diff --git a/README.md b/README.md index 183fa7d..c2fd567 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ # MQT Quantum Auto Optimizer: Automatic Framework for Solving Optimization Problems with Quantum Computers -MQT Quantum Auto Optimizer is a framework that allows one to automatically translate an optimization problem into a quantum-compliant formulation and to solve it with one of the main quantum solvers (Quantum Annelar, QAOA, VQE and GAS) +MQT Quantum Auto Optimizer is a framework that allows one to automatically translate an optimization problem into a quantum-compliant formulation and to solve it with one of the main quantum solvers (Quantum Annealer, Quantum Approximate Optimization Algorithm, Variational Quantum Eigensolver and Grover Adaptive Search) MQT Quantum Auto Optimizer is part of the [Munich Quantum Toolkit (MQT)](https://mqt.readthedocs.io/) developed by the [Chair for Design Automation](https://www.cda.cit.tum.de/) at the [Technical University of Munich](https://www.tum.de/). This framework has been developed in collaboration with the [VLSI Lab](https://www.vlsilab.polito.it/) of [Politecnico di Torino](https://www.polito.it). diff --git a/docs/Constraints.rst b/docs/Constraints.rst new file mode 100644 index 0000000..f3aac6d --- /dev/null +++ b/docs/Constraints.rst @@ -0,0 +1,45 @@ +Constraints Class +================= + +It manages the constraints of the problem. It is used to store the constraints and to check if a solution satisfies them. + +Constraints types supported +--------------------------- + +Types of constraints supported: + +- *Equality*, writing the equality as a quadratic penalty function, i.e. sum = b imposed with g = (sum-b)^2 +- *Inequality*, moving to equality with the continuous auxiliary variables a to be expanded with the encoding technique of the Variables class +- *Not constraint* among binary variables, i.e. Not(a) = b imposed with g = 2ab - a - b + 1 +- *And constraint* among binary variables, i.e. a and b = c imposed with ab -2(a+b)c + 3c +- *Or constraint* among binary variables, i.e. a or b = c imposed with ab + (a+b)(1-2c) + c +- *Xor constraint* among binary variables, i.e. a xor b = c imposed with 2ab - 2(a+b)c - 4(a+b)\_aux+4_aux c +a+b+c+4+\_aux + +Constraints declarations +------------------------ + +The class provides methods to declare variables: + +- *add_constraint(expression: str, hard: bool = True, variable_precision: bool = True)*: adds a constraint to the list of constraints. + - *expression* is a string that represents the constraint + - *hard* parameter is a boolean that indicates if the constraint is hard or soft. + - *variable_precision* parameter is a boolean that indicates if the constraint is to be considered in the precision of the variables. + +Example: +-------- + +.. code-block:: python + + from mqt.qao.constraints import Constraints + from mqt.qao.variables import Variables + + constraint = Constraints() + variables = Variables() + variables.add_binary_variable("a") + variables.add_binary_variable("b") + variables.add_binary_variable("c") + variables.add_discrete_variable("d", [-1, 1, 3]) + variables.add_continuous_variable("e", -2, 2, 0.25, "", "") + constraint.add_constraint("~a = b", True, True, False) + constraint.add_constraint("a | b = c", True, True, False) + constraint.add_constraint("d + e <= 1", True, True, False) diff --git a/docs/Contributing.rst b/docs/Contributing.rst new file mode 100644 index 0000000..c492978 --- /dev/null +++ b/docs/Contributing.rst @@ -0,0 +1 @@ +.. include:: ../.github/contributing.rst diff --git a/docs/DevelopmentGuide.rst b/docs/DevelopmentGuide.rst new file mode 100644 index 0000000..a8fde66 --- /dev/null +++ b/docs/DevelopmentGuide.rst @@ -0,0 +1,103 @@ +Development Guide +================= + +Ready to contribute to the project? Here is how to set up a local development environment. + +Initial Setup +############# + +1. Fork the `cda-tum/mqt-qao `_ repository on GitHub (see https://docs.github.com/en/get-started/quickstart/fork-a-repo). + +2. Clone your fork locally + + .. code-block:: console + + $ git clone git@github.com:your_name_here/mqt-qao + + +3. Change into the project directory + + .. code-block:: console + + $ cd mqt-qao + +4. Create a branch for local development + + .. code-block:: console + + $ git checkout -b name-of-your-bugfix-or-feature + + Now you can make your changes locally. + +5. (Optional, **highly recommended**) Set up a virtual environment + + .. code-block:: console + + $ python3 -m venv venv + $ source venv/bin/activate + + .. note:: + + If you are using Windows, you can use the following command instead: + + .. code-block:: console + + $ python3 -m venv venv + $ venv\Scripts\activate.bat + + Ensure that pip, setuptools, and wheel are up to date: + + .. code-block:: console + + (venv) $ pip install --upgrade pip setuptools wheel + + +6. (Optional) Install `pre-commit `_ to automatically run a set of checks before each commit. + + .. code-block:: console + + (venv) $ pipx install pre-commit + (venv) $ pre-commit install + + If you use macOS, then pre-commit is in brew, use :code:`brew install pre-commit`. + +Building the Python module +########################## + +The recommended way of building the Python module is to perform an editable install using `pip `_. + + .. code-block:: console + + (venv) $ pip install -e . + +The :code:`--editable` flag ensures that changes in the Python code are instantly available without re-running the command. + +Running Python Tests +-------------------- + +The Python part of the code base is tested by unit tests using the `pytest `_ framework. +The corresponding test files can be found in the :code:`tests/` directory. + + .. code-block:: console + + (venv) $ pip install -e ".[test]" + (venv) $ pytest + +This installs all dependencies necessary to run the tests in an isolated environment, builds the Python package, and then runs the tests. + +Python Code Formatting and Linting +---------------------------------- + +The Python code is formatted and linted using a collection of `pre-commit hooks `_. +This collection includes: + +- `ruff `_ -- an extremely fast Python linter and formatter, written in Rust. +- `mypy `_ -- a static type checker for Python code + + +You can install the hooks manually by running :code:`pre-commit install` in the project root directory. +The hooks will then be executed automatically when committing changes. + + .. code-block:: console + + (venv) $ pre-commit run -a diff --git a/docs/ObjectiveFunction.rst b/docs/ObjectiveFunction.rst new file mode 100644 index 0000000..201b481 --- /dev/null +++ b/docs/ObjectiveFunction.rst @@ -0,0 +1,31 @@ +ObjectiveFunction Class +======================= + +It manages the objective functions of the optimization problem. it permits to specify the weights of the objectives in case of multi-objective optimization and the optimization directions. Since the variables can be declared in array form, matrix expressions for the objective functions are supported. + +Objective functions declarations +-------------------------------- + +The class provides methods to declare variables: + +- *add_objective_function(objective_function: Expr, minimization: bool = True, weight: float = 1)* : add an objective function to the optimization problem. + - *objective_function* is an expression of the variables of the optimization problem. + - *minimization* parameter specifies if the objective function is to be minimized or maximized (optimization direction). + - *weight* parameter is the weight of the objective function in case of multi-objective optimization. + +Example: +-------- + +.. code-block:: python + + from mqt.qao.constraints import Constraints + from mqt.qao.variables import Variables + from mqt.qao.objectivefunction import ObjectiveFunction + + variables = Variables() + constraint = Constraints() + a0 = variables.add_binary_variable("a") + b0 = variables.add_discrete_variable("b", [-1, 1, 3]) + c0 = variables.add_continuous_variable("c", -2, 2, 0.25, "", "") + objective_function = ObjectiveFunction() + objective_function.add_objective_function(a0 + b0 * c0 + c0**2) diff --git a/docs/Problem.rst b/docs/Problem.rst new file mode 100644 index 0000000..4f85945 --- /dev/null +++ b/docs/Problem.rst @@ -0,0 +1,49 @@ +Problem Class +============= + +It may be useful to have a class that represents a problem. It includes the variables, constraints and objective function. This class can be used for constructing the quantum-compliant cost function. + +Problem declarations +-------------------- + +The class provides a method for declaring the problem: + +- *create_problem(var: Variables, constraint: Constraints, objective_functions: ObjectiveFunction)* : This method is used to declare the problem. + - *variables* instances of the Variables class + - *constraints* instances of the Constraints class + - *objective_functions* instances of the ObjectiveFunction class. + +and a method for obtaining the HUBO or PUBO formulation of the problem as qubovert PUBO object: + +- *write_the_final_cost_function( lambda_strategy: str, lambda_value: float = 1)* : This method is used to obtain the HUBO or PUBO formulation of the problem as qubovert PUBO object. The method takes two arguments: + - *lambda_strategy* The strategy to be used for the conversion of the problem to HUBO or PUBO. The possible values are: + - upper_bound_only_positive + - maximum_coefficient + - VLM + - MOC + - MOMC + - upper lower bound naive + - upper lower bound posiform and negaform method + - manual + - *lambda_value* The value of the lambda parameter if the use want to manually select it. The default value is 1.0. + +Example: +-------- + +.. code-block:: python + + from mqt.qao.constraints import Constraints + from mqt.qao.variables import Variables + from mqt.qao.objectivefunction import ObjectiveFunction + + variables = Variables() + constraint = Constraints() + a0 = variables.add_binary_variable("a") + b0 = variables.add_discrete_variable("b", [-1, 1, 3]) + c0 = variables.add_continuous_variable("c", -2, 2, 0.25, "", "") + constraint.add_constraint("c >= 1", True, True, False) + objective_function = ObjectiveFunction() + objective_function.add_objective_function(a0 + b0 * c0 + c0**2) + problem = Problem() + problem.create_problem(variables, constraint, objective_function) + pubo = problem.write_the_final_cost_function(lambda_strategy) diff --git a/docs/Quickstart.ipynb b/docs/Quickstart.ipynb new file mode 100644 index 0000000..cf194f7 --- /dev/null +++ b/docs/Quickstart.ipynb @@ -0,0 +1,138 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "ea3d6be5-b9ee-4375-adee-8fa2cb690fca", + "metadata": {}, + "source": [ + "# Quickstart" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "697e4c2b", + "metadata": {}, + "outputs": [], + "source": [ + "from mqt.qao import Constraints, ObjectiveFunction, Problem, Solver, Variables" + ] + }, + { + "cell_type": "markdown", + "id": "02841c4f-a865-452d-a5ca-085a64eccf00", + "metadata": {}, + "source": [ + "## Declare the variables of the problem" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "73c0a2f9-adbd-4f85-8843-b6ab2ef53da8", + "metadata": {}, + "outputs": [], + "source": [ + "var = Variables()\n", + "a = var.add_binary_variable(\"a\")\n", + "b = var.add_discrete_variable(\"b\", [-1, 1, 3])\n", + "c = var.add_continuous_variable(\"c\", -2, 2, 0.25)" + ] + }, + { + "cell_type": "markdown", + "id": "dc5b2a05-c062-46d8-b75e-2bfde4795a19", + "metadata": {}, + "source": [ + "## Declare the objective functions" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b3f643db-f833-433c-87f8-65cdc5355304", + "metadata": {}, + "outputs": [], + "source": [ + "obj_func = ObjectiveFunction()\n", + "obj_func.add_objective_function(a + b * c + c**2)" + ] + }, + { + "cell_type": "markdown", + "id": "7b823498-55e1-47df-9b7b-f5f462f38c50", + "metadata": {}, + "source": [ + "## Declare the constraints" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "0c327466-7905-45b9-980a-f96ca8cffadb", + "metadata": {}, + "outputs": [], + "source": [ + "cst = Constraints()\n", + "cst.add_constraint(\"b + c >= 2\", variable_precision=True)" + ] + }, + { + "cell_type": "markdown", + "id": "53953b24-353e-465e-b4f4-d7c0f2f0f0bf", + "metadata": {}, + "source": [ + "## Declaration of the problem" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "fe643f31-9d3e-4b7f-875a-af27e3dab5ed", + "metadata": {}, + "outputs": [], + "source": [ + "prb = Problem()\n", + "prb.create_problem(var, cst, obj_func)" + ] + }, + { + "cell_type": "markdown", + "id": "93392cb4", + "metadata": {}, + "source": [ + "## Solve with Simulated Annealing" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "010ab172", + "metadata": {}, + "outputs": [], + "source": [ + "solution = Solver().solve_simulated_annealing(prb)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/docs/References.rst b/docs/References.rst new file mode 100644 index 0000000..2a446d8 --- /dev/null +++ b/docs/References.rst @@ -0,0 +1,6 @@ +References +========== + +If you use *MQT Quantum Auto Optimizer* in your work, we would appreciate if you cited :cite:labelpar:`volpe2024towards`. + +.. bibliography:: diff --git a/docs/Solution.rst b/docs/Solution.rst new file mode 100644 index 0000000..ca62076 --- /dev/null +++ b/docs/Solution.rst @@ -0,0 +1,90 @@ +Solution Class +============== + +It is a class that is used to store all the information about the solution of the problem. + +Solution Attributes +------------------- + +The class has the following attributes: + +- energies: list[float], i.e. the list of energies of the solution obtained in each run +- best_energy, i.e. the lowest energy obtained in all the runs +- best_solution: dict[str, Any], i.e. the best solution obtained in all the runs in binary variables +- best_solution_original_var: dict[str, Any], i.e. the best solution obtained in all the runs in variables originally declared +- solutions_original_var: list[dict[str, Any]], i.e. the list of solutions obtained in each run in variables originally declared +- solutions: list[dict[str, Any]], i.e. the list of solutions obtained in each run in binary variables +- time: float: the time taken to solve the problem +- solver_info: dict[str, Any], i.e. the information about the solver setting to solve the problem + + +Solution Methods +---------------- + +The class has the following methods for helping users in analyzing the solution: + +- *optimal_solution_cost_functions_values()*: This method is used to get the cost functions values of the best solution obtained in all the runs +- *check_constraint_optimal_solution()*: This method is used to check if the best solution obtained in all the runs satisfies the constraints +- *check_constraint_all_solutions()*: This method is used to check if all the solutions obtained in all the runs satisfy the constraints +- *show_cumulative(save: bool = False, show: bool = True, filename: str = "", label: str = "", latex: bool = False)* : This method is used to show the cumulative plot of the energies obtained in all the runs. The parameters are: + - save: bool, i.e. whether to save the plot or not in a file + - show: bool, i.e. whether to show the plot or not + - filename: str, i.e. the name of the file where the plot will be saved + - label: str, i.e. the label of the plot + - latex: bool, i.e. whether to show the plot in latex format or not +- *valid_solutions(weak: bool = True)*: This method is used to get the rate of valid solutions obtained in all the runs. The parameters are: + - weak: bool, i.e. whether to consider in the evaluation the weak constraints +- *p_range(ref_value: float | None = None)*: This method is used to get the p-range of the best solution obtained in all the runs, which is the probability of obtaining a final energy lower than a certain value. The parameters are: + - ref_value: float | None, i.e. the reference value to calculate the p-value +- *tts(ref_value: float | None = None, target_probability: float = 0.99)*: This method is used to get the time-to-solution of the best solution obtained in all the runs, which is the time required to obtain a solution with a certain probability. The parameters are: + - ref_value: float | None, i.e. the reference value to calculate the p-range + - target_probability: float, i.e. the target probability to calculate the time-to-solution +- *wring_json_reports(filename: str = "report", weak: bool = False, ref_value: float | None = None, target_probability: float = 0.99, problem_features: bool = False)* : This method is used to write the reports in json format. The parameters are: + - filename: str, i.e. the name of the file where the report will be saved + - weak: bool, i.e. whether to consider in the evaluation the weak constraints + - ref_value: float | None, i.e. the reference value to calculate the p-range + - target_probability: float, i.e. the target probability to calculate the time-to-solution + - problem_features: bool, i.e. whether to show the problem features in the report or not + + + +Examples: +--------- + +.. code-block:: python + + from mqt.qao.constraints import Constraints + from mqt.qao.variables import Variables + from mqt.qao.objectivefunction import ObjectiveFunction + from mqt.qao.problem import Problem + from mqt.qao.solver import Solver + + variables = Variables() + m1 = variables.add_continuous_variables_array( + "M1", [1, 2], -1, 2, -1, "uniform", "logarithmic 2" + ) + m2 = variables.add_continuous_variables_array( + "M2", [2, 1], -1, 2, -1, "uniform", "logarithmic 2" + ) + objective_function = ObjectiveFunction() + objective_function.add_objective_function(np.matmul(m1, m2).item(0, 0)) + constraint = Constraints() + constraint.add_constraint(constraint_expr, variable_precision=True) + problem = Problem() + problem.create_problem(variables, constraint, objective_function) + solver = Solver() + solution = solver.solve_simulated_annealing( + problem, + max_lambda_update=max_lambda_update, + lambda_update_mechanism=lambda_update, + lambda_strategy=lambda_strategy, + ) + + print(solution.optimal_solution_cost_functions_values()) + print(solution.check_constraint_optimal_solution()) + print(solution.check_constraint_all_solutions()) + solution.show_cumulative() + print(solution.valid_solutions()) + print(solution.p_range()) + print(solution.tts()) + solution.wring_json_reports() diff --git a/docs/Solver.rst b/docs/Solver.rst new file mode 100644 index 0000000..bddd3b8 --- /dev/null +++ b/docs/Solver.rst @@ -0,0 +1,330 @@ +Solver Class +============ + +It interface the problems with the quantum solvers. + +Supported solvers +----------------- + +The framework currently supports the following solvers:ΓΉ + +- D-Wave quantum annealer +- D-Wave simulated annealer +- qiskit Quantum Approximate Optimization Algorithm (QAOA) +- qiskit Variational Quantum Eigensolver (VQE) +- qiskit Grover Adaptive Search (GAS) + +Solver Selection and Configuration +---------------------------------- + +The class provides for exploiting the solver: + +- solve_simulated_annealing( + problem: Problem, + auto_setting: bool = False, + beta_range: list[float] | None = None, + num_reads: int = 100, + annealing_time: int = 100, + num_sweeps_per_beta: int = 1, + beta_schedule_type: str = "geometric", + seed: int | None = None, + initial_states: SampleSet | None = None, + initial_states_generator: str = "random", + max_lambda_update: int = 5, + lambda_update_mechanism: str = "sequential penalty increase", + lambda_strategy: str = "upper lower bound posiform and negaform method", + lambda_value: float = 1.0, + save_time: bool = False, + ) : Solve the problem using the simulated annealer. The parameters are: + - *problem*: the problem to solve + - *auto_setting*: if True, the parameters are automatically set + - *beta_range*: the range of beta values to use + - *num_reads*: the number of reads + - *annealing_time*: the annealing time + - *num_sweeps_per_beta*: the number of sweeps per beta + - *beta_schedule_type*: the beta schedule type + - *seed*: the seed + - *initial_states*: the initial states + - *initial_states_generator*: the initial states generator + - *max_lambda_update*: the maximum lambda update if the constraints are not satisfied + - *lambda_update_mechanism*: the lambda update mechanism among: + - *sequential penalty increase* + - *scaled sequential penalty increase* + - *binary search penalty algorithm* +- solve_dwave_quantum_annealer( + problem: Problem, + token: str, + auto_setting: bool = False, + failover: bool = True, + config_file: str | None = None, + endpoint: str | None = None, + solver: dict[str, str] | str = "Advantage_system4.1", + annealing_time_scheduling: float | list[list[float]] = 20.0, + num_reads: int = 100, + auto_scale: bool = True, + flux_drift_compensation: bool = True, + initial_state: dict[str, int] | None = None, + programming_thermalization: float = 1000.0, + readout_thermalization: float = 0.0, + reduce_intersample_correlation: bool = True, + max_lambda_update: int = 5, + lambda_update_mechanism: str = "sequential penalty increase", + lambda_strategy: str = "upper lower bound posiform and negaform method", + lambda_value: float = 1.0, + save_time: bool = False, + save_compilation_time: bool = False, + ) : Solve the problem using the D-Wave quantum annealer. The parameters are: + - *problem*: the problem to solve + - *token*: the token to access the D-Wave API + - *auto_setting*: if True, the parameters are automatically set + - *failover*: if True, the failover is enabled + - *config_file*: the configuration file + - *endpoint*: the endpoint + - *solver*: the solver to use + - *annealing_time_scheduling*: the annealing time scheduling + - *num_reads*: the number of reads + - *auto_scale*: if True, the problem is automatically scaled + - *flux_drift_compensation*: if True, the flux drift compensation is enabled + - *initial_state*: the initial state + - *programming_thermalization*: the programming thermalization + - *readout_thermalization*: the readout thermalization + - *reduce_intersample_correlation*: if True, the intersample correlation is reduced + - *max_lambda_update*: the maximum lambda update if the constraints are not satisfied + - *lambda_update_mechanism*: the lambda update mechanism among: + - *sequential penalty increase* + - *scaled sequential penalty increase* + - *binary search penalty algorithm* +- solve_grover_adaptive_search_qubo( + problem: Problem, + auto_setting: bool = False, + qubit_values: int = 0, + coeff_precision: float = 1.0, + threshold: int = 10, + num_runs: int = 10, + max_lambda_update: int = 5, + boundaries_estimation_method: str = "", + lambda_update_mechanism: str = "sequential penalty increase", + lambda_strategy: str = "upper lower bound posiform and negaform method", + lambda_value: float = 1.0, + save_time: bool = False, + save_compilation_time: bool = False, + ) : Solve the problem using the Grover Adaptive Search. The parameters are: + - *problem*: the problem to solve + - *auto_setting*: if True, the parameters are automatically set + - *qubit_values*: the number of qubit values, if the user want to specify it manually + - *coeff_precision*: the coefficient precision + - *threshold*: the threshold + - *num_runs*: the number of runs + - *max_lambda_update*: the maximum lambda update if the constraints are not satisfied + - *boundaries_estimation_method*: the boundaries estimation method for estimating the necessary number of qubit value + - *lambda_update_mechanism*: the lambda update mechanism among: + - *sequential penalty increase* + - *scaled sequential penalty increase* + - *binary search penalty algorithm* +- solve_qaoa_qubo( + problem: Problem, + auto_setting: bool = False, + num_runs: int = 10, + optimizer: Optimizer | None = None, + reps: int = 1, + initial_state: QuantumCircuit | None = None, + mixer: QuantumCircuit = None, + initial_point: np.ndarray[Any, Any] | None = None, + aggregation: float | Callable[[list[float]], float] | None = None, + callback: Callable[[int, np.ndarray[Any, Any], float, float], None] | None = None, + max_lambda_update: int = 5, + lambda_update_mechanism: str = "sequential penalty increase", + lambda_strategy: str = "upper lower bound posiform and negaform method", + lambda_value: float = 1.0, + save_time: bool = False, + save_compilation_time: bool = False, + ) : Solve the problem using the Quantum Approximate Optimization Algorithm. The parameters are: + - *problem*: the problem to solve + - *auto_setting*: if True, the parameters are automatically set + - *num_runs*: the number of runs + - *optimizer*: the optimizer + - *reps*: the number of repetitions + - *initial_state*: the initial state + - *mixer*: the mixer + - *initial_point*: the initial point + - *aggregation*: the aggregation function + - *callback*: the callback function + - *max_lambda_update*: the maximum lambda update if the constraints are not satisfied + - *lambda_update_mechanism*: the lambda update mechanism among: + - *sequential penalty increase* + - *scaled sequential penalty increase* + - *binary search penalty algorithm* +- solve_vqe_qubo( + self, + problem: Problem, + auto_setting: bool = False, + num_runs: int = 10, + optimizer: Optimizer | None = None, + ansatz: QuantumCircuit | None = None, + initial_point: np.ndarray[Any, Any] | None = None, + aggregation: float | Callable[[list[float]], float] | None = None, + callback: Callable[[int, np.ndarray[Any, Any], float, float], None] | None = None, + max_lambda_update: int = 5, + lambda_update_mechanism: str = "sequential penalty increase", + lambda_strategy: str = "upper lower bound posiform and negaform method", + lambda_value: float = 1.0, + save_time: bool = False, + save_compilation_time: bool = False, + ) : Solve the problem using the Variational Quantum Eigensolver. The parameters are: + - *problem*: the problem to solve + - *auto_setting*: if True, the parameters are automatically set + - *num_runs*: the number of runs + - *optimizer*: the optimizer + - *ansatz*: the ansatz + - *initial_point*: the initial point + - *aggregation*: the aggregation function + - *callback*: the callback function + - *max_lambda_update*: the maximum lambda update if the constraints are not satisfied + - *lambda_update_mechanism*: the lambda update mechanism among: + - *sequential penalty increase* + - *scaled sequential penalty increase* + - *binary search penalty algorithm* + +For each of them, the outcome is a Solution object. + + +Examples: +--------- + +Simulated Annealing +~~~~~~~~~~~~~~~~~~~ +.. code-block:: python + + from mqt.qao.constraints import Constraints + from mqt.qao.variables import Variables + from mqt.qao.objectivefunction import ObjectiveFunction + from mqt.qao.problem import Problem + from mqt.qao.solver import Solver + + variables = Variables() + m1 = variables.add_continuous_variables_array( + "M1", [1, 2], -1, 2, -1, "uniform", "logarithmic 2" + ) + m2 = variables.add_continuous_variables_array( + "M2", [2, 1], -1, 2, -1, "uniform", "logarithmic 2" + ) + objective_function = ObjectiveFunction() + objective_function.add_objective_function(np.matmul(m1, m2).item(0, 0)) + constraint = Constraints() + constraint.add_constraint(constraint_expr, variable_precision=True) + problem = Problem() + problem.create_problem(variables, constraint, objective_function) + solver = Solver() + solution = solver.solve_simulated_annealing( + problem, + max_lambda_update=max_lambda_update, + lambda_update_mechanism=lambda_update, + lambda_strategy=lambda_strategy, + ) + +Quantum Annealing +~~~~~~~~~~~~~~~~~~~ +.. code-block:: python + + from mqt.qao.constraints import Constraints + from mqt.qao.variables import Variables + from mqt.qao.objectivefunction import ObjectiveFunction + from mqt.qao.problem import Problem + from mqt.qao.solver import Solver + + variables = Variables() + m1 = variables.add_continuous_variables_array( + "M1", [1, 2], -1, 2, -1, "uniform", "logarithmic 2" + ) + m2 = variables.add_continuous_variables_array( + "M2", [2, 1], -1, 2, -1, "uniform", "logarithmic 2" + ) + objective_function = ObjectiveFunction() + objective_function.add_objective_function(np.matmul(m1, m2).item(0, 0)) + constraint = Constraints() + constraint.add_constraint(constraint_expr, variable_precision=True) + problem = Problem() + problem.create_problem(variables, constraint, objective_function) + solver = Solver() + solution = solver.solve_dwave_quantum_annealer( + token, + problem, + max_lambda_update=max_lambda_update, + lambda_update_mechanism=lambda_update, + lambda_strategy=lambda_strategy, + ) + + +Grover Adaptive Search +~~~~~~~~~~~~~~~~~~~~~~ +.. code-block:: python + + from mqt.qao.constraints import Constraints + from mqt.qao.variables import Variables + from mqt.qao.objectivefunction import ObjectiveFunction + from mqt.qao.problem import Problem + from mqt.qao.solver import Solver + + variables = Variables() + constraint = Constraints() + a0 = variables.add_binary_variable("a") + b0 = variables.add_binary_variable("b") + c0 = variables.add_binary_variable("c") + cost_function = cast(Expr, -a0 + 2 * b0 - 3 * c0 - 2 * a0 * c0 - 1 * b0 * c0) + objective_function = ObjectiveFunction() + objective_function.add_objective_function(cost_function) + problem = Problem() + problem.create_problem(variables, constraint, objective_function) + solver = Solver() + solution = solver.solve_grover_adaptive_search_qubo( + problem, qubit_values=6, num_runs=10 + ) + + + +Quantum Approximate Optimization Algorithm +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.. code-block:: python + + from mqt.qao.constraints import Constraints + from mqt.qao.variables import Variables + from mqt.qao.objectivefunction import ObjectiveFunction + from mqt.qao.problem import Problem + from mqt.qao.solver import Solver + + variables = Variables() + constraint = Constraints() + a0 = variables.add_binary_variable("a") + b0 = variables.add_binary_variable("b") + c0 = variables.add_binary_variable("c") + cost_function = cast(Expr, -a0 + 2 * b0 - 3 * c0 - 2 * a0 * c0 - 1 * b0 * c0) + objective_function = ObjectiveFunction() + objective_function.add_objective_function(cost_function) + problem = Problem() + problem.create_problem(variables, constraint, objective_function) + solver = Solver() + solution = solver.solve_qaoa_qubo( + problem, + num_runs=10, + ) + + +Variational Quantum Eigensolver +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.. code-block:: python + + variables = Variables() + constraint = Constraints() + a0 = variables.add_binary_variable("a") + b0 = variables.add_binary_variable("b") + c0 = variables.add_binary_variable("c") + cost_function = cast(Expr, -a0 + 2 * b0 - 3 * c0 - 2 * a0 * c0 - 1 * b0 * c0) + objective_function = ObjectiveFunction() + objective_function.add_objective_function(cost_function) + problem = Problem() + problem.create_problem(variables, constraint, objective_function) + solver = Solver() + solution = solver.solve_vqe_qubo( + problem, + num_runs=10, + ) diff --git a/docs/Support.rst b/docs/Support.rst new file mode 100644 index 0000000..dbda9df --- /dev/null +++ b/docs/Support.rst @@ -0,0 +1 @@ +.. include:: ../.github/support.rst diff --git a/docs/Usage.rst b/docs/Usage.rst new file mode 100644 index 0000000..c87827b --- /dev/null +++ b/docs/Usage.rst @@ -0,0 +1,31 @@ +Repository Usage +================ +There are two ways how to use MQT Quantum Auto Optimizer: + +#. Via the pip package ``mqt.qao`` +#. Directly via this repository + +Usage via pip package +--------------------- + +MQT Quantum Auto Optimizer is available via `PyPI `_ + +.. code-block:: console + + (venv) $ pip install mqt.qao + + +.. _pip_usage: + +Usage directly via this repository +---------------------------------- + +For that, the repository must be cloned and installed: + +.. code-block:: + + git clone https://github.com/cda-tum/mqt-qao.git + cd mqt-qao + pip install . + +Afterwards, the package can be used as described :ref:`above `. diff --git a/docs/Variable.rst b/docs/Variable.rst new file mode 100644 index 0000000..4c401d4 --- /dev/null +++ b/docs/Variable.rst @@ -0,0 +1,93 @@ +Variables Class +=============== + +It manages the optimization problems variables. + +Variables types supported +------------------------- +Three types of variables are supported: + +- Binary variables: + - unipolar, assuming 0 or 1 values + - bipolar, assuming -1 or 1 values +- Discrete variables, assuming a user-provided list of values +- Continuous variables, assuming all values in a user-provided range with a specified step + +Variables declarations +---------------------- +The class provides methods to declare variables: + +- *add_binary_variable(name: str)*, for adding binary variables + - *name*: variable name +- *add_binary_variable_array(name: str, shape: list[int])*, for adding array of binary variables (supports 1, 2, and 3 dimensional arrays of variables) + - *name*: variable name + - *shape*: list of integers representing the shape of the array +- *add_spin_variable(name: str)*, for adding bipolar binary variables + - *name*: variable name +- *add_spin_variable_array(name: str, shape: list[int])*, for adding array of bipolar binary variables (supports 1, 2, and 3 dimensional arrays of variables). + - *name*: variable name + - *shape*: list of integers representing the shape of the array +- *add_discrete_variable(name: str, values: list[float])*, for adding discrete variables. It needs the set of values. + - *name*: variable name + - *values*: list of values that the variable can assume +- *add_discrete_variable_array(name: str, values: list[float], shape: list[int])*, for adding array of discrete variables. Consider for all the same set of values (supports 1, 2, and 3 dimensional arrays of variables). + - *name*: variable name + - *values*: list of values that the variable can assume + - *shape*: list of integers representing the shape of the array +- *add_continuous_variable(name: str, min_val: float, max_val: float, precision: float, distribution: str = "uniform", encoding_mechanism: str = "")*, for adding continuous variables. It needs the min, max values and the wanted precision. + - *name*: variable name + - *values*: list of values + - *min_val*: minimum value that the variable can assume + - *max_val*: maximum value that the variable can assume + - *precision*: precision of the values that the variable can assume. If logarithmic encoding is considered the values must the wanted power of the base of the logarithm. + - *distribution*: distribution of the values in the range. It can be one among: + - *uniform* + - *geometric* + - *logarithmic* + - *encoding_mechanism*: encoding mechanism for the variable. By default logarithmic encoding is chosen if the precision is a power of two, arithmetic progression otherwise. It can be one among: + - *dictionary* + - *unitary* + - *logarithmic _base_*, with the possibility of specifying the base of the logarithm. Two is considered as default. + - *arithmetic progression* + - *bounded coefficient _bound_*, where _bound_ is the maximum coefficient that can be used in the encoding. +- *add_continuous_variable_array(name: str, min_val: float, max_val: float, precision: float, distribution: str = "uniform", encoding_mechanism: str = "", shape: list[int])*, for adding array of continuous variables. Consider for all the same min, max values and the wanted precision (supports 1, 2, and 3 dimensional arrays of variables). + - *name*: variable name + - *values*: list of values + - *min_val*: minimum value that the variable can assume + - *max_val*: maximum value that the variable can assume + - *precision*: precision of the values that the variable can assume. If logarithmic encoding is considered the values must the wanted power of the base of the logarithm. + - *distribution*: distribution of the values in the range. It can be one among: + - *uniform* + - *geometric* + - *logarithmic* + - *encoding_mechanism*: encoding mechanism for the variable. By default logarithmic encoding is chosen if the precision is a power of two, arithmetic progression otherwise. It can be one among: + - *dictionary* + - *unitary* + - *logarithmic _base_*, with the possibility of specifying the base of the logarithm. Two is considered as default. + - *arithmetic progression* + - *bounded coefficient _bound_*, where _bound_ is the maximum coefficient that can be used in the encoding. + - *shape*: list of integers representing the shape of the array + +Example: +-------- +.. code-block:: python + + from mqt.qao.variables import Variables + + # Variables object declaration + variables = Variables() + + # declaration of a unipolar binary variable + a0 = variables.add_binary_variable("a") + # declaration of a discrete variable, which can assume values -1, 1, 3 + b0 = variables.add_discrete_variable("b", [-1, 1, 3]) + # declaration of a continuous variable, which can assume values in the range [-2, 2] with a precision of 0.25 + c0 = variables.add_continuous_variable("c", -2, 2, 0.25) + + # declaration of a 2D array of continuous variables in the range [-1, 1] with a precision of 0.5 + m1 = variables.add_continuous_variables_array( + "M1", [1, 2], -1, 2, -1, "uniform", "logarithmic 2" + ) + m2 = variables.add_continuous_variables_array( + "M2", [2, 1], -1, 2, -1, "uniform", "logarithmic 2" + ) diff --git a/docs/_static/custom.css b/docs/_static/custom.css new file mode 100644 index 0000000..04260a5 --- /dev/null +++ b/docs/_static/custom.css @@ -0,0 +1,53 @@ +.acknowledgements { + margin-top: 1rem; + padding-bottom: 1rem; + padding-top: 1rem; + border-top: 1px solid var(--color-background-border); + font-size: var(--font-size--small); + color: var(--color-foreground-secondary); +} + +.acknowledgements-logos { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(100px, 1fr)); + grid-gap: 1em; + align-items: center; + margin-top: 0.5rem; +} +.acknowledgement { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; +} + +/* override the default background color for literal strings */ +body:not([data-theme="light"]) .highlight .sa, +.highlight .sb, +.highlight .sc, +.highlight .dl, +.highlight .sd, +.highlight .s2, +.highlight .se, +.highlight .sh, +.highlight .si, +.highlight .sx, +.highlight .sr, +.highlight .s1, +.highlight .ss, +.highlight .s1, +.highlight .s { + background-color: #00000001; +} + +/* provide dark mode overrides for mystnb variables */ +body:not([data-theme="light"]) { + --mystnb-source-bg-color: #131416; + --mystnb-stdout-bg-color: #1a1c1e; + --mystnb-stderr-bg-color: #442222; + --mystnb-traceback-bg-color: #202020; +} + +body:not([data-theme="light"]) .highlight .gp { + color: #c65d09; +} diff --git a/docs/_static/mqt_dark.png b/docs/_static/mqt_dark.png new file mode 100644 index 0000000..adc910c Binary files /dev/null and b/docs/_static/mqt_dark.png differ diff --git a/docs/_static/mqt_light.png b/docs/_static/mqt_light.png new file mode 100644 index 0000000..be279e6 Binary files /dev/null and b/docs/_static/mqt_light.png differ diff --git a/docs/_static/mqt_qao.png b/docs/_static/mqt_qao.png new file mode 100644 index 0000000..674d1ea Binary files /dev/null and b/docs/_static/mqt_qao.png differ diff --git a/docs/_templates/page.html b/docs/_templates/page.html new file mode 100644 index 0000000..4aad54d --- /dev/null +++ b/docs/_templates/page.html @@ -0,0 +1,76 @@ +{% extends "furo/page.html" %} {% block footer %} + +
+ The Munich Quantum Toolkit has been supported by the European Research Council + (ERC) under the European Union's Horizon 2020 research and innovation program + (grant agreement No. 101001318), the Bavarian State Ministry for Science and + Arts through the Distinguished Professorship Program, as well as the Munich + Quantum Valley, which is supported by the Bavarian state government with funds + from the Hightech Agenda Bayern Plus. +
+
+ TUM Logo +
+
+ TUM Logo +
+
+ Coat of Arms of Bavaria +
+
+ ERC Logo +
+
+ ERC Logo +
+
+ MQV Logo +
+
+
+{% endblock footer %} diff --git a/docs/conf.py b/docs/conf.py new file mode 100644 index 0000000..5db9e1f --- /dev/null +++ b/docs/conf.py @@ -0,0 +1,141 @@ +"""Sphinx configuration file.""" + +from __future__ import annotations + +import warnings +from importlib import metadata +from pathlib import Path +from typing import TYPE_CHECKING + +import pybtex.plugin +from pybtex.style.formatting.unsrt import Style as UnsrtStyle +from pybtex.style.template import field, href + +ROOT = Path(__file__).parent.parent.resolve() + + +try: + version = metadata.version("mqt.qao") +except ModuleNotFoundError: + msg = ( + "Package should be installed to produce documentation! " + "Assuming a modern git archive was used for version discovery." + ) + warnings.warn(msg, stacklevel=1) + + from setuptools_scm import get_version + + version = get_version(root=str(ROOT), fallback_root=ROOT) + +# Filter git details from version +release = version.split("+")[0] +if TYPE_CHECKING: + from pybtex.database import Entry + from pybtex.richtext import HRef + +project = "MQT Quantum Auto Optimizer" +author = "Chair for Design Automation, Technical University of Munich" +language = "en" +project_copyright = "2024, Chair for Design Automation, Technical University of Munich" +# -- General configuration --------------------------------------------------- + +master_doc = "index" + +templates_path = ["_templates"] +html_css_files = ["custom.css"] + +extensions = [ + "sphinx.ext.napoleon", + "sphinx.ext.autodoc", + "sphinx.ext.autosummary", + "sphinx.ext.mathjax", + "sphinx.ext.intersphinx", + "sphinx.ext.autosectionlabel", + "sphinx.ext.viewcode", + "sphinx.ext.githubpages", + "sphinxcontrib.bibtex", + "sphinx_copybutton", + "hoverxref.extension", + "nbsphinx", + "sphinxext.opengraph", + "sphinx_autodoc_typehints", +] + +pygments_style = "colorful" + +add_module_names = False + +modindex_common_prefix = ["mqt.qao."] + +intersphinx_mapping = { + "python": ("https://docs.python.org/3", None), + "typing_extensions": ("https://typing-extensions.readthedocs.io/en/latest/", None), + "qiskit": ("https://qiskit.org/documentation/", None), + "mqt": ("https://mqt.readthedocs.io/en/latest/", None), +} + +nbsphinx_execute = "never" +highlight_language = "python3" +nbsphinx_execute_arguments = [ + "--InlineBackend.figure_formats={'svg', 'pdf'}", + "--InlineBackend.rc=figure.dpi=200", +] +nbsphinx_kernel_name = "python3" + +autosectionlabel_prefix_document = True + +hoverxref_auto_ref = True +hoverxref_domains = ["cite", "py"] +hoverxref_roles = [] +hoverxref_mathjax = True +hoverxref_role_types = { + "ref": "tooltip", + "p": "tooltip", + "labelpar": "tooltip", + "class": "tooltip", + "meth": "tooltip", + "func": "tooltip", + "attr": "tooltip", + "property": "tooltip", +} +exclude_patterns = ["_build", "build", "**.ipynb_checkpoints", "Thumbs.db", ".DS_Store", ".env"] + + +class CDAStyle(UnsrtStyle): + """Custom style for including PDF links.""" + + @staticmethod + def format_url(_e: Entry) -> HRef: + """Format URL field as a link to the PDF.""" + url = field("url", raw=True) + return href()[url, "[PDF]"] + + +pybtex.plugin.register_plugin("pybtex.style.formatting", "cda_style", CDAStyle) + +bibtex_bibfiles = ["refs.bib"] +bibtex_default_style = "cda_style" + +copybutton_prompt_text = r"(?:\(venv\) )?(?:\[.*\] )?\$ " +copybutton_prompt_is_regexp = True +copybutton_line_continuation_character = "\\" + +autosummary_generate = True + + +typehints_use_rtype = False +napoleon_use_rtype = False +napoleon_google_docstring = True +napoleon_numpy_docstring = False + +# -- Options for HTML output ------------------------------------------------- +html_theme = "furo" +html_static_path = ["_static"] +html_theme_options = { + "light_logo": "mqt_dark.png", + "dark_logo": "mqt_light.png", + "source_repository": "https://github.com/cda-tum/mqt-qao/", + "source_branch": "main", + "source_directory": "docs/", + "navigation_with_keys": True, +} diff --git a/docs/index.rst b/docs/index.rst new file mode 100644 index 0000000..a21d86b --- /dev/null +++ b/docs/index.rst @@ -0,0 +1,48 @@ +Welcome to MQT Quantum Auto Optimizer's documentation! +====================================================== + +MQT Quantum Auto Optimizer is a tool for automatic framework to assist users in utilizing quantum solvers for optimization tasks while preserving interfaces that closely resemble conventional optimization practices and is developed as part of the `Munich Quantum Toolkit `_ (*MQT*) by the `Chair for Design Automation `_ at the `Technical University of Munich `_. + +From a user's perspective, the framework is used as follows: + +.. image:: /_static/mqt_qao.png + :width: 100% + :alt: Illustration of the MQT Quantum Auto Optimizer framework + :align: center + +The framework is designed to be user-friendly and to provide a high-level interface for assisting assist users in utilizing quantum solvers for optimization tasks, not requiring any prior knowledge of quantum computing. +The framework prompts users to specify variables, optimization criteria, as well as validity constraints and, afterwards, allows them to choose the desired solver. Subsequently, it automatically transforms the problem description into a format compatible with the chosen solver and provides the resulting solution. Additionally, the framework offers instruments for analyzing solution validity and quality. + +If you are interested in the theory behind MQT Quantum Auto Optimizer, have a look at the publications in the :doc:`references list `. + + +---- + + .. toctree:: + :hidden: + + self + + .. toctree:: + :maxdepth: 1 + :caption: User Guide + :glob: + + Quickstart + Usage + Variable + Constraints + ObjectiveFunction + Problem + Solver + Solution + References + + .. toctree:: + :maxdepth: 1 + :caption: Developers + :glob: + + Contributing + DevelopmentGuide + Support diff --git a/docs/refs.bib b/docs/refs.bib new file mode 100644 index 0000000..42f9a00 --- /dev/null +++ b/docs/refs.bib @@ -0,0 +1,6 @@ +@INPROCEEDINGS{volpe2024towards, + AUTHOR = {D.Volpe and N. Quetschlich and M. Graziano and G. Turvani and R. Wille}, + TITLE = {{Towards an Automatic Framework for Solving Optimization Problems with Quantum Computers}}, + YEAR = {2024}, + BOOKTITLE = {IEEE International Conference on Quantum Software (QSW)}, +} diff --git a/noxfile.py b/noxfile.py index e0b7845..2581909 100644 --- a/noxfile.py +++ b/noxfile.py @@ -15,25 +15,13 @@ nox.needs_version = ">=2024.3.2" nox.options.default_venv_backend = "uv|virtualenv" -PYTHON_ALL_VERSIONS = ["3.10", "3.11"] +PYTHON_ALL_VERSIONS = ["3.9", "3.10", "3.11", "3.12"] BUILD_REQUIREMENTS = [ "setuptools>=66.1", - "setuptools_scm>=7", + "setuptools_scm>=8.1", "wheel>=0.40", - "matplotlib>=3.8", - "numpy>=1.23", - "qiskit==0.45.3", - "qiskit_optimization==0.4.0", - "qiskit_ibm_runtime==0.14.0", - "pytest==7.4.0", - "scikit-learn>=1.3", - "dimod>=0.12.0", - "dwave-preprocessing>=0.6.3 ", - "dwave-samplers==1.2", - "dwave-system>=1.20", - "pandas>=2.1", - "qubovert>=1.0", + "cython>=3.0", ] if os.environ.get("CI", None): diff --git a/pyproject.toml b/pyproject.toml index ef7e3a2..e13bb21 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,7 +1,7 @@ [build-system] requires = [ - "setuptools>=61", - "setuptools_scm>=7", + "setuptools>=66.1", + "setuptools_scm>=8.1", ] build-backend = "setuptools.build_meta" @@ -13,28 +13,22 @@ authors = [ { name = "Deborah Volpe", email = "deborah.volpe@polito.it"}, { name = "Nils Quetschlich", email = "nils.quetschlich@tum.de" }, ] -keywords = ["MQT", "quantum computing", "optimization", "QUBO"] +keywords = ["MQT", "quantum-computing", "optimization", "QUBO"] license = { file = "LICENSE" } -requires-python = ">=3.10,<3.12" +requires-python = ">=3.9" dynamic = ["version"] dependencies = [ - "qubovert>=1.0", - "sympy", - "numpy>=1.23", - "dimod>=0.12.0", - "dwave-samplers==1.2", - "dwave-system>=1.20", - "importlib_metadata>=3.6; python_version < '3.10'", - "importlib_resources>=5.9; python_version < '3.10'", - "docplex", - "qiskit=0.45.3", - "qiskit_optimization==0.4.0", - "qiskit_ibm_runtime==0.14.0", - "matplotlib", - "pandas>=2.1", - "PyPortfolioOpt", - "scikit-learn>=1.3", + "qiskit>=1.0", + "qiskit_optimization>=0.6", + "qiskit_aer>=0.14", + "pandas>=2.1.2", + "numpy>=1.26", + "qubovert>=1.2.5", + "matplotlib>=3.8", + "docplex>=2.21.207", + "dwave-system>=1.21.0", + "dwave-samplers>=1.2.0", ] classifiers = [ @@ -45,8 +39,10 @@ classifiers = [ "Operating System :: MacOS", "Operating System :: POSIX :: Linux", "Programming Language :: Python :: 3 :: Only", + "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", "Intended Audience :: Science/Research", "Natural Language :: English", "Topic :: Scientific/Engineering :: Electronic Design Automation (EDA)", @@ -55,7 +51,6 @@ classifiers = [ [project.optional-dependencies] test = ["pytest>=7.2"] coverage = ["mqt.qao[test]", "pytest-cov>=4"] -dev = ["mqt.qao[coverage]"] docs = [ "furo>=2023.08.17", "sphinx~=7.0", @@ -71,6 +66,7 @@ docs = [ "sphinx-autodoc-typehints", "qiskit[visualization]", ] +dev = ["mqt.qao[coverage,docs]"] [project.urls] Homepage = "https://github.com/cda-tum/mqt-qao" @@ -82,37 +78,17 @@ Research = "https://www.cda.cit.tum.de/research/quantum/" [tool.pytest.ini_options] -pythonpath = ["./src"] minversion = "7.2" testpaths = ["tests"] +pythonpath = ["src"] addopts = ["-ra", "--strict-markers", "--strict-config", "--showlocals"] -log_cli_level = "INFO" +log_cli_level = "info" xfail_strict = true filterwarnings = [ "error", - "ignore:.*pkg_resources.*:DeprecationWarning:", - "ignore:.*sre_.*:DeprecationWarning:", - "ignore:.*Rigetti.*:UserWarning:", - "ignore:.*Values in x.*:RuntimeWarning:", - "ignore:.*The Rebase2QuditGatePass has moved to bqskit.passes.retarget.two.*:DeprecationWarning:", - "ignore:.*The least populated class in y has only 3 members, which is less than n_splits=5.*:UserWarning:", - "ignore:.*divide by zero encountered in det.*:RuntimeWarning:", - "ignore:.*invalid value encountered in det.*:RuntimeWarning:", - "ignore:..*env.action_masks to get variables from other wrappers is deprecated and will be removed in v1.0.*:UserWarning:", - "ignore::SyntaxWarning:.*(docplex).*", - "ignore::DeprecationWarning:.*(docplex).*", - "ignore:.*pytorch.*:UserWarning:", - "ignore::DeprecationWarning:.*(importlib).*", - "ignore:.*:DeprecationWarning:qiskit.*", - "ignore:.*:PendingDeprecationWarning:qiskit.*", - "ignore:.*:ImportWarning:.*", - "ignore:.*:DeprecationWarning:qiskit.providers.ibmq.*", - "ignore:.*qiskit.algorithms.*:DeprecationWarning:.*", - "ignore::sklearn.exceptions.InconsistentVersionWarning:sklearn:", + "ignore:.*Qiskit with Python 3.8.*:DeprecationWarning:", ] -[tool.check-wheel-contents] -ignore = "W002" [tool.coverage] run.source = ["mqt.qao"] @@ -129,19 +105,32 @@ precision = 1 [tool.mypy] -mypy_path = "$MYPY_CONFIG_FILE_DIR/src" files = ["src", "tests"] -python_version = "3.11" -strict = true +mypy_path = ["$MYPY_CONFIG_FILE_DIR/src"] +python_version = "3.9" +warn_unused_configs = true enable_error_code = ["ignore-without-code", "redundant-expr", "truthy-bool"] -warn_unreachable = true +strict = true +disallow_untyped_defs = false explicit_package_bases = true -no_implicit_reexport = true -pretty = true +warn_unreachable = true [[tool.mypy.overrides]] -module = ["qubovert.*", "sympy.*", "dwave.samplers.*", "dwave.system.*", "docplex.*", "qiskit.*", "qiskit_optimization.*", "qiskit_ibm_provider.*", "matplotlib.*", "pandas.*", "pypfopt.*", "sklearn.*"] +module = [ + "qiskit.*", + "qiskit_optimization.*", + "qiskit_algorithms.*", + "qiskit_aer.*", + "matplotlib.*", + "qubovert.*", + "sympy.*", + "qiskit_ibm_runtime.*", + "matplotlib.*", + "docplex.*", + "dimod.*", + "dwave.*" +] ignore_missing_imports = true @@ -151,6 +140,7 @@ extend-include = ["*.ipynb"] src = ["src"] preview = true unsafe-fixes = true + [tool.ruff.lint] extend-select = [ "A", # flake8-builtins @@ -186,30 +176,45 @@ extend-select = [ "SLOT", # flake8-slots "SIM", # flake8-simplify "TCH", # flake8-type-checking - "TID", # flake8-tidy-imports + "TID251", # flake8-tidy-imports.banned-api "TRY", # tryceratops "UP", # pyupgrade "YTT", # flake8-2020 ] ignore = [ - "ANN101", # Missing type annotation for self in method - "ANN102", # Missing type annotation for cls in classmethod + "ANN101", # Missing type annotation for `self` in method + "ANN102", # Missing type annotation for `cls` in classmethod "ISC001", # Conflicts with formatter - "E501", # Line too long (Black is enough) - "PLR", # Design related pylint codes + "PLR09", # Too many <...> + "PLR2004", # Magic value used in comparison + "PLC0415", # Import should be at top of file + "PT004", # Incorrect, just usefixtures instead. "S101", # Use of assert detected - "I001", # isort: Missing import + "S404", # `subprocess` module is possibly insecure ] -flake8-unused-arguments.ignore-variadic-names = true isort.required-imports = ["from __future__ import annotations"] +[tool.ruff.lint.flake8-tidy-imports.banned-api] +"typing.Callable".msg = "Use collections.abc.Callable instead." +"typing.Iterator".msg = "Use collections.abc.Iterator instead." +"typing.Mapping".msg = "Use collections.abc.Mapping instead." +"typing.Sequence".msg = "Use collections.abc.Sequence instead." +"typing.Set".msg = "Use collections.abc.Set instead." +"typing.Self".msg = "Use scikit_build_core._compat.typing.Self instead." +"typing_extensions.Self".msg = "Use scikit_build_core._compat.typing.Self instead." +"typing.assert_never".msg = "Use scikit_build_core._compat.typing.assert_never instead." +"importlib.resources".msg = "Use scikit_build_core._compat.importlib.resources instead." +"importlib_resources".msg = "Use scikit_build_core._compat.importlib.resources instead." + [tool.ruff.lint.per-file-ignores] -"*.pyi" = ["D"] # pydocstyle +"tests/**" = ["T20", "ANN"] +"docs/**" = ["T20"] +"noxfile.py" = ["T20", "TID251"] +"*.pyi" = ["D418", "PYI021"] # pydocstyle "*.ipynb" = [ "D", # pydocstyle "E402", # Allow imports to appear anywhere in Jupyter notebooks "I002", # Allow missing `from __future__ import annotations` import - "I001", # Allow missing unsorted import ] [tool.ruff.lint.pydocstyle] diff --git a/scripts/Knapsack/Data/f10_l-d_kp_20_879 b/scripts/Knapsack/Data/f10_l-d_kp_20_879 new file mode 100644 index 0000000..e2cc105 --- /dev/null +++ b/scripts/Knapsack/Data/f10_l-d_kp_20_879 @@ -0,0 +1,21 @@ +20 879 +91 84 +72 83 +90 43 +46 4 +55 44 +8 6 +35 82 +75 92 +61 25 +15 83 +77 56 +40 18 +63 58 +75 14 +29 48 +75 70 +17 96 +78 32 +40 68 +44 92 diff --git a/scripts/Knapsack/Data/f1_l-d_kp_10_269 b/scripts/Knapsack/Data/f1_l-d_kp_10_269 new file mode 100644 index 0000000..4adaa2c --- /dev/null +++ b/scripts/Knapsack/Data/f1_l-d_kp_10_269 @@ -0,0 +1,11 @@ +10 269 +55 95 +10 4 +47 60 +5 32 +4 23 +50 72 +8 80 +61 62 +85 65 +87 46 diff --git a/scripts/Knapsack/Data/f2_l-d_kp_20_878 b/scripts/Knapsack/Data/f2_l-d_kp_20_878 new file mode 100644 index 0000000..2a9148e --- /dev/null +++ b/scripts/Knapsack/Data/f2_l-d_kp_20_878 @@ -0,0 +1,21 @@ +20 878 +44 92 +46 4 +90 43 +72 83 +91 84 +40 68 +75 92 +35 82 +8 6 +54 44 +78 32 +40 18 +77 56 +15 83 +61 25 +17 96 +75 70 +29 48 +75 14 +63 58 diff --git a/scripts/Knapsack/Data/f3_l-d_kp_4_20 b/scripts/Knapsack/Data/f3_l-d_kp_4_20 new file mode 100644 index 0000000..7388b39 --- /dev/null +++ b/scripts/Knapsack/Data/f3_l-d_kp_4_20 @@ -0,0 +1,5 @@ +4 20 +9 6 +11 5 +13 9 +15 7 diff --git a/scripts/Knapsack/Data/f4_l-d_kp_4_11 b/scripts/Knapsack/Data/f4_l-d_kp_4_11 new file mode 100644 index 0000000..1630d23 --- /dev/null +++ b/scripts/Knapsack/Data/f4_l-d_kp_4_11 @@ -0,0 +1,5 @@ +4 11 +6 2 +10 4 +12 6 +13 7 diff --git a/scripts/Knapsack/Data/f5_l-d_kp_15_375 b/scripts/Knapsack/Data/f5_l-d_kp_15_375 new file mode 100644 index 0000000..ff150c3 --- /dev/null +++ b/scripts/Knapsack/Data/f5_l-d_kp_15_375 @@ -0,0 +1,16 @@ +15 375 +0.125126 56.358531 +19.330424 80.874050 +58.500931 47.987304 +35.029145 89.596240 +82.284005 74.660482 +17.410810 85.894345 +71.050142 51.353496 +30.399487 1.498459 +9.140294 36.445204 +14.731285 16.589862 +98.852504 44.569231 +11.908322 0.466933 +0.891140 37.788018 +53.166295 57.118442 +60.176397 60.716575 diff --git a/scripts/Knapsack/Data/f6_l-d_kp_10_60 b/scripts/Knapsack/Data/f6_l-d_kp_10_60 new file mode 100644 index 0000000..587b40d --- /dev/null +++ b/scripts/Knapsack/Data/f6_l-d_kp_10_60 @@ -0,0 +1,11 @@ +10 60 +20 30 +18 25 +17 20 +15 18 +15 17 +10 11 +5 5 +3 2 +1 1 +1 1 diff --git a/scripts/Knapsack/Data/f7_l-d_kp_7_50 b/scripts/Knapsack/Data/f7_l-d_kp_7_50 new file mode 100644 index 0000000..04963f9 --- /dev/null +++ b/scripts/Knapsack/Data/f7_l-d_kp_7_50 @@ -0,0 +1,8 @@ +7 50 +70 31 +20 10 +39 20 +37 19 +7 4 +5 3 +10 6 diff --git a/scripts/Knapsack/Data/f8_l-d_kp_23_10000 b/scripts/Knapsack/Data/f8_l-d_kp_23_10000 new file mode 100644 index 0000000..1dd6547 --- /dev/null +++ b/scripts/Knapsack/Data/f8_l-d_kp_23_10000 @@ -0,0 +1,24 @@ +23 10000 +981 983 +980 982 +979 981 +978 980 +977 979 +976 978 +487 488 +974 976 +970 972 +485 486 +485 486 +970 972 +970 972 +484 485 +484 485 +976 969 +974 966 +482 483 +962 964 +961 963 +959 961 +958 958 +857 959 diff --git a/scripts/Knapsack/Data/f9_l-d_kp_5_80 b/scripts/Knapsack/Data/f9_l-d_kp_5_80 new file mode 100644 index 0000000..9c6bafd --- /dev/null +++ b/scripts/Knapsack/Data/f9_l-d_kp_5_80 @@ -0,0 +1,6 @@ +5 80 +33 15 +24 20 +36 17 +37 8 +12 31 diff --git a/scripts/Knapsack/Data/knapPI_1_1000_1000_1 b/scripts/Knapsack/Data/knapPI_1_1000_1000_1 new file mode 100644 index 0000000..bae8935 --- /dev/null +++ b/scripts/Knapsack/Data/knapPI_1_1000_1000_1 @@ -0,0 +1,1002 @@ +1000 5002 +94 485 +506 326 +416 248 +992 421 +649 322 +237 795 +457 43 +815 845 +446 955 +422 252 +791 9 +359 901 +667 122 +598 94 +7 738 +544 574 +334 715 +766 882 +994 367 +893 984 +633 299 +131 433 +428 682 +700 72 +617 874 +874 138 +720 856 +419 145 +794 995 +196 529 +997 199 +116 277 +908 97 +539 719 +707 242 +569 107 +537 122 +931 70 +726 98 +487 600 +772 645 +513 267 +81 972 +943 895 +58 213 +303 748 +764 487 +536 923 +724 29 +789 674 +479 540 +142 554 +339 467 +641 46 +196 710 +494 553 +66 191 +824 724 +208 730 +711 988 +800 90 +314 340 +289 549 +401 196 +466 865 +689 678 +833 570 +225 936 +244 722 +849 651 +113 123 +379 431 +361 508 +65 585 +486 853 +686 642 +286 992 +889 725 +24 286 +491 812 +891 859 +90 663 +181 88 +214 179 +17 187 +472 619 +418 261 +419 846 +356 192 +682 261 +306 514 +201 886 +385 530 +952 849 +500 294 +194 799 +737 391 +324 330 +992 298 +224 790 +260 275 +97 826 +210 72 +649 866 +919 951 +63 748 +958 685 +804 956 +518 564 +428 183 +537 400 +346 721 +153 207 +971 323 +662 611 +197 116 +91 109 +529 795 +126 343 +747 862 +469 685 +770 10 +934 881 +723 984 +895 403 +568 360 +172 449 +958 541 +383 272 +308 877 +970 359 +583 707 +48 308 +930 770 +569 30 +3 208 +20 311 +609 100 +887 939 +825 422 +930 785 +904 370 +241 989 +379 969 +376 143 +962 972 +889 28 +443 61 +216 638 +338 348 +160 347 +406 66 +159 391 +31 638 +204 295 +420 826 +153 196 +425 449 +331 855 +565 143 +838 487 +9 140 +918 564 +533 615 +232 135 +957 564 +591 360 +576 793 +746 163 +377 859 +858 760 +86 711 +434 662 +558 159 +279 660 +840 268 +735 948 +574 315 +126 676 +912 341 +739 689 +821 894 +625 706 +917 490 +201 478 +993 671 +149 932 +52 899 +759 237 +267 187 +256 472 +783 772 +117 98 +516 906 +180 911 +25 635 +380 225 +712 823 +266 164 +216 343 +448 732 +541 502 +664 740 +954 576 +726 612 +772 902 +531 454 +943 411 +750 973 +327 703 +917 850 +5 77 +113 220 +913 802 +791 403 +998 181 +859 10 +345 525 +431 919 +675 668 +833 527 +438 462 +523 291 +916 605 +420 457 +115 405 +660 417 +261 279 +772 685 +388 596 +764 307 +843 224 +206 322 +407 840 +639 975 +852 401 +542 91 +60 327 +757 330 +82 182 +637 603 +93 793 +614 615 +136 733 +187 864 +102 16 +972 863 +163 987 +501 306 +477 34 +492 840 +121 700 +80 706 +138 787 +660 105 +229 834 +827 798 +448 310 +230 609 +832 690 +489 561 +586 579 +291 60 +665 388 +660 309 +702 407 +153 200 +606 313 +123 970 +253 33 +709 273 +832 277 +108 997 +888 40 +481 227 +283 860 +858 940 +284 608 +711 990 +850 590 +239 806 +943 52 +195 801 +95 764 +410 710 +664 386 +900 593 +112 50 +963 494 +754 156 +458 936 +19 965 +225 86 +569 723 +97 184 +194 868 +754 340 +602 412 +61 487 +695 209 +347 346 +719 860 +100 307 +97 95 +843 821 +745 941 +286 821 +492 587 +116 201 +531 665 +424 527 +253 812 +426 424 +413 459 +980 343 +291 836 +833 506 +486 179 +9 916 +575 430 +922 596 +145 808 +897 269 +404 512 +742 811 +728 685 +269 567 +103 776 +745 855 +35 718 +779 853 +71 97 +80 146 +842 746 +128 15 +941 965 +227 512 +30 480 +342 958 +605 665 +531 191 +364 964 +359 515 +867 606 +820 822 +313 536 +207 693 +911 19 +308 335 +430 101 +685 922 +641 294 +113 910 +141 410 +690 250 +700 546 +559 729 +481 609 +503 720 +766 976 +7 759 +882 798 +859 74 +182 648 +425 299 +542 785 +683 846 +853 390 +938 897 +89 416 +624 837 +181 247 +878 293 +933 144 +580 938 +252 467 +207 480 +658 955 +20 665 +954 26 +347 564 +759 449 +446 26 +14 521 +657 301 +710 321 +980 613 +188 388 +636 879 +203 990 +432 188 +129 963 +630 820 +509 300 +237 822 +373 255 +838 277 +395 153 +692 400 +103 227 +218 518 +384 447 +931 315 +396 813 +389 324 +640 502 +287 299 +297 780 +977 376 +512 516 +219 212 +555 329 +398 810 +289 486 +798 485 +598 416 +49 952 +572 894 +697 358 +770 21 +725 647 +542 44 +214 683 +887 361 +45 814 +94 231 +282 8 +82 165 +319 496 +626 699 +146 852 +541 459 +874 535 +725 314 +777 944 +554 306 +208 459 +787 637 +976 447 +912 408 +444 107 +3 962 +301 565 +164 407 +437 857 +652 317 +764 98 +41 818 +737 600 +176 288 +136 902 +128 567 +394 190 +235 749 +42 908 +824 276 +684 748 +979 592 +568 393 +367 363 +52 163 +642 983 +335 179 +126 16 +130 478 +583 259 +129 868 +752 295 +167 596 +856 71 +640 622 +770 864 +431 644 +195 5 +448 365 +701 429 +952 64 +880 854 +168 770 +79 88 +961 157 +472 368 +217 421 +709 719 +147 271 +296 975 +909 816 +764 962 +251 535 +878 438 +753 696 +570 881 +253 318 +666 45 +931 52 +433 496 +810 313 +678 138 +123 334 +212 988 +66 508 +206 770 +750 751 +64 780 +466 441 +337 207 +510 516 +796 674 +175 408 +437 920 +938 573 +848 634 +561 878 +718 990 +948 826 +649 696 +569 800 +663 411 +582 422 +843 707 +202 334 +702 986 +579 494 +725 150 +803 562 +340 380 +156 832 +832 979 +602 376 +234 511 +688 414 +184 160 +978 982 +413 238 +633 490 +585 899 +606 251 +963 526 +350 897 +242 39 +539 657 +739 452 +267 538 +165 831 +177 460 +720 185 +802 934 +644 440 +82 490 +798 168 +197 71 +173 977 +81 458 +235 204 +112 803 +103 139 +268 399 +879 420 +643 991 +106 578 +122 972 +444 177 +262 398 +691 348 +997 496 +446 276 +171 825 +549 614 +281 121 +211 730 +112 341 +408 284 +730 698 +363 17 +89 546 +605 672 +938 974 +168 866 +705 377 +47 559 +400 340 +215 527 +114 779 +51 761 +881 483 +549 92 +679 390 +328 583 +250 661 +203 391 +481 336 +752 661 +707 125 +82 89 +63 275 +660 359 +21 178 +287 780 +219 42 +500 5 +820 380 +95 772 +44 816 +748 9 +678 484 +276 545 +478 589 +663 157 +594 901 +757 777 +947 74 +448 247 +570 55 +313 479 +981 785 +795 958 +552 680 +389 393 +280 944 +864 596 +636 619 +512 611 +892 852 +184 283 +947 299 +614 766 +625 312 +149 826 +377 726 +474 733 +18 805 +662 679 +416 403 +1 964 +530 337 +752 541 +22 478 +981 369 +777 946 +957 821 +275 833 +584 837 +582 490 +121 37 +951 594 +668 129 +118 258 +319 246 +896 362 +521 755 +948 504 +248 71 +474 177 +351 176 +54 803 +155 237 +660 677 +871 33 +486 115 +294 597 +425 769 +245 536 +382 956 +371 341 +708 184 +544 234 +794 569 +387 216 +738 537 +520 84 +281 810 +502 657 +91 33 +503 159 +924 520 +16 668 +33 287 +344 229 +349 374 +606 474 +896 672 +595 915 +441 511 +102 123 +52 569 +654 199 +710 396 +434 715 +245 59 +36 610 +661 917 +413 927 +13 270 +370 117 +400 516 +195 215 +984 216 +476 237 +164 615 +405 499 +674 477 +196 760 +608 285 +907 56 +532 966 +51 622 +716 221 +327 194 +880 91 +710 347 +267 252 +400 473 +376 516 +609 385 +320 357 +196 958 +538 665 +935 792 +404 64 +100 420 +126 671 +855 968 +94 877 +731 177 +253 523 +8 139 +393 152 +543 732 +348 246 +318 565 +489 740 +22 902 +998 17 +49 973 +381 298 +10 611 +429 32 +221 11 +150 337 +717 136 +530 889 +332 522 +942 805 +565 28 +216 931 +61 757 +170 609 +872 544 +644 905 +208 595 +680 246 +697 113 +639 175 +679 156 +961 244 +361 883 +802 265 +359 883 +839 462 +718 485 +280 272 +252 204 +280 984 +102 409 +615 398 +296 909 +481 370 +956 882 +230 214 +259 766 +922 35 +706 421 +272 271 +156 370 +552 848 +485 50 +536 976 +70 270 +902 796 +452 963 +35 379 +947 991 +378 551 +57 897 +352 307 +669 421 +702 74 +141 388 +458 559 +463 980 +756 615 +887 681 +332 231 +528 207 +656 818 +254 331 +787 979 +495 445 +370 348 +10 724 +200 401 +327 646 +17 668 +374 242 +755 302 +980 861 +376 830 +8 77 +32 441 +460 589 +804 990 +23 189 +869 868 +943 996 +715 363 +628 237 +73 420 +199 565 +38 214 +209 333 +327 726 +912 175 +799 58 +372 625 +976 66 +120 169 +667 475 +188 204 +28 90 +704 496 +649 1 +746 474 +697 449 +712 252 +289 332 +625 287 +953 189 +462 889 +302 63 +79 378 +41 206 +823 897 +908 230 +665 382 +36 575 +732 60 +809 529 +66 477 +291 290 +591 89 +583 961 +252 461 +479 702 +530 532 +224 680 +788 53 +309 642 +366 1000 +352 891 +402 822 +545 152 +113 324 +967 633 +454 267 +723 381 +14 272 +20 506 +308 419 +644 461 +713 526 +482 978 +336 468 +289 729 +496 795 +326 581 +530 383 +167 226 +522 421 +830 386 +91 273 +116 484 +747 676 +395 107 +958 229 +756 902 +262 962 +703 105 +511 84 +481 991 +449 701 +888 689 +599 655 +306 600 +492 538 +803 499 +445 881 +316 981 +889 473 +785 383 +765 679 +491 573 +589 589 +124 480 +741 145 +898 624 +725 923 +682 915 +131 232 +398 974 +906 735 +753 678 +312 640 +790 644 +301 212 +945 123 +447 253 +197 943 +27 18 +573 916 +589 327 +934 640 +209 615 +529 470 +899 655 +15 288 +592 401 +92 840 +575 633 +814 707 +354 424 +127 682 +374 194 +566 855 +594 190 +973 728 +645 178 +603 275 +712 88 +32 367 +298 544 +561 738 +906 963 +626 460 +143 266 +504 727 +836 33 +361 442 +431 628 +554 384 +24 244 +416 482 +735 765 +243 446 +454 247 +932 913 +494 560 +648 528 +357 594 +596 935 +788 462 +536 621 +759 660 +200 564 +566 302 +741 936 +217 592 +219 724 +832 118 +819 299 +487 251 +473 129 +241 96 +64 167 +516 169 +857 381 +218 976 +490 767 +504 837 +707 407 +342 203 +475 387 +175 735 +786 706 +171 335 +232 40 +888 821 +866 131 +976 159 +253 978 +619 53 +642 849 +460 478 +218 19 +218 230 +667 453 +949 336 +89 931 +488 588 +568 449 +526 566 +0 0 0 0 0 0 1 0 0 0 1 0 1 1 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 1 0 0 1 0 1 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 1 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 1 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 1 1 0 0 0 1 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 1 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 1 0 1 0 0 1 0 0 0 0 0 0 0 diff --git a/scripts/Knapsack/Data/knapPI_1_100_1000_1 b/scripts/Knapsack/Data/knapPI_1_100_1000_1 new file mode 100644 index 0000000..109fc20 --- /dev/null +++ b/scripts/Knapsack/Data/knapPI_1_100_1000_1 @@ -0,0 +1,102 @@ +100 995 +94 485 +506 326 +416 248 +992 421 +649 322 +237 795 +457 43 +815 845 +446 955 +422 252 +791 9 +359 901 +667 122 +598 94 +7 738 +544 574 +334 715 +766 882 +994 367 +893 984 +633 299 +131 433 +428 682 +700 72 +617 874 +874 138 +720 856 +419 145 +794 995 +196 529 +997 199 +116 277 +908 97 +539 719 +707 242 +569 107 +537 122 +931 70 +726 98 +487 600 +772 645 +513 267 +81 972 +943 895 +58 213 +303 748 +764 487 +536 923 +724 29 +789 674 +479 540 +142 554 +339 467 +641 46 +196 710 +494 553 +66 191 +824 724 +208 730 +711 988 +800 90 +314 340 +289 549 +401 196 +466 865 +689 678 +833 570 +225 936 +244 722 +849 651 +113 123 +379 431 +361 508 +65 585 +486 853 +686 642 +286 992 +889 725 +24 286 +491 812 +891 859 +90 663 +181 88 +214 179 +17 187 +472 619 +418 261 +419 846 +356 192 +682 261 +306 514 +201 886 +385 530 +952 849 +500 294 +194 799 +737 391 +324 330 +992 298 +224 790 +0 0 0 0 0 0 1 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 1 0 1 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 diff --git a/scripts/Knapsack/Data/knapPI_1_2000_1000_1 b/scripts/Knapsack/Data/knapPI_1_2000_1000_1 new file mode 100644 index 0000000..6c17313 --- /dev/null +++ b/scripts/Knapsack/Data/knapPI_1_2000_1000_1 @@ -0,0 +1,2002 @@ +2000 10011 +94 485 +506 326 +416 248 +992 421 +649 322 +237 795 +457 43 +815 845 +446 955 +422 252 +791 9 +359 901 +667 122 +598 94 +7 738 +544 574 +334 715 +766 882 +994 367 +893 984 +633 299 +131 433 +428 682 +700 72 +617 874 +874 138 +720 856 +419 145 +794 995 +196 529 +997 199 +116 277 +908 97 +539 719 +707 242 +569 107 +537 122 +931 70 +726 98 +487 600 +772 645 +513 267 +81 972 +943 895 +58 213 +303 748 +764 487 +536 923 +724 29 +789 674 +479 540 +142 554 +339 467 +641 46 +196 710 +494 553 +66 191 +824 724 +208 730 +711 988 +800 90 +314 340 +289 549 +401 196 +466 865 +689 678 +833 570 +225 936 +244 722 +849 651 +113 123 +379 431 +361 508 +65 585 +486 853 +686 642 +286 992 +889 725 +24 286 +491 812 +891 859 +90 663 +181 88 +214 179 +17 187 +472 619 +418 261 +419 846 +356 192 +682 261 +306 514 +201 886 +385 530 +952 849 +500 294 +194 799 +737 391 +324 330 +992 298 +224 790 +260 275 +97 826 +210 72 +649 866 +919 951 +63 748 +958 685 +804 956 +518 564 +428 183 +537 400 +346 721 +153 207 +971 323 +662 611 +197 116 +91 109 +529 795 +126 343 +747 862 +469 685 +770 10 +934 881 +723 984 +895 403 +568 360 +172 449 +958 541 +383 272 +308 877 +970 359 +583 707 +48 308 +930 770 +569 30 +3 208 +20 311 +609 100 +887 939 +825 422 +930 785 +904 370 +241 989 +379 969 +376 143 +962 972 +889 28 +443 61 +216 638 +338 348 +160 347 +406 66 +159 391 +31 638 +204 295 +420 826 +153 196 +425 449 +331 855 +565 143 +838 487 +9 140 +918 564 +533 615 +232 135 +957 564 +591 360 +576 793 +746 163 +377 859 +858 760 +86 711 +434 662 +558 159 +279 660 +840 268 +735 948 +574 315 +126 676 +912 341 +739 689 +821 894 +625 706 +917 490 +201 478 +993 671 +149 932 +52 899 +759 237 +267 187 +256 472 +783 772 +117 98 +516 906 +180 911 +25 635 +380 225 +712 823 +266 164 +216 343 +448 732 +541 502 +664 740 +954 576 +726 612 +772 902 +531 454 +943 411 +750 973 +327 703 +917 850 +5 77 +113 220 +913 802 +791 403 +998 181 +859 10 +345 525 +431 919 +675 668 +833 527 +438 462 +523 291 +916 605 +420 457 +115 405 +660 417 +261 279 +772 685 +388 596 +764 307 +843 224 +206 322 +407 840 +639 975 +852 401 +542 91 +60 327 +757 330 +82 182 +637 603 +93 793 +614 615 +136 733 +187 864 +102 16 +972 863 +163 987 +501 306 +477 34 +492 840 +121 700 +80 706 +138 787 +660 105 +229 834 +827 798 +448 310 +230 609 +832 690 +489 561 +586 579 +291 60 +665 388 +660 309 +702 407 +153 200 +606 313 +123 970 +253 33 +709 273 +832 277 +108 997 +888 40 +481 227 +283 860 +858 940 +284 608 +711 990 +850 590 +239 806 +943 52 +195 801 +95 764 +410 710 +664 386 +900 593 +112 50 +963 494 +754 156 +458 936 +19 965 +225 86 +569 723 +97 184 +194 868 +754 340 +602 412 +61 487 +695 209 +347 346 +719 860 +100 307 +97 95 +843 821 +745 941 +286 821 +492 587 +116 201 +531 665 +424 527 +253 812 +426 424 +413 459 +980 343 +291 836 +833 506 +486 179 +9 916 +575 430 +922 596 +145 808 +897 269 +404 512 +742 811 +728 685 +269 567 +103 776 +745 855 +35 718 +779 853 +71 97 +80 146 +842 746 +128 15 +941 965 +227 512 +30 480 +342 958 +605 665 +531 191 +364 964 +359 515 +867 606 +820 822 +313 536 +207 693 +911 19 +308 335 +430 101 +685 922 +641 294 +113 910 +141 410 +690 250 +700 546 +559 729 +481 609 +503 720 +766 976 +7 759 +882 798 +859 74 +182 648 +425 299 +542 785 +683 846 +853 390 +938 897 +89 416 +624 837 +181 247 +878 293 +933 144 +580 938 +252 467 +207 480 +658 955 +20 665 +954 26 +347 564 +759 449 +446 26 +14 521 +657 301 +710 321 +980 613 +188 388 +636 879 +203 990 +432 188 +129 963 +630 820 +509 300 +237 822 +373 255 +838 277 +395 153 +692 400 +103 227 +218 518 +384 447 +931 315 +396 813 +389 324 +640 502 +287 299 +297 780 +977 376 +512 516 +219 212 +555 329 +398 810 +289 486 +798 485 +598 416 +49 952 +572 894 +697 358 +770 21 +725 647 +542 44 +214 683 +887 361 +45 814 +94 231 +282 8 +82 165 +319 496 +626 699 +146 852 +541 459 +874 535 +725 314 +777 944 +554 306 +208 459 +787 637 +976 447 +912 408 +444 107 +3 962 +301 565 +164 407 +437 857 +652 317 +764 98 +41 818 +737 600 +176 288 +136 902 +128 567 +394 190 +235 749 +42 908 +824 276 +684 748 +979 592 +568 393 +367 363 +52 163 +642 983 +335 179 +126 16 +130 478 +583 259 +129 868 +752 295 +167 596 +856 71 +640 622 +770 864 +431 644 +195 5 +448 365 +701 429 +952 64 +880 854 +168 770 +79 88 +961 157 +472 368 +217 421 +709 719 +147 271 +296 975 +909 816 +764 962 +251 535 +878 438 +753 696 +570 881 +253 318 +666 45 +931 52 +433 496 +810 313 +678 138 +123 334 +212 988 +66 508 +206 770 +750 751 +64 780 +466 441 +337 207 +510 516 +796 674 +175 408 +437 920 +938 573 +848 634 +561 878 +718 990 +948 826 +649 696 +569 800 +663 411 +582 422 +843 707 +202 334 +702 986 +579 494 +725 150 +803 562 +340 380 +156 832 +832 979 +602 376 +234 511 +688 414 +184 160 +978 982 +413 238 +633 490 +585 899 +606 251 +963 526 +350 897 +242 39 +539 657 +739 452 +267 538 +165 831 +177 460 +720 185 +802 934 +644 440 +82 490 +798 168 +197 71 +173 977 +81 458 +235 204 +112 803 +103 139 +268 399 +879 420 +643 991 +106 578 +122 972 +444 177 +262 398 +691 348 +997 496 +446 276 +171 825 +549 614 +281 121 +211 730 +112 341 +408 284 +730 698 +363 17 +89 546 +605 672 +938 974 +168 866 +705 377 +47 559 +400 340 +215 527 +114 779 +51 761 +881 483 +549 92 +679 390 +328 583 +250 661 +203 391 +481 336 +752 661 +707 125 +82 89 +63 275 +660 359 +21 178 +287 780 +219 42 +500 5 +820 380 +95 772 +44 816 +748 9 +678 484 +276 545 +478 589 +663 157 +594 901 +757 777 +947 74 +448 247 +570 55 +313 479 +981 785 +795 958 +552 680 +389 393 +280 944 +864 596 +636 619 +512 611 +892 852 +184 283 +947 299 +614 766 +625 312 +149 826 +377 726 +474 733 +18 805 +662 679 +416 403 +1 964 +530 337 +752 541 +22 478 +981 369 +777 946 +957 821 +275 833 +584 837 +582 490 +121 37 +951 594 +668 129 +118 258 +319 246 +896 362 +521 755 +948 504 +248 71 +474 177 +351 176 +54 803 +155 237 +660 677 +871 33 +486 115 +294 597 +425 769 +245 536 +382 956 +371 341 +708 184 +544 234 +794 569 +387 216 +738 537 +520 84 +281 810 +502 657 +91 33 +503 159 +924 520 +16 668 +33 287 +344 229 +349 374 +606 474 +896 672 +595 915 +441 511 +102 123 +52 569 +654 199 +710 396 +434 715 +245 59 +36 610 +661 917 +413 927 +13 270 +370 117 +400 516 +195 215 +984 216 +476 237 +164 615 +405 499 +674 477 +196 760 +608 285 +907 56 +532 966 +51 622 +716 221 +327 194 +880 91 +710 347 +267 252 +400 473 +376 516 +609 385 +320 357 +196 958 +538 665 +935 792 +404 64 +100 420 +126 671 +855 968 +94 877 +731 177 +253 523 +8 139 +393 152 +543 732 +348 246 +318 565 +489 740 +22 902 +998 17 +49 973 +381 298 +10 611 +429 32 +221 11 +150 337 +717 136 +530 889 +332 522 +942 805 +565 28 +216 931 +61 757 +170 609 +872 544 +644 905 +208 595 +680 246 +697 113 +639 175 +679 156 +961 244 +361 883 +802 265 +359 883 +839 462 +718 485 +280 272 +252 204 +280 984 +102 409 +615 398 +296 909 +481 370 +956 882 +230 214 +259 766 +922 35 +706 421 +272 271 +156 370 +552 848 +485 50 +536 976 +70 270 +902 796 +452 963 +35 379 +947 991 +378 551 +57 897 +352 307 +669 421 +702 74 +141 388 +458 559 +463 980 +756 615 +887 681 +332 231 +528 207 +656 818 +254 331 +787 979 +495 445 +370 348 +10 724 +200 401 +327 646 +17 668 +374 242 +755 302 +980 861 +376 830 +8 77 +32 441 +460 589 +804 990 +23 189 +869 868 +943 996 +715 363 +628 237 +73 420 +199 565 +38 214 +209 333 +327 726 +912 175 +799 58 +372 625 +976 66 +120 169 +667 475 +188 204 +28 90 +704 496 +649 1 +746 474 +697 449 +712 252 +289 332 +625 287 +953 189 +462 889 +302 63 +79 378 +41 206 +823 897 +908 230 +665 382 +36 575 +732 60 +809 529 +66 477 +291 290 +591 89 +583 961 +252 461 +479 702 +530 532 +224 680 +788 53 +309 642 +366 1000 +352 891 +402 822 +545 152 +113 324 +967 633 +454 267 +723 381 +14 272 +20 506 +308 419 +644 461 +713 526 +482 978 +336 468 +289 729 +496 795 +326 581 +530 383 +167 226 +522 421 +830 386 +91 273 +116 484 +747 676 +395 107 +958 229 +756 902 +262 962 +703 105 +511 84 +481 991 +449 701 +888 689 +599 655 +306 600 +492 538 +803 499 +445 881 +316 981 +889 473 +785 383 +765 679 +491 573 +589 589 +124 480 +741 145 +898 624 +725 923 +682 915 +131 232 +398 974 +906 735 +753 678 +312 640 +790 644 +301 212 +945 123 +447 253 +197 943 +27 18 +573 916 +589 327 +934 640 +209 615 +529 470 +899 655 +15 288 +592 401 +92 840 +575 633 +814 707 +354 424 +127 682 +374 194 +566 855 +594 190 +973 728 +645 178 +603 275 +712 88 +32 367 +298 544 +561 738 +906 963 +626 460 +143 266 +504 727 +836 33 +361 442 +431 628 +554 384 +24 244 +416 482 +735 765 +243 446 +454 247 +932 913 +494 560 +648 528 +357 594 +596 935 +788 462 +536 621 +759 660 +200 564 +566 302 +741 936 +217 592 +219 724 +832 118 +819 299 +487 251 +473 129 +241 96 +64 167 +516 169 +857 381 +218 976 +490 767 +504 837 +707 407 +342 203 +475 387 +175 735 +786 706 +171 335 +232 40 +888 821 +866 131 +976 159 +253 978 +619 53 +642 849 +460 478 +218 19 +218 230 +667 453 +949 336 +89 931 +488 588 +568 449 +526 566 +860 272 +4 883 +772 731 +734 80 +259 213 +270 177 +6 872 +424 626 +204 940 +313 150 +159 379 +205 833 +25 517 +951 724 +721 973 +635 581 +293 839 +712 272 +410 412 +465 839 +366 492 +74 553 +23 718 +416 738 +764 839 +49 390 +817 588 +507 523 +152 630 +256 770 +562 746 +495 49 +414 369 +78 537 +912 115 +59 215 +259 971 +258 602 +841 551 +137 40 +590 494 +383 252 +869 158 +939 72 +282 177 +880 667 +479 483 +454 815 +730 19 +556 745 +195 339 +409 614 +580 302 +99 319 +913 670 +798 513 +318 566 +790 27 +344 322 +80 645 +468 210 +922 841 +179 925 +347 521 +231 975 +597 269 +607 929 +903 478 +310 970 +223 684 +10 231 +845 673 +905 348 +58 232 +93 727 +759 597 +912 397 +906 539 +43 907 +76 892 +552 699 +670 408 +671 361 +353 789 +837 529 +12 190 +889 880 +912 236 +377 715 +56 718 +585 439 +852 814 +715 902 +421 658 +330 410 +51 412 +840 90 +697 678 +848 951 +826 37 +198 593 +341 737 +274 211 +740 134 +339 847 +875 490 +400 95 +603 435 +474 737 +126 860 +973 310 +973 548 +581 984 +788 660 +629 86 +799 635 +475 941 +959 56 +80 372 +917 650 +91 964 +783 735 +773 682 +712 151 +655 283 +953 773 +279 643 +701 898 +706 817 +147 269 +355 731 +100 507 +498 841 +261 207 +591 752 +630 318 +374 126 +960 153 +917 101 +406 560 +759 743 +618 816 +981 980 +641 1 +131 82 +920 886 +534 377 +453 465 +397 753 +51 842 +301 547 +197 580 +910 754 +211 37 +851 548 +42 896 +919 656 +30 537 +674 78 +979 540 +764 597 +937 314 +656 845 +590 361 +337 930 +997 654 +643 841 +652 810 +632 98 +827 814 +659 898 +56 237 +97 236 +304 397 +771 468 +680 160 +344 168 +561 189 +632 123 +666 783 +235 991 +71 775 +327 565 +824 906 +1 604 +948 233 +851 693 +780 209 +603 279 +380 231 +84 675 +684 370 +757 814 +605 276 +304 238 +358 710 +294 931 +742 879 +37 492 +4 81 +707 347 +131 417 +660 582 +89 801 +455 195 +303 403 +680 247 +970 356 +934 627 +951 858 +404 803 +446 236 +349 572 +93 485 +672 586 +158 748 +772 235 +891 859 +532 788 +621 345 +347 861 +227 342 +555 779 +16 595 +303 963 +941 260 +833 366 +190 835 +622 733 +345 834 +893 442 +192 773 +430 880 +160 873 +767 793 +170 173 +810 402 +318 60 +690 628 +224 19 +52 146 +411 685 +203 138 +785 593 +219 202 +61 500 +919 89 +191 433 +711 63 +294 514 +937 865 +253 393 +103 269 +316 111 +625 614 +639 272 +641 973 +139 609 +45 236 +316 496 +218 24 +293 871 +747 227 +879 420 +633 850 +10 127 +356 170 +665 224 +536 722 +823 189 +603 597 +392 286 +258 22 +771 957 +820 536 +139 221 +566 281 +229 238 +325 531 +804 449 +786 735 +983 670 +847 646 +388 272 +632 605 +253 394 +405 508 +137 537 +283 955 +678 477 +659 969 +706 692 +786 963 +313 829 +143 638 +713 206 +244 185 +489 187 +844 129 +896 300 +602 114 +210 305 +930 199 +692 916 +457 839 +241 899 +950 452 +229 185 +212 561 +222 848 +32 191 +747 830 +869 860 +245 873 +575 649 +818 591 +204 974 +584 974 +822 452 +198 397 +942 350 +942 597 +899 13 +375 392 +327 343 +479 756 +66 387 +950 924 +464 188 +286 68 +573 552 +294 166 +137 435 +557 14 +423 797 +427 254 +95 300 +715 431 +403 367 +453 197 +735 233 +1 149 +145 62 +782 38 +848 69 +456 425 +490 810 +679 878 +461 503 +844 308 +70 798 +599 437 +888 798 +395 36 +733 583 +795 412 +368 195 +94 878 +114 388 +46 438 +795 532 +583 3 +321 268 +714 417 +332 277 +257 229 +906 445 +301 380 +277 974 +651 248 +218 433 +109 1000 +558 874 +388 939 +121 760 +372 473 +228 811 +208 766 +326 306 +572 556 +50 521 +753 364 +77 460 +266 136 +227 458 +502 784 +337 648 +31 783 +629 960 +215 137 +353 591 +274 875 +343 440 +758 263 +838 40 +478 835 +595 943 +255 749 +331 263 +362 597 +84 5 +16 999 +459 161 +220 35 +16 891 +865 459 +719 996 +292 592 +175 54 +461 985 +301 401 +759 298 +715 459 +207 77 +129 611 +681 159 +261 467 +893 737 +399 895 +377 49 +189 382 +360 285 +14 388 +728 972 +314 265 +225 729 +534 810 +914 973 +94 818 +549 295 +674 532 +434 58 +211 736 +986 187 +863 896 +802 998 +279 997 +31 476 +810 259 +968 475 +187 494 +791 130 +190 151 +410 639 +592 855 +886 480 +875 478 +763 386 +352 672 +58 361 +815 894 +562 460 +571 148 +322 660 +465 628 +418 329 +198 975 +554 1 +656 507 +108 750 +453 109 +909 915 +576 700 +646 75 +114 896 +313 229 +692 85 +759 144 +643 536 +462 919 +860 516 +904 473 +959 25 +663 25 +209 611 +564 44 +233 722 +478 980 +716 563 +616 672 +107 914 +979 541 +466 882 +971 142 +76 259 +886 35 +498 543 +150 689 +442 721 +136 142 +36 530 +37 503 +344 450 +550 248 +355 599 +980 919 +473 636 +957 181 +324 873 +859 154 +570 427 +294 604 +260 313 +674 363 +339 594 +259 813 +382 829 +660 49 +430 791 +760 554 +682 499 +664 226 +358 345 +114 432 +142 758 +19 64 +753 843 +163 637 +121 941 +94 965 +398 448 +587 857 +98 968 +142 351 +303 758 +968 351 +533 980 +982 662 +568 357 +519 914 +277 548 +622 723 +517 23 +720 170 +635 351 +55 113 +263 783 +285 766 +189 527 +628 206 +7 644 +290 258 +655 861 +387 728 +641 69 +742 128 +741 392 +793 145 +802 51 +897 112 +262 253 +193 340 +882 932 +131 817 +482 965 +573 480 +443 724 +203 839 +965 500 +75 746 +807 811 +805 373 +513 605 +472 252 +797 172 +690 394 +295 177 +784 98 +532 377 +155 486 +110 855 +884 290 +173 130 +78 355 +714 842 +633 233 +477 101 +119 686 +718 736 +15 930 +472 700 +328 69 +793 607 +199 879 +999 916 +177 960 +525 408 +948 679 +498 138 +495 185 +890 782 +906 49 +334 453 +385 630 +399 429 +338 853 +520 545 +829 651 +481 765 +99 159 +680 1000 +87 179 +802 717 +890 885 +839 32 +339 838 +883 186 +67 470 +544 185 +357 921 +457 376 +444 986 +642 934 +152 171 +59 645 +616 46 +59 681 +987 43 +353 234 +530 103 +958 496 +613 389 +838 931 +85 579 +86 132 +569 908 +479 772 +683 677 +400 343 +370 703 +882 139 +146 344 +116 387 +760 909 +407 539 +447 304 +388 655 +41 378 +658 92 +119 862 +28 411 +457 362 +198 397 +17 290 +432 152 +321 611 +427 173 +205 137 +344 946 +563 365 +304 475 +47 982 +694 920 +91 802 +961 66 +644 778 +109 744 +959 464 +969 313 +42 341 +108 685 +648 331 +49 85 +228 676 +929 91 +527 534 +967 166 +316 51 +582 966 +840 841 +575 625 +503 114 +911 16 +305 113 +989 826 +836 506 +369 738 +587 564 +232 455 +452 735 +900 264 +952 548 +81 738 +995 853 +562 575 +739 569 +705 365 +5 620 +557 264 +490 193 +294 21 +361 373 +900 84 +47 250 +205 288 +145 132 +846 151 +658 419 +849 521 +680 974 +148 655 +96 648 +210 737 +690 298 +19 187 +831 981 +679 965 +726 954 +528 166 +15 248 +564 636 +847 560 +721 563 +9 24 +700 896 +446 803 +858 16 +699 274 +271 714 +977 449 +533 229 +154 280 +756 423 +871 868 +912 124 +727 970 +968 231 +569 935 +163 808 +618 23 +685 210 +650 88 +807 151 +393 770 +276 555 +304 613 +911 866 +233 223 +42 303 +400 305 +162 306 +51 900 +734 964 +933 397 +366 898 +16 59 +177 628 +360 225 +742 537 +725 612 +868 633 +489 314 +501 478 +632 981 +365 904 +196 819 +496 108 +744 179 +145 152 +501 598 +880 349 +248 80 +683 762 +500 314 +389 513 +620 205 +91 584 +721 652 +859 894 +665 198 +416 143 +481 671 +320 302 +865 611 +126 631 +757 526 +963 526 +781 403 +240 231 +330 830 +518 283 +824 864 +935 755 +51 159 +309 220 +18 447 +863 800 +1 833 +749 805 +658 791 +577 412 +579 857 +509 408 +154 895 +923 360 +397 827 +687 971 +959 961 +617 519 +637 335 +623 238 +174 883 +775 222 +608 886 +306 708 +1000 475 +957 876 +641 123 +472 127 +726 384 +305 745 +714 284 +643 429 +708 685 +631 512 +489 503 +829 599 +746 983 +732 462 +732 992 +669 270 +422 491 +54 282 +900 831 +682 167 +666 115 +957 661 +109 564 +454 934 +964 608 +933 513 +140 53 +195 659 +24 646 +657 164 +231 763 +169 825 +128 949 +537 355 +264 811 +46 164 +4 851 +900 289 +802 392 +68 224 +450 460 +126 903 +58 347 +398 638 +486 101 +451 587 +335 797 +162 881 +106 210 +745 243 +969 969 +432 298 +159 253 +634 593 +565 453 +16 657 +610 72 +503 222 +511 319 +752 61 +55 694 +469 384 +829 801 +692 136 +177 536 +211 958 +499 647 +115 526 +984 28 +818 904 +233 509 +424 884 +976 565 +371 601 +406 323 +334 522 +784 192 +676 103 +168 451 +427 867 +432 602 +531 783 +337 311 +677 994 +537 172 +1000 51 +379 389 +103 237 +785 721 +943 597 +412 492 +572 331 +828 380 +771 259 +939 726 +594 55 +19 501 +500 459 +376 790 +689 4 +776 634 +474 117 +575 601 +953 808 +143 544 +510 542 +221 590 +615 827 +599 817 +567 617 +545 32 +727 879 +558 692 +307 685 +564 88 +331 911 +568 546 +881 580 +649 997 +746 937 +393 988 +237 351 +517 661 +521 630 +213 360 +820 908 +199 203 +813 479 +14 251 +803 162 +448 905 +207 167 +86 862 +123 369 +220 181 +158 765 +944 251 +424 909 +311 645 +399 568 +59 847 +253 538 +233 540 +312 99 +790 423 +849 246 +202 165 +552 544 +653 52 +788 131 +893 372 +113 471 +498 625 +442 684 +929 378 +86 534 +12 73 +318 540 +258 671 +524 127 +579 412 +424 972 +468 823 +364 663 +81 784 +399 588 +896 496 +151 170 +626 153 +367 199 +837 152 +640 258 +124 283 +572 289 +408 608 +358 463 +895 180 +884 329 +523 221 +438 294 +278 125 +25 625 +729 427 +996 796 +956 151 +188 867 +519 122 +35 370 +311 840 +195 115 +829 875 +784 912 +904 85 +99 969 +443 714 +0 0 0 0 0 0 1 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 1 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 1 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 1 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 1 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 1 0 0 0 0 0 1 1 0 1 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 1 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 diff --git a/scripts/Knapsack/Data/knapPI_1_200_1000_1 b/scripts/Knapsack/Data/knapPI_1_200_1000_1 new file mode 100644 index 0000000..ba4efe4 --- /dev/null +++ b/scripts/Knapsack/Data/knapPI_1_200_1000_1 @@ -0,0 +1,202 @@ +200 1008 +94 485 +506 326 +416 248 +992 421 +649 322 +237 795 +457 43 +815 845 +446 955 +422 252 +791 9 +359 901 +667 122 +598 94 +7 738 +544 574 +334 715 +766 882 +994 367 +893 984 +633 299 +131 433 +428 682 +700 72 +617 874 +874 138 +720 856 +419 145 +794 995 +196 529 +997 199 +116 277 +908 97 +539 719 +707 242 +569 107 +537 122 +931 70 +726 98 +487 600 +772 645 +513 267 +81 972 +943 895 +58 213 +303 748 +764 487 +536 923 +724 29 +789 674 +479 540 +142 554 +339 467 +641 46 +196 710 +494 553 +66 191 +824 724 +208 730 +711 988 +800 90 +314 340 +289 549 +401 196 +466 865 +689 678 +833 570 +225 936 +244 722 +849 651 +113 123 +379 431 +361 508 +65 585 +486 853 +686 642 +286 992 +889 725 +24 286 +491 812 +891 859 +90 663 +181 88 +214 179 +17 187 +472 619 +418 261 +419 846 +356 192 +682 261 +306 514 +201 886 +385 530 +952 849 +500 294 +194 799 +737 391 +324 330 +992 298 +224 790 +260 275 +97 826 +210 72 +649 866 +919 951 +63 748 +958 685 +804 956 +518 564 +428 183 +537 400 +346 721 +153 207 +971 323 +662 611 +197 116 +91 109 +529 795 +126 343 +747 862 +469 685 +770 10 +934 881 +723 984 +895 403 +568 360 +172 449 +958 541 +383 272 +308 877 +970 359 +583 707 +48 308 +930 770 +569 30 +3 208 +20 311 +609 100 +887 939 +825 422 +930 785 +904 370 +241 989 +379 969 +376 143 +962 972 +889 28 +443 61 +216 638 +338 348 +160 347 +406 66 +159 391 +31 638 +204 295 +420 826 +153 196 +425 449 +331 855 +565 143 +838 487 +9 140 +918 564 +533 615 +232 135 +957 564 +591 360 +576 793 +746 163 +377 859 +858 760 +86 711 +434 662 +558 159 +279 660 +840 268 +735 948 +574 315 +126 676 +912 341 +739 689 +821 894 +625 706 +917 490 +201 478 +993 671 +149 932 +52 899 +759 237 +267 187 +256 472 +783 772 +117 98 +516 906 +180 911 +25 635 +380 225 +712 823 +266 164 +216 343 +0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 1 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 1 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 diff --git a/scripts/Knapsack/Data/knapPI_1_500_1000_1 b/scripts/Knapsack/Data/knapPI_1_500_1000_1 new file mode 100644 index 0000000..19f4aba --- /dev/null +++ b/scripts/Knapsack/Data/knapPI_1_500_1000_1 @@ -0,0 +1,502 @@ +500 2543 +94 485 +506 326 +416 248 +992 421 +649 322 +237 795 +457 43 +815 845 +446 955 +422 252 +791 9 +359 901 +667 122 +598 94 +7 738 +544 574 +334 715 +766 882 +994 367 +893 984 +633 299 +131 433 +428 682 +700 72 +617 874 +874 138 +720 856 +419 145 +794 995 +196 529 +997 199 +116 277 +908 97 +539 719 +707 242 +569 107 +537 122 +931 70 +726 98 +487 600 +772 645 +513 267 +81 972 +943 895 +58 213 +303 748 +764 487 +536 923 +724 29 +789 674 +479 540 +142 554 +339 467 +641 46 +196 710 +494 553 +66 191 +824 724 +208 730 +711 988 +800 90 +314 340 +289 549 +401 196 +466 865 +689 678 +833 570 +225 936 +244 722 +849 651 +113 123 +379 431 +361 508 +65 585 +486 853 +686 642 +286 992 +889 725 +24 286 +491 812 +891 859 +90 663 +181 88 +214 179 +17 187 +472 619 +418 261 +419 846 +356 192 +682 261 +306 514 +201 886 +385 530 +952 849 +500 294 +194 799 +737 391 +324 330 +992 298 +224 790 +260 275 +97 826 +210 72 +649 866 +919 951 +63 748 +958 685 +804 956 +518 564 +428 183 +537 400 +346 721 +153 207 +971 323 +662 611 +197 116 +91 109 +529 795 +126 343 +747 862 +469 685 +770 10 +934 881 +723 984 +895 403 +568 360 +172 449 +958 541 +383 272 +308 877 +970 359 +583 707 +48 308 +930 770 +569 30 +3 208 +20 311 +609 100 +887 939 +825 422 +930 785 +904 370 +241 989 +379 969 +376 143 +962 972 +889 28 +443 61 +216 638 +338 348 +160 347 +406 66 +159 391 +31 638 +204 295 +420 826 +153 196 +425 449 +331 855 +565 143 +838 487 +9 140 +918 564 +533 615 +232 135 +957 564 +591 360 +576 793 +746 163 +377 859 +858 760 +86 711 +434 662 +558 159 +279 660 +840 268 +735 948 +574 315 +126 676 +912 341 +739 689 +821 894 +625 706 +917 490 +201 478 +993 671 +149 932 +52 899 +759 237 +267 187 +256 472 +783 772 +117 98 +516 906 +180 911 +25 635 +380 225 +712 823 +266 164 +216 343 +448 732 +541 502 +664 740 +954 576 +726 612 +772 902 +531 454 +943 411 +750 973 +327 703 +917 850 +5 77 +113 220 +913 802 +791 403 +998 181 +859 10 +345 525 +431 919 +675 668 +833 527 +438 462 +523 291 +916 605 +420 457 +115 405 +660 417 +261 279 +772 685 +388 596 +764 307 +843 224 +206 322 +407 840 +639 975 +852 401 +542 91 +60 327 +757 330 +82 182 +637 603 +93 793 +614 615 +136 733 +187 864 +102 16 +972 863 +163 987 +501 306 +477 34 +492 840 +121 700 +80 706 +138 787 +660 105 +229 834 +827 798 +448 310 +230 609 +832 690 +489 561 +586 579 +291 60 +665 388 +660 309 +702 407 +153 200 +606 313 +123 970 +253 33 +709 273 +832 277 +108 997 +888 40 +481 227 +283 860 +858 940 +284 608 +711 990 +850 590 +239 806 +943 52 +195 801 +95 764 +410 710 +664 386 +900 593 +112 50 +963 494 +754 156 +458 936 +19 965 +225 86 +569 723 +97 184 +194 868 +754 340 +602 412 +61 487 +695 209 +347 346 +719 860 +100 307 +97 95 +843 821 +745 941 +286 821 +492 587 +116 201 +531 665 +424 527 +253 812 +426 424 +413 459 +980 343 +291 836 +833 506 +486 179 +9 916 +575 430 +922 596 +145 808 +897 269 +404 512 +742 811 +728 685 +269 567 +103 776 +745 855 +35 718 +779 853 +71 97 +80 146 +842 746 +128 15 +941 965 +227 512 +30 480 +342 958 +605 665 +531 191 +364 964 +359 515 +867 606 +820 822 +313 536 +207 693 +911 19 +308 335 +430 101 +685 922 +641 294 +113 910 +141 410 +690 250 +700 546 +559 729 +481 609 +503 720 +766 976 +7 759 +882 798 +859 74 +182 648 +425 299 +542 785 +683 846 +853 390 +938 897 +89 416 +624 837 +181 247 +878 293 +933 144 +580 938 +252 467 +207 480 +658 955 +20 665 +954 26 +347 564 +759 449 +446 26 +14 521 +657 301 +710 321 +980 613 +188 388 +636 879 +203 990 +432 188 +129 963 +630 820 +509 300 +237 822 +373 255 +838 277 +395 153 +692 400 +103 227 +218 518 +384 447 +931 315 +396 813 +389 324 +640 502 +287 299 +297 780 +977 376 +512 516 +219 212 +555 329 +398 810 +289 486 +798 485 +598 416 +49 952 +572 894 +697 358 +770 21 +725 647 +542 44 +214 683 +887 361 +45 814 +94 231 +282 8 +82 165 +319 496 +626 699 +146 852 +541 459 +874 535 +725 314 +777 944 +554 306 +208 459 +787 637 +976 447 +912 408 +444 107 +3 962 +301 565 +164 407 +437 857 +652 317 +764 98 +41 818 +737 600 +176 288 +136 902 +128 567 +394 190 +235 749 +42 908 +824 276 +684 748 +979 592 +568 393 +367 363 +52 163 +642 983 +335 179 +126 16 +130 478 +583 259 +129 868 +752 295 +167 596 +856 71 +640 622 +770 864 +431 644 +195 5 +448 365 +701 429 +952 64 +880 854 +168 770 +79 88 +961 157 +472 368 +217 421 +709 719 +147 271 +296 975 +909 816 +764 962 +251 535 +878 438 +753 696 +570 881 +253 318 +666 45 +931 52 +433 496 +810 313 +678 138 +123 334 +212 988 +0 0 0 0 0 0 1 0 0 0 1 0 1 1 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 1 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 1 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 1 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 diff --git a/scripts/Knapsack/Data/knapPI_2_1000_1000_1 b/scripts/Knapsack/Data/knapPI_2_1000_1000_1 new file mode 100644 index 0000000..f318ce1 --- /dev/null +++ b/scripts/Knapsack/Data/knapPI_2_1000_1000_1 @@ -0,0 +1,1002 @@ +1000 5002 +482 485 +257 326 +286 248 +517 421 +404 322 +713 795 +45 43 +924 845 +873 955 +160 252 +1 9 +838 901 +40 122 +58 94 +676 738 +627 574 +766 715 +862 882 +405 367 +923 984 +379 299 +461 433 +612 682 +133 72 +813 874 +97 138 +908 856 +165 145 +996 995 +623 529 +220 199 +298 277 +157 97 +723 719 +144 242 +48 107 +129 122 +148 70 +35 98 +644 600 +632 645 +272 267 +1040 972 +977 895 +312 213 +778 748 +567 487 +965 923 +1 29 +616 674 +569 540 +628 554 +493 467 +76 46 +733 710 +575 553 +288 191 +775 724 +723 730 +912 988 +64 90 +354 340 +565 549 +210 196 +922 865 +775 678 +566 570 +934 936 +626 722 +742 651 +194 123 +485 431 +483 508 +617 585 +876 853 +653 642 +896 992 +652 725 +220 286 +727 812 +900 859 +563 663 +56 88 +157 179 +280 187 +537 619 +284 261 +920 846 +124 192 +239 261 +459 514 +931 886 +504 530 +910 849 +382 294 +795 799 +485 391 +351 330 +289 298 +865 790 +250 275 +738 826 +75 72 +788 866 +947 951 +651 748 +595 685 +993 956 +663 564 +265 183 +338 400 +637 721 +206 207 +328 323 +618 611 +64 116 +139 109 +806 795 +412 343 +912 862 +715 685 +1 10 +929 881 +1025 984 +410 403 +273 360 +507 449 +450 541 +174 272 +882 877 +427 359 +787 707 +355 308 +734 770 +1 30 +248 208 +397 311 +159 100 +874 939 +449 422 +857 785 +286 370 +976 989 +908 969 +103 143 +1071 972 +1 28 +117 61 +697 638 +424 348 +439 347 +74 66 +442 391 +568 638 +195 295 +854 826 +281 196 +433 449 +845 855 +224 143 +487 487 +181 140 +496 564 +690 615 +124 135 +575 564 +374 360 +766 793 +149 163 +776 859 +793 760 +674 711 +696 662 +90 159 +732 660 +214 268 +935 948 +228 315 +619 676 +349 341 +734 689 +964 894 +644 706 +484 490 +491 478 +628 671 +1009 932 +944 899 +315 237 +92 187 +554 472 +757 772 +88 98 +952 906 +818 911 +628 635 +316 225 +818 823 +255 164 +432 343 +763 732 +490 502 +721 740 +587 576 +530 612 +992 902 +491 454 +343 411 +880 973 +645 703 +761 850 +152 77 +241 220 +727 802 +352 403 +246 181 +1 10 +479 525 +958 919 +749 668 +551 527 +538 462 +319 291 +580 605 +501 457 +487 405 +349 417 +252 279 +731 685 +637 596 +339 307 +257 224 +271 322 +740 840 +1002 975 +404 401 +190 91 +254 327 +277 330 +100 182 +648 603 +810 793 +535 615 +702 733 +855 864 +76 16 +773 863 +917 987 +279 306 +123 34 +922 840 +613 700 +658 706 +705 787 +101 105 +807 834 +883 798 +358 310 +634 609 +786 690 +618 561 +644 579 +141 60 +466 388 +340 309 +495 407 +283 200 +352 313 +886 970 +95 33 +291 273 +217 277 +1007 997 +1 40 +219 227 +764 860 +1025 940 +600 608 +895 990 +690 590 +738 806 +1 52 +772 801 +727 764 +774 710 +340 386 +503 593 +1 50 +432 494 +228 156 +993 936 +1058 965 +130 86 +821 723 +189 184 +943 868 +343 340 +404 412 +560 487 +196 209 +418 346 +782 860 +314 307 +59 95 +778 821 +979 941 +828 821 +584 587 +122 201 +741 665 +566 527 +760 812 +385 424 +395 459 +250 343 +789 836 +492 506 +261 179 +914 916 +380 430 +537 596 +731 808 +361 269 +473 512 +737 811 +708 685 +635 567 +804 776 +827 855 +695 718 +756 853 +57 97 +178 146 +688 746 +1 15 +871 965 +415 512 +510 480 +1057 958 +764 665 +193 191 +905 964 +583 515 +696 606 +887 822 +444 536 +741 693 +12 19 +313 335 +81 101 +828 922 +354 294 +981 910 +499 410 +283 250 +545 546 +635 729 +540 609 +689 720 +946 976 +730 759 +703 798 +14 74 +644 648 +241 299 +793 785 +912 846 +461 390 +801 897 +424 416 +744 837 +272 247 +338 293 +193 144 +987 938 +432 467 +505 480 +944 955 +653 665 +38 26 +468 564 +461 449 +1 26 +576 521 +329 301 +274 321 +701 613 +432 388 +851 879 +915 990 +137 188 +927 963 +903 820 +373 300 +770 822 +160 255 +285 277 +231 153 +366 400 +317 227 +423 518 +420 447 +216 315 +772 813 +271 324 +566 502 +243 299 +725 780 +390 376 +491 516 +225 212 +392 329 +781 810 +434 486 +535 485 +368 416 +938 952 +946 894 +353 358 +1 21 +707 647 +143 44 +630 683 +364 361 +822 814 +147 231 +54 8 +91 165 +431 496 +606 699 +917 852 +553 459 +473 535 +222 314 +954 944 +369 306 +413 459 +717 637 +491 447 +447 408 +44 107 +994 962 +518 565 +448 407 +931 857 +369 317 +181 98 +815 818 +655 600 +267 288 +960 902 +611 567 +271 190 +771 749 +993 908 +359 276 +810 748 +563 592 +360 393 +264 363 +199 163 +1074 983 +131 179 +41 16 +423 478 +197 259 +779 868 +344 295 +536 596 +140 71 +669 622 +938 864 +715 644 +67 5 +321 365 +434 429 +19 64 +928 854 +759 770 +178 88 +160 157 +277 368 +467 421 +653 719 +330 271 +966 975 +817 816 +1045 962 +508 535 +492 438 +743 696 +884 881 +259 318 +56 45 +1 52 +421 496 +270 313 +99 138 +429 334 +1004 988 +512 508 +702 770 +657 751 +862 780 +516 441 +246 207 +592 516 +641 674 +390 408 +831 920 +522 573 +611 634 +825 878 +929 990 +734 826 +718 696 +883 800 +355 411 +426 422 +668 707 +235 334 +1080 986 +397 494 +137 150 +648 562 +342 380 +799 832 +1067 979 +313 376 +452 511 +441 414 +214 160 +1059 982 +260 238 +579 490 +897 899 +316 251 +526 526 +909 897 +139 39 +634 657 +384 452 +577 538 +840 831 +509 460 +262 185 +934 934 +513 440 +556 490 +97 168 +107 71 +937 977 +370 458 +193 204 +802 803 +134 139 +390 399 +439 420 +1034 991 +636 578 +1008 972 +191 177 +429 398 +445 348 +483 496 +347 276 +769 825 +540 614 +212 121 +789 730 +317 341 +381 284 +714 698 +24 17 +570 546 +771 672 +1052 974 +776 866 +290 377 +470 559 +367 340 +626 527 +879 779 +688 761 +553 483 +112 92 +440 390 +510 583 +741 661 +473 391 +289 336 +574 661 +85 125 +36 89 +362 275 +310 359 +129 178 +763 780 +31 42 +69 5 +470 380 +739 772 +726 816 +57 9 +476 484 +498 545 +669 589 +112 157 +934 901 +854 777 +112 74 +246 247 +1 55 +481 479 +883 785 +1051 958 +763 680 +417 393 +900 944 +573 596 +601 619 +588 611 +900 852 +327 283 +199 299 +847 766 +240 312 +862 826 +635 726 +680 733 +806 805 +767 679 +495 403 +870 964 +259 337 +476 541 +512 478 +467 369 +1001 946 +798 821 +819 833 +835 837 +502 490 +119 37 +652 594 +82 129 +242 258 +215 246 +291 362 +687 755 +550 504 +1 71 +249 177 +203 176 +865 803 +189 237 +758 677 +90 33 +188 115 +621 597 +807 769 +481 536 +1031 956 +349 341 +222 184 +260 234 +551 569 +245 216 +631 537 +183 84 +873 810 +656 657 +5 33 +137 159 +579 520 +656 668 +373 287 +232 229 +352 374 +428 474 +598 672 +943 915 +582 511 +120 123 +573 569 +218 199 +347 396 +628 715 +1 59 +642 610 +959 917 +983 927 +186 270 +60 117 +513 516 +143 215 +234 216 +290 237 +597 615 +452 499 +521 477 +837 760 +267 285 +20 56 +1027 966 +690 622 +235 221 +199 194 +186 91 +374 347 +244 252 +424 473 +438 516 +385 385 +337 357 +945 958 +686 665 +698 792 +16 64 +464 420 +655 671 +911 968 +839 877 +144 177 +535 523 +65 139 +230 152 +806 732 +312 246 +578 565 +699 740 +817 902 +105 17 +886 973 +360 298 +658 611 +53 32 +1 11 +319 337 +36 136 +879 889 +595 522 +721 805 +80 28 +981 931 +838 757 +654 609 +480 544 +973 905 +647 595 +243 246 +152 113 +183 175 +140 156 +263 244 +856 883 +338 265 +792 883 +403 462 +560 485 +238 272 +214 204 +1011 984 +453 409 +330 398 +819 909 +469 370 +882 882 +279 214 +811 766 +82 35 +341 421 +271 271 +397 370 +876 848 +128 50 +1016 976 +243 270 +843 796 +949 963 +451 379 +1091 991 +594 551 +867 897 +353 307 +471 421 +100 74 +401 388 +591 559 +884 980 +607 615 +651 681 +209 231 +133 207 +741 818 +372 331 +950 979 +403 445 +419 348 +780 724 +345 401 +618 646 +766 668 +335 242 +288 302 +795 861 +777 830 +117 77 +541 441 +499 589 +1025 990 +217 189 +799 868 +944 996 +329 363 +232 237 +367 420 +552 565 +220 214 +353 333 +811 726 +176 175 +35 58 +548 625 +1 66 +142 169 +400 475 +298 204 +27 90 +421 496 +40 1 +462 474 +359 449 +299 252 +395 332 +382 287 +206 189 +980 889 +1 63 +285 378 +109 206 +813 897 +219 230 +361 382 +601 575 +155 60 +442 529 +405 477 +253 290 +57 89 +894 961 +548 461 +763 702 +542 532 +704 680 +44 53 +545 642 +1018 1000 +803 891 +730 822 +59 152 +423 324 +590 633 +266 267 +325 381 +307 272 +422 506 +403 419 +524 461 +613 526 +1033 978 +403 468 +820 729 +777 795 +631 581 +298 383 +302 226 +505 421 +461 386 +351 273 +556 484 +638 676 +152 107 +236 229 +831 902 +882 962 +38 105 +100 84 +1006 991 +661 701 +596 689 +748 655 +528 600 +587 538 +492 499 +783 881 +1017 981 +546 473 +368 383 +618 679 +662 573 +563 589 +553 480 +161 145 +612 624 +926 923 +972 915 +249 232 +948 974 +662 735 +735 678 +682 640 +722 644 +146 212 +75 123 +276 253 +890 943 +1 18 +1007 916 +302 327 +607 640 +646 615 +488 470 +565 655 +239 288 +448 401 +906 840 +564 633 +647 707 +339 424 +757 682 +213 194 +829 855 +229 190 +703 728 +257 178 +255 275 +123 88 +321 367 +517 544 +768 738 +1040 963 +439 460 +282 266 +739 727 +128 33 +471 442 +714 628 +467 384 +298 244 +411 482 +760 765 +435 446 +245 247 +865 913 +658 560 +457 528 +694 594 +882 935 +415 462 +555 621 +705 660 +525 564 +276 302 +871 936 +582 592 +639 724 +181 118 +200 299 +201 251 +35 129 +5 96 +85 167 +239 169 +359 381 +948 976 +771 767 +804 837 +457 407 +284 203 +485 387 +803 735 +629 706 +358 335 +13 40 +808 821 +68 131 +96 159 +956 978 +101 53 +767 849 +577 478 +1 19 +278 230 +388 453 +318 336 +847 931 +592 588 +494 449 +615 566 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 diff --git a/scripts/Knapsack/Data/knapPI_2_100_1000_1 b/scripts/Knapsack/Data/knapPI_2_100_1000_1 new file mode 100644 index 0000000..1e85ecf --- /dev/null +++ b/scripts/Knapsack/Data/knapPI_2_100_1000_1 @@ -0,0 +1,102 @@ +100 995 +482 485 +257 326 +286 248 +517 421 +404 322 +713 795 +45 43 +924 845 +873 955 +160 252 +1 9 +838 901 +40 122 +58 94 +676 738 +627 574 +766 715 +862 882 +405 367 +923 984 +379 299 +461 433 +612 682 +133 72 +813 874 +97 138 +908 856 +165 145 +996 995 +623 529 +220 199 +298 277 +157 97 +723 719 +144 242 +48 107 +129 122 +148 70 +35 98 +644 600 +632 645 +272 267 +1040 972 +977 895 +312 213 +778 748 +567 487 +965 923 +1 29 +616 674 +569 540 +628 554 +493 467 +76 46 +733 710 +575 553 +288 191 +775 724 +723 730 +912 988 +64 90 +354 340 +565 549 +210 196 +922 865 +775 678 +566 570 +934 936 +626 722 +742 651 +194 123 +485 431 +483 508 +617 585 +876 853 +653 642 +896 992 +652 725 +220 286 +727 812 +900 859 +563 663 +56 88 +157 179 +280 187 +537 619 +284 261 +920 846 +124 192 +239 261 +459 514 +931 886 +504 530 +910 849 +382 294 +795 799 +485 391 +351 330 +289 298 +865 790 +0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 diff --git a/scripts/Knapsack/Data/knapPI_2_2000_1000_1 b/scripts/Knapsack/Data/knapPI_2_2000_1000_1 new file mode 100644 index 0000000..af42377 --- /dev/null +++ b/scripts/Knapsack/Data/knapPI_2_2000_1000_1 @@ -0,0 +1,2002 @@ +2000 10011 +482 485 +257 326 +286 248 +517 421 +404 322 +713 795 +45 43 +924 845 +873 955 +160 252 +1 9 +838 901 +40 122 +58 94 +676 738 +627 574 +766 715 +862 882 +405 367 +923 984 +379 299 +461 433 +612 682 +133 72 +813 874 +97 138 +908 856 +165 145 +996 995 +623 529 +220 199 +298 277 +157 97 +723 719 +144 242 +48 107 +129 122 +148 70 +35 98 +644 600 +632 645 +272 267 +1040 972 +977 895 +312 213 +778 748 +567 487 +965 923 +1 29 +616 674 +569 540 +628 554 +493 467 +76 46 +733 710 +575 553 +288 191 +775 724 +723 730 +912 988 +64 90 +354 340 +565 549 +210 196 +922 865 +775 678 +566 570 +934 936 +626 722 +742 651 +194 123 +485 431 +483 508 +617 585 +876 853 +653 642 +896 992 +652 725 +220 286 +727 812 +900 859 +563 663 +56 88 +157 179 +280 187 +537 619 +284 261 +920 846 +124 192 +239 261 +459 514 +931 886 +504 530 +910 849 +382 294 +795 799 +485 391 +351 330 +289 298 +865 790 +250 275 +738 826 +75 72 +788 866 +947 951 +651 748 +595 685 +993 956 +663 564 +265 183 +338 400 +637 721 +206 207 +328 323 +618 611 +64 116 +139 109 +806 795 +412 343 +912 862 +715 685 +1 10 +929 881 +1025 984 +410 403 +273 360 +507 449 +450 541 +174 272 +882 877 +427 359 +787 707 +355 308 +734 770 +1 30 +248 208 +397 311 +159 100 +874 939 +449 422 +857 785 +286 370 +976 989 +908 969 +103 143 +1071 972 +1 28 +117 61 +697 638 +424 348 +439 347 +74 66 +442 391 +568 638 +195 295 +854 826 +281 196 +433 449 +845 855 +224 143 +487 487 +181 140 +496 564 +690 615 +124 135 +575 564 +374 360 +766 793 +149 163 +776 859 +793 760 +674 711 +696 662 +90 159 +732 660 +214 268 +935 948 +228 315 +619 676 +349 341 +734 689 +964 894 +644 706 +484 490 +491 478 +628 671 +1009 932 +944 899 +315 237 +92 187 +554 472 +757 772 +88 98 +952 906 +818 911 +628 635 +316 225 +818 823 +255 164 +432 343 +763 732 +490 502 +721 740 +587 576 +530 612 +992 902 +491 454 +343 411 +880 973 +645 703 +761 850 +152 77 +241 220 +727 802 +352 403 +246 181 +1 10 +479 525 +958 919 +749 668 +551 527 +538 462 +319 291 +580 605 +501 457 +487 405 +349 417 +252 279 +731 685 +637 596 +339 307 +257 224 +271 322 +740 840 +1002 975 +404 401 +190 91 +254 327 +277 330 +100 182 +648 603 +810 793 +535 615 +702 733 +855 864 +76 16 +773 863 +917 987 +279 306 +123 34 +922 840 +613 700 +658 706 +705 787 +101 105 +807 834 +883 798 +358 310 +634 609 +786 690 +618 561 +644 579 +141 60 +466 388 +340 309 +495 407 +283 200 +352 313 +886 970 +95 33 +291 273 +217 277 +1007 997 +1 40 +219 227 +764 860 +1025 940 +600 608 +895 990 +690 590 +738 806 +1 52 +772 801 +727 764 +774 710 +340 386 +503 593 +1 50 +432 494 +228 156 +993 936 +1058 965 +130 86 +821 723 +189 184 +943 868 +343 340 +404 412 +560 487 +196 209 +418 346 +782 860 +314 307 +59 95 +778 821 +979 941 +828 821 +584 587 +122 201 +741 665 +566 527 +760 812 +385 424 +395 459 +250 343 +789 836 +492 506 +261 179 +914 916 +380 430 +537 596 +731 808 +361 269 +473 512 +737 811 +708 685 +635 567 +804 776 +827 855 +695 718 +756 853 +57 97 +178 146 +688 746 +1 15 +871 965 +415 512 +510 480 +1057 958 +764 665 +193 191 +905 964 +583 515 +696 606 +887 822 +444 536 +741 693 +12 19 +313 335 +81 101 +828 922 +354 294 +981 910 +499 410 +283 250 +545 546 +635 729 +540 609 +689 720 +946 976 +730 759 +703 798 +14 74 +644 648 +241 299 +793 785 +912 846 +461 390 +801 897 +424 416 +744 837 +272 247 +338 293 +193 144 +987 938 +432 467 +505 480 +944 955 +653 665 +38 26 +468 564 +461 449 +1 26 +576 521 +329 301 +274 321 +701 613 +432 388 +851 879 +915 990 +137 188 +927 963 +903 820 +373 300 +770 822 +160 255 +285 277 +231 153 +366 400 +317 227 +423 518 +420 447 +216 315 +772 813 +271 324 +566 502 +243 299 +725 780 +390 376 +491 516 +225 212 +392 329 +781 810 +434 486 +535 485 +368 416 +938 952 +946 894 +353 358 +1 21 +707 647 +143 44 +630 683 +364 361 +822 814 +147 231 +54 8 +91 165 +431 496 +606 699 +917 852 +553 459 +473 535 +222 314 +954 944 +369 306 +413 459 +717 637 +491 447 +447 408 +44 107 +994 962 +518 565 +448 407 +931 857 +369 317 +181 98 +815 818 +655 600 +267 288 +960 902 +611 567 +271 190 +771 749 +993 908 +359 276 +810 748 +563 592 +360 393 +264 363 +199 163 +1074 983 +131 179 +41 16 +423 478 +197 259 +779 868 +344 295 +536 596 +140 71 +669 622 +938 864 +715 644 +67 5 +321 365 +434 429 +19 64 +928 854 +759 770 +178 88 +160 157 +277 368 +467 421 +653 719 +330 271 +966 975 +817 816 +1045 962 +508 535 +492 438 +743 696 +884 881 +259 318 +56 45 +1 52 +421 496 +270 313 +99 138 +429 334 +1004 988 +512 508 +702 770 +657 751 +862 780 +516 441 +246 207 +592 516 +641 674 +390 408 +831 920 +522 573 +611 634 +825 878 +929 990 +734 826 +718 696 +883 800 +355 411 +426 422 +668 707 +235 334 +1080 986 +397 494 +137 150 +648 562 +342 380 +799 832 +1067 979 +313 376 +452 511 +441 414 +214 160 +1059 982 +260 238 +579 490 +897 899 +316 251 +526 526 +909 897 +139 39 +634 657 +384 452 +577 538 +840 831 +509 460 +262 185 +934 934 +513 440 +556 490 +97 168 +107 71 +937 977 +370 458 +193 204 +802 803 +134 139 +390 399 +439 420 +1034 991 +636 578 +1008 972 +191 177 +429 398 +445 348 +483 496 +347 276 +769 825 +540 614 +212 121 +789 730 +317 341 +381 284 +714 698 +24 17 +570 546 +771 672 +1052 974 +776 866 +290 377 +470 559 +367 340 +626 527 +879 779 +688 761 +553 483 +112 92 +440 390 +510 583 +741 661 +473 391 +289 336 +574 661 +85 125 +36 89 +362 275 +310 359 +129 178 +763 780 +31 42 +69 5 +470 380 +739 772 +726 816 +57 9 +476 484 +498 545 +669 589 +112 157 +934 901 +854 777 +112 74 +246 247 +1 55 +481 479 +883 785 +1051 958 +763 680 +417 393 +900 944 +573 596 +601 619 +588 611 +900 852 +327 283 +199 299 +847 766 +240 312 +862 826 +635 726 +680 733 +806 805 +767 679 +495 403 +870 964 +259 337 +476 541 +512 478 +467 369 +1001 946 +798 821 +819 833 +835 837 +502 490 +119 37 +652 594 +82 129 +242 258 +215 246 +291 362 +687 755 +550 504 +1 71 +249 177 +203 176 +865 803 +189 237 +758 677 +90 33 +188 115 +621 597 +807 769 +481 536 +1031 956 +349 341 +222 184 +260 234 +551 569 +245 216 +631 537 +183 84 +873 810 +656 657 +5 33 +137 159 +579 520 +656 668 +373 287 +232 229 +352 374 +428 474 +598 672 +943 915 +582 511 +120 123 +573 569 +218 199 +347 396 +628 715 +1 59 +642 610 +959 917 +983 927 +186 270 +60 117 +513 516 +143 215 +234 216 +290 237 +597 615 +452 499 +521 477 +837 760 +267 285 +20 56 +1027 966 +690 622 +235 221 +199 194 +186 91 +374 347 +244 252 +424 473 +438 516 +385 385 +337 357 +945 958 +686 665 +698 792 +16 64 +464 420 +655 671 +911 968 +839 877 +144 177 +535 523 +65 139 +230 152 +806 732 +312 246 +578 565 +699 740 +817 902 +105 17 +886 973 +360 298 +658 611 +53 32 +1 11 +319 337 +36 136 +879 889 +595 522 +721 805 +80 28 +981 931 +838 757 +654 609 +480 544 +973 905 +647 595 +243 246 +152 113 +183 175 +140 156 +263 244 +856 883 +338 265 +792 883 +403 462 +560 485 +238 272 +214 204 +1011 984 +453 409 +330 398 +819 909 +469 370 +882 882 +279 214 +811 766 +82 35 +341 421 +271 271 +397 370 +876 848 +128 50 +1016 976 +243 270 +843 796 +949 963 +451 379 +1091 991 +594 551 +867 897 +353 307 +471 421 +100 74 +401 388 +591 559 +884 980 +607 615 +651 681 +209 231 +133 207 +741 818 +372 331 +950 979 +403 445 +419 348 +780 724 +345 401 +618 646 +766 668 +335 242 +288 302 +795 861 +777 830 +117 77 +541 441 +499 589 +1025 990 +217 189 +799 868 +944 996 +329 363 +232 237 +367 420 +552 565 +220 214 +353 333 +811 726 +176 175 +35 58 +548 625 +1 66 +142 169 +400 475 +298 204 +27 90 +421 496 +40 1 +462 474 +359 449 +299 252 +395 332 +382 287 +206 189 +980 889 +1 63 +285 378 +109 206 +813 897 +219 230 +361 382 +601 575 +155 60 +442 529 +405 477 +253 290 +57 89 +894 961 +548 461 +763 702 +542 532 +704 680 +44 53 +545 642 +1018 1000 +803 891 +730 822 +59 152 +423 324 +590 633 +266 267 +325 381 +307 272 +422 506 +403 419 +524 461 +613 526 +1033 978 +403 468 +820 729 +777 795 +631 581 +298 383 +302 226 +505 421 +461 386 +351 273 +556 484 +638 676 +152 107 +236 229 +831 902 +882 962 +38 105 +100 84 +1006 991 +661 701 +596 689 +748 655 +528 600 +587 538 +492 499 +783 881 +1017 981 +546 473 +368 383 +618 679 +662 573 +563 589 +553 480 +161 145 +612 624 +926 923 +972 915 +249 232 +948 974 +662 735 +735 678 +682 640 +722 644 +146 212 +75 123 +276 253 +890 943 +1 18 +1007 916 +302 327 +607 640 +646 615 +488 470 +565 655 +239 288 +448 401 +906 840 +564 633 +647 707 +339 424 +757 682 +213 194 +829 855 +229 190 +703 728 +257 178 +255 275 +123 88 +321 367 +517 544 +768 738 +1040 963 +439 460 +282 266 +739 727 +128 33 +471 442 +714 628 +467 384 +298 244 +411 482 +760 765 +435 446 +245 247 +865 913 +658 560 +457 528 +694 594 +882 935 +415 462 +555 621 +705 660 +525 564 +276 302 +871 936 +582 592 +639 724 +181 118 +200 299 +201 251 +35 129 +5 96 +85 167 +239 169 +359 381 +948 976 +771 767 +804 837 +457 407 +284 203 +485 387 +803 735 +629 706 +358 335 +13 40 +808 821 +68 131 +96 159 +956 978 +101 53 +767 849 +577 478 +1 19 +278 230 +388 453 +318 336 +847 931 +592 588 +494 449 +615 566 +265 272 +806 883 +754 731 +94 80 +113 213 +203 177 +896 872 +712 626 +1000 940 +69 150 +279 379 +847 833 +509 517 +686 724 +946 973 +652 581 +872 839 +237 272 +314 412 +789 839 +440 492 +526 553 +714 718 +791 738 +816 839 +385 390 +557 588 +562 523 +715 630 +815 770 +752 746 +1 49 +280 369 +498 537 +116 115 +155 215 +872 971 +572 602 +551 551 +1 40 +399 494 +306 252 +153 158 +81 72 +84 177 +755 667 +504 483 +724 815 +94 19 +725 745 +266 339 +660 614 +263 302 +341 319 +635 670 +519 513 +647 566 +24 27 +259 322 +707 645 +162 210 +925 841 +830 925 +600 521 +931 975 +177 269 +862 929 +437 478 +918 970 +737 684 +227 231 +595 673 +343 348 +194 232 +683 727 +616 597 +401 397 +608 539 +923 907 +928 892 +731 699 +435 408 +265 361 +828 789 +583 529 +275 190 +812 880 +212 236 +659 715 +725 718 +348 439 +774 814 +845 902 +593 658 +393 410 +511 412 +5 90 +689 678 +916 951 +120 37 +624 593 +781 737 +174 211 +156 134 +769 847 +433 490 +57 95 +389 435 +822 737 +760 860 +360 310 +545 548 +991 984 +669 660 +142 86 +707 635 +935 941 +156 56 +357 372 +630 650 +1041 964 +734 735 +730 682 +166 151 +223 283 +834 773 +648 643 +918 898 +781 817 +362 269 +760 731 +454 507 +853 841 +294 207 +779 752 +407 318 +86 126 +182 153 +49 101 +623 560 +786 743 +765 816 +981 980 +29 1 +69 82 +914 886 +448 377 +476 465 +752 753 +847 842 +609 547 +660 580 +700 754 +1 37 +616 548 +963 896 +735 656 +615 537 +143 78 +582 540 +525 597 +253 314 +877 845 +321 361 +988 930 +562 654 +866 841 +754 810 +193 98 +846 814 +977 898 +220 237 +310 236 +375 397 +512 468 +112 160 +176 168 +262 189 +123 123 +826 783 +1063 991 +839 775 +505 565 +838 906 +680 604 +229 233 +759 693 +188 209 +241 279 +166 231 +773 675 +324 370 +777 814 +285 276 +200 238 +663 710 +916 931 +833 879 +433 492 +168 81 +386 347 +360 417 +612 582 +755 801 +282 195 +474 403 +215 247 +351 356 +571 627 +838 858 +722 803 +277 236 +521 572 +585 485 +526 586 +808 748 +291 235 +838 859 +793 788 +394 345 +801 861 +395 342 +783 779 +555 595 +910 963 +195 260 +315 366 +796 835 +687 733 +808 834 +357 442 +690 773 +974 880 +928 873 +722 793 +164 173 +394 402 +38 60 +688 628 +1 19 +146 146 +741 685 +88 138 +636 593 +265 202 +590 500 +66 89 +508 433 +133 63 +494 514 +785 865 +433 393 +364 269 +129 111 +659 614 +330 272 +950 973 +673 609 +285 236 +493 496 +120 24 +795 871 +186 227 +391 420 +933 850 +112 127 +186 170 +190 224 +714 722 +267 189 +548 597 +346 286 +1 22 +958 957 +576 536 +311 221 +292 281 +261 238 +622 531 +472 449 +714 735 +575 670 +667 646 +297 272 +546 605 +390 394 +595 508 +570 537 +893 955 +408 477 +947 969 +697 692 +896 963 +914 829 +623 638 +122 206 +229 185 +210 187 +36 129 +266 300 +207 114 +391 305 +174 199 +897 916 +802 839 +966 899 +464 452 +163 185 +552 561 +825 848 +167 191 +864 830 +885 860 +952 873 +574 649 +632 591 +915 974 +1037 974 +471 452 +364 397 +331 350 +671 597 +34 13 +405 392 +273 343 +844 756 +438 387 +888 924 +174 188 +1 68 +581 552 +112 166 +406 435 +3 14 +782 797 +186 254 +228 300 +483 431 +346 367 +220 197 +237 233 +249 149 +51 62 +1 38 +106 69 +430 425 +855 810 +834 878 +484 503 +240 308 +781 798 +394 437 +805 798 +23 36 +527 583 +418 412 +182 195 +783 878 +347 388 +478 438 +435 532 +18 3 +332 268 +373 417 +282 277 +273 229 +486 445 +358 380 +884 974 +329 248 +491 433 +1039 1000 +781 874 +889 939 +813 760 +538 473 +721 811 +810 766 +236 306 +558 556 +527 521 +377 364 +467 460 +230 136 +537 458 +839 784 +623 648 +693 783 +922 960 +42 137 +524 591 +845 875 +503 440 +310 263 +91 40 +916 835 +863 943 +726 749 +214 263 +621 597 +59 5 +1029 999 +118 161 +1 35 +933 891 +377 459 +926 996 +675 592 +1 54 +1080 985 +444 401 +259 298 +383 459 +144 77 +617 611 +169 159 +392 467 +821 737 +887 895 +135 49 +482 382 +347 285 +326 388 +1048 972 +353 265 +691 729 +822 810 +1056 973 +867 818 +349 295 +566 532 +126 58 +758 736 +113 187 +923 896 +1063 998 +914 997 +564 476 +221 259 +536 475 +465 494 +124 130 +222 151 +669 639 +774 855 +565 480 +431 478 +471 386 +602 672 +371 361 +821 894 +447 460 +122 148 +749 660 +706 628 +367 329 +898 975 +17 1 +584 507 +815 750 +53 109 +878 915 +735 700 +38 75 +880 896 +233 229 +1 85 +147 144 +595 536 +841 919 +584 516 +425 473 +1 25 +1 25 +682 611 +22 44 +798 722 +954 980 +615 563 +585 672 +976 914 +448 541 +917 882 +178 142 +346 259 +113 35 +641 543 +652 689 +819 721 +235 142 +509 530 +602 503 +519 450 +305 248 +608 599 +911 919 +546 636 +205 181 +799 873 +112 154 +440 427 +669 604 +313 313 +441 363 +601 594 +815 813 +898 829 +133 49 +808 791 +463 554 +471 499 +215 226 +325 345 +402 432 +671 758 +113 64 +933 843 +585 637 +945 941 +891 965 +502 448 +798 857 +982 968 +258 351 +691 758 +307 351 +901 980 +670 662 +338 357 +921 914 +642 548 +793 723 +1 23 +214 170 +326 351 +35 113 +755 783 +747 766 +497 527 +233 206 +551 644 +348 258 +921 861 +675 728 +122 69 +173 128 +397 392 +81 145 +112 51 +179 112 +245 253 +300 340 +1027 932 +832 817 +970 965 +493 480 +633 724 +812 839 +549 500 +726 746 +767 811 +450 373 +641 605 +351 252 +162 172 +388 394 +229 177 +84 98 +325 377 +518 486 +792 855 +382 290 +146 130 +426 355 +885 842 +255 233 +81 101 +671 686 +676 736 +844 930 +748 700 +92 69 +696 607 +949 879 +904 916 +1037 960 +345 408 +681 679 +130 138 +123 185 +684 782 +9 49 +464 453 +551 630 +364 429 +845 853 +450 545 +645 651 +853 765 +155 159 +1007 1000 +120 179 +743 717 +816 885 +71 32 +833 838 +148 186 +486 470 +270 185 +836 921 +385 376 +954 986 +852 934 +90 171 +552 645 +1 46 +762 681 +1 43 +231 234 +99 103 +536 496 +486 389 +945 931 +639 579 +164 132 +966 908 +679 772 +736 677 +425 343 +714 703 +134 139 +337 344 +418 387 +840 909 +471 539 +361 304 +745 655 +374 378 +153 92 +841 862 +428 411 +420 362 +383 397 +331 290 +182 152 +687 611 +188 173 +226 137 +982 946 +432 365 +410 475 +971 982 +832 920 +710 802 +1 66 +711 778 +715 744 +535 464 +399 313 +401 341 +620 685 +339 331 +150 85 +741 676 +89 91 +535 534 +229 166 +124 51 +970 966 +849 841 +558 625 +173 114 +1 16 +29 113 +800 826 +581 506 +794 738 +657 564 +364 455 +711 735 +283 264 +526 548 +717 738 +900 853 +557 575 +495 569 +316 365 +599 620 +340 264 +144 193 +1 21 +285 373 +168 84 +167 250 +190 288 +86 132 +180 151 +337 419 +522 521 +907 974 +601 655 +690 648 +830 737 +398 298 +227 187 +1017 981 +870 965 +979 954 +149 166 +330 248 +655 636 +565 560 +624 563 +11 24 +813 896 +821 803 +1 16 +291 274 +809 714 +406 449 +192 229 +188 280 +494 423 +769 868 +115 124 +945 970 +312 231 +859 935 +809 808 +61 23 +110 210 +149 88 +192 151 +742 770 +600 555 +580 613 +771 866 +230 223 +258 303 +383 305 +312 306 +951 900 +962 964 +467 397 +966 898 +63 59 +571 628 +182 225 +473 537 +624 612 +619 633 +275 314 +551 478 +1071 981 +868 904 +776 819 +187 108 +245 179 +196 152 +686 598 +321 349 +100 80 +796 762 +292 314 +417 513 +293 205 +510 584 +731 652 +983 894 +149 198 +220 143 +601 671 +304 302 +575 611 +631 631 +533 526 +533 526 +439 403 +141 231 +794 830 +242 283 +772 864 +728 755 +62 159 +141 220 +454 447 +892 800 +880 833 +804 805 +724 791 +499 412 +850 857 +476 408 +859 895 +313 360 +874 827 +875 971 +909 961 +431 519 +432 335 +329 238 +935 883 +204 222 +827 886 +764 708 +376 475 +933 876 +69 123 +76 127 +310 384 +798 745 +311 284 +388 429 +776 685 +593 512 +577 503 +576 599 +925 983 +439 462 +1064 992 +236 270 +393 491 +267 282 +766 831 +146 167 +28 115 +579 661 +539 564 +902 934 +527 608 +586 513 +1 53 +725 659 +706 646 +120 164 +752 763 +828 825 +887 949 +321 355 +775 811 +188 164 +766 851 +253 289 +483 392 +130 224 +419 460 +886 903 +440 347 +579 638 +45 101 +666 587 +736 797 +792 881 +219 210 +194 243 +938 969 +225 298 +161 253 +576 593 +439 453 +663 657 +172 72 +225 222 +402 319 +1 61 +750 694 +448 384 +739 801 +218 136 +522 536 +1012 958 +557 647 +610 526 +1 28 +999 904 +484 509 +922 884 +539 565 +635 601 +417 323 +615 522 +149 192 +66 103 +483 451 +903 867 +555 602 +874 783 +346 311 +1027 994 +187 172 +1 51 +332 389 +193 237 +796 721 +561 597 +417 492 +248 331 +358 380 +190 259 +653 726 +54 55 +496 501 +395 459 +729 790 +1 4 +715 634 +170 117 +666 601 +711 808 +457 544 +504 542 +598 590 +829 827 +864 817 +657 617 +1 32 +815 879 +593 692 +709 685 +90 88 +820 911 +553 546 +528 580 +948 997 +1018 937 +1069 988 +433 351 +563 661 +617 630 +367 360 +897 908 +263 203 +545 479 +270 251 +212 162 +967 905 +227 167 +779 862 +346 369 +86 181 +684 765 +291 251 +992 909 +712 645 +664 568 +896 847 +547 538 +466 540 +193 99 +438 423 +323 246 +88 165 +549 544 +120 52 +218 131 +273 372 +500 471 +651 625 +696 684 +432 378 +542 534 +46 73 +458 540 +639 671 +207 127 +507 412 +1067 972 +825 823 +716 663 +755 784 +608 588 +514 496 +209 170 +133 153 +209 199 +216 152 +355 258 +208 283 +305 289 +616 608 +428 463 +157 180 +404 329 +271 221 +266 294 +119 125 +534 625 +376 427 +712 796 +131 151 +883 867 +214 122 +416 370 +752 840 +41 115 +806 875 +947 912 +163 85 +958 969 +734 714 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 diff --git a/scripts/Knapsack/Data/knapPI_2_200_1000_1 b/scripts/Knapsack/Data/knapPI_2_200_1000_1 new file mode 100644 index 0000000..6d163d1 --- /dev/null +++ b/scripts/Knapsack/Data/knapPI_2_200_1000_1 @@ -0,0 +1,202 @@ +200 1008 +482 485 +257 326 +286 248 +517 421 +404 322 +713 795 +45 43 +924 845 +873 955 +160 252 +1 9 +838 901 +40 122 +58 94 +676 738 +627 574 +766 715 +862 882 +405 367 +923 984 +379 299 +461 433 +612 682 +133 72 +813 874 +97 138 +908 856 +165 145 +996 995 +623 529 +220 199 +298 277 +157 97 +723 719 +144 242 +48 107 +129 122 +148 70 +35 98 +644 600 +632 645 +272 267 +1040 972 +977 895 +312 213 +778 748 +567 487 +965 923 +1 29 +616 674 +569 540 +628 554 +493 467 +76 46 +733 710 +575 553 +288 191 +775 724 +723 730 +912 988 +64 90 +354 340 +565 549 +210 196 +922 865 +775 678 +566 570 +934 936 +626 722 +742 651 +194 123 +485 431 +483 508 +617 585 +876 853 +653 642 +896 992 +652 725 +220 286 +727 812 +900 859 +563 663 +56 88 +157 179 +280 187 +537 619 +284 261 +920 846 +124 192 +239 261 +459 514 +931 886 +504 530 +910 849 +382 294 +795 799 +485 391 +351 330 +289 298 +865 790 +250 275 +738 826 +75 72 +788 866 +947 951 +651 748 +595 685 +993 956 +663 564 +265 183 +338 400 +637 721 +206 207 +328 323 +618 611 +64 116 +139 109 +806 795 +412 343 +912 862 +715 685 +1 10 +929 881 +1025 984 +410 403 +273 360 +507 449 +450 541 +174 272 +882 877 +427 359 +787 707 +355 308 +734 770 +1 30 +248 208 +397 311 +159 100 +874 939 +449 422 +857 785 +286 370 +976 989 +908 969 +103 143 +1071 972 +1 28 +117 61 +697 638 +424 348 +439 347 +74 66 +442 391 +568 638 +195 295 +854 826 +281 196 +433 449 +845 855 +224 143 +487 487 +181 140 +496 564 +690 615 +124 135 +575 564 +374 360 +766 793 +149 163 +776 859 +793 760 +674 711 +696 662 +90 159 +732 660 +214 268 +935 948 +228 315 +619 676 +349 341 +734 689 +964 894 +644 706 +484 490 +491 478 +628 671 +1009 932 +944 899 +315 237 +92 187 +554 472 +757 772 +88 98 +952 906 +818 911 +628 635 +316 225 +818 823 +255 164 +432 343 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 diff --git a/scripts/Knapsack/Data/knapPI_2_500_1000_1 b/scripts/Knapsack/Data/knapPI_2_500_1000_1 new file mode 100644 index 0000000..10207e4 --- /dev/null +++ b/scripts/Knapsack/Data/knapPI_2_500_1000_1 @@ -0,0 +1,502 @@ +500 2543 +482 485 +257 326 +286 248 +517 421 +404 322 +713 795 +45 43 +924 845 +873 955 +160 252 +1 9 +838 901 +40 122 +58 94 +676 738 +627 574 +766 715 +862 882 +405 367 +923 984 +379 299 +461 433 +612 682 +133 72 +813 874 +97 138 +908 856 +165 145 +996 995 +623 529 +220 199 +298 277 +157 97 +723 719 +144 242 +48 107 +129 122 +148 70 +35 98 +644 600 +632 645 +272 267 +1040 972 +977 895 +312 213 +778 748 +567 487 +965 923 +1 29 +616 674 +569 540 +628 554 +493 467 +76 46 +733 710 +575 553 +288 191 +775 724 +723 730 +912 988 +64 90 +354 340 +565 549 +210 196 +922 865 +775 678 +566 570 +934 936 +626 722 +742 651 +194 123 +485 431 +483 508 +617 585 +876 853 +653 642 +896 992 +652 725 +220 286 +727 812 +900 859 +563 663 +56 88 +157 179 +280 187 +537 619 +284 261 +920 846 +124 192 +239 261 +459 514 +931 886 +504 530 +910 849 +382 294 +795 799 +485 391 +351 330 +289 298 +865 790 +250 275 +738 826 +75 72 +788 866 +947 951 +651 748 +595 685 +993 956 +663 564 +265 183 +338 400 +637 721 +206 207 +328 323 +618 611 +64 116 +139 109 +806 795 +412 343 +912 862 +715 685 +1 10 +929 881 +1025 984 +410 403 +273 360 +507 449 +450 541 +174 272 +882 877 +427 359 +787 707 +355 308 +734 770 +1 30 +248 208 +397 311 +159 100 +874 939 +449 422 +857 785 +286 370 +976 989 +908 969 +103 143 +1071 972 +1 28 +117 61 +697 638 +424 348 +439 347 +74 66 +442 391 +568 638 +195 295 +854 826 +281 196 +433 449 +845 855 +224 143 +487 487 +181 140 +496 564 +690 615 +124 135 +575 564 +374 360 +766 793 +149 163 +776 859 +793 760 +674 711 +696 662 +90 159 +732 660 +214 268 +935 948 +228 315 +619 676 +349 341 +734 689 +964 894 +644 706 +484 490 +491 478 +628 671 +1009 932 +944 899 +315 237 +92 187 +554 472 +757 772 +88 98 +952 906 +818 911 +628 635 +316 225 +818 823 +255 164 +432 343 +763 732 +490 502 +721 740 +587 576 +530 612 +992 902 +491 454 +343 411 +880 973 +645 703 +761 850 +152 77 +241 220 +727 802 +352 403 +246 181 +1 10 +479 525 +958 919 +749 668 +551 527 +538 462 +319 291 +580 605 +501 457 +487 405 +349 417 +252 279 +731 685 +637 596 +339 307 +257 224 +271 322 +740 840 +1002 975 +404 401 +190 91 +254 327 +277 330 +100 182 +648 603 +810 793 +535 615 +702 733 +855 864 +76 16 +773 863 +917 987 +279 306 +123 34 +922 840 +613 700 +658 706 +705 787 +101 105 +807 834 +883 798 +358 310 +634 609 +786 690 +618 561 +644 579 +141 60 +466 388 +340 309 +495 407 +283 200 +352 313 +886 970 +95 33 +291 273 +217 277 +1007 997 +1 40 +219 227 +764 860 +1025 940 +600 608 +895 990 +690 590 +738 806 +1 52 +772 801 +727 764 +774 710 +340 386 +503 593 +1 50 +432 494 +228 156 +993 936 +1058 965 +130 86 +821 723 +189 184 +943 868 +343 340 +404 412 +560 487 +196 209 +418 346 +782 860 +314 307 +59 95 +778 821 +979 941 +828 821 +584 587 +122 201 +741 665 +566 527 +760 812 +385 424 +395 459 +250 343 +789 836 +492 506 +261 179 +914 916 +380 430 +537 596 +731 808 +361 269 +473 512 +737 811 +708 685 +635 567 +804 776 +827 855 +695 718 +756 853 +57 97 +178 146 +688 746 +1 15 +871 965 +415 512 +510 480 +1057 958 +764 665 +193 191 +905 964 +583 515 +696 606 +887 822 +444 536 +741 693 +12 19 +313 335 +81 101 +828 922 +354 294 +981 910 +499 410 +283 250 +545 546 +635 729 +540 609 +689 720 +946 976 +730 759 +703 798 +14 74 +644 648 +241 299 +793 785 +912 846 +461 390 +801 897 +424 416 +744 837 +272 247 +338 293 +193 144 +987 938 +432 467 +505 480 +944 955 +653 665 +38 26 +468 564 +461 449 +1 26 +576 521 +329 301 +274 321 +701 613 +432 388 +851 879 +915 990 +137 188 +927 963 +903 820 +373 300 +770 822 +160 255 +285 277 +231 153 +366 400 +317 227 +423 518 +420 447 +216 315 +772 813 +271 324 +566 502 +243 299 +725 780 +390 376 +491 516 +225 212 +392 329 +781 810 +434 486 +535 485 +368 416 +938 952 +946 894 +353 358 +1 21 +707 647 +143 44 +630 683 +364 361 +822 814 +147 231 +54 8 +91 165 +431 496 +606 699 +917 852 +553 459 +473 535 +222 314 +954 944 +369 306 +413 459 +717 637 +491 447 +447 408 +44 107 +994 962 +518 565 +448 407 +931 857 +369 317 +181 98 +815 818 +655 600 +267 288 +960 902 +611 567 +271 190 +771 749 +993 908 +359 276 +810 748 +563 592 +360 393 +264 363 +199 163 +1074 983 +131 179 +41 16 +423 478 +197 259 +779 868 +344 295 +536 596 +140 71 +669 622 +938 864 +715 644 +67 5 +321 365 +434 429 +19 64 +928 854 +759 770 +178 88 +160 157 +277 368 +467 421 +653 719 +330 271 +966 975 +817 816 +1045 962 +508 535 +492 438 +743 696 +884 881 +259 318 +56 45 +1 52 +421 496 +270 313 +99 138 +429 334 +1004 988 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 diff --git a/scripts/Knapsack/Data/knapPI_3_1000_1000_1 b/scripts/Knapsack/Data/knapPI_3_1000_1000_1 new file mode 100644 index 0000000..936772c --- /dev/null +++ b/scripts/Knapsack/Data/knapPI_3_1000_1000_1 @@ -0,0 +1,1002 @@ +1000 4990 +585 485 +194 94 +426 326 +606 506 +348 248 +516 416 +521 421 +1092 992 +422 322 +749 649 +895 795 +337 237 +143 43 +557 457 +945 845 +915 815 +1055 955 +546 446 +352 252 +522 422 +109 9 +891 791 +1001 901 +459 359 +222 122 +767 667 +194 94 +698 598 +838 738 +107 7 +674 574 +644 544 +815 715 +434 334 +982 882 +866 766 +467 367 +1094 994 +1084 984 +993 893 +399 299 +733 633 +533 433 +231 131 +782 682 +528 428 +172 72 +800 700 +974 874 +717 617 +238 138 +974 874 +956 856 +820 720 +245 145 +519 419 +1095 995 +894 794 +629 529 +296 196 +299 199 +1097 997 +377 277 +216 116 +197 97 +1008 908 +819 719 +639 539 +342 242 +807 707 +207 107 +669 569 +222 122 +637 537 +170 70 +1031 931 +198 98 +826 726 +700 600 +587 487 +745 645 +872 772 +367 267 +613 513 +1072 972 +181 81 +995 895 +1043 943 +313 213 +158 58 +848 748 +403 303 +587 487 +864 764 +1023 923 +636 536 +129 29 +824 724 +774 674 +889 789 +640 540 +579 479 +654 554 +242 142 +567 467 +439 339 +146 46 +741 641 +810 710 +296 196 +653 553 +594 494 +291 191 +166 66 +824 724 +924 824 +830 730 +308 208 +1088 988 +811 711 +190 90 +900 800 +440 340 +414 314 +649 549 +389 289 +296 196 +501 401 +965 865 +566 466 +778 678 +789 689 +670 570 +933 833 +1036 936 +325 225 +822 722 +344 244 +751 651 +949 849 +223 123 +213 113 +531 431 +479 379 +608 508 +461 361 +685 585 +165 65 +953 853 +586 486 +742 642 +786 686 +1092 992 +386 286 +825 725 +989 889 +386 286 +124 24 +912 812 +591 491 +959 859 +991 891 +763 663 +190 90 +188 88 +281 181 +279 179 +314 214 +287 187 +117 17 +719 619 +572 472 +361 261 +518 418 +946 846 +519 419 +292 192 +456 356 +361 261 +782 682 +614 514 +406 306 +986 886 +301 201 +630 530 +485 385 +949 849 +1052 952 +394 294 +600 500 +899 799 +294 194 +491 391 +837 737 +430 330 +424 324 +398 298 +1092 992 +890 790 +324 224 +375 275 +360 260 +926 826 +197 97 +172 72 +310 210 +966 866 +749 649 +1051 951 +1019 919 +848 748 +163 63 +785 685 +1058 958 +1056 956 +904 804 +664 564 +618 518 +283 183 +528 428 +500 400 +637 537 +821 721 +446 346 +307 207 +253 153 +423 323 +1071 971 +711 611 +762 662 +216 116 +297 197 +209 109 +191 91 +895 795 +629 529 +443 343 +226 126 +962 862 +847 747 +785 685 +569 469 +110 10 +870 770 +981 881 +1034 934 +1084 984 +823 723 +503 403 +995 895 +460 360 +668 568 +549 449 +272 172 +641 541 +1058 958 +372 272 +483 383 +977 877 +408 308 +459 359 +1070 970 +807 707 +683 583 +408 308 +148 48 +870 770 +1030 930 +130 30 +669 569 +308 208 +103 3 +411 311 +120 20 +200 100 +709 609 +1039 939 +987 887 +522 422 +925 825 +885 785 +1030 930 +470 370 +1004 904 +1089 989 +341 241 +1069 969 +479 379 +243 143 +476 376 +1072 972 +1062 962 +128 28 +989 889 +161 61 +543 443 +738 638 +316 216 +448 348 +438 338 +447 347 +260 160 +166 66 +506 406 +491 391 +259 159 +738 638 +131 31 +395 295 +304 204 +926 826 +520 420 +296 196 +253 153 +549 449 +525 425 +955 855 +431 331 +243 143 +665 565 +587 487 +938 838 +240 140 +109 9 +664 564 +1018 918 +715 615 +633 533 +235 135 +332 232 +664 564 +1057 957 +460 360 +691 591 +893 793 +676 576 +263 163 +846 746 +959 859 +477 377 +860 760 +958 858 +811 711 +186 86 +762 662 +534 434 +259 159 +658 558 +760 660 +379 279 +368 268 +940 840 +1048 948 +835 735 +415 315 +674 574 +776 676 +226 126 +441 341 +1012 912 +789 689 +839 739 +994 894 +921 821 +806 706 +725 625 +590 490 +1017 917 +578 478 +301 201 +771 671 +1093 993 +1032 932 +249 149 +999 899 +152 52 +337 237 +859 759 +287 187 +367 267 +572 472 +356 256 +872 772 +883 783 +198 98 +217 117 +1006 906 +616 516 +1011 911 +280 180 +735 635 +125 25 +325 225 +480 380 +923 823 +812 712 +264 164 +366 266 +443 343 +316 216 +832 732 +548 448 +602 502 +641 541 +840 740 +764 664 +676 576 +1054 954 +712 612 +826 726 +1002 902 +872 772 +554 454 +631 531 +511 411 +1043 943 +1073 973 +850 750 +803 703 +427 327 +950 850 +1017 917 +177 77 +105 5 +320 220 +213 113 +902 802 +1013 913 +503 403 +891 791 +281 181 +1098 998 +110 10 +959 859 +625 525 +445 345 +1019 919 +531 431 +768 668 +775 675 +627 527 +933 833 +562 462 +538 438 +391 291 +623 523 +705 605 +1016 916 +557 457 +520 420 +505 405 +215 115 +517 417 +760 660 +379 279 +361 261 +785 685 +872 772 +696 596 +488 388 +407 307 +864 764 +324 224 +943 843 +422 322 +306 206 +940 840 +507 407 +1075 975 +739 639 +501 401 +952 852 +191 91 +642 542 +427 327 +160 60 +430 330 +857 757 +282 182 +182 82 +703 603 +737 637 +893 793 +193 93 +715 615 +714 614 +833 733 +236 136 +964 864 +287 187 +116 16 +202 102 +963 863 +1072 972 +1087 987 +263 163 +406 306 +601 501 +134 34 +577 477 +940 840 +592 492 +800 700 +221 121 +806 706 +180 80 +887 787 +238 138 +205 105 +760 660 +934 834 +329 229 +898 798 +927 827 +410 310 +548 448 +709 609 +330 230 +790 690 +932 832 +661 561 +589 489 +679 579 +686 586 +160 60 +391 291 +488 388 +765 665 +409 309 +760 660 +507 407 +802 702 +300 200 +253 153 +413 313 +706 606 +1070 970 +223 123 +133 33 +353 253 +373 273 +809 709 +377 277 +932 832 +1097 997 +208 108 +140 40 +988 888 +327 227 +581 481 +960 860 +383 283 +1040 940 +958 858 +708 608 +384 284 +1090 990 +811 711 +690 590 +950 850 +906 806 +339 239 +152 52 +1043 943 +901 801 +295 195 +864 764 +195 95 +810 710 +510 410 +486 386 +764 664 +693 593 +1000 900 +150 50 +212 112 +594 494 +1063 963 +256 156 +854 754 +1036 936 +558 458 +1065 965 +119 19 +186 86 +325 225 +823 723 +669 569 +284 184 +197 97 +968 868 +294 194 +440 340 +854 754 +512 412 +702 602 +587 487 +161 61 +309 209 +795 695 +446 346 +447 347 +960 860 +819 719 +407 307 +200 100 +195 95 +197 97 +921 821 +943 843 +1041 941 +845 745 +921 821 +386 286 +687 587 +592 492 +301 201 +216 116 +765 665 +631 531 +627 527 +524 424 +912 812 +353 253 +524 424 +526 426 +559 459 +513 413 +443 343 +1080 980 +936 836 +391 291 +606 506 +933 833 +279 179 +586 486 +1016 916 +109 9 +530 430 +675 575 +696 596 +1022 922 +908 808 +245 145 +369 269 +997 897 +612 512 +504 404 +911 811 +842 742 +785 685 +828 728 +667 567 +369 269 +876 776 +203 103 +955 855 +845 745 +818 718 +135 35 +953 853 +879 779 +197 97 +171 71 +246 146 +180 80 +846 746 +942 842 +115 15 +228 128 +1065 965 +1041 941 +612 512 +327 227 +580 480 +130 30 +1058 958 +442 342 +765 665 +705 605 +291 191 +631 531 +1064 964 +464 364 +615 515 +459 359 +706 606 +967 867 +922 822 +920 820 +636 536 +413 313 +793 693 +307 207 +119 19 +1011 911 +435 335 +408 308 +201 101 +530 430 +1022 922 +785 685 +394 294 +741 641 +1010 910 +213 113 +510 410 +241 141 +350 250 +790 690 +646 546 +800 700 +829 729 +659 559 +709 609 +581 481 +820 720 +603 503 +1076 976 +866 766 +859 759 +107 7 +898 798 +982 882 +174 74 +959 859 +748 648 +282 182 +399 299 +525 425 +885 785 +642 542 +946 846 +783 683 +490 390 +953 853 +997 897 +1038 938 +516 416 +189 89 +937 837 +724 624 +347 247 +281 181 +393 293 +978 878 +244 144 +1033 933 +1038 938 +680 580 +567 467 +352 252 +580 480 +307 207 +1055 955 +758 658 +765 665 +120 20 +126 26 +1054 954 +664 564 +447 347 +549 449 +859 759 +126 26 +546 446 +621 521 +114 14 +401 301 +757 657 +421 321 +810 710 +713 613 +1080 980 +488 388 +288 188 +979 879 +736 636 +1090 990 +303 203 +288 188 +532 432 +1063 963 +229 129 +920 820 +730 630 +400 300 +609 509 +922 822 +337 237 +355 255 +473 373 +377 277 +938 838 +253 153 +495 395 +500 400 +792 692 +327 227 +203 103 +618 518 +318 218 +547 447 +484 384 +415 315 +1031 931 +913 813 +496 396 +424 324 +489 389 +602 502 +740 640 +399 299 +387 287 +880 780 +397 297 +476 376 +1077 977 +616 516 +612 512 +312 212 +319 219 +429 329 +655 555 +910 810 +498 398 +586 486 +389 289 +585 485 +898 798 +516 416 +698 598 +1052 952 +149 49 +994 894 +672 572 +458 358 +797 697 +121 21 +870 770 +747 647 +825 725 +144 44 +642 542 +783 683 +314 214 +461 361 +987 887 +914 814 +145 45 +331 231 +194 94 +108 8 +382 282 +265 165 +182 82 +596 496 +419 319 +799 699 +726 626 +952 852 +246 146 +559 459 +641 541 +635 535 +974 874 +414 314 +825 725 +1044 944 +877 777 +406 306 +654 554 +559 459 +308 208 +737 637 +887 787 +547 447 +1076 976 +508 408 +1012 912 +207 107 +544 444 +1062 962 +103 3 +665 565 +401 301 +507 407 +264 164 +957 857 +537 437 +417 317 +752 652 +198 98 +864 764 +918 818 +141 41 +700 600 +837 737 +388 288 +276 176 +1002 902 +236 136 +667 567 +228 128 +290 190 +494 394 +849 749 +335 235 +1008 908 +142 42 +376 276 +924 824 +848 748 +784 684 +692 592 +1079 979 +493 393 +668 568 +463 363 +467 367 +263 163 +152 52 +1083 983 +742 642 +279 179 +435 335 +116 16 +226 126 +578 478 +230 130 +359 259 +683 583 +968 868 +229 129 +395 295 +852 752 +696 596 +267 167 +171 71 +956 856 +722 622 +740 640 +964 864 +870 770 +744 644 +531 431 +105 5 +295 195 +465 365 +548 448 +529 429 +801 701 +164 64 +1052 952 +954 854 +980 880 +870 770 +268 168 +188 88 +179 79 +257 157 +1061 961 +468 368 +572 472 +521 421 +317 217 +819 719 +809 709 +371 271 +247 147 +1075 975 +396 296 +916 816 +1009 909 +1062 962 +864 764 +635 535 +351 251 +538 438 +978 878 +796 696 +853 753 +981 881 +670 570 +418 318 +353 253 +145 45 +766 666 +152 52 +1031 931 +596 496 +533 433 +413 313 +910 810 +238 138 +778 678 +434 334 +223 123 +1088 988 +312 212 +0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 1 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 1 0 1 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 diff --git a/scripts/Knapsack/Data/knapPI_3_100_1000_1 b/scripts/Knapsack/Data/knapPI_3_100_1000_1 new file mode 100644 index 0000000..ded5c60 --- /dev/null +++ b/scripts/Knapsack/Data/knapPI_3_100_1000_1 @@ -0,0 +1,102 @@ +100 997 +585 485 +194 94 +426 326 +606 506 +348 248 +516 416 +521 421 +1092 992 +422 322 +749 649 +895 795 +337 237 +143 43 +557 457 +945 845 +915 815 +1055 955 +546 446 +352 252 +522 422 +109 9 +891 791 +1001 901 +459 359 +222 122 +767 667 +194 94 +698 598 +838 738 +107 7 +674 574 +644 544 +815 715 +434 334 +982 882 +866 766 +467 367 +1094 994 +1084 984 +993 893 +399 299 +733 633 +533 433 +231 131 +782 682 +528 428 +172 72 +800 700 +974 874 +717 617 +238 138 +974 874 +956 856 +820 720 +245 145 +519 419 +1095 995 +894 794 +629 529 +296 196 +299 199 +1097 997 +377 277 +216 116 +197 97 +1008 908 +819 719 +639 539 +342 242 +807 707 +207 107 +669 569 +222 122 +637 537 +170 70 +1031 931 +198 98 +826 726 +700 600 +587 487 +745 645 +872 772 +367 267 +613 513 +1072 972 +181 81 +995 895 +1043 943 +313 213 +158 58 +848 748 +403 303 +587 487 +864 764 +1023 923 +636 536 +129 29 +824 724 +774 674 +889 789 +0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 1 0 0 0 diff --git a/scripts/Knapsack/Data/knapPI_3_2000_1000_1 b/scripts/Knapsack/Data/knapPI_3_2000_1000_1 new file mode 100644 index 0000000..444b1e8 --- /dev/null +++ b/scripts/Knapsack/Data/knapPI_3_2000_1000_1 @@ -0,0 +1,2002 @@ +2000 9819 +585 485 +194 94 +426 326 +606 506 +348 248 +516 416 +521 421 +1092 992 +422 322 +749 649 +895 795 +337 237 +143 43 +557 457 +945 845 +915 815 +1055 955 +546 446 +352 252 +522 422 +109 9 +891 791 +1001 901 +459 359 +222 122 +767 667 +194 94 +698 598 +838 738 +107 7 +674 574 +644 544 +815 715 +434 334 +982 882 +866 766 +467 367 +1094 994 +1084 984 +993 893 +399 299 +733 633 +533 433 +231 131 +782 682 +528 428 +172 72 +800 700 +974 874 +717 617 +238 138 +974 874 +956 856 +820 720 +245 145 +519 419 +1095 995 +894 794 +629 529 +296 196 +299 199 +1097 997 +377 277 +216 116 +197 97 +1008 908 +819 719 +639 539 +342 242 +807 707 +207 107 +669 569 +222 122 +637 537 +170 70 +1031 931 +198 98 +826 726 +700 600 +587 487 +745 645 +872 772 +367 267 +613 513 +1072 972 +181 81 +995 895 +1043 943 +313 213 +158 58 +848 748 +403 303 +587 487 +864 764 +1023 923 +636 536 +129 29 +824 724 +774 674 +889 789 +640 540 +579 479 +654 554 +242 142 +567 467 +439 339 +146 46 +741 641 +810 710 +296 196 +653 553 +594 494 +291 191 +166 66 +824 724 +924 824 +830 730 +308 208 +1088 988 +811 711 +190 90 +900 800 +440 340 +414 314 +649 549 +389 289 +296 196 +501 401 +965 865 +566 466 +778 678 +789 689 +670 570 +933 833 +1036 936 +325 225 +822 722 +344 244 +751 651 +949 849 +223 123 +213 113 +531 431 +479 379 +608 508 +461 361 +685 585 +165 65 +953 853 +586 486 +742 642 +786 686 +1092 992 +386 286 +825 725 +989 889 +386 286 +124 24 +912 812 +591 491 +959 859 +991 891 +763 663 +190 90 +188 88 +281 181 +279 179 +314 214 +287 187 +117 17 +719 619 +572 472 +361 261 +518 418 +946 846 +519 419 +292 192 +456 356 +361 261 +782 682 +614 514 +406 306 +986 886 +301 201 +630 530 +485 385 +949 849 +1052 952 +394 294 +600 500 +899 799 +294 194 +491 391 +837 737 +430 330 +424 324 +398 298 +1092 992 +890 790 +324 224 +375 275 +360 260 +926 826 +197 97 +172 72 +310 210 +966 866 +749 649 +1051 951 +1019 919 +848 748 +163 63 +785 685 +1058 958 +1056 956 +904 804 +664 564 +618 518 +283 183 +528 428 +500 400 +637 537 +821 721 +446 346 +307 207 +253 153 +423 323 +1071 971 +711 611 +762 662 +216 116 +297 197 +209 109 +191 91 +895 795 +629 529 +443 343 +226 126 +962 862 +847 747 +785 685 +569 469 +110 10 +870 770 +981 881 +1034 934 +1084 984 +823 723 +503 403 +995 895 +460 360 +668 568 +549 449 +272 172 +641 541 +1058 958 +372 272 +483 383 +977 877 +408 308 +459 359 +1070 970 +807 707 +683 583 +408 308 +148 48 +870 770 +1030 930 +130 30 +669 569 +308 208 +103 3 +411 311 +120 20 +200 100 +709 609 +1039 939 +987 887 +522 422 +925 825 +885 785 +1030 930 +470 370 +1004 904 +1089 989 +341 241 +1069 969 +479 379 +243 143 +476 376 +1072 972 +1062 962 +128 28 +989 889 +161 61 +543 443 +738 638 +316 216 +448 348 +438 338 +447 347 +260 160 +166 66 +506 406 +491 391 +259 159 +738 638 +131 31 +395 295 +304 204 +926 826 +520 420 +296 196 +253 153 +549 449 +525 425 +955 855 +431 331 +243 143 +665 565 +587 487 +938 838 +240 140 +109 9 +664 564 +1018 918 +715 615 +633 533 +235 135 +332 232 +664 564 +1057 957 +460 360 +691 591 +893 793 +676 576 +263 163 +846 746 +959 859 +477 377 +860 760 +958 858 +811 711 +186 86 +762 662 +534 434 +259 159 +658 558 +760 660 +379 279 +368 268 +940 840 +1048 948 +835 735 +415 315 +674 574 +776 676 +226 126 +441 341 +1012 912 +789 689 +839 739 +994 894 +921 821 +806 706 +725 625 +590 490 +1017 917 +578 478 +301 201 +771 671 +1093 993 +1032 932 +249 149 +999 899 +152 52 +337 237 +859 759 +287 187 +367 267 +572 472 +356 256 +872 772 +883 783 +198 98 +217 117 +1006 906 +616 516 +1011 911 +280 180 +735 635 +125 25 +325 225 +480 380 +923 823 +812 712 +264 164 +366 266 +443 343 +316 216 +832 732 +548 448 +602 502 +641 541 +840 740 +764 664 +676 576 +1054 954 +712 612 +826 726 +1002 902 +872 772 +554 454 +631 531 +511 411 +1043 943 +1073 973 +850 750 +803 703 +427 327 +950 850 +1017 917 +177 77 +105 5 +320 220 +213 113 +902 802 +1013 913 +503 403 +891 791 +281 181 +1098 998 +110 10 +959 859 +625 525 +445 345 +1019 919 +531 431 +768 668 +775 675 +627 527 +933 833 +562 462 +538 438 +391 291 +623 523 +705 605 +1016 916 +557 457 +520 420 +505 405 +215 115 +517 417 +760 660 +379 279 +361 261 +785 685 +872 772 +696 596 +488 388 +407 307 +864 764 +324 224 +943 843 +422 322 +306 206 +940 840 +507 407 +1075 975 +739 639 +501 401 +952 852 +191 91 +642 542 +427 327 +160 60 +430 330 +857 757 +282 182 +182 82 +703 603 +737 637 +893 793 +193 93 +715 615 +714 614 +833 733 +236 136 +964 864 +287 187 +116 16 +202 102 +963 863 +1072 972 +1087 987 +263 163 +406 306 +601 501 +134 34 +577 477 +940 840 +592 492 +800 700 +221 121 +806 706 +180 80 +887 787 +238 138 +205 105 +760 660 +934 834 +329 229 +898 798 +927 827 +410 310 +548 448 +709 609 +330 230 +790 690 +932 832 +661 561 +589 489 +679 579 +686 586 +160 60 +391 291 +488 388 +765 665 +409 309 +760 660 +507 407 +802 702 +300 200 +253 153 +413 313 +706 606 +1070 970 +223 123 +133 33 +353 253 +373 273 +809 709 +377 277 +932 832 +1097 997 +208 108 +140 40 +988 888 +327 227 +581 481 +960 860 +383 283 +1040 940 +958 858 +708 608 +384 284 +1090 990 +811 711 +690 590 +950 850 +906 806 +339 239 +152 52 +1043 943 +901 801 +295 195 +864 764 +195 95 +810 710 +510 410 +486 386 +764 664 +693 593 +1000 900 +150 50 +212 112 +594 494 +1063 963 +256 156 +854 754 +1036 936 +558 458 +1065 965 +119 19 +186 86 +325 225 +823 723 +669 569 +284 184 +197 97 +968 868 +294 194 +440 340 +854 754 +512 412 +702 602 +587 487 +161 61 +309 209 +795 695 +446 346 +447 347 +960 860 +819 719 +407 307 +200 100 +195 95 +197 97 +921 821 +943 843 +1041 941 +845 745 +921 821 +386 286 +687 587 +592 492 +301 201 +216 116 +765 665 +631 531 +627 527 +524 424 +912 812 +353 253 +524 424 +526 426 +559 459 +513 413 +443 343 +1080 980 +936 836 +391 291 +606 506 +933 833 +279 179 +586 486 +1016 916 +109 9 +530 430 +675 575 +696 596 +1022 922 +908 808 +245 145 +369 269 +997 897 +612 512 +504 404 +911 811 +842 742 +785 685 +828 728 +667 567 +369 269 +876 776 +203 103 +955 855 +845 745 +818 718 +135 35 +953 853 +879 779 +197 97 +171 71 +246 146 +180 80 +846 746 +942 842 +115 15 +228 128 +1065 965 +1041 941 +612 512 +327 227 +580 480 +130 30 +1058 958 +442 342 +765 665 +705 605 +291 191 +631 531 +1064 964 +464 364 +615 515 +459 359 +706 606 +967 867 +922 822 +920 820 +636 536 +413 313 +793 693 +307 207 +119 19 +1011 911 +435 335 +408 308 +201 101 +530 430 +1022 922 +785 685 +394 294 +741 641 +1010 910 +213 113 +510 410 +241 141 +350 250 +790 690 +646 546 +800 700 +829 729 +659 559 +709 609 +581 481 +820 720 +603 503 +1076 976 +866 766 +859 759 +107 7 +898 798 +982 882 +174 74 +959 859 +748 648 +282 182 +399 299 +525 425 +885 785 +642 542 +946 846 +783 683 +490 390 +953 853 +997 897 +1038 938 +516 416 +189 89 +937 837 +724 624 +347 247 +281 181 +393 293 +978 878 +244 144 +1033 933 +1038 938 +680 580 +567 467 +352 252 +580 480 +307 207 +1055 955 +758 658 +765 665 +120 20 +126 26 +1054 954 +664 564 +447 347 +549 449 +859 759 +126 26 +546 446 +621 521 +114 14 +401 301 +757 657 +421 321 +810 710 +713 613 +1080 980 +488 388 +288 188 +979 879 +736 636 +1090 990 +303 203 +288 188 +532 432 +1063 963 +229 129 +920 820 +730 630 +400 300 +609 509 +922 822 +337 237 +355 255 +473 373 +377 277 +938 838 +253 153 +495 395 +500 400 +792 692 +327 227 +203 103 +618 518 +318 218 +547 447 +484 384 +415 315 +1031 931 +913 813 +496 396 +424 324 +489 389 +602 502 +740 640 +399 299 +387 287 +880 780 +397 297 +476 376 +1077 977 +616 516 +612 512 +312 212 +319 219 +429 329 +655 555 +910 810 +498 398 +586 486 +389 289 +585 485 +898 798 +516 416 +698 598 +1052 952 +149 49 +994 894 +672 572 +458 358 +797 697 +121 21 +870 770 +747 647 +825 725 +144 44 +642 542 +783 683 +314 214 +461 361 +987 887 +914 814 +145 45 +331 231 +194 94 +108 8 +382 282 +265 165 +182 82 +596 496 +419 319 +799 699 +726 626 +952 852 +246 146 +559 459 +641 541 +635 535 +974 874 +414 314 +825 725 +1044 944 +877 777 +406 306 +654 554 +559 459 +308 208 +737 637 +887 787 +547 447 +1076 976 +508 408 +1012 912 +207 107 +544 444 +1062 962 +103 3 +665 565 +401 301 +507 407 +264 164 +957 857 +537 437 +417 317 +752 652 +198 98 +864 764 +918 818 +141 41 +700 600 +837 737 +388 288 +276 176 +1002 902 +236 136 +667 567 +228 128 +290 190 +494 394 +849 749 +335 235 +1008 908 +142 42 +376 276 +924 824 +848 748 +784 684 +692 592 +1079 979 +493 393 +668 568 +463 363 +467 367 +263 163 +152 52 +1083 983 +742 642 +279 179 +435 335 +116 16 +226 126 +578 478 +230 130 +359 259 +683 583 +968 868 +229 129 +395 295 +852 752 +696 596 +267 167 +171 71 +956 856 +722 622 +740 640 +964 864 +870 770 +744 644 +531 431 +105 5 +295 195 +465 365 +548 448 +529 429 +801 701 +164 64 +1052 952 +954 854 +980 880 +870 770 +268 168 +188 88 +179 79 +257 157 +1061 961 +468 368 +572 472 +521 421 +317 217 +819 719 +809 709 +371 271 +247 147 +1075 975 +396 296 +916 816 +1009 909 +1062 962 +864 764 +635 535 +351 251 +538 438 +978 878 +796 696 +853 753 +981 881 +670 570 +418 318 +353 253 +145 45 +766 666 +152 52 +1031 931 +596 496 +533 433 +413 313 +910 810 +238 138 +778 678 +434 334 +223 123 +1088 988 +312 212 +608 508 +166 66 +870 770 +306 206 +851 751 +850 750 +880 780 +164 64 +541 441 +566 466 +307 207 +437 337 +616 516 +610 510 +774 674 +896 796 +508 408 +275 175 +1020 920 +537 437 +673 573 +1038 938 +734 634 +948 848 +978 878 +661 561 +1090 990 +818 718 +926 826 +1048 948 +796 696 +749 649 +900 800 +669 569 +511 411 +763 663 +522 422 +682 582 +807 707 +943 843 +434 334 +302 202 +1086 986 +802 702 +594 494 +679 579 +250 150 +825 725 +662 562 +903 803 +480 380 +440 340 +932 832 +256 156 +1079 979 +932 832 +476 376 +702 602 +611 511 +334 234 +514 414 +788 688 +260 160 +284 184 +1082 982 +1078 978 +338 238 +513 413 +590 490 +733 633 +999 899 +685 585 +351 251 +706 606 +626 526 +1063 963 +997 897 +450 350 +139 39 +342 242 +757 657 +639 539 +552 452 +839 739 +638 538 +367 267 +931 831 +265 165 +560 460 +277 177 +285 185 +820 720 +1034 934 +902 802 +540 440 +744 644 +590 490 +182 82 +268 168 +898 798 +171 71 +297 197 +1077 977 +273 173 +558 458 +181 81 +304 204 +335 235 +903 803 +212 112 +239 139 +203 103 +499 399 +368 268 +520 420 +979 879 +1091 991 +743 643 +678 578 +206 106 +1072 972 +222 122 +277 177 +544 444 +498 398 +362 262 +448 348 +791 691 +596 496 +1097 997 +376 276 +546 446 +925 825 +271 171 +714 614 +649 549 +221 121 +381 281 +830 730 +311 211 +441 341 +212 112 +384 284 +508 408 +798 698 +830 730 +117 17 +463 363 +646 546 +189 89 +772 672 +705 605 +1074 974 +1038 938 +966 866 +268 168 +477 377 +805 705 +659 559 +147 47 +440 340 +500 400 +627 527 +315 215 +879 779 +214 114 +861 761 +151 51 +583 483 +981 881 +192 92 +649 549 +490 390 +779 679 +683 583 +428 328 +761 661 +350 250 +491 391 +303 203 +436 336 +581 481 +761 661 +852 752 +225 125 +807 707 +189 89 +182 82 +375 275 +163 63 +459 359 +760 660 +278 178 +121 21 +880 780 +387 287 +142 42 +319 219 +105 5 +600 500 +480 380 +920 820 +872 772 +195 95 +916 816 +144 44 +109 9 +848 748 +584 484 +778 678 +645 545 +376 276 +689 589 +578 478 +257 157 +763 663 +1001 901 +694 594 +877 777 +857 757 +174 74 +1047 947 +347 247 +548 448 +155 55 +670 570 +579 479 +413 313 +885 785 +1081 981 +1058 958 +895 795 +780 680 +652 552 +493 393 +489 389 +1044 944 +380 280 +696 596 +964 864 +719 619 +736 636 +711 611 +612 512 +952 852 +992 892 +383 283 +284 184 +399 299 +1047 947 +866 766 +714 614 +412 312 +725 625 +926 826 +249 149 +826 726 +477 377 +833 733 +574 474 +905 805 +118 18 +779 679 +762 662 +503 403 +516 416 +1064 964 +101 1 +437 337 +630 530 +641 541 +852 752 +578 478 +122 22 +469 369 +1081 981 +1046 946 +877 777 +921 821 +1057 957 +933 833 +375 275 +937 837 +684 584 +590 490 +682 582 +137 37 +221 121 +694 594 +1051 951 +229 129 +768 668 +358 258 +218 118 +346 246 +419 319 +462 362 +996 896 +855 755 +621 521 +604 504 +1048 948 +171 71 +348 248 +277 177 +574 474 +276 176 +451 351 +903 803 +154 54 +337 237 +255 155 +777 677 +760 660 +133 33 +971 871 +215 115 +586 486 +697 597 +394 294 +869 769 +525 425 +636 536 +345 245 +1056 956 +482 382 +441 341 +471 371 +284 184 +808 708 +334 234 +644 544 +669 569 +894 794 +316 216 +487 387 +637 537 +838 738 +184 84 +620 520 +910 810 +381 281 +757 657 +602 502 +133 33 +191 91 +259 159 +603 503 +620 520 +1024 924 +768 668 +116 16 +387 287 +133 33 +329 229 +444 344 +474 374 +449 349 +574 474 +706 606 +772 672 +996 896 +1015 915 +695 595 +611 511 +541 441 +223 123 +202 102 +669 569 +152 52 +299 199 +754 654 +496 396 +810 710 +815 715 +534 434 +159 59 +345 245 +710 610 +136 36 +1017 917 +761 661 +1027 927 +513 413 +370 270 +113 13 +217 117 +470 370 +616 516 +500 400 +315 215 +295 195 +316 216 +1084 984 +337 237 +576 476 +715 615 +264 164 +599 499 +505 405 +577 477 +774 674 +860 760 +296 196 +385 285 +708 608 +156 56 +1007 907 +1066 966 +632 532 +722 622 +151 51 +321 221 +816 716 +294 194 +427 327 +191 91 +980 880 +447 347 +810 710 +352 252 +367 267 +573 473 +500 400 +616 516 +476 376 +485 385 +709 609 +457 357 +420 320 +1058 958 +296 196 +765 665 +638 538 +892 792 +1035 935 +164 64 +504 404 +520 420 +200 100 +771 671 +226 126 +1068 968 +955 855 +977 877 +194 94 +277 177 +831 731 +623 523 +353 253 +239 139 +108 8 +252 152 +493 393 +832 732 +643 543 +346 246 +448 348 +665 565 +418 318 +840 740 +589 489 +1002 902 +122 22 +117 17 +1098 998 +1073 973 +149 49 +398 298 +481 381 +711 611 +110 10 +132 32 +529 429 +111 11 +321 221 +437 337 +250 150 +236 136 +817 717 +989 889 +630 530 +622 522 +432 332 +905 805 +1042 942 +128 28 +665 565 +1031 931 +316 216 +857 757 +161 61 +709 609 +270 170 +644 544 +972 872 +1005 905 +744 644 +695 595 +308 208 +346 246 +780 680 +213 113 +797 697 +275 175 +739 639 +256 156 +779 679 +344 244 +1061 961 +983 883 +461 361 +365 265 +902 802 +983 883 +459 359 +562 462 +939 839 +585 485 +818 718 +372 272 +380 280 +304 204 +352 252 +1084 984 +380 280 +509 409 +202 102 +498 398 +715 615 +1009 909 +396 296 +470 370 +581 481 +982 882 +1056 956 +314 214 +330 230 +866 766 +359 259 +135 35 +1022 922 +521 421 +806 706 +371 271 +372 272 +470 370 +256 156 +948 848 +652 552 +150 50 +585 485 +1076 976 +636 536 +370 270 +170 70 +896 796 +1002 902 +1063 963 +552 452 +479 379 +135 35 +1091 991 +1047 947 +651 551 +478 378 +997 897 +157 57 +407 307 +452 352 +521 421 +769 669 +174 74 +802 702 +488 388 +241 141 +659 559 +558 458 +1080 980 +563 463 +715 615 +856 756 +781 681 +987 887 +331 231 +432 332 +307 207 +628 528 +918 818 +756 656 +431 331 +354 254 +1079 979 +887 787 +545 445 +595 495 +448 348 +470 370 +824 724 +110 10 +501 401 +300 200 +746 646 +427 327 +768 668 +117 17 +342 242 +474 374 +402 302 +855 755 +961 861 +1080 980 +930 830 +476 376 +177 77 +108 8 +541 441 +132 32 +689 589 +560 460 +1090 990 +904 804 +289 189 +123 23 +968 868 +969 869 +1096 996 +1043 943 +463 363 +815 715 +337 237 +728 628 +520 420 +173 73 +665 565 +299 199 +314 214 +138 38 +433 333 +309 209 +826 726 +427 327 +275 175 +1012 912 +158 58 +899 799 +725 625 +472 372 +166 66 +1076 976 +269 169 +220 120 +575 475 +767 667 +304 204 +288 188 +190 90 +128 28 +596 496 +804 704 +101 1 +749 649 +574 474 +846 746 +549 449 +797 697 +352 252 +812 712 +432 332 +389 289 +387 287 +725 625 +289 189 +1053 953 +989 889 +562 462 +163 63 +402 302 +478 378 +179 79 +306 206 +141 41 +997 897 +923 823 +330 230 +1008 908 +482 382 +765 665 +675 575 +136 36 +160 60 +832 732 +629 529 +909 809 +577 477 +166 66 +390 290 +391 291 +189 89 +691 591 +1061 961 +683 583 +561 461 +352 252 +802 702 +579 479 +632 532 +630 530 +780 680 +324 224 +153 53 +888 788 +742 642 +409 309 +1100 1000 +466 366 +991 891 +452 352 +922 822 +502 402 +252 152 +645 545 +424 324 +213 113 +733 633 +1067 967 +367 267 +554 454 +481 381 +823 723 +372 272 +114 14 +606 506 +120 20 +519 419 +408 308 +561 461 +744 644 +626 526 +813 713 +1078 978 +582 482 +568 468 +436 336 +829 729 +389 289 +895 795 +596 496 +681 581 +426 326 +483 383 +630 530 +326 226 +267 167 +521 421 +622 522 +486 386 +930 830 +373 273 +191 91 +584 484 +216 116 +776 676 +847 747 +207 107 +495 395 +329 229 +1058 958 +1002 902 +856 756 +1062 962 +362 262 +205 105 +803 703 +184 84 +611 511 +1091 991 +581 481 +801 701 +549 449 +789 689 +988 888 +755 655 +699 599 +700 600 +406 306 +638 538 +592 492 +599 499 +903 803 +981 881 +545 445 +1081 981 +416 316 +573 473 +989 889 +483 383 +885 785 +779 679 +865 765 +673 573 +591 491 +689 589 +689 589 +580 480 +224 124 +245 145 +841 741 +724 624 +998 898 +1023 923 +825 725 +1015 915 +782 682 +332 232 +231 131 +1074 974 +498 398 +835 735 +1006 906 +778 678 +853 753 +740 640 +412 312 +744 644 +890 790 +312 212 +401 301 +223 123 +1045 945 +353 253 +547 447 +1043 943 +297 197 +118 18 +127 27 +1016 916 +673 573 +427 327 +689 589 +740 640 +1034 934 +715 615 +309 209 +570 470 +629 529 +755 655 +999 899 +388 288 +115 15 +501 401 +692 592 +940 840 +192 92 +733 633 +675 575 +807 707 +914 814 +524 424 +454 354 +782 682 +227 127 +294 194 +474 374 +955 855 +666 566 +290 190 +694 594 +828 728 +1073 973 +278 178 +745 645 +375 275 +703 603 +188 88 +812 712 +467 367 +132 32 +644 544 +398 298 +838 738 +661 561 +1063 963 +1006 906 +560 460 +726 626 +366 266 +243 143 +827 727 +604 504 +133 33 +936 836 +542 442 +461 361 +728 628 +531 431 +484 384 +654 554 +344 244 +124 24 +582 482 +516 416 +865 765 +835 735 +546 446 +343 243 +347 247 +554 454 +1013 913 +1032 932 +660 560 +594 494 +628 528 +748 648 +694 594 +457 357 +1035 935 +696 596 +562 462 +888 788 +721 621 +636 536 +760 660 +859 759 +664 564 +300 200 +402 302 +666 566 +1036 936 +841 741 +692 592 +317 217 +824 724 +319 219 +218 118 +932 832 +399 299 +919 819 +351 251 +587 487 +229 129 +573 473 +196 96 +341 241 +267 167 +164 64 +269 169 +616 516 +481 381 +957 857 +1076 976 +318 218 +867 767 +590 490 +937 837 +604 504 +507 407 +807 707 +303 203 +442 342 +487 387 +575 475 +835 735 +275 175 +806 706 +886 786 +435 335 +271 171 +140 40 +332 232 +921 821 +988 888 +231 131 +966 866 +259 159 +1076 976 +1078 978 +353 253 +153 53 +719 619 +949 849 +742 642 +578 478 +560 460 +119 19 +318 218 +330 230 +318 218 +553 453 +767 667 +436 336 +1049 949 +1031 931 +189 89 +688 588 +588 488 +549 449 +668 568 +666 566 +626 526 +0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 1 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 1 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 1 0 1 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 1 0 0 0 1 0 0 1 0 1 0 0 0 0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 1 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 1 0 0 0 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 1 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 1 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 1 0 0 0 0 0 0 0 1 1 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 diff --git a/scripts/Knapsack/Data/knapPI_3_200_1000_1 b/scripts/Knapsack/Data/knapPI_3_200_1000_1 new file mode 100644 index 0000000..4f19afe --- /dev/null +++ b/scripts/Knapsack/Data/knapPI_3_200_1000_1 @@ -0,0 +1,202 @@ +200 997 +585 485 +194 94 +426 326 +606 506 +348 248 +516 416 +521 421 +1092 992 +422 322 +749 649 +895 795 +337 237 +143 43 +557 457 +945 845 +915 815 +1055 955 +546 446 +352 252 +522 422 +109 9 +891 791 +1001 901 +459 359 +222 122 +767 667 +194 94 +698 598 +838 738 +107 7 +674 574 +644 544 +815 715 +434 334 +982 882 +866 766 +467 367 +1094 994 +1084 984 +993 893 +399 299 +733 633 +533 433 +231 131 +782 682 +528 428 +172 72 +800 700 +974 874 +717 617 +238 138 +974 874 +956 856 +820 720 +245 145 +519 419 +1095 995 +894 794 +629 529 +296 196 +299 199 +1097 997 +377 277 +216 116 +197 97 +1008 908 +819 719 +639 539 +342 242 +807 707 +207 107 +669 569 +222 122 +637 537 +170 70 +1031 931 +198 98 +826 726 +700 600 +587 487 +745 645 +872 772 +367 267 +613 513 +1072 972 +181 81 +995 895 +1043 943 +313 213 +158 58 +848 748 +403 303 +587 487 +864 764 +1023 923 +636 536 +129 29 +824 724 +774 674 +889 789 +640 540 +579 479 +654 554 +242 142 +567 467 +439 339 +146 46 +741 641 +810 710 +296 196 +653 553 +594 494 +291 191 +166 66 +824 724 +924 824 +830 730 +308 208 +1088 988 +811 711 +190 90 +900 800 +440 340 +414 314 +649 549 +389 289 +296 196 +501 401 +965 865 +566 466 +778 678 +789 689 +670 570 +933 833 +1036 936 +325 225 +822 722 +344 244 +751 651 +949 849 +223 123 +213 113 +531 431 +479 379 +608 508 +461 361 +685 585 +165 65 +953 853 +586 486 +742 642 +786 686 +1092 992 +386 286 +825 725 +989 889 +386 286 +124 24 +912 812 +591 491 +959 859 +991 891 +763 663 +190 90 +188 88 +281 181 +279 179 +314 214 +287 187 +117 17 +719 619 +572 472 +361 261 +518 418 +946 846 +519 419 +292 192 +456 356 +361 261 +782 682 +614 514 +406 306 +986 886 +301 201 +630 530 +485 385 +949 849 +1052 952 +394 294 +600 500 +899 799 +294 194 +491 391 +837 737 +430 330 +424 324 +398 298 +1092 992 +890 790 +324 224 +0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 diff --git a/scripts/Knapsack/Data/knapPI_3_500_1000_1 b/scripts/Knapsack/Data/knapPI_3_500_1000_1 new file mode 100644 index 0000000..bb76997 --- /dev/null +++ b/scripts/Knapsack/Data/knapPI_3_500_1000_1 @@ -0,0 +1,502 @@ +500 2517 +585 485 +194 94 +426 326 +606 506 +348 248 +516 416 +521 421 +1092 992 +422 322 +749 649 +895 795 +337 237 +143 43 +557 457 +945 845 +915 815 +1055 955 +546 446 +352 252 +522 422 +109 9 +891 791 +1001 901 +459 359 +222 122 +767 667 +194 94 +698 598 +838 738 +107 7 +674 574 +644 544 +815 715 +434 334 +982 882 +866 766 +467 367 +1094 994 +1084 984 +993 893 +399 299 +733 633 +533 433 +231 131 +782 682 +528 428 +172 72 +800 700 +974 874 +717 617 +238 138 +974 874 +956 856 +820 720 +245 145 +519 419 +1095 995 +894 794 +629 529 +296 196 +299 199 +1097 997 +377 277 +216 116 +197 97 +1008 908 +819 719 +639 539 +342 242 +807 707 +207 107 +669 569 +222 122 +637 537 +170 70 +1031 931 +198 98 +826 726 +700 600 +587 487 +745 645 +872 772 +367 267 +613 513 +1072 972 +181 81 +995 895 +1043 943 +313 213 +158 58 +848 748 +403 303 +587 487 +864 764 +1023 923 +636 536 +129 29 +824 724 +774 674 +889 789 +640 540 +579 479 +654 554 +242 142 +567 467 +439 339 +146 46 +741 641 +810 710 +296 196 +653 553 +594 494 +291 191 +166 66 +824 724 +924 824 +830 730 +308 208 +1088 988 +811 711 +190 90 +900 800 +440 340 +414 314 +649 549 +389 289 +296 196 +501 401 +965 865 +566 466 +778 678 +789 689 +670 570 +933 833 +1036 936 +325 225 +822 722 +344 244 +751 651 +949 849 +223 123 +213 113 +531 431 +479 379 +608 508 +461 361 +685 585 +165 65 +953 853 +586 486 +742 642 +786 686 +1092 992 +386 286 +825 725 +989 889 +386 286 +124 24 +912 812 +591 491 +959 859 +991 891 +763 663 +190 90 +188 88 +281 181 +279 179 +314 214 +287 187 +117 17 +719 619 +572 472 +361 261 +518 418 +946 846 +519 419 +292 192 +456 356 +361 261 +782 682 +614 514 +406 306 +986 886 +301 201 +630 530 +485 385 +949 849 +1052 952 +394 294 +600 500 +899 799 +294 194 +491 391 +837 737 +430 330 +424 324 +398 298 +1092 992 +890 790 +324 224 +375 275 +360 260 +926 826 +197 97 +172 72 +310 210 +966 866 +749 649 +1051 951 +1019 919 +848 748 +163 63 +785 685 +1058 958 +1056 956 +904 804 +664 564 +618 518 +283 183 +528 428 +500 400 +637 537 +821 721 +446 346 +307 207 +253 153 +423 323 +1071 971 +711 611 +762 662 +216 116 +297 197 +209 109 +191 91 +895 795 +629 529 +443 343 +226 126 +962 862 +847 747 +785 685 +569 469 +110 10 +870 770 +981 881 +1034 934 +1084 984 +823 723 +503 403 +995 895 +460 360 +668 568 +549 449 +272 172 +641 541 +1058 958 +372 272 +483 383 +977 877 +408 308 +459 359 +1070 970 +807 707 +683 583 +408 308 +148 48 +870 770 +1030 930 +130 30 +669 569 +308 208 +103 3 +411 311 +120 20 +200 100 +709 609 +1039 939 +987 887 +522 422 +925 825 +885 785 +1030 930 +470 370 +1004 904 +1089 989 +341 241 +1069 969 +479 379 +243 143 +476 376 +1072 972 +1062 962 +128 28 +989 889 +161 61 +543 443 +738 638 +316 216 +448 348 +438 338 +447 347 +260 160 +166 66 +506 406 +491 391 +259 159 +738 638 +131 31 +395 295 +304 204 +926 826 +520 420 +296 196 +253 153 +549 449 +525 425 +955 855 +431 331 +243 143 +665 565 +587 487 +938 838 +240 140 +109 9 +664 564 +1018 918 +715 615 +633 533 +235 135 +332 232 +664 564 +1057 957 +460 360 +691 591 +893 793 +676 576 +263 163 +846 746 +959 859 +477 377 +860 760 +958 858 +811 711 +186 86 +762 662 +534 434 +259 159 +658 558 +760 660 +379 279 +368 268 +940 840 +1048 948 +835 735 +415 315 +674 574 +776 676 +226 126 +441 341 +1012 912 +789 689 +839 739 +994 894 +921 821 +806 706 +725 625 +590 490 +1017 917 +578 478 +301 201 +771 671 +1093 993 +1032 932 +249 149 +999 899 +152 52 +337 237 +859 759 +287 187 +367 267 +572 472 +356 256 +872 772 +883 783 +198 98 +217 117 +1006 906 +616 516 +1011 911 +280 180 +735 635 +125 25 +325 225 +480 380 +923 823 +812 712 +264 164 +366 266 +443 343 +316 216 +832 732 +548 448 +602 502 +641 541 +840 740 +764 664 +676 576 +1054 954 +712 612 +826 726 +1002 902 +872 772 +554 454 +631 531 +511 411 +1043 943 +1073 973 +850 750 +803 703 +427 327 +950 850 +1017 917 +177 77 +105 5 +320 220 +213 113 +902 802 +1013 913 +503 403 +891 791 +281 181 +1098 998 +110 10 +959 859 +625 525 +445 345 +1019 919 +531 431 +768 668 +775 675 +627 527 +933 833 +562 462 +538 438 +391 291 +623 523 +705 605 +1016 916 +557 457 +520 420 +505 405 +215 115 +517 417 +760 660 +379 279 +361 261 +785 685 +872 772 +696 596 +488 388 +407 307 +864 764 +324 224 +943 843 +422 322 +306 206 +940 840 +507 407 +1075 975 +739 639 +501 401 +952 852 +191 91 +642 542 +427 327 +160 60 +430 330 +857 757 +282 182 +182 82 +703 603 +737 637 +893 793 +193 93 +715 615 +714 614 +833 733 +236 136 +964 864 +287 187 +116 16 +202 102 +963 863 +1072 972 +1087 987 +263 163 +406 306 +601 501 +134 34 +577 477 +0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 1 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 diff --git a/scripts/Knapsack/Knapsack.py b/scripts/Knapsack/Knapsack.py new file mode 100644 index 0000000..78b7dd4 --- /dev/null +++ b/scripts/Knapsack/Knapsack.py @@ -0,0 +1,109 @@ +from __future__ import annotations + +import locale +import os +from pathlib import Path +from typing import cast + +import numpy as np +from sympy import Expr + +# for managing symbols +from mqt.qao import Constraints, ObjectiveFunction, Problem, Solver, Variables + +lambdas_method = [ + "upper_bound_only_positive", + "maximum_coefficient", + "VLM", + "MOMC", + "MOC", + "upper lower bound naive", + "upper lower bound posiform and negaform method", +] +lambdas_conf = [ + ("upper_bound_only_positive", "sequential penalty increase"), + ("maximum_coefficient", "sequential penalty increase"), + ("VLM", "sequential penalty increase"), + ("MOMC", "sequential penalty increase"), + ("MOC", "sequential penalty increase"), + ("upper lower bound naive", "sequential penalty increase"), + ("upper lower bound posiform and negaform method", "sequential penalty increase"), + ("upper_bound_only_positive", "scaled sequential penalty increase"), + ("maximum_coefficient", "scaled sequential penalty increase"), + ("VLM", "scaled sequential penalty increase"), + ("MOMC", "scaled sequential penalty increase"), + ("MOC", "scaled sequential penalty increase"), + ("upper lower bound naive", "scaled sequential penalty increase"), + ("upper lower bound posiform and negaform method", "scaled sequential penalty increase"), + ("upper_bound_only_positive", "binary search penalty algorithm"), + ("maximum_coefficient", "binary search penalty algorithm"), + ("VLM", "binary search penalty algorithm"), + ("MOMC", "binary search penalty algorithm"), + ("MOC", "binary search penalty algorithm"), + ("upper lower bound naive", "binary search penalty algorithm"), + ("upper lower bound posiform and negaform method", "binary search penalty algorithm"), +] + +files = os.listdir("Data/") +for file in files: + print(file) + with Path("./Data/" + file).open("r", encoding=locale.getpreferredencoding(False)) as f: + lines = f.readlines() + el = lines[0].split() + objects = int(el[0]) + W_max = float(el[1]) + w = [] + p = [] + for i in range(1, len(lines)): + el = lines[i].split() + p.append(float(el[0])) + w.append(float(el[1])) + p_arr = np.asarray(p) + w_arr = np.asarray(w) + + for lambdas in lambdas_method: + variables = Variables() + obj = variables.add_binary_variables_array("obj", [objects]) + objective_function = ObjectiveFunction() + objective_function.add_objective_function(cast(Expr, np.dot(np.transpose(obj), p_arr)), minimization=False) + constraint = Constraints() + constraint.add_constraint(str(np.dot(np.transpose(obj), w_arr)) + " <= " + format(W_max)) + problem = Problem() + problem.create_problem(variables, constraint, objective_function) + solver = Solver() + solution = solver.solve_simulated_annealing( + problem, lambda_strategy=lambdas, auto_setting=True, save_time=True, max_lambda_update=1 + ) + if not isinstance(solution, bool): + all_satisfy, each_satisfy = solution.check_constraint_optimal_solution() + solution.valid_solutions() + solution.wring_json_reports( + filename="simulated_annealing_knapsack_" + file + "_" + lambdas, problem_features=True + ) + + for lambdas_m, lambdas_update in lambdas_conf: + variables = Variables() + obj = variables.add_binary_variables_array("obj", [objects]) + objective_function = ObjectiveFunction() + objective_function.add_objective_function(cast(Expr, np.dot(np.transpose(obj), p_arr)), minimization=False) + constraint = Constraints() + constraint.add_constraint(str(np.dot(np.transpose(obj), w_arr)) + " <= " + format(W_max)) + problem = Problem() + problem.create_problem(variables, constraint, objective_function) + solver = Solver() + solution = solver.solve_simulated_annealing( + problem, + lambda_strategy=lambdas_m, + lambda_update_mechanism=lambdas_update, + auto_setting=True, + save_time=True, + max_lambda_update=1, + ) + if not isinstance(solution, bool): + all_satisfy, each_satisfy = solution.check_constraint_optimal_solution() + print(all_satisfy, each_satisfy) + solution.valid_solutions() + solution.wring_json_reports( + filename="simulated_annealing_knapsack_" + file + "_" + lambdas_m + "_" + lambdas_update, + problem_features=True, + ) diff --git a/scripts/linear_regression/LinearRegression.py b/scripts/linear_regression/LinearRegression.py new file mode 100644 index 0000000..46231b5 --- /dev/null +++ b/scripts/linear_regression/LinearRegression.py @@ -0,0 +1,160 @@ +from __future__ import annotations + +from typing import cast + +import numpy as np +import pandas as pd +from sklearn.decomposition import PCA +from sklearn.utils import shuffle +from sympy import Expr + +# for managing symbols +from mqt.qao import Constraints, ObjectiveFunction, Problem, Solver, Variables + +df = pd.read_csv("iris_csv.csv") +df = shuffle(df) +d = len(df.columns) - 1 +N = len(df[df.keys()[1]]) +feat = 2 +X = np.zeros([N, d]) +Y = np.zeros(N) +TrainingPercentage = 0.7 +N_Traning = int(N * TrainingPercentage) +N_Test = N - N_Traning +i = 0 +for key in df: + j = 0 + if key != "class": + for el in df[key]: + X[j, i] = el + j += 1 + i += 1 + else: + for el in df[key]: + if el == "Iris-setosa": + Y[j] = 1 + else: + Y[j] = -1 + j += 1 +pca = PCA(n_components=feat) +X = pca.fit_transform(X=X, y=Y) +X_traning = np.hstack((X[:N_Traning, :], np.ones((N_Traning, 1)))) +X_test = np.hstack((X[N_Traning:, :], np.ones((N_Test, 1)))) + +Y_traning = Y[:N_Traning] +Y_test = Y[N_Traning:] +variables = Variables() +w = variables.add_continuous_variables_array("w", [feat + 1, 1], -0.25, 0.25, 0.25) +objective_function = ObjectiveFunction() +objective_function.add_objective_function( + cast( + Expr, + ( + np.dot(np.dot(np.dot(np.transpose(w), np.transpose(X_traning)), X_traning), w) + - 2 * np.dot(np.dot(np.transpose(w), np.transpose(X_traning)), Y_traning) + + np.dot(np.transpose(Y_traning), Y_traning) + )[0, 0], + ) +) +constraint = Constraints() +problem = Problem() +problem.create_problem(variables, constraint, objective_function) +solver = Solver() + +PredictionRes = {} + +solution = solver.solve_simulated_annealing( + problem, auto_setting=True, save_time=True, max_lambda_update=0, save_compilation_time=True +) +if not isinstance(solution, bool): + all_satisfy, each_satisfy = solution.check_constraint_optimal_solution() + print(all_satisfy, each_satisfy) + solution.valid_solutions() + print(solution.best_energy) + solution.wring_json_reports(filename="simulated_annealing_linear_regression_Iris", problem_features=True) + w_conf = solution.best_solution["w"] + Y_obtained_training = np.dot(X_traning, w_conf) + TP_tr = 0 + TN_tr = 0 + FP_tr = 0 + FN_tr = 0 + for i in range(N_Traning): + if Y_obtained_training[i] > 0: + if Y_traning[i] == 1: + TP_tr += 1 + else: + FP_tr += 1 + elif Y_traning[i] == 1: + FN_tr += 1 + else: + TN_tr += 1 + + try: + Accuracy_tr = (TN_tr + TP_tr) / (TN_tr + TP_tr + FP_tr + FN_tr) + except ZeroDivisionError: + Accuracy_tr = 0 + + try: + Precision_tr = TP_tr / (TP_tr + FP_tr) + except ZeroDivisionError: + Precision_tr = 0 + + try: + Recall_tr = TP_tr / (TP_tr + FN_tr) + except ZeroDivisionError: + Recall_tr = 0 + + try: + F1_score_tr = 2 * Precision_tr * Recall_tr / (Precision_tr + Recall_tr) + except ZeroDivisionError: + F1_score_tr = 0 + + PredictionRes["Accuracy training"] = Accuracy_tr + PredictionRes["Precision training"] = Precision_tr + PredictionRes["Recall training"] = Recall_tr + PredictionRes["F1 training"] = F1_score_tr + Y_obtained_test = np.dot(X_test, w_conf) + print(Accuracy_tr, Precision_tr, Recall_tr) + TP_t = 0 + TN_t = 0 + FP_t = 0 + FN_t = 0 + for i in range(N_Test - 1): + if Y_obtained_test[i] > 0: + if Y_test[i] == 1: + TP_t += 1 + else: + FP_t += 1 + elif Y_test[i] == 1: + FN_t += 1 + else: + TN_t += 1 + + try: + Accuracy_t = (TN_t + TP_t) / (TN_t + TP_t + FP_t + FN_t) + except ZeroDivisionError: + Accuracy_t = 0 + + try: + Precision_t = TP_t / (TP_t + FP_t) + except ZeroDivisionError: + Precision_t = 0 + + try: + Recall_t = TP_t / (TP_t + FN_t) + except ZeroDivisionError: + Recall_t = 0 + + try: + F1_score_t = 2 * Precision_t * Recall_t / (Precision_t + Recall_t) + except ZeroDivisionError: + F1_score_t = 0 + print(Accuracy_t, Precision_t, Recall_t) + PredictionRes["Accuracy test"] = Accuracy_t + PredictionRes["Precision test"] = Precision_t + PredictionRes["Recall test"] = Recall_t + PredictionRes["F1 test"] = F1_score_t + + +df1 = pd.DataFrame.from_dict(PredictionRes, orient="index") +df1.to_csv("PredictionResSimulatedAnnealing.csv") diff --git a/scripts/linear_regression/PredictionResSimulatedAnnealing.csv b/scripts/linear_regression/PredictionResSimulatedAnnealing.csv new file mode 100644 index 0000000..53de89d --- /dev/null +++ b/scripts/linear_regression/PredictionResSimulatedAnnealing.csv @@ -0,0 +1,9 @@ +,0 +Accuracy training,1.0 +Precision training,1.0 +Recall training,1.0 +F1 training,1.0 +Accuracy test,1.0 +Precision test,1.0 +Recall test,1.0 +F1 test,1.0 diff --git a/scripts/linear_regression/iris_csv.csv b/scripts/linear_regression/iris_csv.csv new file mode 100644 index 0000000..3c63137 --- /dev/null +++ b/scripts/linear_regression/iris_csv.csv @@ -0,0 +1,101 @@ +sepallength,sepalwidth,petallength,petalwidth,class +5.1,3.5,1.4,0.2,Iris-setosa +4.9,3.0,1.4,0.2,Iris-setosa +4.7,3.2,1.3,0.2,Iris-setosa +4.6,3.1,1.5,0.2,Iris-setosa +5.0,3.6,1.4,0.2,Iris-setosa +5.4,3.9,1.7,0.4,Iris-setosa +4.6,3.4,1.4,0.3,Iris-setosa +5.0,3.4,1.5,0.2,Iris-setosa +4.4,2.9,1.4,0.2,Iris-setosa +4.9,3.1,1.5,0.1,Iris-setosa +5.4,3.7,1.5,0.2,Iris-setosa +4.8,3.4,1.6,0.2,Iris-setosa +4.8,3.0,1.4,0.1,Iris-setosa +4.3,3.0,1.1,0.1,Iris-setosa +5.8,4.0,1.2,0.2,Iris-setosa +5.7,4.4,1.5,0.4,Iris-setosa +5.4,3.9,1.3,0.4,Iris-setosa +5.1,3.5,1.4,0.3,Iris-setosa +5.7,3.8,1.7,0.3,Iris-setosa +5.1,3.8,1.5,0.3,Iris-setosa +5.4,3.4,1.7,0.2,Iris-setosa +5.1,3.7,1.5,0.4,Iris-setosa +4.6,3.6,1.0,0.2,Iris-setosa +5.1,3.3,1.7,0.5,Iris-setosa +4.8,3.4,1.9,0.2,Iris-setosa +5.0,3.0,1.6,0.2,Iris-setosa +5.0,3.4,1.6,0.4,Iris-setosa +5.2,3.5,1.5,0.2,Iris-setosa +5.2,3.4,1.4,0.2,Iris-setosa +4.7,3.2,1.6,0.2,Iris-setosa +4.8,3.1,1.6,0.2,Iris-setosa +5.4,3.4,1.5,0.4,Iris-setosa +5.2,4.1,1.5,0.1,Iris-setosa +5.5,4.2,1.4,0.2,Iris-setosa +4.9,3.1,1.5,0.1,Iris-setosa +5.0,3.2,1.2,0.2,Iris-setosa +5.5,3.5,1.3,0.2,Iris-setosa +4.9,3.1,1.5,0.1,Iris-setosa +4.4,3.0,1.3,0.2,Iris-setosa +5.1,3.4,1.5,0.2,Iris-setosa +5.0,3.5,1.3,0.3,Iris-setosa +4.5,2.3,1.3,0.3,Iris-setosa +4.4,3.2,1.3,0.2,Iris-setosa +5.0,3.5,1.6,0.6,Iris-setosa +5.1,3.8,1.9,0.4,Iris-setosa +4.8,3.0,1.4,0.3,Iris-setosa +5.1,3.8,1.6,0.2,Iris-setosa +4.6,3.2,1.4,0.2,Iris-setosa +5.3,3.7,1.5,0.2,Iris-setosa +5.0,3.3,1.4,0.2,Iris-setosa +7.0,3.2,4.7,1.4,Iris-versicolor +6.4,3.2,4.5,1.5,Iris-versicolor +6.9,3.1,4.9,1.5,Iris-versicolor +5.5,2.3,4.0,1.3,Iris-versicolor +6.5,2.8,4.6,1.5,Iris-versicolor +5.7,2.8,4.5,1.3,Iris-versicolor +6.3,3.3,4.7,1.6,Iris-versicolor +4.9,2.4,3.3,1.0,Iris-versicolor +6.6,2.9,4.6,1.3,Iris-versicolor +5.2,2.7,3.9,1.4,Iris-versicolor +5.0,2.0,3.5,1.0,Iris-versicolor +5.9,3.0,4.2,1.5,Iris-versicolor +6.0,2.2,4.0,1.0,Iris-versicolor +6.1,2.9,4.7,1.4,Iris-versicolor +5.6,2.9,3.6,1.3,Iris-versicolor +6.7,3.1,4.4,1.4,Iris-versicolor +5.6,3.0,4.5,1.5,Iris-versicolor +5.8,2.7,4.1,1.0,Iris-versicolor +6.2,2.2,4.5,1.5,Iris-versicolor +5.6,2.5,3.9,1.1,Iris-versicolor +5.9,3.2,4.8,1.8,Iris-versicolor +6.1,2.8,4.0,1.3,Iris-versicolor +6.3,2.5,4.9,1.5,Iris-versicolor +6.1,2.8,4.7,1.2,Iris-versicolor +6.4,2.9,4.3,1.3,Iris-versicolor +6.6,3.0,4.4,1.4,Iris-versicolor +6.8,2.8,4.8,1.4,Iris-versicolor +6.7,3.0,5.0,1.7,Iris-versicolor +6.0,2.9,4.5,1.5,Iris-versicolor +5.7,2.6,3.5,1.0,Iris-versicolor +5.5,2.4,3.8,1.1,Iris-versicolor +5.5,2.4,3.7,1.0,Iris-versicolor +5.8,2.7,3.9,1.2,Iris-versicolor +6.0,2.7,5.1,1.6,Iris-versicolor +5.4,3.0,4.5,1.5,Iris-versicolor +6.0,3.4,4.5,1.6,Iris-versicolor +6.7,3.1,4.7,1.5,Iris-versicolor +6.3,2.3,4.4,1.3,Iris-versicolor +5.6,3.0,4.1,1.3,Iris-versicolor +5.5,2.5,4.0,1.3,Iris-versicolor +5.5,2.6,4.4,1.2,Iris-versicolor +6.1,3.0,4.6,1.4,Iris-versicolor +5.8,2.6,4.0,1.2,Iris-versicolor +5.0,2.3,3.3,1.0,Iris-versicolor +5.6,2.7,4.2,1.3,Iris-versicolor +5.7,3.0,4.2,1.2,Iris-versicolor +5.7,2.9,4.2,1.3,Iris-versicolor +6.2,2.9,4.3,1.3,Iris-versicolor +5.1,2.5,3.0,1.1,Iris-versicolor +5.7,2.8,4.1,1.3,Iris-versicolor diff --git a/scripts/linear_regression/simulated_annealing_linear_regression_Iris.json b/scripts/linear_regression/simulated_annealing_linear_regression_Iris.json new file mode 100644 index 0000000..273d4cc --- /dev/null +++ b/scripts/linear_regression/simulated_annealing_linear_regression_Iris.json @@ -0,0 +1,333 @@ +{ + "solver name": "Simulated annealer", + "num reads": 100, + "annealing time": 16, + "compilation time": 6167900.0, + "energies": [ + 24.613856939869713, 24.613856939869713, 24.613856939869713, + 24.613856939869713, 24.613856939869713, 24.613856939869713, + 24.613856939869713, 24.613856939869713, 24.613856939869713, + 24.613856939869713, 24.613856939869713, 24.613856939869713, + 24.613856939869713, 24.613856939869713, 24.613856939869713, + 24.613856939869713, 24.613856939869713, 24.613856939869713, + 24.613856939869713, 24.613856939869713, 24.613856939869713, + 24.613856939869713, 24.613856939869713, 24.613856939869713, + 24.613856939869713, 24.613856939869713, 24.613856939869713, + 24.613856939869713, 24.613856939869713, 24.613856939869713, + 24.613856939869713, 24.613856939869713, 24.613856939869713, + 24.613856939869713, 24.613856939869713, 24.613856939869713, + 24.613856939869713, 24.613856939869713, 24.613856939869713, + 24.613856939869713, 24.613856939869713, 24.613856939869713, + 24.613856939869713, 24.613856939869713, 24.613856939869713, + 24.613856939869713, 24.613856939869713, 24.613856939869713, + 24.613856939869713, 24.613856939869713, 24.613856939869713, + 24.613856939869713, 24.613856939869713, 24.613856939869713, + 24.613856939869713, 24.613856939869713, 24.613856939869713, + 24.613856939869713, 24.613856939869713, 24.613856939869713, + 24.613856939869713, 24.613856939869713, 24.613856939869713, + 24.613856939869713, 24.613856939869713, 24.613856939869713, + 24.613856939869713, 24.613856939869713, 24.613856939869713, + 24.613856939869713, 24.613856939869713, 24.613856939869713, + 24.613856939869713, 24.613856939869713, 24.613856939869713, + 24.613856939869713, 24.613856939869713, 24.613856939869713, + 24.613856939869713, 24.613856939869713, 24.613856939869713, + 24.613856939869713, 24.613856939869713, 24.613856939869713, + 24.613856939869713, 24.613856939869713, 24.613856939869713, + 24.613856939869713, 24.613856939869713, 24.613856939869713, + 24.613856939869713, 24.613856939869713, 24.613856939869713, + 24.613856939869713, 24.613856939869713, 24.613856939869713, + 24.613856939869713, 24.613856939869713, 24.613856939869713, + 24.613856939869713 + ], + "best energy": 24.613856939869713, + "cost functions energy best solution": { + "195.845749787118*w_0_0**2 + 6.6681082873237*w_0_0*w_1_0 + 26.613062206613*w_0_0*w_2_0 + 226.263839976905*w_0_0 + 15.5869513719764*w_1_0**2 + 2.54624645289538*w_1_0*w_2_0 - 6.47188048155888*w_1_0 + 70.0*w_2_0**2 + 12.0*w_2_0 + 70.0": 24.61385693986972 + }, + "constraint satisfaction best solution": true, + "best solution": { "w": [[-0.25], [0.25], [0.0]] }, + "solutions": [ + { "w": [[-0.25], [0.25], [0.0]] }, + { "w": [[-0.25], [0.25], [0.0]] }, + { "w": [[-0.25], [0.25], [0.0]] }, + { "w": [[-0.25], [0.25], [0.0]] }, + { "w": [[-0.25], [0.25], [0.0]] }, + { "w": [[-0.25], [0.25], [0.0]] }, + { "w": [[-0.25], [0.25], [0.0]] }, + { "w": [[-0.25], [0.25], [0.0]] }, + { "w": [[-0.25], [0.25], [0.0]] }, + { "w": [[-0.25], [0.25], [0.0]] }, + { "w": [[-0.25], [0.25], [0.0]] }, + { "w": [[-0.25], [0.25], [0.0]] }, + { "w": [[-0.25], [0.25], [0.0]] }, + { "w": [[-0.25], [0.25], [0.0]] }, + { "w": [[-0.25], [0.25], [0.0]] }, + { "w": [[-0.25], [0.25], [0.0]] }, + { "w": [[-0.25], [0.25], [0.0]] }, + { "w": [[-0.25], [0.25], [0.0]] }, + { "w": [[-0.25], [0.25], [0.0]] }, + { "w": [[-0.25], [0.25], [0.0]] }, + { "w": [[-0.25], [0.25], [0.0]] }, + { "w": [[-0.25], [0.25], [0.0]] }, + { "w": [[-0.25], [0.25], [0.0]] }, + { "w": [[-0.25], [0.25], [0.0]] }, + { "w": [[-0.25], [0.25], [0.0]] }, + { "w": [[-0.25], [0.25], [0.0]] }, + { "w": [[-0.25], [0.25], [0.0]] }, + { "w": [[-0.25], [0.25], [0.0]] }, + { "w": [[-0.25], [0.25], [0.0]] }, + { "w": [[-0.25], [0.25], [0.0]] }, + { "w": [[-0.25], [0.25], [0.0]] }, + { "w": [[-0.25], [0.25], [0.0]] }, + { "w": [[-0.25], [0.25], [0.0]] }, + { "w": [[-0.25], [0.25], [0.0]] }, + { "w": [[-0.25], [0.25], [0.0]] }, + { "w": [[-0.25], [0.25], [0.0]] }, + { "w": [[-0.25], [0.25], [0.0]] }, + { "w": [[-0.25], [0.25], [0.0]] }, + { "w": [[-0.25], [0.25], [0.0]] }, + { "w": [[-0.25], [0.25], [0.0]] }, + { "w": [[-0.25], [0.25], [0.0]] }, + { "w": [[-0.25], [0.25], [0.0]] }, + { "w": [[-0.25], [0.25], [0.0]] }, + { "w": [[-0.25], [0.25], [0.0]] }, + { "w": [[-0.25], [0.25], [0.0]] }, + { "w": [[-0.25], [0.25], [0.0]] }, + { "w": [[-0.25], [0.25], [0.0]] }, + { "w": [[-0.25], [0.25], [0.0]] }, + { "w": [[-0.25], [0.25], [0.0]] }, + { "w": [[-0.25], [0.25], [0.0]] }, + { "w": [[-0.25], [0.25], [0.0]] }, + { "w": [[-0.25], [0.25], [0.0]] }, + { "w": [[-0.25], [0.25], [0.0]] }, + { "w": [[-0.25], [0.25], [0.0]] }, + { "w": [[-0.25], [0.25], [0.0]] }, + { "w": [[-0.25], [0.25], [0.0]] }, + { "w": [[-0.25], [0.25], [0.0]] }, + { "w": [[-0.25], [0.25], [0.0]] }, + { "w": [[-0.25], [0.25], [0.0]] }, + { "w": [[-0.25], [0.25], [0.0]] }, + { "w": [[-0.25], [0.25], [0.0]] }, + { "w": [[-0.25], [0.25], [0.0]] }, + { "w": [[-0.25], [0.25], [0.0]] }, + { "w": [[-0.25], [0.25], [0.0]] }, + { "w": [[-0.25], [0.25], [0.0]] }, + { "w": [[-0.25], [0.25], [0.0]] }, + { "w": [[-0.25], [0.25], [0.0]] }, + { "w": [[-0.25], [0.25], [0.0]] }, + { "w": [[-0.25], [0.25], [0.0]] }, + { "w": [[-0.25], [0.25], [0.0]] }, + { "w": [[-0.25], [0.25], [0.0]] }, + { "w": [[-0.25], [0.25], [0.0]] }, + { "w": [[-0.25], [0.25], [0.0]] }, + { "w": [[-0.25], [0.25], [0.0]] }, + { "w": [[-0.25], [0.25], [0.0]] }, + { "w": [[-0.25], [0.25], [0.0]] }, + { "w": [[-0.25], [0.25], [0.0]] }, + { "w": [[-0.25], [0.25], [0.0]] }, + { "w": [[-0.25], [0.25], [0.0]] }, + { "w": [[-0.25], [0.25], [0.0]] }, + { "w": [[-0.25], [0.25], [0.0]] }, + { "w": [[-0.25], [0.25], [0.0]] }, + { "w": [[-0.25], [0.25], [0.0]] }, + { "w": [[-0.25], [0.25], [0.0]] }, + { "w": [[-0.25], [0.25], [0.0]] }, + { "w": [[-0.25], [0.25], [0.0]] }, + { "w": [[-0.25], [0.25], [0.0]] }, + { "w": [[-0.25], [0.25], [0.0]] }, + { "w": [[-0.25], [0.25], [0.0]] }, + { "w": [[-0.25], [0.25], [0.0]] }, + { "w": [[-0.25], [0.25], [0.0]] }, + { "w": [[-0.25], [0.25], [0.0]] }, + { "w": [[-0.25], [0.25], [0.0]] }, + { "w": [[-0.25], [0.25], [0.0]] }, + { "w": [[-0.25], [0.25], [0.0]] }, + { "w": [[-0.25], [0.25], [0.0]] }, + { "w": [[-0.25], [0.25], [0.0]] }, + { "w": [[-0.25], [0.25], [0.0]] }, + { "w": [[-0.25], [0.25], [0.0]] }, + { "w": [[-0.25], [0.25], [0.0]] } + ], + "best solution binary": { + "b0": 0.0, + "b1": 0.0, + "b2": 1.0, + "b3": 1.0, + "b4": 0.0, + "b5": 1.0 + }, + "solutions binary": [ + { "b0": 0.0, "b1": 0.0, "b2": 1.0, "b3": 1.0, "b4": 0.0, "b5": 1.0 }, + { "b0": 0.0, "b1": 0.0, "b2": 1.0, "b3": 1.0, "b4": 1.0, "b5": 0.0 }, + { "b0": 0.0, "b1": 0.0, "b2": 1.0, "b3": 1.0, "b4": 1.0, "b5": 0.0 }, + { "b0": 0.0, "b1": 0.0, "b2": 1.0, "b3": 1.0, "b4": 0.0, "b5": 1.0 }, + { "b0": 0.0, "b1": 0.0, "b2": 1.0, "b3": 1.0, "b4": 1.0, "b5": 0.0 }, + { "b0": 0.0, "b1": 0.0, "b2": 1.0, "b3": 1.0, "b4": 1.0, "b5": 0.0 }, + { "b0": 0.0, "b1": 0.0, "b2": 1.0, "b3": 1.0, "b4": 1.0, "b5": 0.0 }, + { "b0": 0.0, "b1": 0.0, "b2": 1.0, "b3": 1.0, "b4": 1.0, "b5": 0.0 }, + { "b0": 0.0, "b1": 0.0, "b2": 1.0, "b3": 1.0, "b4": 1.0, "b5": 0.0 }, + { "b0": 0.0, "b1": 0.0, "b2": 1.0, "b3": 1.0, "b4": 1.0, "b5": 0.0 }, + { "b0": 0.0, "b1": 0.0, "b2": 1.0, "b3": 1.0, "b4": 1.0, "b5": 0.0 }, + { "b0": 0.0, "b1": 0.0, "b2": 1.0, "b3": 1.0, "b4": 1.0, "b5": 0.0 }, + { "b0": 0.0, "b1": 0.0, "b2": 1.0, "b3": 1.0, "b4": 0.0, "b5": 1.0 }, + { "b0": 0.0, "b1": 0.0, "b2": 1.0, "b3": 1.0, "b4": 1.0, "b5": 0.0 }, + { "b0": 0.0, "b1": 0.0, "b2": 1.0, "b3": 1.0, "b4": 1.0, "b5": 0.0 }, + { "b0": 0.0, "b1": 0.0, "b2": 1.0, "b3": 1.0, "b4": 1.0, "b5": 0.0 }, + { "b0": 0.0, "b1": 0.0, "b2": 1.0, "b3": 1.0, "b4": 0.0, "b5": 1.0 }, + { "b0": 0.0, "b1": 0.0, "b2": 1.0, "b3": 1.0, "b4": 1.0, "b5": 0.0 }, + { "b0": 0.0, "b1": 0.0, "b2": 1.0, "b3": 1.0, "b4": 1.0, "b5": 0.0 }, + { "b0": 0.0, "b1": 0.0, "b2": 1.0, "b3": 1.0, "b4": 1.0, "b5": 0.0 }, + { "b0": 0.0, "b1": 0.0, "b2": 1.0, "b3": 1.0, "b4": 0.0, "b5": 1.0 }, + { "b0": 0.0, "b1": 0.0, "b2": 1.0, "b3": 1.0, "b4": 1.0, "b5": 0.0 }, + { "b0": 0.0, "b1": 0.0, "b2": 1.0, "b3": 1.0, "b4": 1.0, "b5": 0.0 }, + { "b0": 0.0, "b1": 0.0, "b2": 1.0, "b3": 1.0, "b4": 1.0, "b5": 0.0 }, + { "b0": 0.0, "b1": 0.0, "b2": 1.0, "b3": 1.0, "b4": 0.0, "b5": 1.0 }, + { "b0": 0.0, "b1": 0.0, "b2": 1.0, "b3": 1.0, "b4": 1.0, "b5": 0.0 }, + { "b0": 0.0, "b1": 0.0, "b2": 1.0, "b3": 1.0, "b4": 1.0, "b5": 0.0 }, + { "b0": 0.0, "b1": 0.0, "b2": 1.0, "b3": 1.0, "b4": 1.0, "b5": 0.0 }, + { "b0": 0.0, "b1": 0.0, "b2": 1.0, "b3": 1.0, "b4": 1.0, "b5": 0.0 }, + { "b0": 0.0, "b1": 0.0, "b2": 1.0, "b3": 1.0, "b4": 0.0, "b5": 1.0 }, + { "b0": 0.0, "b1": 0.0, "b2": 1.0, "b3": 1.0, "b4": 0.0, "b5": 1.0 }, + { "b0": 0.0, "b1": 0.0, "b2": 1.0, "b3": 1.0, "b4": 0.0, "b5": 1.0 }, + { "b0": 0.0, "b1": 0.0, "b2": 1.0, "b3": 1.0, "b4": 1.0, "b5": 0.0 }, + { "b0": 0.0, "b1": 0.0, "b2": 1.0, "b3": 1.0, "b4": 1.0, "b5": 0.0 }, + { "b0": 0.0, "b1": 0.0, "b2": 1.0, "b3": 1.0, "b4": 1.0, "b5": 0.0 }, + { "b0": 0.0, "b1": 0.0, "b2": 1.0, "b3": 1.0, "b4": 1.0, "b5": 0.0 }, + { "b0": 0.0, "b1": 0.0, "b2": 1.0, "b3": 1.0, "b4": 0.0, "b5": 1.0 }, + { "b0": 0.0, "b1": 0.0, "b2": 1.0, "b3": 1.0, "b4": 1.0, "b5": 0.0 }, + { "b0": 0.0, "b1": 0.0, "b2": 1.0, "b3": 1.0, "b4": 1.0, "b5": 0.0 }, + { "b0": 0.0, "b1": 0.0, "b2": 1.0, "b3": 1.0, "b4": 1.0, "b5": 0.0 }, + { "b0": 0.0, "b1": 0.0, "b2": 1.0, "b3": 1.0, "b4": 1.0, "b5": 0.0 }, + { "b0": 0.0, "b1": 0.0, "b2": 1.0, "b3": 1.0, "b4": 0.0, "b5": 1.0 }, + { "b0": 0.0, "b1": 0.0, "b2": 1.0, "b3": 1.0, "b4": 1.0, "b5": 0.0 }, + { "b0": 0.0, "b1": 0.0, "b2": 1.0, "b3": 1.0, "b4": 0.0, "b5": 1.0 }, + { "b0": 0.0, "b1": 0.0, "b2": 1.0, "b3": 1.0, "b4": 1.0, "b5": 0.0 }, + { "b0": 0.0, "b1": 0.0, "b2": 1.0, "b3": 1.0, "b4": 1.0, "b5": 0.0 }, + { "b0": 0.0, "b1": 0.0, "b2": 1.0, "b3": 1.0, "b4": 0.0, "b5": 1.0 }, + { "b0": 0.0, "b1": 0.0, "b2": 1.0, "b3": 1.0, "b4": 1.0, "b5": 0.0 }, + { "b0": 0.0, "b1": 0.0, "b2": 1.0, "b3": 1.0, "b4": 0.0, "b5": 1.0 }, + { "b0": 0.0, "b1": 0.0, "b2": 1.0, "b3": 1.0, "b4": 0.0, "b5": 1.0 }, + { "b0": 0.0, "b1": 0.0, "b2": 1.0, "b3": 1.0, "b4": 1.0, "b5": 0.0 }, + { "b0": 0.0, "b1": 0.0, "b2": 1.0, "b3": 1.0, "b4": 0.0, "b5": 1.0 }, + { "b0": 0.0, "b1": 0.0, "b2": 1.0, "b3": 1.0, "b4": 1.0, "b5": 0.0 }, + { "b0": 0.0, "b1": 0.0, "b2": 1.0, "b3": 1.0, "b4": 1.0, "b5": 0.0 }, + { "b0": 0.0, "b1": 0.0, "b2": 1.0, "b3": 1.0, "b4": 1.0, "b5": 0.0 }, + { "b0": 0.0, "b1": 0.0, "b2": 1.0, "b3": 1.0, "b4": 1.0, "b5": 0.0 }, + { "b0": 0.0, "b1": 0.0, "b2": 1.0, "b3": 1.0, "b4": 0.0, "b5": 1.0 }, + { "b0": 0.0, "b1": 0.0, "b2": 1.0, "b3": 1.0, "b4": 0.0, "b5": 1.0 }, + { "b0": 0.0, "b1": 0.0, "b2": 1.0, "b3": 1.0, "b4": 0.0, "b5": 1.0 }, + { "b0": 0.0, "b1": 0.0, "b2": 1.0, "b3": 1.0, "b4": 0.0, "b5": 1.0 }, + { "b0": 0.0, "b1": 0.0, "b2": 1.0, "b3": 1.0, "b4": 1.0, "b5": 0.0 }, + { "b0": 0.0, "b1": 0.0, "b2": 1.0, "b3": 1.0, "b4": 0.0, "b5": 1.0 }, + { "b0": 0.0, "b1": 0.0, "b2": 1.0, "b3": 1.0, "b4": 1.0, "b5": 0.0 }, + { "b0": 0.0, "b1": 0.0, "b2": 1.0, "b3": 1.0, "b4": 0.0, "b5": 1.0 }, + { "b0": 0.0, "b1": 0.0, "b2": 1.0, "b3": 1.0, "b4": 0.0, "b5": 1.0 }, + { "b0": 0.0, "b1": 0.0, "b2": 1.0, "b3": 1.0, "b4": 0.0, "b5": 1.0 }, + { "b0": 0.0, "b1": 0.0, "b2": 1.0, "b3": 1.0, "b4": 1.0, "b5": 0.0 }, + { "b0": 0.0, "b1": 0.0, "b2": 1.0, "b3": 1.0, "b4": 1.0, "b5": 0.0 }, + { "b0": 0.0, "b1": 0.0, "b2": 1.0, "b3": 1.0, "b4": 1.0, "b5": 0.0 }, + { "b0": 0.0, "b1": 0.0, "b2": 1.0, "b3": 1.0, "b4": 1.0, "b5": 0.0 }, + { "b0": 0.0, "b1": 0.0, "b2": 1.0, "b3": 1.0, "b4": 1.0, "b5": 0.0 }, + { "b0": 0.0, "b1": 0.0, "b2": 1.0, "b3": 1.0, "b4": 1.0, "b5": 0.0 }, + { "b0": 0.0, "b1": 0.0, "b2": 1.0, "b3": 1.0, "b4": 0.0, "b5": 1.0 }, + { "b0": 0.0, "b1": 0.0, "b2": 1.0, "b3": 1.0, "b4": 0.0, "b5": 1.0 }, + { "b0": 0.0, "b1": 0.0, "b2": 1.0, "b3": 1.0, "b4": 0.0, "b5": 1.0 }, + { "b0": 0.0, "b1": 0.0, "b2": 1.0, "b3": 1.0, "b4": 1.0, "b5": 0.0 }, + { "b0": 0.0, "b1": 0.0, "b2": 1.0, "b3": 1.0, "b4": 0.0, "b5": 1.0 }, + { "b0": 0.0, "b1": 0.0, "b2": 1.0, "b3": 1.0, "b4": 1.0, "b5": 0.0 }, + { "b0": 0.0, "b1": 0.0, "b2": 1.0, "b3": 1.0, "b4": 1.0, "b5": 0.0 }, + { "b0": 0.0, "b1": 0.0, "b2": 1.0, "b3": 1.0, "b4": 1.0, "b5": 0.0 }, + { "b0": 0.0, "b1": 0.0, "b2": 1.0, "b3": 1.0, "b4": 0.0, "b5": 1.0 }, + { "b0": 0.0, "b1": 0.0, "b2": 1.0, "b3": 1.0, "b4": 1.0, "b5": 0.0 }, + { "b0": 0.0, "b1": 0.0, "b2": 1.0, "b3": 1.0, "b4": 0.0, "b5": 1.0 }, + { "b0": 0.0, "b1": 0.0, "b2": 1.0, "b3": 1.0, "b4": 1.0, "b5": 0.0 }, + { "b0": 0.0, "b1": 0.0, "b2": 1.0, "b3": 1.0, "b4": 0.0, "b5": 1.0 }, + { "b0": 0.0, "b1": 0.0, "b2": 1.0, "b3": 1.0, "b4": 1.0, "b5": 0.0 }, + { "b0": 0.0, "b1": 0.0, "b2": 1.0, "b3": 1.0, "b4": 0.0, "b5": 1.0 }, + { "b0": 0.0, "b1": 0.0, "b2": 1.0, "b3": 1.0, "b4": 1.0, "b5": 0.0 }, + { "b0": 0.0, "b1": 0.0, "b2": 1.0, "b3": 1.0, "b4": 1.0, "b5": 0.0 }, + { "b0": 0.0, "b1": 0.0, "b2": 1.0, "b3": 1.0, "b4": 1.0, "b5": 0.0 }, + { "b0": 0.0, "b1": 0.0, "b2": 1.0, "b3": 1.0, "b4": 1.0, "b5": 0.0 }, + { "b0": 0.0, "b1": 0.0, "b2": 1.0, "b3": 1.0, "b4": 1.0, "b5": 0.0 }, + { "b0": 0.0, "b1": 0.0, "b2": 1.0, "b3": 1.0, "b4": 1.0, "b5": 0.0 }, + { "b0": 0.0, "b1": 0.0, "b2": 1.0, "b3": 1.0, "b4": 0.0, "b5": 1.0 }, + { "b0": 0.0, "b1": 0.0, "b2": 1.0, "b3": 1.0, "b4": 0.0, "b5": 1.0 }, + { "b0": 0.0, "b1": 0.0, "b2": 1.0, "b3": 1.0, "b4": 0.0, "b5": 1.0 }, + { "b0": 0.0, "b1": 0.0, "b2": 1.0, "b3": 1.0, "b4": 0.0, "b5": 1.0 }, + { "b0": 0.0, "b1": 0.0, "b2": 1.0, "b3": 1.0, "b4": 0.0, "b5": 1.0 }, + { "b0": 0.0, "b1": 0.0, "b2": 1.0, "b3": 1.0, "b4": 1.0, "b5": 0.0 }, + { "b0": 0.0, "b1": 0.0, "b2": 1.0, "b3": 1.0, "b4": 1.0, "b5": 0.0 } + ], + "time": 20970.0, + "valid solution rate": { "0": 1.0 }, + "p range": 1.0, + "TTS": 20970.0, + "qubo": { + "(0, 1)": 24.48071872338975, + "(0,)": 42.24552747666033, + "()": 31.88076750778388, + "(1,)": 42.24552747666033, + "(0, 2)": 0.41675676795773126, + "(0, 3)": 0.41675676795773126, + "(2,)": -3.168051752401938, + "(3,)": -3.168051752401938, + "(1, 2)": 0.41675676795773126, + "(1, 3)": 0.41675676795773126, + "(0, 4)": 1.6633163879133126, + "(0, 5)": 1.6633163879133126, + "(4,)": -3.197456791219274, + "(5,)": -3.197456791219274, + "(1, 4)": 1.6633163879133126, + "(1, 5)": 1.6633163879133126, + "(2, 3)": 1.94836892149705, + "(2, 4)": 0.15914040330596124, + "(2, 5)": 0.15914040330596124, + "(3, 4)": 0.15914040330596124, + "(3, 5)": 0.15914040330596124, + "(4, 5)": 8.75 + }, + "qubo num var": 6, + "qubo contributions": { "2": 15, "1": 6, "0": 1 }, + "qubo contributions average": { "2": 0.0, "1": 0.0, "0": 31.88076750778388 }, + "qubo contributions variance": { "2": 0.0, "1": 0.0, "0": 0.0 }, + "qubo coefficient average": 1.449125795808358, + "qubo coefficient variance": 44.09927701362135, + "pubo": { + "('b0', 'b1')": 24.48071872338975, + "('b0',)": 42.24552747666033, + "()": 31.88076750778388, + "('b1',)": 42.24552747666033, + "('b0', 'b2')": 0.41675676795773126, + "('b0', 'b3')": 0.41675676795773126, + "('b2',)": -3.168051752401938, + "('b3',)": -3.168051752401938, + "('b1', 'b2')": 0.41675676795773126, + "('b1', 'b3')": 0.41675676795773126, + "('b0', 'b4')": 1.6633163879133126, + "('b0', 'b5')": 1.6633163879133126, + "('b4',)": -3.197456791219274, + "('b5',)": -3.197456791219274, + "('b1', 'b4')": 1.6633163879133126, + "('b1', 'b5')": 1.6633163879133126, + "('b2', 'b3')": 1.94836892149705, + "('b2', 'b4')": 0.15914040330596124, + "('b2', 'b5')": 0.15914040330596124, + "('b3', 'b4')": 0.15914040330596124, + "('b3', 'b5')": 0.15914040330596124, + "('b4', 'b5')": 8.75 + }, + "num var": 6, + "pubo contributions": { "2": 15, "1": 6, "0": 1 }, + "pubo contributions average": { + "2": 2.942396125439655, + "1": 11.960006311013037, + "0": 31.88076750778388 + }, + "pubo contributions variance": { + "2": 37.44408929297084, + "1": 458.6065402468196, + "0": 0.0 + }, + "pubo coefficient average": 6.717124875248044, + "pubo coefficient variance": 196.59840831499267, + "lambdas": [] +} diff --git a/src/mqt/qao/__init__.py b/src/mqt/qao/__init__.py index 3077977..e3f5615 100644 --- a/src/mqt/qao/__init__.py +++ b/src/mqt/qao/__init__.py @@ -2,20 +2,20 @@ import logging -from mqt.qao.variables import Variable, Variables from mqt.qao.constraints import Constraints from mqt.qao.objectivefunction import ObjectiveFunction from mqt.qao.problem import Problem from mqt.qao.solvers import Solution, Solver +from mqt.qao.variables import Variable, Variables __all__ = [ - "Variable", - "Variables", "Constraints", "ObjectiveFunction", "Problem", "Solution", "Solver", + "Variable", + "Variables", ] logger = logging.getLogger("mqt-qao") diff --git a/src/mqt/qao/constraints.py b/src/mqt/qao/constraints.py index 85e2ab3..54417e8 100644 --- a/src/mqt/qao/constraints.py +++ b/src/mqt/qao/constraints.py @@ -7,7 +7,7 @@ # for managing symbols from sympy import Expr, expand -from mqt.qao.variables import Variables +from .variables import Variable, Variables class Constraints: @@ -204,11 +204,11 @@ def _not_constraint(self, elem: tuple[str, bool, bool, bool], var: Variables) -> print("Wrong constraint format\n") return False a = self._convert_expression_logic( - expand(cast(Expr, (el[0]))).evalf(), # type: ignore[no-untyped-call] + expand(cast(Expr, (el[0]))).evalf(), var.binary_variables_name_weight, ) b = self._convert_expression_logic( - expand(cast(Expr, (el[1]))).evalf(), # type: ignore[no-untyped-call] + expand(cast(Expr, (el[1]))).evalf(), var.binary_variables_name_weight, ) ret = 2 * a * b - a - b + 1 @@ -218,15 +218,7 @@ def _not_constraint(self, elem: tuple[str, bool, bool, bool], var: Variables) -> print("Wrong constraint format\n") return False - op = [] - for e in el: - for elms in var.binary_variables_name_weight.values(): - if isinstance(elms, list): - for elm in elms: - if not isinstance(elm, str) and e == next(iter(elm[0].variables)): - op.append(elm[0]) # noqa: PERF401 - elif e == next(iter(elms[0].variables)): - op.append(elms[0]) + op = self._logic_constraint(el, var) ret = 2 * op[0] * op[1] - op[0] - op[1] + 1 return ret @@ -243,60 +235,34 @@ def _not_constraint_check(self, constraint: str, variables: Variables, solution: bool -- saying if the constraint is satisfied or not """ el = (constraint).replace("~", "").split("=") - expr1 = expand(cast(Expr, (el[0]))).evalf() # type: ignore[no-untyped-call] - expr2 = expand(cast(Expr, (el[1]))).evalf() # type: ignore[no-untyped-call] + expr1 = expand(cast(Expr, (el[0]))).evalf() + expr2 = expand(cast(Expr, (el[1]))).evalf() expr1_to_sub = bool(not str(expr1).replace(".", "").isnumeric()) expr2_to_sub = bool(not str(expr2).replace(".", "").isnumeric()) if expr2_to_sub or expr1_to_sub: for var in solution: if var in variables.variables_dict: if isinstance(solution[var], float): - if expr1_to_sub: - expr1 = expr1.subs({variables.variables_dict[var].symbol: solution[var]}) - if expr2_to_sub: - expr2 = expr2.subs({variables.variables_dict[var].symbol: solution[var]}) + expr1, expr2 = self._constraint_check_sub_single_var( + expr1_to_sub, expr2_to_sub, expr1, expr2, solution[var], variables.variables_dict[var] + ) elif isinstance(solution[var], list): - for i in range(len(solution[var])): - if isinstance(solution[var][i], list): - for j in range(len(solution[var][i])): - if isinstance(solution[var][i][j], list): - for k in range(len(solution[var][i][j])): - if expr1_to_sub: - expr1 = expr1.subs( - { - variables.variables_dict[var][i][j][k].symbol: solution[var][i][ - j - ][k] - } - ) - if expr2_to_sub: - expr2 = expr2.subs( - { - variables.variables_dict[var][i][j][k].symbol: solution[var][i][ - j - ][k] - } - ) - else: - if expr1_to_sub: - expr1 = expr1.subs( - {variables.variables_dict[var][i][j].symbol: solution[var][i][j]} - ) - if expr2_to_sub: - expr2 = expr2.subs( - {variables.variables_dict[var][i][j].symbol: solution[var][i][j]} - ) - else: - if expr1_to_sub: - expr1 = expr1.subs({variables.variables_dict[var][i].symbol: solution[var][i]}) - if expr2_to_sub: - expr2 = expr2.subs({variables.variables_dict[var][i].symbol: solution[var][i]}) + expr1, expr2 = self._constraint_check_sub_list_var( + solution, + variables, + expr1, + expr2, + var, + expr1_to_sub, + expr2_to_sub, + ) try: return bool(expr1) != bool(expr2) except ValueError: return False - def _not_constraint_check_no_sub(self, constraint: str, solution: dict[str, int]) -> bool: + @staticmethod + def _not_constraint_check_no_sub(constraint: str, solution: dict[str, int]) -> bool: """function for checking the not constraint penalty function. Keyword arguments: @@ -307,8 +273,8 @@ def _not_constraint_check_no_sub(self, constraint: str, solution: dict[str, int] bool -- saying if the constraint is satisfied or not """ el = (constraint).replace("~", "").split("=") - expr1 = expand(cast(Expr, (el[0]))).evalf() # type: ignore[no-untyped-call] - expr2 = expand(cast(Expr, (el[1]))).evalf() # type: ignore[no-untyped-call] + expr1 = expand(cast(Expr, (el[0]))).evalf() + expr2 = expand(cast(Expr, (el[1]))).evalf() expr1_to_sub = True if not str(expr1).replace(".", "").isnumeric(): symbols_in_the_expression1 = expr1.free_symbols @@ -360,15 +326,15 @@ def _and_constraint(self, elem: tuple[str, bool, bool, bool], var: Variables) -> print("Wrong constraint format\n") return False a = self._convert_expression_logic( - expand(cast(Expr, (el2[0]))).evalf(), # type: ignore[no-untyped-call] + expand(cast(Expr, (el2[0]))).evalf(), var.binary_variables_name_weight, ) b = self._convert_expression_logic( - expand(cast(Expr, (el2[1]))).evalf(), # type: ignore[no-untyped-call] + expand(cast(Expr, (el2[1]))).evalf(), var.binary_variables_name_weight, ) c = self._convert_expression_logic( - expand(cast(Expr, (el[1]))).evalf(), # type: ignore[no-untyped-call] + expand(cast(Expr, (el[1]))).evalf(), var.binary_variables_name_weight, ) ret = a * b - 2 * (a + b) * c + 3 * c @@ -383,15 +349,7 @@ def _and_constraint(self, elem: tuple[str, bool, bool, bool], var: Variables) -> return False el = [el2[0], el2[1], el[1]] - op = [] - for e in el: - for elms in var.binary_variables_name_weight.values(): - if isinstance(elms, list): - for elm in elms: - if not isinstance(elm, str) and e == next(iter(elm[0].variables)): - op.append(elm[0]) # noqa: PERF401 - elif e == next(iter(elms[0].variables)): - op.append(elms[0]) + op = self._logic_constraint(el, var) ret = op[0] * op[1] - 2 * (op[0] + op[1]) * op[2] + 3 * op[2] return ret @@ -415,9 +373,9 @@ def _and_constraint_check(self, constraint: str, variables: Variables, solution: if len(el2) != 2: print("Wrong constraint format\n") return False - expr1 = expand(cast(Expr, (el2[0]))).evalf() # type: ignore[no-untyped-call] - expr2 = expand(cast(Expr, (el2[1]))).evalf() # type: ignore[no-untyped-call] - expr3 = expand(cast(Expr, (el[1]))).evalf() # type: ignore[no-untyped-call] + expr1 = expand(cast(Expr, (el2[0]))).evalf() + expr2 = expand(cast(Expr, (el2[1]))).evalf() + expr3 = expand(cast(Expr, (el[1]))).evalf() expr1_to_sub = bool(not str(expr1).replace(".", "").isnumeric()) expr2_to_sub = bool(not str(expr2).replace(".", "").isnumeric()) expr3_to_sub = bool(not str(expr3).replace(".", "").isnumeric()) @@ -425,68 +383,27 @@ def _and_constraint_check(self, constraint: str, variables: Variables, solution: for var in solution: if var in variables.variables_dict: if isinstance(solution[var], float): - if expr1_to_sub: - expr1 = expr1.subs({variables.variables_dict[var].symbol: solution[var]}) - if expr2_to_sub: - expr2 = expr2.subs({variables.variables_dict[var].symbol: solution[var]}) - if expr3_to_sub: - expr3 = expr3.subs({variables.variables_dict[var].symbol: solution[var]}) + expr1, expr2, expr3 = self._constraint_check_three_sub_single_var( + expr1_to_sub, + expr2_to_sub, + expr3_to_sub, + expr1, + expr2, + expr3, + solution[var], + variables.variables_dict[var], + ) elif isinstance(solution[var], list): - for i in range(len(solution[var])): - if isinstance(solution[var][i], list): - for j in range(len(solution[var][i])): - if isinstance(solution[var][i][j], list): - for k in range(len(solution[var][i][j])): - if expr1_to_sub: - expr1 = expr1.subs( - { - variables.variables_dict[var][i][j][k].symbol: solution[var][i][ - j - ][k] - } - ) - if expr2_to_sub: - expr2 = expr2.subs( - { - variables.variables_dict[var][i][j][k].symbol: solution[var][i][ - j - ][k] - } - ) - if expr3_to_sub: - expr3 = expr3.subs( - { - variables.variables_dict[var][i][j][k].symbol: solution[var][i][ - j - ][k] - } - ) - else: - if expr1_to_sub: - expr1 = expr1.subs( - {variables.variables_dict[var][i][j].symbol: solution[var][i][j]} - ) - if expr2_to_sub: - expr2 = expr2.subs( - {variables.variables_dict[var][i][j].symbol: solution[var][i][j]} - ) - if expr3_to_sub: - expr3 = expr3.subs( - {variables.variables_dict[var][i][j].symbol: solution[var][i][j]} - ) - else: - if expr1_to_sub: - expr1 = expr1.subs({variables.variables_dict[var][i].symbol: solution[var][i]}) - if expr2_to_sub: - expr2 = expr2.subs({variables.variables_dict[var][i].symbol: solution[var][i]}) - if expr3_to_sub: - expr3 = expr3.subs({variables.variables_dict[var][i].symbol: solution[var][i]}) + expr1, expr2, expr3 = self._constraint_check_three_sub_list_var( + solution, variables, expr1, expr2, expr3, var, expr1_to_sub, expr2_to_sub, expr3_to_sub + ) try: return bool(expr1) and bool(expr2) == bool(expr3) except ValueError: return False - def _and_constraint_check_no_sub(self, constraint: str, solution: dict[str, int]) -> bool: + @staticmethod + def _and_constraint_check_no_sub(constraint: str, solution: dict[str, int]) -> bool: """function for checking the and constraint penalty function. Keyword arguments: @@ -504,9 +421,9 @@ def _and_constraint_check_no_sub(self, constraint: str, solution: dict[str, int] if len(el2) != 2: print("Wrong constraint format\n") return False - expr1 = expand(cast(Expr, (el2[0]))).evalf() # type: ignore[no-untyped-call] - expr2 = expand(cast(Expr, (el2[1]))).evalf() # type: ignore[no-untyped-call] - expr3 = expand(cast(Expr, (el[1]))).evalf() # type: ignore[no-untyped-call] + expr1 = expand(cast(Expr, (el2[0]))).evalf() + expr2 = expand(cast(Expr, (el2[1]))).evalf() + expr3 = expand(cast(Expr, (el[1]))).evalf() expr1_to_sub = True if not str(expr1).replace(".", "").isnumeric(): symbols_in_the_expression1 = expr1.free_symbols @@ -565,15 +482,15 @@ def _or_constraint(self, elem: tuple[str, bool, bool, bool], var: Variables) -> print("Wrong constraint format\n") return False a = self._convert_expression_logic( - expand(cast(Expr, (el2[0]))).evalf(), # type: ignore[no-untyped-call] + expand(cast(Expr, (el2[0]))).evalf(), var.binary_variables_name_weight, ) b = self._convert_expression_logic( - expand(cast(Expr, (el2[1]))).evalf(), # type: ignore[no-untyped-call] + expand(cast(Expr, (el2[1]))).evalf(), var.binary_variables_name_weight, ) c = self._convert_expression_logic( - expand(cast(Expr, (el[1]))).evalf(), # type: ignore[no-untyped-call] + expand(cast(Expr, (el[1]))).evalf(), var.binary_variables_name_weight, ) ret = a * b + (a + b) * (1 - 2 * c) + c @@ -588,15 +505,7 @@ def _or_constraint(self, elem: tuple[str, bool, bool, bool], var: Variables) -> return False el = [el2[0], el2[1], el[1]] - op = [] - for e in el: - for elms in var.binary_variables_name_weight.values(): - if isinstance(elms, list): - for elm in elms: - if not isinstance(elm, str) and e == next(iter(elm[0].variables)): - op.append(elm[0]) # noqa: PERF401 - elif e == next(iter(elms[0].variables)): - op.append(elms[0]) + op = self._logic_constraint(el, var) ret = op[0] * op[1] + (op[0] + op[1]) * (1 - 2 * op[2]) + op[2] return ret @@ -619,9 +528,9 @@ def _or_constraint_check(self, constraint: str, variables: Variables, solution: if len(el2) != 2: print("Wrong constraint format\n") return False - expr1 = expand(cast(Expr, (el2[0]))).evalf() # type: ignore[no-untyped-call] - expr2 = expand(cast(Expr, (el2[1]))).evalf() # type: ignore[no-untyped-call] - expr3 = expand(cast(Expr, (el[1]))).evalf() # type: ignore[no-untyped-call] + expr1 = expand(cast(Expr, (el2[0]))).evalf() + expr2 = expand(cast(Expr, (el2[1]))).evalf() + expr3 = expand(cast(Expr, (el[1]))).evalf() expr1_to_sub = bool(not str(expr1).replace(".", "").isnumeric()) expr2_to_sub = bool(not str(expr2).replace(".", "").isnumeric()) expr3_to_sub = bool(not str(expr3).replace(".", "").isnumeric()) @@ -629,68 +538,27 @@ def _or_constraint_check(self, constraint: str, variables: Variables, solution: for var in solution: if var in variables.variables_dict: if isinstance(solution[var], float): - if expr1_to_sub: - expr1 = expr1.subs({variables.variables_dict[var].symbol: solution[var]}) - if expr2_to_sub: - expr2 = expr2.subs({variables.variables_dict[var].symbol: solution[var]}) - if expr3_to_sub: - expr3 = expr3.subs({variables.variables_dict[var].symbol: solution[var]}) + expr1, expr2, expr3 = self._constraint_check_three_sub_single_var( + expr1_to_sub, + expr2_to_sub, + expr3_to_sub, + expr1, + expr2, + expr3, + solution[var], + variables.variables_dict[var], + ) elif isinstance(solution[var], list): - for i in range(len(solution[var])): - if isinstance(solution[var][i], list): - for j in range(len(solution[var][i])): - if isinstance(solution[var][i][j], list): - for k in range(len(solution[var][i][j])): - if expr1_to_sub: - expr1 = expr1.subs( - { - variables.variables_dict[var][i][j][k].symbol: solution[var][i][ - j - ][k] - } - ) - if expr2_to_sub: - expr2 = expr2.subs( - { - variables.variables_dict[var][i][j][k].symbol: solution[var][i][ - j - ][k] - } - ) - if expr3_to_sub: - expr3 = expr3.subs( - { - variables.variables_dict[var][i][j][k].symbol: solution[var][i][ - j - ][k] - } - ) - else: - if expr1_to_sub: - expr1 = expr1.subs( - {variables.variables_dict[var][i][j].symbol: solution[var][i][j]} - ) - if expr2_to_sub: - expr2 = expr2.subs( - {variables.variables_dict[var][i][j].symbol: solution[var][i][j]} - ) - if expr3_to_sub: - expr3 = expr3.subs( - {variables.variables_dict[var][i][j].symbol: solution[var][i][j]} - ) - else: - if expr1_to_sub: - expr1 = expr1.subs({variables.variables_dict[var][i].symbol: solution[var][i]}) - if expr2_to_sub: - expr2 = expr2.subs({variables.variables_dict[var][i].symbol: solution[var][i]}) - if expr3_to_sub: - expr3 = expr3.subs({variables.variables_dict[var][i].symbol: solution[var][i]}) + expr1, expr2, expr3 = self._constraint_check_three_sub_list_var( + solution, variables, expr1, expr2, expr3, var, expr1_to_sub, expr2_to_sub, expr3_to_sub + ) try: return bool(expr1) or bool(expr2) == bool(expr3) except ValueError: return False - def _or_constraint_check_no_sub(self, constraint: str, solution: dict[str, int]) -> bool: + @staticmethod + def _or_constraint_check_no_sub(constraint: str, solution: dict[str, int]) -> bool: """function for checking the or constraint penalty function. Keyword arguments: @@ -708,9 +576,9 @@ def _or_constraint_check_no_sub(self, constraint: str, solution: dict[str, int]) if len(el2) != 2: print("Wrong constraint format\n") return False - expr1 = expand(cast(Expr, (el2[0]))).evalf() # type: ignore[no-untyped-call] - expr2 = expand(cast(Expr, (el2[1]))).evalf() # type: ignore[no-untyped-call] - expr3 = expand(cast(Expr, (el[1]))).evalf() # type: ignore[no-untyped-call] + expr1 = expand(cast(Expr, (el2[0]))).evalf() + expr2 = expand(cast(Expr, (el2[1]))).evalf() + expr3 = expand(cast(Expr, (el[1]))).evalf() expr1_to_sub = True if not str(expr1).replace(".", "").isnumeric(): symbols_in_the_expression1 = expr1.free_symbols @@ -745,6 +613,19 @@ def _or_constraint_check_no_sub(self, constraint: str, solution: dict[str, int]) except ValueError: return False + @staticmethod + def _logic_constraint(el: list[str], var: Variables) -> list[PUBO]: + op = [] + for e in el: + for elms in var.binary_variables_name_weight.values(): + if isinstance(elms, list): + for elm in elms: + if not isinstance(elm, str) and e == next(iter(elm[0].variables)): + op.append(elm[0]) # noqa: PERF401 + elif e == next(iter(elms[0].variables)): + op.append(elms[0]) + return op + def _xor_constraint(self, elem: tuple[str, bool, bool, bool], var: Variables) -> PUBO | bool: """function for writing the xor constraint penalty function. @@ -767,9 +648,9 @@ def _xor_constraint(self, elem: tuple[str, bool, bool, bool], var: Variables) -> if len(el2) != 2: print("Wrong constraint format\n") return False - a = self._convert_expression_logic(expand(cast(Expr, (el2[0]))).evalf(), var.binary_variables_name_weight) # type: ignore[no-untyped-call] - b = self._convert_expression_logic(expand(cast(Expr, (el2[1]))).evalf(), var.binary_variables_name_weight) # type: ignore[no-untyped-call] - c = self._convert_expression_logic(expand(cast(Expr, (el[1]))).evalf(), var.binary_variables_name_weight) # type: ignore[no-untyped-call] + a = self._convert_expression_logic(expand(cast(Expr, (el2[0]))).evalf(), var.binary_variables_name_weight) + b = self._convert_expression_logic(expand(cast(Expr, (el2[1]))).evalf(), var.binary_variables_name_weight) + c = self._convert_expression_logic(expand(cast(Expr, (el[1]))).evalf(), var.binary_variables_name_weight) ret = a + b + c - 2 * a * c - 2 * b * c - 2 * a * b + 4 * a * b * c else: el = str(elem[0]).replace(" ", "").split("=") @@ -781,21 +662,83 @@ def _xor_constraint(self, elem: tuple[str, bool, bool, bool], var: Variables) -> print("Wrong constraint format\n") return False el = [el2[0], el2[1], el[1]] - op = [] - for e in el: - for elms in var.binary_variables_name_weight.values(): - if isinstance(elms, list): - for elm in elms: - if not isinstance(elm, str) and e == next(iter(elm[0].variables)): - op.append(elm[0]) # noqa: PERF401 - elif e == next(iter(elms[0].variables)): - op.append(elms[0]) + op = self._logic_constraint(el, var) a = op[0] b = op[1] c = op[2] ret = a + b + c - 2 * a * c - 2 * b * c - 2 * a * b + 4 * a * b * c return ret + @staticmethod + def _constraint_check_three_sub_single_var( + expr1_to_sub: bool, + expr2_to_sub: bool, + expr3_to_sub: bool, + expr1: Expr, + expr2: Expr, + expr3: Expr, + sol_val: float, + variable: Variable, + ) -> tuple[Expr, Expr, Expr]: + if expr1_to_sub: + expr1 = expr1.subs({variable.symbol: sol_val}) + if expr2_to_sub: + expr2 = expr2.subs({variable.symbol: sol_val}) + if expr3_to_sub: + expr3 = expr3.subs({variable.symbol: sol_val}) + return expr1, expr2, expr3 + + def _constraint_check_three_sub_list_var( + self, + solution: dict[str, Any], + variables: Variables, + expr1: Expr, + expr2: Expr, + expr3: Expr, + var: str, + expr1_to_sub: bool, + expr2_to_sub: bool, + expr3_to_sub: bool, + ) -> tuple[Expr, Expr, Expr]: + for i in range(len(solution[var])): + if isinstance(solution[var][i], list): + for j in range(len(solution[var][i])): + if isinstance(solution[var][i][j], list): + for k in range(len(solution[var][i][j])): + expr1, expr2, expr3 = self._constraint_check_three_sub_single_var( + expr1_to_sub, + expr2_to_sub, + expr3_to_sub, + expr1, + expr2, + expr3, + solution[var][i][j][k], + variables.variables_dict[var][i][j][k], + ) + else: + expr1, expr2, expr3 = self._constraint_check_three_sub_single_var( + expr1_to_sub, + expr2_to_sub, + expr3_to_sub, + expr1, + expr2, + expr3, + solution[var][i][j], + variables.variables_dict[var][i][j], + ) + else: + expr1, expr2, expr3 = self._constraint_check_three_sub_single_var( + expr1_to_sub, + expr2_to_sub, + expr3_to_sub, + expr1, + expr2, + expr3, + solution[var][i], + variables.variables_dict[var][i], + ) + return expr1, expr2, expr3 + def _xor_constraint_check(self, constraint: str, variables: Variables, solution: dict[str, Any]) -> bool: """function for checking the xor constraint penalty function. @@ -815,9 +758,9 @@ def _xor_constraint_check(self, constraint: str, variables: Variables, solution: if len(el2) != 2: print("Wrong constraint format\n") return False - expr1 = expand(cast(Expr, (el2[0]))).evalf() # type: ignore[no-untyped-call] - expr2 = expand(cast(Expr, (el2[1]))).evalf() # type: ignore[no-untyped-call] - expr3 = expand(cast(Expr, (el[1]))).evalf() # type: ignore[no-untyped-call] + expr1 = expand(cast(Expr, (el2[0]))).evalf() + expr2 = expand(cast(Expr, (el2[1]))).evalf() + expr3 = expand(cast(Expr, (el[1]))).evalf() expr1_to_sub = bool(not str(expr1).replace(".", "").isnumeric()) expr2_to_sub = bool(not str(expr2).replace(".", "").isnumeric()) expr3_to_sub = bool(not str(expr3).replace(".", "").isnumeric()) @@ -825,68 +768,27 @@ def _xor_constraint_check(self, constraint: str, variables: Variables, solution: for var in solution: if var in variables.variables_dict: if isinstance(solution[var], float): - if expr1_to_sub: - expr1 = expr1.subs({variables.variables_dict[var].symbol: solution[var]}) - if expr2_to_sub: - expr2 = expr2.subs({variables.variables_dict[var].symbol: solution[var]}) - if expr3_to_sub: - expr3 = expr3.subs({variables.variables_dict[var].symbol: solution[var]}) + expr1, expr2, expr3 = self._constraint_check_three_sub_single_var( + expr1_to_sub, + expr2_to_sub, + expr3_to_sub, + expr1, + expr2, + expr3, + solution[var], + variables.variables_dict[var], + ) elif isinstance(solution[var], list): - for i in range(len(solution[var])): - if isinstance(solution[var][i], list): - for j in range(len(solution[var][i])): - if isinstance(solution[var][i][j], list): - for k in range(len(solution[var][i][j])): - if expr1_to_sub: - expr1 = expr1.subs( - { - variables.variables_dict[var][i][j][k].symbol: solution[var][i][ - j - ][k] - } - ) - if expr2_to_sub: - expr2 = expr2.subs( - { - variables.variables_dict[var][i][j][k].symbol: solution[var][i][ - j - ][k] - } - ) - if expr3_to_sub: - expr3 = expr3.subs( - { - variables.variables_dict[var][i][j][k].symbol: solution[var][i][ - j - ][k] - } - ) - else: - if expr1_to_sub: - expr1 = expr1.subs( - {variables.variables_dict[var][i][j].symbol: solution[var][i][j]} - ) - if expr2_to_sub: - expr2 = expr2.subs( - {variables.variables_dict[var][i][j].symbol: solution[var][i][j]} - ) - if expr3_to_sub: - expr3 = expr3.subs( - {variables.variables_dict[var][i][j].symbol: solution[var][i][j]} - ) - else: - if expr1_to_sub: - expr1 = expr1.subs({variables.variables_dict[var][i].symbol: solution[var][i]}) - if expr2_to_sub: - expr2 = expr2.subs({variables.variables_dict[var][i].symbol: solution[var][i]}) - if expr3_to_sub: - expr3 = expr3.subs({variables.variables_dict[var][i].symbol: solution[var][i]}) + expr1, expr2, expr3 = self._constraint_check_three_sub_list_var( + solution, variables, expr1, expr2, expr3, var, expr1_to_sub, expr2_to_sub, expr3_to_sub + ) try: return bool(expr1) ^ bool(expr2) == bool(expr3) except ValueError: return False - def _xor_constraint_check_no_sub(self, constraint: str, solution: dict[str, int]) -> bool: + @staticmethod + def _xor_constraint_check_no_sub(constraint: str, solution: dict[str, int]) -> bool: """function for checking the xor constraint penalty function. Keyword arguments: @@ -904,9 +806,9 @@ def _xor_constraint_check_no_sub(self, constraint: str, solution: dict[str, int] if len(el2) != 2: print("Wrong constraint format\n") return False - expr1 = expand(cast(Expr, (el2[0]))).evalf() # type: ignore[no-untyped-call] - expr2 = expand(cast(Expr, (el2[1]))).evalf() # type: ignore[no-untyped-call] - expr3 = expand(cast(Expr, (el[1]))).evalf() # type: ignore[no-untyped-call] + expr1 = expand(cast(Expr, (el2[0]))).evalf() + expr2 = expand(cast(Expr, (el2[1]))).evalf() + expr3 = expand(cast(Expr, (el[1]))).evalf() expr1_to_sub = True if not str(expr1).replace(".", "").isnumeric(): symbols_in_the_expression1 = expr1.free_symbols @@ -941,6 +843,59 @@ def _xor_constraint_check_no_sub(self, constraint: str, solution: dict[str, int] except ValueError: return False + @staticmethod + def _constraint_check_sub_single_var( + expr1_to_sub: bool, expr2_to_sub: bool, expr1: Expr, expr2: Expr, sol_val: float, variable: Variable + ) -> tuple[Expr, Expr]: + if expr1_to_sub: + expr1 = expr1.subs({variable.symbol: sol_val}) + if expr2_to_sub: + expr2 = expr2.subs({variable.symbol: sol_val}) + return expr1, expr2 + + def _constraint_check_sub_list_var( + self, + solution: dict[str, Any], + variables: Variables, + expr1: Expr, + expr2: Expr, + var: str, + expr1_to_sub: bool, + expr2_to_sub: bool, + ) -> tuple[Expr, Expr]: + for i in range(len(solution[var])): + if isinstance(solution[var][i], list): + for j in range(len(solution[var][i])): + if isinstance(solution[var][i][j], list): + for k in range(len(solution[var][i][j])): + expr1, expr2 = self._constraint_check_sub_single_var( + expr1_to_sub, + expr2_to_sub, + expr1, + expr2, + solution[var][i][j][k], + variables.variables_dict[var][i][j][k], + ) + else: + expr1, expr2 = self._constraint_check_sub_single_var( + expr1_to_sub, + expr2_to_sub, + expr1, + expr2, + solution[var][i][j], + variables.variables_dict[var][i][j], + ) + else: + expr1, expr2 = self._constraint_check_sub_single_var( + expr1_to_sub, + expr2_to_sub, + expr1, + expr2, + solution[var][i], + variables.variables_dict[var][i], + ) + return expr1, expr2 + def _greq_constraint( self, elem: tuple[str, bool, bool, bool], var: Variables, aux: Variables, i: int, j: int ) -> tuple[ @@ -975,7 +930,7 @@ def _greq_constraint( exp = PUBO() if elem[3]: ret_func = self._convert_expression_prec( - expand(cast(Expr, (el[0] + "-" + el[1]))).evalf(), # type: ignore[no-untyped-call] + expand(cast(Expr, (el[0] + "-" + el[1]))).evalf(), var.binary_variables_name_weight, var.variables_dict, ) @@ -984,11 +939,11 @@ def _greq_constraint( var_precision = ret_func[1] else: exp = self._convert_expression( - expand(cast(Expr, (el[0] + "-" + el[1]))).evalf(), # type: ignore[no-untyped-call] + expand(cast(Expr, (el[0] + "-" + el[1]))).evalf(), var.binary_variables_name_weight, ) - min_val, max_val, const = self._min_max_const_estimation(exp) + _min_val, max_val, const = self._min_max_const_estimation(exp) if max_val + const > 0: if len(str(max_val + const).split(".")) == 2: if elem[3] and float("0." + str(max_val + const).split(".")[1]) != 0.0: @@ -1010,8 +965,8 @@ def _greq_constraint( ret = (exp) ** 2, i, j, aux else: el = str(elem[0]).split(">=") - exp = expand(cast(Expr, (el[0] + "-" + el[1]))).evalf() # type: ignore[no-untyped-call] - min_val, max_val, const = self._min_max_const_estimation(exp) + exp = expand(cast(Expr, (el[0] + "-" + el[1]))).evalf() + _min_val, max_val, const = self._min_max_const_estimation(exp) if max_val + const > 0: if len(str(max_val + const).split(".")) == 2: precision = float("0." + str(max_val + const).split(".")[1]) @@ -1048,60 +1003,28 @@ def _greq_constraint_check(self, constraint: str, variables: Variables, solution bool -- saying if the constraint is satisfied or not """ el = constraint.split(">=") - expr1 = expand(cast(Expr, (el[0]))).evalf() # type: ignore[no-untyped-call] - expr2 = expand(cast(Expr, (el[1]))).evalf() # type: ignore[no-untyped-call] + expr1 = expand(cast(Expr, (el[0]))).evalf() + expr2 = expand(cast(Expr, (el[1]))).evalf() expr1_to_sub = bool(not str(expr1).replace(".", "").isnumeric()) expr2_to_sub = bool(not str(expr2).replace(".", "").isnumeric()) if expr2_to_sub or expr1_to_sub: for var in solution: if var in variables.variables_dict: if isinstance(solution[var], float): - if expr1_to_sub: - expr1 = expr1.subs({variables.variables_dict[var].symbol: solution[var]}) - if expr2_to_sub: - expr2 = expr2.subs({variables.variables_dict[var].symbol: solution[var]}) + expr1, expr2 = self._constraint_check_sub_single_var( + expr1_to_sub, expr2_to_sub, expr1, expr2, solution[var], variables.variables_dict[var] + ) elif isinstance(solution[var], list): - for i in range(len(solution[var])): - if isinstance(solution[var][i], list): - for j in range(len(solution[var][i])): - if isinstance(solution[var][i][j], list): - for k in range(len(solution[var][i][j])): - if expr1_to_sub: - expr1 = expr1.subs( - { - variables.variables_dict[var][i][j][k].symbol: solution[var][i][ - j - ][k] - } - ) - if expr2_to_sub: - expr2 = expr2.subs( - { - variables.variables_dict[var][i][j][k].symbol: solution[var][i][ - j - ][k] - } - ) - else: - if expr1_to_sub: - expr1 = expr1.subs( - {variables.variables_dict[var][i][j].symbol: solution[var][i][j]} - ) - if expr2_to_sub: - expr2 = expr2.subs( - {variables.variables_dict[var][i][j].symbol: solution[var][i][j]} - ) - else: - if expr1_to_sub: - expr1 = expr1.subs({variables.variables_dict[var][i].symbol: solution[var][i]}) - if expr2_to_sub: - expr2 = expr2.subs({variables.variables_dict[var][i].symbol: solution[var][i]}) + expr1, expr2 = self._constraint_check_sub_list_var( + solution, variables, expr1, expr2, var, expr1_to_sub, expr2_to_sub + ) try: return float(expr1) >= float(expr2) except ValueError: return False - def _greq_constraint_check_no_sub(self, constraint: str, solution: dict[str, int]) -> bool: + @staticmethod + def _greq_constraint_check_no_sub(constraint: str, solution: dict[str, int]) -> bool: """function for checking the grater equal constraint penalty function. Keyword arguments: @@ -1112,8 +1035,8 @@ def _greq_constraint_check_no_sub(self, constraint: str, solution: dict[str, int bool -- saying if the constraint is satisfied or not """ el = (constraint).split(">=") - expr1 = expand(cast(Expr, (el[0]))).evalf() # type: ignore[no-untyped-call] - expr2 = expand(cast(Expr, (el[1]))).evalf() # type: ignore[no-untyped-call] + expr1 = expand(cast(Expr, (el[0]))).evalf() + expr2 = expand(cast(Expr, (el[1]))).evalf() expr1_to_sub = True if not str(expr1).replace(".", "").isnumeric(): symbols_in_the_expression1 = expr1.free_symbols @@ -1174,7 +1097,7 @@ def _lteq_constraint( exp = PUBO() if elem[3]: ret_func = self._convert_expression_prec( - expand(cast(Expr, (el[0] + "-" + el[1]))).evalf(), # type: ignore[no-untyped-call] + expand(cast(Expr, (el[0] + "-" + el[1]))).evalf(), var.binary_variables_name_weight, var.variables_dict, ) @@ -1183,10 +1106,10 @@ def _lteq_constraint( var_precision = ret_func[1] else: exp = self._convert_expression( - expand(cast(Expr, (el[0] + "-" + el[1]))).evalf(), # type: ignore[no-untyped-call] + expand(cast(Expr, (el[0] + "-" + el[1]))).evalf(), var.binary_variables_name_weight, ) - min_val, max_val, const = self._min_max_const_estimation(exp) + min_val, _max_val, const = self._min_max_const_estimation(exp) const = -const if const - min_val > 0: if len(str(const - min_val).split(".")) == 2: @@ -1209,8 +1132,8 @@ def _lteq_constraint( ret = (exp) ** 2, i, j, aux else: el = str(elem[0]).split("<=") - exp = expand(cast(Expr, (el[0] + "-" + el[1]))).evalf() # type: ignore[no-untyped-call] - min_val, max_val, const = self._min_max_const_estimation(exp) + exp = expand(cast(Expr, (el[0] + "-" + el[1]))).evalf() + min_val, _max_val, const = self._min_max_const_estimation(exp) const = -const if const - min_val > 0: if len(str(const - min_val).split(".")) == 2: @@ -1247,60 +1170,28 @@ def _lteq_constraint_check(self, constraint: str, variables: Variables, solution bool -- saying if the constraint is satisfied or not """ el = constraint.split("<=") - expr1 = expand(cast(Expr, (el[0]))).evalf() # type: ignore[no-untyped-call] - expr2 = expand(cast(Expr, (el[1]))).evalf() # type: ignore[no-untyped-call] + expr1 = expand(cast(Expr, (el[0]))).evalf() + expr2 = expand(cast(Expr, (el[1]))).evalf() expr1_to_sub = bool(not str(expr1).replace(".", "").isnumeric()) expr2_to_sub = bool(not str(expr2).replace(".", "").isnumeric()) if expr2_to_sub or expr1_to_sub: for var in solution: if var in variables.variables_dict: if isinstance(solution[var], float): - if expr1_to_sub: - expr1 = expr1.subs({variables.variables_dict[var].symbol: solution[var]}) - if expr2_to_sub: - expr2 = expr2.subs({variables.variables_dict[var].symbol: solution[var]}) + expr1, expr2 = self._constraint_check_sub_single_var( + expr1_to_sub, expr2_to_sub, expr1, expr2, solution[var], variables.variables_dict[var] + ) elif isinstance(solution[var], list): - for i in range(len(solution[var])): - if isinstance(solution[var][i], list): - for j in range(len(solution[var][i])): - if isinstance(solution[var][i][j], list): - for k in range(len(solution[var][i][j])): - if expr1_to_sub: - expr1 = expr1.subs( - { - variables.variables_dict[var][i][j][k].symbol: solution[var][i][ - j - ][k] - } - ) - if expr2_to_sub: - expr2 = expr2.subs( - { - variables.variables_dict[var][i][j][k].symbol: solution[var][i][ - j - ][k] - } - ) - else: - if expr1_to_sub: - expr1 = expr1.subs( - {variables.variables_dict[var][i][j].symbol: solution[var][i][j]} - ) - if expr2_to_sub: - expr2 = expr2.subs( - {variables.variables_dict[var][i][j].symbol: solution[var][i][j]} - ) - else: - if expr1_to_sub: - expr1 = expr1.subs({variables.variables_dict[var][i].symbol: solution[var][i]}) - if expr2_to_sub: - expr2 = expr2.subs({variables.variables_dict[var][i].symbol: solution[var][i]}) + expr1, expr2 = self._constraint_check_sub_list_var( + solution, variables, expr1, expr2, var, expr1_to_sub, expr2_to_sub + ) try: return float(expr1) <= float(expr2) except ValueError: return False - def _lteq_constraint_check_no_sub(self, constraint: str, solution: dict[str, int]) -> bool: + @staticmethod + def _lteq_constraint_check_no_sub(constraint: str, solution: dict[str, int]) -> bool: """function for checking the less equal constraint penalty function. Keyword arguments: @@ -1311,8 +1202,8 @@ def _lteq_constraint_check_no_sub(self, constraint: str, solution: dict[str, int bool -- saying if the constraint is satisfied or not """ el = (constraint).split("<=") - expr1 = expand(cast(Expr, (el[0]))).evalf() # type: ignore[no-untyped-call] - expr2 = expand(cast(Expr, (el[1]))).evalf() # type: ignore[no-untyped-call] + expr1 = expand(cast(Expr, (el[0]))).evalf() + expr2 = expand(cast(Expr, (el[1]))).evalf() expr1_to_sub = True if not str(expr1).replace(".", "").isnumeric(): symbols_in_the_expression1 = expr1.free_symbols @@ -1373,7 +1264,7 @@ def _grt_constraint( exp = PUBO() if elem[3]: ret_func = self._convert_expression_prec( - expand(cast(Expr, (el[0] + "-" + el[1]))).evalf(), # type: ignore[no-untyped-call] + expand(cast(Expr, (el[0] + "-" + el[1]))).evalf(), var.binary_variables_name_weight, var.variables_dict, ) @@ -1382,10 +1273,10 @@ def _grt_constraint( var_precision = ret_func[1] else: exp = self._convert_expression( - expand(cast(Expr, (el[0] + "-" + el[1]))).evalf(), # type: ignore[no-untyped-call] + expand(cast(Expr, (el[0] + "-" + el[1]))).evalf(), var.binary_variables_name_weight, ) - min_val, max_val, const = self._min_max_const_estimation(exp) + _min_val, max_val, const = self._min_max_const_estimation(exp) if max_val + const > 0: if len(str(max_val + const).split(".")) == 2: if elem[3] and float("0." + str(max_val + const).split(".")[1]) != 0.0: @@ -1410,8 +1301,8 @@ def _grt_constraint( ret = (exp) ** 2, i, j, aux else: el = str(elem[0]).split(">") - exp = expand(cast(Expr, (el[0] + "-" + el[1]))).evalf() # type: ignore[no-untyped-call] - min_val, max_val, const = self._min_max_const_estimation(exp) + exp = expand(cast(Expr, (el[0] + "-" + el[1]))).evalf() + _min_val, max_val, const = self._min_max_const_estimation(exp) if max_val + const > 0: if len(str(max_val + const).split(".")) == 2: precision = float("0." + str(max_val + const).split(".")[1]) @@ -1456,60 +1347,28 @@ def _grt_constraint_check(self, constraint: str, variables: Variables, solution: bool -- saying if the constraint is satisfied or not """ el = constraint.split(">") - expr1 = expand(cast(Expr, (el[0]))).evalf() # type: ignore[no-untyped-call] - expr2 = expand(cast(Expr, (el[1]))).evalf() # type: ignore[no-untyped-call] + expr1 = expand(cast(Expr, (el[0]))).evalf() + expr2 = expand(cast(Expr, (el[1]))).evalf() expr1_to_sub = bool(not str(expr1).replace(".", "").isnumeric()) expr2_to_sub = bool(not str(expr2).replace(".", "").isnumeric()) if expr2_to_sub or expr1_to_sub: for var in solution: if var in variables.variables_dict: if isinstance(solution[var], float): - if expr1_to_sub: - expr1 = expr1.subs({variables.variables_dict[var].symbol: solution[var]}) - if expr2_to_sub: - expr2 = expr2.subs({variables.variables_dict[var].symbol: solution[var]}) + expr1, expr2 = self._constraint_check_sub_single_var( + expr1_to_sub, expr2_to_sub, expr1, expr2, solution[var], variables.variables_dict[var] + ) elif isinstance(solution[var], list): - for i in range(len(solution[var])): - if isinstance(solution[var][i], list): - for j in range(len(solution[var][i])): - if isinstance(solution[var][i][j], list): - for k in range(len(solution[var][i][j])): - if expr1_to_sub: - expr1 = expr1.subs( - { - variables.variables_dict[var][i][j][k].symbol: solution[var][i][ - j - ][k] - } - ) - if expr2_to_sub: - expr2 = expr2.subs( - { - variables.variables_dict[var][i][j][k].symbol: solution[var][i][ - j - ][k] - } - ) - else: - if expr1_to_sub: - expr1 = expr1.subs( - {variables.variables_dict[var][i][j].symbol: solution[var][i][j]} - ) - if expr2_to_sub: - expr2 = expr2.subs( - {variables.variables_dict[var][i][j].symbol: solution[var][i][j]} - ) - else: - if expr1_to_sub: - expr1 = expr1.subs({variables.variables_dict[var][i].symbol: solution[var][i]}) - if expr2_to_sub: - expr2 = expr2.subs({variables.variables_dict[var][i].symbol: solution[var][i]}) + expr1, expr2 = self._constraint_check_sub_list_var( + solution, variables, expr1, expr2, var, expr1_to_sub, expr2_to_sub + ) try: return float(expr1) > float(expr2) except ValueError: return False - def _grt_constraint_check_no_sub(self, constraint: str, solution: dict[str, int]) -> bool: + @staticmethod + def _grt_constraint_check_no_sub(constraint: str, solution: dict[str, int]) -> bool: """function for checking the greater equal constraint penalty function. Keyword arguments: @@ -1520,8 +1379,8 @@ def _grt_constraint_check_no_sub(self, constraint: str, solution: dict[str, int] bool -- saying if the constraint is satisfied or not """ el = (constraint).split(">") - expr1 = expand(cast(Expr, (el[0]))).evalf() # type: ignore[no-untyped-call] - expr2 = expand(cast(Expr, (el[1]))).evalf() # type: ignore[no-untyped-call] + expr1 = expand(cast(Expr, (el[0]))).evalf() + expr2 = expand(cast(Expr, (el[1]))).evalf() expr1_to_sub = True if not str(expr1).replace(".", "").isnumeric(): symbols_in_the_expression1 = expr1.free_symbols @@ -1582,7 +1441,7 @@ def _lt_constraint( exp = PUBO() if elem[3]: ret_func = self._convert_expression_prec( - expand(cast(Expr, (el[0] + "-" + el[1]))).evalf(), # type: ignore[no-untyped-call] + expand(cast(Expr, (el[0] + "-" + el[1]))).evalf(), var.binary_variables_name_weight, var.variables_dict, ) @@ -1591,10 +1450,10 @@ def _lt_constraint( var_precision = ret_func[1] else: exp = self._convert_expression( - expand(cast(Expr, (el[0] + "-" + el[1]))).evalf(), # type: ignore[no-untyped-call] + expand(cast(Expr, (el[0] + "-" + el[1]))).evalf(), var.binary_variables_name_weight, ) - min_val, max_val, const = self._min_max_const_estimation(exp) + min_val, _max_val, const = self._min_max_const_estimation(exp) precision = 1.0 const = -const if const - min_val > 0: @@ -1607,9 +1466,8 @@ def _lt_constraint( precision = float("0." + str(const - min_val).split(".")[1]) if precision == 0.0: precision = 1 - else: - if elem[3]: - precision = min(1, var_precision) + elif elem[3]: + precision = min(1, var_precision) if precision != const - min_val: aux_var = aux.add_continuous_variable("aux" + format(j), precision, const - min_val, precision) j += 1 @@ -1622,8 +1480,8 @@ def _lt_constraint( ret = (exp) ** 2, i, j, aux else: el = str(elem[0]).split("<") - exp = expand(cast(Expr, (el[0] + "-" + el[1]))).evalf() # type: ignore[no-untyped-call] - min_val, max_val, const = self._min_max_const_estimation(exp) + exp = expand(cast(Expr, (el[0] + "-" + el[1]))).evalf() + min_val, _max_val, const = self._min_max_const_estimation(exp) const = -const if const - min_val > 0: if len(str(const - min_val).split(".")) == 2: @@ -1669,60 +1527,28 @@ def _lt_constraint_check(self, constraint: str, variables: Variables, solution: bool -- saying if the constraint is satisfied or not """ el = constraint.split("<") - expr1 = expand(cast(Expr, (el[0]))).evalf() # type: ignore[no-untyped-call] - expr2 = expand(cast(Expr, (el[1]))).evalf() # type: ignore[no-untyped-call] + expr1 = expand(cast(Expr, (el[0]))).evalf() + expr2 = expand(cast(Expr, (el[1]))).evalf() expr1_to_sub = bool(not str(expr1).replace(".", "").isnumeric()) expr2_to_sub = bool(not str(expr2).replace(".", "").isnumeric()) if expr2_to_sub or expr1_to_sub: for var in solution: if var in variables.variables_dict: if isinstance(solution[var], float): - if expr1_to_sub: - expr1 = expr1.subs({variables.variables_dict[var].symbol: solution[var]}) - if expr2_to_sub: - expr2 = expr2.subs({variables.variables_dict[var].symbol: solution[var]}) + expr1, expr2 = self._constraint_check_sub_single_var( + expr1_to_sub, expr2_to_sub, expr1, expr2, solution[var], variables.variables_dict[var] + ) elif isinstance(solution[var], list): - for i in range(len(solution[var])): - if isinstance(solution[var][i], list): - for j in range(len(solution[var][i])): - if isinstance(solution[var][i][j], list): - for k in range(len(solution[var][i][j])): - if expr1_to_sub: - expr1 = expr1.subs( - { - variables.variables_dict[var][i][j][k].symbol: solution[var][i][ - j - ][k] - } - ) - if expr2_to_sub: - expr2 = expr2.subs( - { - variables.variables_dict[var][i][j][k].symbol: solution[var][i][ - j - ][k] - } - ) - else: - if expr1_to_sub: - expr1 = expr1.subs( - {variables.variables_dict[var][i][j].symbol: solution[var][i][j]} - ) - if expr2_to_sub: - expr2 = expr2.subs( - {variables.variables_dict[var][i][j].symbol: solution[var][i][j]} - ) - else: - if expr1_to_sub: - expr1 = expr1.subs({variables.variables_dict[var][i].symbol: solution[var][i]}) - if expr2_to_sub: - expr2 = expr2.subs({variables.variables_dict[var][i].symbol: solution[var][i]}) + expr1, expr2 = self._constraint_check_sub_list_var( + solution, variables, expr1, expr2, var, expr1_to_sub, expr2_to_sub + ) try: return float(expr1) < float(expr2) except ValueError: return False - def _lt_constraint_check_no_sub(self, constraint: str, solution: dict[str, int]) -> bool: + @staticmethod + def _lt_constraint_check_no_sub(constraint: str, solution: dict[str, int]) -> bool: """function for checking the less equal constraint penalty function. Keyword arguments: @@ -1733,8 +1559,8 @@ def _lt_constraint_check_no_sub(self, constraint: str, solution: dict[str, int]) bool -- saying if the constraint is satisfied or not """ el = (constraint).split("<") - expr1 = expand(cast(Expr, (el[0]))).evalf() # type: ignore[no-untyped-call] - expr2 = expand(cast(Expr, (el[1]))).evalf() # type: ignore[no-untyped-call] + expr1 = expand(cast(Expr, (el[0]))).evalf() + expr2 = expand(cast(Expr, (el[1]))).evalf() expr1_to_sub = True if not str(expr1).replace(".", "").isnumeric(): symbols_in_the_expression1 = expr1.free_symbols @@ -1779,13 +1605,13 @@ def _eq_constraint(self, elem: tuple[str, bool, bool, bool], var: Variables) -> if elem[2]: el = str(elem[0]).split("=") exp = self._convert_expression( - expand(cast(Expr, (el[0] + "-" + el[1]))).evalf(), # type: ignore[no-untyped-call] + expand(cast(Expr, (el[0] + "-" + el[1]))).evalf(), var.binary_variables_name_weight, ) ret = (exp) ** 2 else: el = str(elem[0]).split("=") - exp = expand(cast(Expr, (el[0] + "-" + el[1]))).evalf() # type: ignore[no-untyped-call] + exp = expand(cast(Expr, (el[0] + "-" + el[1]))).evalf() hamiltonian = self._expression_to_hamiltonian( cast(Expr, exp), list(var.binary_variables_name_weight.values()) ) @@ -1804,60 +1630,28 @@ def _eq_constraint_check(self, constraint: str, variables: Variables, solution: bool -- saying if the constraint is satisfied or not """ el = constraint.split("=") - expr1 = expand(cast(Expr, (el[0]))).evalf() # type: ignore[no-untyped-call] - expr2 = expand(cast(Expr, (el[1]))).evalf() # type: ignore[no-untyped-call] + expr1 = expand(cast(Expr, (el[0]))).evalf() + expr2 = expand(cast(Expr, (el[1]))).evalf() expr1_to_sub = bool(not str(expr1).replace(".", "").isnumeric()) expr2_to_sub = bool(not str(expr2).replace(".", "").isnumeric()) if expr2_to_sub or expr1_to_sub: for var in solution: if var in variables.variables_dict: if isinstance(solution[var], float): - if expr1_to_sub: - expr1 = expr1.subs({variables.variables_dict[var].symbol: solution[var]}) - if expr2_to_sub: - expr2 = expr2.subs({variables.variables_dict[var].symbol: solution[var]}) + expr1, expr2 = self._constraint_check_sub_single_var( + expr1_to_sub, expr2_to_sub, expr1, expr2, solution[var], variables.variables_dict[var] + ) elif isinstance(solution[var], list): - for i in range(len(solution[var])): - if isinstance(solution[var][i], list): - for j in range(len(solution[var][i])): - if isinstance(solution[var][i][j], list): - for k in range(len(solution[var][i][j])): - if expr1_to_sub: - expr1 = expr1.subs( - { - variables.variables_dict[var][i][j][k].symbol: solution[var][i][ - j - ][k] - } - ) - if expr2_to_sub: - expr2 = expr2.subs( - { - variables.variables_dict[var][i][j][k].symbol: solution[var][i][ - j - ][k] - } - ) - else: - if expr1_to_sub: - expr1 = expr1.subs( - {variables.variables_dict[var][i][j].symbol: solution[var][i][j]} - ) - if expr2_to_sub: - expr2 = expr2.subs( - {variables.variables_dict[var][i][j].symbol: solution[var][i][j]} - ) - else: - if expr1_to_sub: - expr1 = expr1.subs({variables.variables_dict[var][i].symbol: solution[var][i]}) - if expr2_to_sub: - expr2 = expr2.subs({variables.variables_dict[var][i].symbol: solution[var][i]}) + expr1, expr2 = self._constraint_check_sub_list_var( + solution, variables, expr1, expr2, var, expr1_to_sub, expr2_to_sub + ) try: return float(expr1) == float(expr2) except ValueError: return False - def _eq_constraint_check_no_sub(self, constraint: str, solution: dict[str, int]) -> bool: + @staticmethod + def _eq_constraint_check_no_sub(constraint: str, solution: dict[str, int]) -> bool: """function for checking the equality constraint penalty function. Keyword arguments: @@ -1868,8 +1662,8 @@ def _eq_constraint_check_no_sub(self, constraint: str, solution: dict[str, int]) bool -- saying if the constraint is satisfied or not """ el = (constraint).split("=") - expr1 = expand(cast(Expr, (el[0]))).evalf() # type: ignore[no-untyped-call] - expr2 = expand(cast(Expr, (el[1]))).evalf() # type: ignore[no-untyped-call] + expr1 = expand(cast(Expr, (el[0]))).evalf() + expr2 = expand(cast(Expr, (el[1]))).evalf() expr1_to_sub = True if not str(expr1).replace(".", "").isnumeric(): symbols_in_the_expression1 = expr1.free_symbols @@ -1897,6 +1691,88 @@ def _eq_constraint_check_no_sub(self, constraint: str, solution: dict[str, int]) except ValueError: return False + @staticmethod + def _convert_expression_power( + powers: list[str], binary_variables_name_weight: dict[str, Any], to_add: float + ) -> float | bool: + temp = 0.0 + try: + power = int(powers[1]) + except TypeError: + print("Expression not supported\n") + return False + key = powers[0] + if key not in binary_variables_name_weight: + print("Expression not supported\n") + return False + if isinstance(binary_variables_name_weight[key], list): + encoding = binary_variables_name_weight[key][0] + if encoding == "dictionary": + for elem in binary_variables_name_weight[key]: + if not isinstance(elem, str): + t = 1.0 + t *= elem[0] + if len(elem) == 2: + t *= elem[1] ** power + elif len(elem) == 3: + t = t * elem[1] ** power + elem[2] ** power + temp += t + else: + for elem in binary_variables_name_weight[key]: + if not isinstance(elem, str): + t = 1.0 + t *= elem[0] + if len(elem) == 2: + t *= elem[1] + elif len(elem) == 3: + t = t * elem[1] + elem[2] + temp += t + temp **= power + else: + t = 1.0 + t *= binary_variables_name_weight[key][0] + if len(binary_variables_name_weight[key]) == 2: + t *= (binary_variables_name_weight[key][1]) ** power + elif len(binary_variables_name_weight[key]) == 3: + t = (t * binary_variables_name_weight[key][1] + binary_variables_name_weight[key][2]) ** power + temp += t + to_add *= temp + return to_add + + @staticmethod + def _convert_expression_no_power( + poly_field: str, binary_variables_name_weight: dict[str, Any], to_add: float + ) -> float | bool: + temp = 0.0 + key = poly_field + if key not in binary_variables_name_weight: + try: + to_add *= float(key) + except TypeError: + print("Expression not supported\n") + return False + else: + if isinstance(binary_variables_name_weight[key], list): + for elem in binary_variables_name_weight[key]: + if not isinstance(elem, str): + t = 1.0 + t *= elem[0] + if len(elem) == 2: + t *= elem[1] + elif len(elem) == 3: + t = t * elem[1] + elem[2] + temp += t + else: + t = 1.0 + t *= binary_variables_name_weight[key][0] + if len(binary_variables_name_weight[key]) == 2: + t *= binary_variables_name_weight[key][1] + elif len(binary_variables_name_weight[key]) == 3: + t = t * binary_variables_name_weight[key][1] + binary_variables_name_weight[key][2] + temp += t + to_add *= temp + return to_add + def _convert_expression(self, expr: Expr, binary_variables_name_weight: dict[str, Any]) -> PUBO | bool: """function for translating an expression in the problem variable @@ -1911,84 +1787,19 @@ def _convert_expression(self, expr: Expr, binary_variables_name_weight: dict[str func = PUBO() sign = "+" for field in fields: - if field != "+" and field != "-": + if field not in {"+", "-"}: poly_fields = field.split("*") to_add = 1.0 for poly_field in poly_fields: powers = poly_field.split("^") - temp = 0.0 if len(powers) == 2: - try: - power = int(powers[1]) - except TypeError: - print("Expression not supported\n") - return False - key = powers[0] - if key not in binary_variables_name_weight: - print("Expression not supported\n") - return False - if isinstance(binary_variables_name_weight[key], list): - encoding = binary_variables_name_weight[key][0] - if encoding == "dictionary": - for elem in binary_variables_name_weight[key]: - if not isinstance(elem, str): - t = 1.0 - t *= elem[0] - if len(elem) == 2: - t *= elem[1] ** power - elif len(elem) == 3: - t = t * elem[1] ** power + elem[2] ** power - temp += t - else: - for elem in binary_variables_name_weight[key]: - if not isinstance(elem, str): - t = 1.0 - t *= elem[0] - if len(elem) == 2: - t *= elem[1] - elif len(elem) == 3: - t = t * elem[1] + elem[2] - temp += t - temp = temp**power - else: - t = 1.0 - t *= binary_variables_name_weight[key][0] - if len(binary_variables_name_weight[key]) == 2: - t *= (binary_variables_name_weight[key][1]) ** power - elif len(binary_variables_name_weight[key]) == 3: - t = ( - t * binary_variables_name_weight[key][1] + binary_variables_name_weight[key][2] - ) ** power - temp += t - to_add *= temp + ret = self._convert_expression_power(powers, binary_variables_name_weight, to_add) else: - key = poly_field - if key not in binary_variables_name_weight: - try: - to_add *= float(key) - except TypeError: - print("Expression not supported\n") - return False - else: - if isinstance(binary_variables_name_weight[key], list): - for elem in binary_variables_name_weight[key]: - if not isinstance(elem, str): - t = 1.0 - t *= elem[0] - if len(elem) == 2: - t *= elem[1] - elif len(elem) == 3: - t = t * elem[1] + elem[2] - temp += t - else: - t = 1.0 - t *= binary_variables_name_weight[key][0] - if len(binary_variables_name_weight[key]) == 2: - t *= binary_variables_name_weight[key][1] - elif len(binary_variables_name_weight[key]) == 3: - t = t * binary_variables_name_weight[key][1] + binary_variables_name_weight[key][2] - temp += t - to_add *= temp + ret = self._convert_expression_no_power(poly_field, binary_variables_name_weight, to_add) + + if isinstance(ret, bool): + return False + to_add = ret if sign == "+": func += to_add @@ -1998,6 +1809,167 @@ def _convert_expression(self, expr: Expr, binary_variables_name_weight: dict[str sign = field return func + @staticmethod + def _convert_expression_prec_power( + powers: list[str], + binary_variables_name_weight: dict[str, Any], + variables_dict: dict[str, Any], + to_add: float, + min_precision: float, + ) -> tuple[float, float] | bool: + temp = 0.0 + try: + power = int(powers[1]) + except TypeError: + print("Expression not supported\n") + return False + key = powers[0] + if key not in binary_variables_name_weight: + print("Expression not supported\n") + return False + if isinstance(binary_variables_name_weight[key], list): + encoding = binary_variables_name_weight[key][0] + if encoding == "dictionary": + for elem in binary_variables_name_weight[key]: + if not isinstance(elem, str): + t = 1.0 + t *= elem[0] + if len(elem) == 2: + t *= elem[1] ** power + elif len(elem) == 3: + t = t * elem[1] ** power + elem[2] ** power + temp += t + else: + for elem in binary_variables_name_weight[key]: + if not isinstance(elem, str): + t = 1.0 + t *= elem[0] + if len(elem) == 2: + t *= elem[1] + elif len(elem) == 3: + t = t * elem[1] + elem[2] + temp += t + temp **= power + else: + t = 1.0 + t *= binary_variables_name_weight[key][0] + if len(binary_variables_name_weight[key]) == 2: + t *= (binary_variables_name_weight[key][1]) ** power + elif len(binary_variables_name_weight[key]) == 3: + t = (t * binary_variables_name_weight[key][1] + binary_variables_name_weight[key][2]) ** power + temp += t + to_add *= temp + name = key.split("_") + if len(name) == 1: + if variables_dict[name[0]].type == "c" and min_precision > variables_dict[name[0]].precision: + min_precision = variables_dict[name[0]].precision + elif ( + len(name) == 2 + and name[1].isnumeric() + and name[0] in variables_dict + and variables_dict[name[0]][int(name[1])].type == "c" + ): + min_precision = min(min_precision, variables_dict[name[0]][int(name[1])].precision) + elif ( + len(name) == 3 + and name[1].isnumeric() + and name[2].isnumeric() + and name[0] in variables_dict + and variables_dict[name[0]][int(name[1])][int(name[2])].type == "c" + ): + min_precision = min(min_precision, variables_dict[name[0]][int(name[1])][int(name[2])].precision) + elif ( + len(name) == 4 + and name[1].isnumeric() + and name[2].isnumeric() + and name[3].isnumeric() + and name[0] in variables_dict + and variables_dict[name[0]][int(name[1])][int(name[2])][int(name[3])].type == "c" + and min_precision > variables_dict[name[0]][int(name[1])][int(name[2])][int(name[3])].precision + ): + min_precision = variables_dict[name[0]][int(name[1])][int(name[2])][int(name[3])].precision + elif ( + name is variables_dict.keys() + and variables_dict[name[0]].type == "c" + and min_precision > variables_dict[name[0]].precision + ): + min_precision = variables_dict[name[0]].precision + + return to_add, min_precision + + @staticmethod + def _convert_expression_prec_no_power( + poly_field: str, + binary_variables_name_weight: dict[str, Any], + variables_dict: dict[str, Any], + to_add: float, + min_precision: float, + ) -> tuple[float, float] | bool: + temp = 0.0 + key = poly_field + if key not in binary_variables_name_weight: + try: + to_add *= float(key) + except ValueError: + print("Expression not supported\n") + return False + else: + if isinstance(binary_variables_name_weight[key], list): + for elem in binary_variables_name_weight[key]: + if not isinstance(elem, str): + t = 1.0 + t *= elem[0] + if len(elem) == 2: + t *= elem[1] + elif len(elem) == 3: + t = t * elem[1] + elem[2] + temp += t + else: + t = 1.0 + t *= binary_variables_name_weight[key][0] + if len(binary_variables_name_weight[key]) == 2: + t *= binary_variables_name_weight[key][1] + elif len(binary_variables_name_weight[key]) == 3: + t = t * binary_variables_name_weight[key][1] + binary_variables_name_weight[key][2] + temp += t + to_add *= temp + name = key.split("_") + if len(name) == 1 and variables_dict[name[0]].type == "c": + min_precision = min(min_precision, variables_dict[name[0]].precision) + elif ( + len(name) == 2 + and name[1].isnumeric() + and name[0] in variables_dict + and variables_dict[name[0]][int(name[1])].type == "c" + and min_precision > variables_dict[name[0]][int(name[1])].precision + ): + min_precision = variables_dict[name[0]][int(name[1])].precision + elif len(name) == 3 and name[1].isnumeric() and name[2].isnumeric() and name[0] in variables_dict: + if ( + variables_dict[name[0]][int(name[1])][int(name[2])].type == "c" + and min_precision > variables_dict[name[0]][int(name[1])][int(name[2])].precision + ): + min_precision = variables_dict[name[0]][int(name[1])][int(name[2])].precision + elif ( + len(name) == 4 + and name[1].isnumeric() + and name[2].isnumeric() + and name[3].isnumeric() + and name[0] in variables_dict + and variables_dict[name[0]][int(name[1])][int(name[2])][int(name[3])].type == "c" + ): + min_precision = min( + min_precision, + variables_dict[name[0]][int(name[1])][int(name[2])][int(name[3])].precision, + ) + elif ( + name is variables_dict.keys() + and variables_dict[name[0]].type == "c" + and min_precision > variables_dict[name[0]].precision + ): + min_precision = variables_dict[name[0]].precision + return to_add, min_precision + def _convert_expression_prec( self, expr: Expr, binary_variables_name_weight: dict[str, Any], variables_dict: dict[str, Any] ) -> tuple[PUBO, float] | bool: @@ -2013,172 +1985,26 @@ def _convert_expression_prec( fields = str(expr).replace("**", "^").split(" ") func = PUBO() sign = "+" - min_precision = 1 + min_precision = 1.0 for field in fields: - if field != "+" and field != "-": + if field not in {"+", "-"}: poly_fields = field.split("*") to_add = 1.0 for poly_field in poly_fields: powers = poly_field.split("^") - temp = 0.0 + if len(powers) == 2: - try: - power = int(powers[1]) - except TypeError: - print("Expression not supported\n") - return False - key = powers[0] - if key not in binary_variables_name_weight: - print("Expression not supported\n") - return False - if isinstance(binary_variables_name_weight[key], list): - encoding = binary_variables_name_weight[key][0] - if encoding == "dictionary": - for elem in binary_variables_name_weight[key]: - if not isinstance(elem, str): - t = 1.0 - t *= elem[0] - if len(elem) == 2: - t *= elem[1] ** power - elif len(elem) == 3: - t = t * elem[1] ** power + elem[2] ** power - temp += t - else: - for elem in binary_variables_name_weight[key]: - if not isinstance(elem, str): - t = 1.0 - t *= elem[0] - if len(elem) == 2: - t *= elem[1] - elif len(elem) == 3: - t = t * elem[1] + elem[2] - temp += t - temp = temp**power - else: - t = 1.0 - t *= binary_variables_name_weight[key][0] - if len(binary_variables_name_weight[key]) == 2: - t *= (binary_variables_name_weight[key][1]) ** power - elif len(binary_variables_name_weight[key]) == 3: - t = ( - t * binary_variables_name_weight[key][1] + binary_variables_name_weight[key][2] - ) ** power - temp += t - to_add *= temp - name = key.split("_") - if len(name) == 1: - if ( - variables_dict[name[0]].type == "c" - and min_precision > variables_dict[name[0]].precision - ): - min_precision = variables_dict[name[0]].precision - elif ( - len(name) == 2 - and name[1].isnumeric() - and name[0] in variables_dict - and variables_dict[name[0]][int(name[1])].type == "c" - ): - if min_precision > variables_dict[name[0]][int(name[1])].precision: - min_precision = variables_dict[name[0]][int(name[1])].precision - elif ( - len(name) == 3 - and name[1].isnumeric() - and name[2].isnumeric() - and name[0] in variables_dict - and variables_dict[name[0]][int(name[1])][int(name[2])].type == "c" - ): - if min_precision > variables_dict[name[0]][int(name[1])][int(name[2])].precision: - min_precision = variables_dict[name[0]][int(name[1])][int(name[2])].precision - elif ( - len(name) == 4 - and name[1].isnumeric() - and name[2].isnumeric() - and name[3].isnumeric() - and name[0] in variables_dict - and variables_dict[name[0]][int(name[1])][int(name[2])][int(name[3])].type == "c" - and min_precision - > variables_dict[name[0]][int(name[1])][int(name[2])][int(name[3])].precision - ): - min_precision = variables_dict[name[0]][int(name[1])][int(name[2])][int(name[3])].precision - elif ( - name is variables_dict.keys() - and variables_dict[name[0]].type == "c" - and min_precision > variables_dict[name[0]].precision - ): - min_precision = variables_dict[name[0]].precision + ret = self._convert_expression_prec_power( + powers, binary_variables_name_weight, variables_dict, to_add, min_precision + ) else: - key = poly_field - if key not in binary_variables_name_weight: - try: - to_add *= float(key) - except ValueError: - print("Expression not supported\n") - return False - else: - if isinstance(binary_variables_name_weight[key], list): - for elem in binary_variables_name_weight[key]: - if not isinstance(elem, str): - t = 1.0 - t *= elem[0] - if len(elem) == 2: - t *= elem[1] - elif len(elem) == 3: - t = t * elem[1] + elem[2] - temp += t - else: - t = 1.0 - t *= binary_variables_name_weight[key][0] - if len(binary_variables_name_weight[key]) == 2: - t *= binary_variables_name_weight[key][1] - elif len(binary_variables_name_weight[key]) == 3: - t = t * binary_variables_name_weight[key][1] + binary_variables_name_weight[key][2] - temp += t - to_add *= temp - name = key.split("_") - if len(name) == 1 and variables_dict[name[0]].type == "c": - if min_precision > variables_dict[name[0]].precision: - min_precision = variables_dict[name[0]].precision - elif ( - len(name) == 2 - and name[1].isnumeric() - and name[0] in variables_dict - and variables_dict[name[0]][int(name[1])].type == "c" - and min_precision > variables_dict[name[0]][int(name[1])].precision - ): - min_precision = variables_dict[name[0]][int(name[1])].precision - elif ( - len(name) == 3 - and name[1].isnumeric() - and name[2].isnumeric() - and name[0] in variables_dict - ): - if ( - variables_dict[name[0]][int(name[1])][int(name[2])].type == "c" - and min_precision > variables_dict[name[0]][int(name[1])][int(name[2])].precision - ): - min_precision = variables_dict[name[0]][int(name[1])][int(name[2])].precision - elif ( - len(name) == 4 - and name[1].isnumeric() - and name[2].isnumeric() - and name[3].isnumeric() - and name[0] in variables_dict - and variables_dict[name[0]][int(name[1])][int(name[2])][int(name[3])].type == "c" - ): - if ( - min_precision - > variables_dict[name[0]][int(name[1])][int(name[2])][int(name[3])].precision - ): - min_precision = variables_dict[name[0]][int(name[1])][int(name[2])][ - int(name[3]) - ].precision - else: - if ( - name is variables_dict.keys() - and variables_dict[name[0]].type == "c" - and min_precision > variables_dict[name[0]].precision - ): - min_precision = variables_dict[name[0]].precision + ret = self._convert_expression_prec_no_power( + poly_field, binary_variables_name_weight, variables_dict, to_add, min_precision + ) + if isinstance(ret, bool): + return ret + to_add = ret[0] + min_precision = ret[1] if sign == "+": func += to_add @@ -2188,7 +2014,8 @@ def _convert_expression_prec( sign = field return func, min_precision - def _convert_expression_logic(self, expr: Expr, binary_variables_name_weight: dict[str, Any]) -> boolean_var | bool: + @staticmethod + def _convert_expression_logic(expr: Expr, binary_variables_name_weight: dict[str, Any]) -> boolean_var | bool: """function for translating an expression in the problem variable in case of logic constraints Keyword arguments: @@ -2211,7 +2038,8 @@ def _convert_expression_logic(self, expr: Expr, binary_variables_name_weight: di ret = binary_variables_name_weight[key][0] return ret - def _min_max_const_estimation(self, exp: PUBO) -> tuple[float, float, float]: + @staticmethod + def _min_max_const_estimation(exp: PUBO) -> tuple[float, float, float]: """function for estimating minimum and maximum value and the constraint value Keyword arguments: @@ -2234,6 +2062,52 @@ def _min_max_const_estimation(self, exp: PUBO) -> tuple[float, float, float]: min_val += exp[key] return min_val, max_val, const + @staticmethod + def _expression_to_hamiltonian_power( + powers: list[str], binary_variables_name_weight_val: list[Any], to_add: float + ) -> float | bool: + try: + power = int(powers[1]) + except TypeError: + print("Expression not supported\n") + return False + key = powers[0] + for elm in binary_variables_name_weight_val: + if isinstance(elm, list): + for el in elm: + if not isinstance(el, str) and key == (next(iter(el[0].variables))): + to_add *= el[0] ** power + break + elif not isinstance(elm, str) and key == next(iter(elm[0].variables)): + to_add *= elm[0] ** power + break + return to_add + + @staticmethod + def _expression_to_hamiltonian_no_power( + poly_field: str, binary_variables_name_weight_val: list[Any], to_add: float + ) -> float: + key = poly_field + is_float = False + try: + temp = float(key) + except ValueError: + pass + else: + to_add *= temp + is_float = True + + if not is_float: + for elm in binary_variables_name_weight_val: + if isinstance(elm, list): + for el in elm: + if not isinstance(el, str) and key == next(iter(el[0].variables)): + to_add *= el[0] + elif not isinstance(elm, str) and key == next(iter(elm[0].variables)): + to_add *= elm[0] + + return to_add + def _expression_to_hamiltonian(self, exp: Expr, binary_variables_name_weight_val: list[Any]) -> PUBO: """function for translating an expression in the problem variable into an Hamiltonian when is directly written with the inside binary variables @@ -2248,46 +2122,20 @@ def _expression_to_hamiltonian(self, exp: Expr, binary_variables_name_weight_val hamiltonian = PUBO() sign = "+" for field in fields: - if field != "+" and field != "-": + if field not in {"+", "-"}: poly_fields = field.split("*") to_add = 1.0 for poly_field in poly_fields: powers = poly_field.split("^") if len(powers) == 2: - try: - power = int(powers[1]) - except TypeError: - print("Expression not supported\n") - return False - key = powers[0] - for elm in binary_variables_name_weight_val: - if isinstance(elm, list): - for el in elm: - if not isinstance(el, str) and key == (next(iter(el[0].variables))): - to_add *= el[0] ** power - break - elif not isinstance(elm, str) and key == next(iter(elm[0].variables)): - to_add *= elm[0] ** power - break + t = self._expression_to_hamiltonian_power(powers, binary_variables_name_weight_val, to_add) + if not isinstance(t, bool): + to_add = t else: - key = poly_field - is_float = False - try: - temp = float(key) - except ValueError: - pass - else: - to_add *= temp - is_float = True - - if not is_float: - for elm in binary_variables_name_weight_val: - if isinstance(elm, list): - for el in elm: - if not isinstance(el, str) and key == next(iter(el[0].variables)): - to_add *= el[0] - elif not isinstance(elm, str) and key == next(iter(elm[0].variables)): - to_add *= elm[0] + to_add = self._expression_to_hamiltonian_no_power( + poly_field, binary_variables_name_weight_val, to_add + ) + if sign == "+": hamiltonian += to_add else: diff --git a/src/mqt/qao/objectivefunction.py b/src/mqt/qao/objectivefunction.py index dcac1e9..f064fe0 100644 --- a/src/mqt/qao/objectivefunction.py +++ b/src/mqt/qao/objectivefunction.py @@ -8,7 +8,7 @@ if TYPE_CHECKING: from qubovert import PUBO - from mqt.qao.variables import Variables + from .variables import Variables class ObjectiveFunction: @@ -32,7 +32,113 @@ def add_objective_function(self, objective_function: Expr, minimization: bool = """ if not minimization: objective_function = -objective_function - self.objective_functions.append((cast(Expr, expand(objective_function).evalf()), weight)) # type: ignore[no-untyped-call] + self.objective_functions.append((cast(Expr, expand(objective_function).evalf()), weight)) + + @staticmethod + def rewrite_powers(powers: list[str], var: Variables, to_add: float) -> float | bool: + temp = 0.0 + try: + power = int(powers[1]) + except TypeError: + print("Expression not supported\n") + return False + key = powers[0] + if key not in var.binary_variables_name_weight: + print("Expression not supported\n") + return False + if isinstance(var.binary_variables_name_weight[key], list): + encoding = var.binary_variables_name_weight[key][0] + if encoding == "dictionary": + for elem in var.binary_variables_name_weight[key]: + if not isinstance(elem, str): + t = 1.0 + t *= elem[0] + if len(elem) == 2: + t *= elem[1] ** power + elif len(elem) == 3: + t = t * elem[1] ** power + elem[2] ** power + temp += t + else: + for elem in var.binary_variables_name_weight[key]: + if not isinstance(elem, str): + t = 1.0 + t *= elem[0] + if len(elem) == 2: + t *= elem[1] + elif len(elem) == 3: + t = t * elem[1] + elem[2] + temp += t + temp **= power + elif isinstance(var.binary_variables_name_weight[key], tuple): + t = 1.0 + t *= var.binary_variables_name_weight[key][0] + if len(var.binary_variables_name_weight[key]) == 2: + t *= (var.binary_variables_name_weight[key][1]) ** power + elif len(var.binary_variables_name_weight[key]) == 3: + t = (t * var.binary_variables_name_weight[key][1] + var.binary_variables_name_weight[key][2]) ** power + temp += t + else: + temp = var.binary_variables_name_weight[key] + to_add *= temp + + return to_add + + @staticmethod + def rewrite_no_power(poly_field: str, var: Variables, to_add: float) -> float | bool: + temp = 0.0 + key = poly_field + if key not in var.binary_variables_name_weight: + try: + to_add *= float(key) + except TypeError: + print("Expression not supported\n") + return False + else: + if isinstance(var.binary_variables_name_weight[key], list): + for elem in var.binary_variables_name_weight[key]: + if not isinstance(elem, str): + t = 1.0 + t *= elem[0] + if len(elem) == 2: + t *= elem[1] + elif len(elem) == 3: + t = t * elem[1] + elem[2] + temp += t + elif isinstance(var.binary_variables_name_weight[key], tuple): + t = 1.0 + t *= var.binary_variables_name_weight[key][0] + if len(var.binary_variables_name_weight[key]) == 2: + t *= var.binary_variables_name_weight[key][1] + elif len(var.binary_variables_name_weight[key]) == 3: + t = t * var.binary_variables_name_weight[key][1] + var.binary_variables_name_weight[key][2] + temp += t + else: + temp += var.binary_variables_name_weight[key] + to_add *= temp + return to_add + + def rewrite_elem(self, field: str, var: Variables, func: float, sign: str) -> float | bool: + poly_fields = field.split("*") + to_add = 1.0 + for poly_field in poly_fields: + powers = poly_field.split("^") + + if len(powers) == 2: + t = self.rewrite_powers(powers, var, to_add) + if isinstance(t, bool): + return False + to_add = t + else: + t = self.rewrite_no_power(poly_field, var, to_add) + if isinstance(t, bool): + return False + to_add = t + if sign == "+": + func += to_add + else: + func -= to_add + + return func def rewrite_cost_functions(self, pubo: PUBO, var: Variables) -> PUBO | bool: """function for rewriting the cost functions according with the variable structure @@ -53,102 +159,41 @@ def rewrite_cost_functions(self, pubo: PUBO, var: Variables) -> PUBO | bool: func = 0.0 sign = "+" for field in fields: - if field != "+" and field != "-": - poly_fields = field.split("*") - to_add = 1.0 - for poly_field in poly_fields: - powers = poly_field.split("^") - temp = 0.0 - if len(powers) == 2: - try: - power = int(powers[1]) - except TypeError: - print("Expression not supported\n") - return False - key = powers[0] - if key not in var.binary_variables_name_weight: - print("Expression not supported\n") - return False - if isinstance(var.binary_variables_name_weight[key], list): - encoding = var.binary_variables_name_weight[key][0] - if encoding == "dictionary": - for elem in var.binary_variables_name_weight[key]: - if not isinstance(elem, str): - t = 1.0 - t *= elem[0] - if len(elem) == 2: - t *= elem[1] ** power - elif len(elem) == 3: - t = t * elem[1] ** power + elem[2] ** power - temp += t - else: - for elem in var.binary_variables_name_weight[key]: - if not isinstance(elem, str): - t = 1.0 - t *= elem[0] - if len(elem) == 2: - t *= elem[1] - elif len(elem) == 3: - t = t * elem[1] + elem[2] - temp += t - temp = temp**power - elif isinstance(var.binary_variables_name_weight[key], tuple): - t = 1.0 - t *= var.binary_variables_name_weight[key][0] - if len(var.binary_variables_name_weight[key]) == 2: - t *= (var.binary_variables_name_weight[key][1]) ** power - elif len(var.binary_variables_name_weight[key]) == 3: - t = ( - t * var.binary_variables_name_weight[key][1] - + var.binary_variables_name_weight[key][2] - ) ** power - temp += t - else: - temp = var.binary_variables_name_weight[key] - to_add *= temp - else: - key = poly_field - if key not in var.binary_variables_name_weight: - try: - to_add *= float(key) - except TypeError: - print("Expression not supported\n") - return False - else: - if isinstance(var.binary_variables_name_weight[key], list): - for elem in var.binary_variables_name_weight[key]: - if not isinstance(elem, str): - t = 1.0 - t *= elem[0] - if len(elem) == 2: - t *= elem[1] - elif len(elem) == 3: - t = t * elem[1] + elem[2] - temp += t - elif isinstance(var.binary_variables_name_weight[key], tuple): - t = 1.0 - t *= var.binary_variables_name_weight[key][0] - if len(var.binary_variables_name_weight[key]) == 2: - t *= var.binary_variables_name_weight[key][1] - elif len(var.binary_variables_name_weight[key]) == 3: - t = ( - t * var.binary_variables_name_weight[key][1] - + var.binary_variables_name_weight[key][2] - ) - temp += t - else: - temp += var.binary_variables_name_weight[key] - to_add *= temp - - if sign == "+": - func += to_add - else: - func -= to_add + if field not in {"+", "-"}: + t = self.rewrite_elem(field, var, func, sign) + if isinstance(t, bool): + return False + func = t else: sign = field pubo += func * obj[1] return pubo + @staticmethod + def var_list_substitution(var: str, solution: dict[str, Any], variables: Variables, temp_expression: Expr) -> Expr: + for i in range(len(solution[var])): + if isinstance(solution[var][i], list): + for j in range(len(solution[var][i])): + if isinstance(solution[var][i][j], list): + for k in range(len(solution[var][i][j])): + temp_expression = temp_expression.subs({ + variables.variables_dict[var][i][j][k].symbol: solution[var][i][j][k] + }) + else: + temp_expression = temp_expression.subs({ + variables.variables_dict[var][i][j].symbol: solution[var][i][j] + }) + else: + temp_expression = temp_expression.subs({variables.variables_dict[var][i].symbol: solution[var][i]}) + return temp_expression + + def var_substitution(self, var: str, solution: dict[str, Any], variables: Variables, temp_expression: Expr) -> Expr: + if isinstance(solution[var], float): + temp_expression = temp_expression.subs({variables.variables_dict[var].symbol: solution[var]}) + elif isinstance(solution[var], list): + temp_expression = self.var_list_substitution(var, solution, variables, temp_expression) + return temp_expression + def substitute_values(self, solution: dict[str, Any], variables: Variables) -> dict[str, float] | bool: """function for substituting solutions into the cost functions expressions @@ -166,25 +211,7 @@ def substitute_values(self, solution: dict[str, Any], variables: Variables) -> d temp_expression = obj[0] for var in solution: if var in variables.variables_dict: - if isinstance(solution[var], float): - temp_expression = temp_expression.subs({variables.variables_dict[var].symbol: solution[var]}) # type: ignore[no-untyped-call] - elif isinstance(solution[var], list): - for i in range(len(solution[var])): - if isinstance(solution[var][i], list): - for j in range(len(solution[var][i])): - if isinstance(solution[var][i][j], list): - for k in range(len(solution[var][i][j])): - temp_expression = temp_expression.subs( # type: ignore[no-untyped-call] - {variables.variables_dict[var][i][j][k].symbol: solution[var][i][j][k]} - ) - else: - temp_expression = temp_expression.subs( # type: ignore[no-untyped-call] - {variables.variables_dict[var][i][j].symbol: solution[var][i][j]} - ) - else: - temp_expression = temp_expression.subs( # type: ignore[no-untyped-call] - {variables.variables_dict[var][i].symbol: solution[var][i]} - ) + temp_expression = self.var_substitution(var, solution, variables, temp_expression) try: objective_functions_values[str(obj[0])] = float(temp_expression) except ValueError: diff --git a/src/mqt/qao/problem.py b/src/mqt/qao/problem.py index ca99306..33f77d7 100644 --- a/src/mqt/qao/problem.py +++ b/src/mqt/qao/problem.py @@ -7,7 +7,9 @@ import numpy as np from qubovert import PUBO -from mqt.qao import Constraints, ObjectiveFunction, Variables +from .constraints import Constraints +from .objectivefunction import ObjectiveFunction +from .variables import Variables class Problem: @@ -149,7 +151,8 @@ def update_lambda_cost_function( return self.pubo - def _upper_bound_with_only_positive_coefficient(self, cost_function: PUBO) -> float | bool: + @staticmethod + def _upper_bound_with_only_positive_coefficient(cost_function: PUBO) -> float | bool: """function for estimating the weights for constraints Keyword arguments: @@ -172,7 +175,8 @@ def _upper_bound_with_only_positive_coefficient(self, cost_function: PUBO) -> fl upperbound += cost_function[key] return upperbound - def _maximum_qubo_coefficient(self, cost_function: PUBO) -> float: + @staticmethod + def _maximum_qubo_coefficient(cost_function: PUBO) -> float: """function for estimating the weights for constraints Keyword arguments: @@ -196,7 +200,8 @@ def _maximum_qubo_coefficient(self, cost_function: PUBO) -> float: offset = cost_function[key] return max_coeff + offset - def _vlm(self, cost_function: PUBO) -> float: + @staticmethod + def _vlm(cost_function: PUBO) -> float: """function for estimating the weights for constraints Keyword arguments: @@ -224,7 +229,8 @@ def _vlm(self, cost_function: PUBO) -> float: n_sum[elem] -= cost_function[key] return float(np.max([np.array(list(p_sum.values())), np.array(list(n_sum.values()))])) - def _momc(self, cost_function: PUBO, constraint_function: PUBO) -> float: + @staticmethod + def _momc(cost_function: PUBO, constraint_function: PUBO) -> float: """function for estimating the weights for constraints Keyword arguments: @@ -273,7 +279,8 @@ def _momc(self, cost_function: PUBO, constraint_function: PUBO) -> float: return wc_max return max(1.0, wc_max / wg_min) - def _moc(self, cost_function: PUBO, constraint_function: PUBO) -> float: + @staticmethod + def _moc(cost_function: PUBO, constraint_function: PUBO) -> float: """function for estimating the weights for constraints Keyword arguments: @@ -337,7 +344,8 @@ def _moc(self, cost_function: PUBO, constraint_function: PUBO) -> float: val = v return max(1, val) - def upper_lower_bound_naive_method(self, cost_function: PUBO) -> float: + @staticmethod + def upper_lower_bound_naive_method(cost_function: PUBO) -> float: """function for estimating the weights for constraints Keyword arguments: @@ -357,7 +365,8 @@ def upper_lower_bound_naive_method(self, cost_function: PUBO) -> float: lower_bound += cost_function[key] return upper_bound - lower_bound - def upper_lower_bound_posiform_and_negaform_method(self, cost_function: PUBO) -> float: + @staticmethod + def upper_lower_bound_posiform_and_negaform_method(cost_function: PUBO) -> float: """function for estimating the weights for constraints Keyword arguments: @@ -392,7 +401,8 @@ def upper_lower_bound_posiform_and_negaform_method(self, cost_function: PUBO) -> upperbound += n_sum[key] return upperbound - lowerbound - def _sequential_penalty_increase(self, current_lambda: float) -> float: + @staticmethod + def _sequential_penalty_increase(current_lambda: float) -> float: """function for updating weights for constraints Keyword arguments: @@ -403,7 +413,8 @@ def _sequential_penalty_increase(self, current_lambda: float) -> float: """ return current_lambda * 10 - def _scaled_sequential_penalty_increase(self, current_lambda: float, wu: float, t: int) -> float: + @staticmethod + def _scaled_sequential_penalty_increase(current_lambda: float, wu: float, t: int) -> float: """function for updating weights for constraints Keyword arguments: @@ -417,7 +428,8 @@ def _scaled_sequential_penalty_increase(self, current_lambda: float, wu: float, scale_factor = wu ** (1 / t) return float(round(current_lambda * scale_factor)) - def _binary_search_penalty_algorithm(self, current_lambda: float, wu: float) -> float: + @staticmethod + def _binary_search_penalty_algorithm(current_lambda: float, wu: float) -> float: """function for updating weights for constraints Keyword arguments: diff --git a/src/mqt/qao/solvers.py b/src/mqt/qao/solvers.py index d9f20c9..c9eddca 100644 --- a/src/mqt/qao/solvers.py +++ b/src/mqt/qao/solvers.py @@ -3,7 +3,7 @@ import json import logging -from math import ceil, log, sqrt +from math import ceil, log, log2, sqrt from pathlib import Path from time import time_ns from typing import TYPE_CHECKING, Any @@ -14,34 +14,28 @@ from dwave.samplers import SimulatedAnnealingSampler from dwave.system import DWaveSampler, EmbeddingComposite from matplotlib import rc -from qiskit.algorithms import QAOA, VQE -from qiskit.circuit import QuantumCircuit, Parameter +from qiskit.circuit import Parameter, QuantumCircuit from qiskit.circuit.library import TwoLocal -from qiskit.exceptions import QiskitError +from qiskit.primitives import Sampler +from qiskit_algorithms import QAOA, SamplingVQE +from qiskit_algorithms.optimizers import COBYLA from qiskit_optimization.algorithms import ( GroverOptimizer, - MinimumEigenOptimizationResult, MinimumEigenOptimizer, - OptimizationResult, + SolutionSample, ) -from qiskit_ibm_runtime import QiskitRuntimeService # type: ignore[import-untyped] from qiskit_optimization.translators import from_docplex_mp -from qiskit.providers.basicaer import BasicAer from qubovert import PUBO, QUBO if TYPE_CHECKING: from collections.abc import Callable + from dimod import SampleSet - from qiskit.algorithms.optimizers import Optimizer - from qiskit.opflow import ( - ExpectationBase, - GradientBase, - OperatorBase, - ) + from qiskit_algorithms.optimizers import Optimizer from qiskit_optimization.problems import QuadraticProgram -from mqt.qao.problem import Problem +from .problem import Problem class Solver: @@ -384,11 +378,6 @@ def solve_grover_adaptive_search_qubo( self, problem: Problem, auto_setting: bool = False, - simulator: bool = True, - backend_name: str = "qasm_simulator", - channel: str = "", - token: str = "", - instance: str = "", qubit_values: int = 0, coeff_precision: float = 1.0, threshold: int = 10, @@ -448,43 +437,13 @@ def solve_grover_adaptive_search_qubo( if auto_setting: # To change with the experience # num_runs = 100 threshold = 2 * len(self.qubo.variables) - qubit_values = ceil( - log( - abs(self.problem.upper_lower_bound_posiform_and_negaform_method(scaled_qubo)), - 2, - ) - ) - else: - if boundaries_estimation_method == "upper lower bound posiform and negaform method": - qubit_values = ceil( - log( - abs(self.problem.upper_lower_bound_posiform_and_negaform_method(scaled_qubo)), - 2, - ) - ) - elif boundaries_estimation_method == "naive": - qubit_values = ceil( - log( - abs(self.problem.upper_lower_bound_naive_method(scaled_qubo)), - 2, - ) - ) + qubit_values = ceil(log2(abs(self.problem.upper_lower_bound_posiform_and_negaform_method(scaled_qubo)))) + elif boundaries_estimation_method == "upper lower bound posiform and negaform method": + qubit_values = ceil(log2(abs(self.problem.upper_lower_bound_posiform_and_negaform_method(scaled_qubo)))) + elif boundaries_estimation_method == "naive": + qubit_values = ceil(log2(abs(self.problem.upper_lower_bound_naive_method(scaled_qubo)))) - if simulator: - try: # Load your IBM Quantum account - QiskitRuntimeService.save_account(channel=channel, token=token, instance=instance, overwrite=True) - backend = QiskitRuntimeService().backend(backend_name) - except QiskitError: - print("The chosen simulator doesn't exist or the IBM cannot be used. Qasm simulator will used.") - backend = BasicAer.get_backend("qasm_simulator") - else: - try: - QiskitRuntimeService.save_account(channel=channel, token=token, instance=instance, overwrite=True) - backend = QiskitRuntimeService().backend(backend_name) - except QiskitError: - print("The chosen backend doesn't exist or the IBM cannot be used. Qasm simulator will used.") - backend = BasicAer.get_backend("qasm_simulator") - grover_optimizer = GroverOptimizer(qubit_values, num_iterations=threshold, quantum_instance=backend) + grover_optimizer = GroverOptimizer(qubit_values, num_iterations=threshold, sampler=Sampler()) if save_time: start = time_ns() @@ -523,30 +482,14 @@ def solve_grover_adaptive_search_qubo( scaled_qubo = round(scaled_qubo_c / min_coeff) qp = self._from_qubovert_to_qiskit_model(scaled_qubo) - if auto_setting: + if auto_setting or boundaries_estimation_method == "upper lower bound posiform and negaform method": qubit_values = ceil( - log( - abs(self.problem.upper_lower_bound_posiform_and_negaform_method(scaled_qubo)), - 2, - ) + log2(abs(self.problem.upper_lower_bound_posiform_and_negaform_method(scaled_qubo))) ) - else: - if boundaries_estimation_method == "upper lower bound posiform and negaform method": - qubit_values = ceil( - log( - abs(self.problem.upper_lower_bound_posiform_and_negaform_method(scaled_qubo)), - 2, - ) - ) - elif boundaries_estimation_method == "naive": - qubit_values = ceil( - log( - abs(self.problem.upper_lower_bound_naive_method(scaled_qubo)), - 2, - ) - ) - - grover_optimizer = GroverOptimizer(qubit_values, num_iterations=threshold, quantum_instance=backend) + elif boundaries_estimation_method == "naive": + qubit_values = ceil(log2(abs(self.problem.upper_lower_bound_naive_method(scaled_qubo)))) + + grover_optimizer = GroverOptimizer(qubit_values, num_iterations=threshold, sampler=Sampler()) if save_time: start = time_ns() @@ -580,21 +523,13 @@ def solve_qaoa_qubo( self, problem: Problem, auto_setting: bool = False, - simulator: bool = True, - backend_name: str = "qasm_simulator", - channel: str = "", - token: str = "", - instance: str = "", num_runs: int = 10, - optimizer: Optimizer = None, + optimizer: Optimizer | None = None, reps: int = 1, initial_state: QuantumCircuit | None = None, - mixer: QuantumCircuit | OperatorBase = None, + mixer: QuantumCircuit = None, initial_point: np.ndarray[Any, Any] | None = None, - gradient: GradientBase | Callable[[np.ndarray[Any, Any] | list[Any]], list[Any]] | None = None, - expectation: ExpectationBase | None = None, - include_custom: bool = False, - max_evals_grouped: int = 1, + aggregation: float | Callable[[list[float]], float] | None = None, callback: Callable[[int, np.ndarray[Any, Any], float, float], None] | None = None, max_lambda_update: int = 5, lambda_update_mechanism: str = "sequential penalty increase", @@ -652,31 +587,17 @@ def solve_qaoa_qubo( initial_state = QuantumCircuit(var_num) for _idx in range(var_num): initial_state.h(_idx) - if simulator: - try: - QiskitRuntimeService.save_account(channel=channel, token=token, instance=instance, overwrite=True) - backend = QiskitRuntimeService().backend(backend_name) - except QiskitError: - print("The chosen backend doesn't exist or the IBM cannot be used. Qasm simulator will used.") - backend = BasicAer.get_backend("qasm_simulator") - else: - try: - QiskitRuntimeService.save_account(channel=channel, token=token, instance=instance, overwrite=True) - backend = QiskitRuntimeService().backend(backend_name) - except QiskitError: - print("The chosen backend doesn't exist or the IBM cannot be used. Qasm simulator will used.") - backend = BasicAer.get_backend("qasm_simulator") + + if optimizer is None: + optimizer = COBYLA() qaoa_mes = QAOA( - quantum_instance=backend, + sampler=Sampler(), optimizer=optimizer, reps=reps, initial_state=initial_state, mixer=mixer, initial_point=initial_point, - gradient=gradient, - expectation=expectation, - include_custom=include_custom, - max_evals_grouped=max_evals_grouped, + aggregation=aggregation, callback=callback, ) qaoa = MinimumEigenOptimizer(qaoa_mes) @@ -745,19 +666,11 @@ def solve_vqe_qubo( self, problem: Problem, auto_setting: bool = False, - simulator: bool = True, - backend_name: str = "qasm_simulator", - channel: str = "", - token: str = "", - instance: str = "", num_runs: int = 10, optimizer: Optimizer | None = None, - ansatz: QuantumCircuit | OperatorBase | None = None, + ansatz: QuantumCircuit | None = None, initial_point: np.ndarray[Any, Any] | None = None, - gradient: GradientBase | Callable[[np.ndarray[Any, Any] | list[Any]], list[Any]] | None = None, - expectation: ExpectationBase | None = None, - include_custom: bool = False, - max_evals_grouped: int = 1, + aggregation: float | Callable[[list[float]], float] | None = None, callback: Callable[[int, np.ndarray[Any, Any], float, float], None] | None = None, max_lambda_update: int = 5, lambda_update_mechanism: str = "sequential penalty increase", @@ -801,32 +714,18 @@ def solve_vqe_qubo( compilation_time = -1 logging.getLogger("qiskit").setLevel(logging.ERROR) res = [] - if auto_setting and ansatz is None: + if auto_setting or ansatz is None: ansatz = TwoLocal(num_qubits=len(self.qubo.variables), rotation_blocks="ry", entanglement_blocks="cz") - if simulator: - try: - QiskitRuntimeService.save_account(channel=channel, token=token, instance=instance, overwrite=True) - backend = QiskitRuntimeService().backend(backend_name) - except QiskitError: - print("The chosen backend doesn't exist or the IBM cannot be used. Qasm simulator will used.") - backend = BasicAer.get_backend("qasm_simulator") - else: - try: - QiskitRuntimeService.save_account(channel=channel, token=token, instance=instance, overwrite=True) - backend = QiskitRuntimeService().backend(backend_name) - except QiskitError: - print("The chosen backend doesn't exist or the IBM cannot be used. Qasm simulator will used.") - backend = BasicAer.get_backend("qasm_simulator") - vqe_mes = VQE( - quantum_instance=backend, + if optimizer is None: + optimizer = COBYLA() + + vqe_mes = SamplingVQE( + sampler=Sampler(), optimizer=optimizer, ansatz=ansatz, initial_point=initial_point, - gradient=gradient, - expectation=expectation, - include_custom=include_custom, - max_evals_grouped=max_evals_grouped, + aggregation=aggregation, callback=callback, ) vqe = MinimumEigenOptimizer(vqe_mes) @@ -893,7 +792,8 @@ def solve_vqe_qubo( def get_lambda_updates(self) -> int: return self._number_of_lambda_update - def _from_qubovert_to_qiskit_model(self, qubo: QUBO) -> QuadraticProgram: + @staticmethod + def _from_qubovert_to_qiskit_model(qubo: QUBO) -> QuadraticProgram: """function for converting the qubovert formulation into the qiskit quadratic model one Keyword arguments: @@ -1031,7 +931,7 @@ def create_dwave_annealing_solution( self.energies.append(sample[1] + offset) self.best_energy = samples.first.energy + offset - for sample in list(samples.samples()): # type: ignore[no-untyped-call] + for sample in list(samples.samples()): converted_sol = self.problem.variables.convert_simulated_annealing_solution(pubo.convert_solution(sample)) if isinstance(converted_sol, dict): self.solutions.append(converted_sol) @@ -1053,7 +953,7 @@ def create_dwave_annealing_solution( def create_qiskit_qubo_solution( self, - res: list[MinimumEigenOptimizationResult] | list[OptimizationResult], + res: list[SolutionSample], pubo: PUBO, qubo: QUBO, time: float = -1.0, @@ -1168,7 +1068,7 @@ def show_cumulative( rc("text", usetex=True) plt.rc("text", usetex=True) if label: - n, bins, patches = plt.hist( + plt.hist( self.energies, cumulative=True, histtype="step", @@ -1177,17 +1077,15 @@ def show_cumulative( label=r"\textit{" + label + "}", ) else: - n, bins, patches = plt.hist(self.energies, cumulative=True, histtype="step", linewidth=2, bins=100) + plt.hist(self.energies, cumulative=True, histtype="step", linewidth=2, bins=100) plt.title(r"\textbf{Cumulative distribution}", fontsize=20) plt.xlabel(r"\textit{Energy}", fontsize=20) plt.ylabel(r"\textit{occurrence}", fontsize=20) else: if label: - n, bins, patches = plt.hist( - self.energies, cumulative=True, histtype="step", linewidth=2, bins=100, label=label - ) + plt.hist(self.energies, cumulative=True, histtype="step", linewidth=2, bins=100, label=label) else: - n, bins, patches = plt.hist(self.energies, cumulative=True, histtype="step", linewidth=2, bins=100) + plt.hist(self.energies, cumulative=True, histtype="step", linewidth=2, bins=100) plt.title("Cumulative distribution", fontsize=20) plt.xlabel("Energy", fontsize=20) plt.ylabel("occurrence", fontsize=20) @@ -1206,9 +1104,8 @@ def show_cumulative( plt.savefig(filename + ".png", format="png") plt.savefig(filename + ".pdf", format="pdf") plt.close() - else: - if show: - plt.show() + elif show: + plt.show() def valid_solutions(self, weak: bool = True) -> float: """function for evaluating the rate of valid solution and the amount of violations @@ -1236,7 +1133,7 @@ def valid_solutions(self, weak: bool = True) -> float: else: self.valid_solution_rate[count] = 1 for key in self.valid_solution_rate: - self.valid_solution_rate[key] = self.valid_solution_rate[key] / len(all_satisfied) + self.valid_solution_rate[key] /= len(all_satisfied) return self.valid_solution_rate[0] def p_range(self, ref_value: float | None = None) -> float: diff --git a/src/mqt/qao/variables.py b/src/mqt/qao/variables.py index 99b524e..b21f75d 100644 --- a/src/mqt/qao/variables.py +++ b/src/mqt/qao/variables.py @@ -3,7 +3,7 @@ # numpy for matrix management from __future__ import annotations -from math import ceil, floor, log, sqrt +from math import ceil, floor, log, log2, sqrt from typing import Any import numpy as np @@ -437,6 +437,102 @@ def _variable_binarization( return constraints, i + def conv_var(self, v1: Variable, solution: dict[str, float]) -> float | bool: + temp = 0.0 + if isinstance(self.binary_variables_name_weight[v1.name], list): + for el in self.binary_variables_name_weight[v1.name]: + if not isinstance(el, str): + key = next(iter(el[0].variables)) + if key not in solution: + print("The variable is not found\n") + return False + if solution[key] == 1: + temp += el[1] if len(el) > 1 else 1 + if len(el) == 3: + temp += el[2] + elif next(iter(self.binary_variables_name_weight[v1.name][0].variables)) in solution: + key = next(iter(self.binary_variables_name_weight[v1.name][0].variables)) + if solution[key] == 1: + temp += ( + self.binary_variables_name_weight[v1.name][1] + if len(self.binary_variables_name_weight[v1.name]) > 1 + else 1 + ) + if len(self.binary_variables_name_weight[v1.name]) == 3: + temp += self.binary_variables_name_weight[v1.name][2] + else: + print("The variable is not found\n") + return False + + return temp + + def conv_list(self, v1: list[Variable], solution: dict[str, float]) -> list[float] | bool: + nested_temp_list = [] + for v2 in v1: + if not isinstance(v2, list) and v2.name in self.binary_variables_name_weight: + temp = self.conv_var(v2, solution) + if isinstance(temp, bool): + return False + nested_temp_list.append(temp) + return nested_temp_list + + def convert_solution_var( + self, converted_solution: dict[str, Any], var: str, solution: dict[str, float] + ) -> dict[str, Any] | bool: + """function for converting a solution coming from simulated annealing""" + converted_solution[var] = [] + for j, v in enumerate(self.variables_dict[var]): + if isinstance(v, list): + converted_solution[var].append([]) + for v1 in v: + if not isinstance(v1, list) and v1.name in self.binary_variables_name_weight: + temp = self.conv_var(v1, solution) + if isinstance(temp, bool): + return False + converted_solution[var][j].append(temp) + elif isinstance(v1, list): + nested_temp_list = self.conv_list(v1, solution) + if isinstance(nested_temp_list, bool): + return False + converted_solution[var][j].append(nested_temp_list) + elif v.name in self.binary_variables_name_weight: + temp = self.conv_var(v, solution) + if isinstance(temp, bool): + return False + converted_solution[var].append(temp) + return converted_solution + + def converted_solution_single_var( + self, converted_solution: dict[str, Any], var: str, solution: dict[str, float] + ) -> dict[str, Any] | bool: + converted_solution[var] = 0.0 + if var not in self.binary_variables_name_weight: + print("The variable is not found\n") + return False + if isinstance(self.binary_variables_name_weight[var], list): + for el in self.binary_variables_name_weight[var]: + if not isinstance(el, str): + key = next(iter(el[0].variables)) + if key not in solution: + print("The variable is not found\n") + return False + if solution[key] == 1: + converted_solution[var] += el[1] if len(el) > 1 else 1 + if len(el) == 3: + converted_solution[var] += el[2] + elif next(iter(self.binary_variables_name_weight[var][0].variables)) in solution: + key = next(iter(self.binary_variables_name_weight[var][0].variables)) + if solution[key] == 1: + converted_solution[var] += ( + self.binary_variables_name_weight[var][1] if len(self.binary_variables_name_weight[var]) > 1 else 1 + ) + if len(self.binary_variables_name_weight[var]) == 3: + converted_solution[var] += self.binary_variables_name_weight[var][2] + else: + print("The variable is not found\n") + return False + return converted_solution + def convert_simulated_annealing_solution(self, solution: dict[str, float]) -> dict[str, Any] | bool: """function for converting a solution coming from simulated annealing @@ -449,180 +545,16 @@ def convert_simulated_annealing_solution(self, solution: dict[str, float]) -> di """ converted_solution: dict[str, Any] = {} for var in self.variables_dict: - if isinstance(self.variables_dict[var], Variable): - converted_solution[var] = 0.0 - if var in self.binary_variables_name_weight: - if isinstance(self.binary_variables_name_weight[var], list): - for el in self.binary_variables_name_weight[var]: - if ( - not isinstance(el, str) - and next(iter(el[0].variables)) in solution - and solution[next(iter(el[0].variables))] == 1 - ): - if len(el) > 1: - converted_solution[var] += el[1] - else: - converted_solution[var] += 1 - if not isinstance(el, str) and next(iter(el[0].variables)) in solution and len(el) == 3: - converted_solution[var] += el[2] - if not isinstance(el, str) and next(iter(el[0].variables)) not in solution: - print("The variable is not found\n") - return False - else: - if ( - next(iter(self.binary_variables_name_weight[var][0].variables)) in solution - and solution[next(iter(self.binary_variables_name_weight[var][0].variables))] == 1 - ): - if len(self.binary_variables_name_weight[var]) > 1: - converted_solution[var] += self.binary_variables_name_weight[var][1] - else: - converted_solution[var] += 1 - - if ( - next(iter(self.binary_variables_name_weight[var][0].variables)) in solution - and len(self.binary_variables_name_weight[var]) == 3 - ): - converted_solution[var] += self.binary_variables_name_weight[var][2] - if next(iter(self.binary_variables_name_weight[var][0].variables)) not in solution: - print("The variable is not found\n") - return False - - else: - print("The variable is not found\n") + if not isinstance(self.variables_dict[var], Variable): + temp = self.convert_solution_var(converted_solution, var, solution) + if isinstance(temp, bool): return False + converted_solution = temp else: - converted_solution[var] = [] - j = 0 - for v in self.variables_dict[var]: - if not isinstance(v, list) and v.name in self.binary_variables_name_weight: - temp = 0.0 - if isinstance(self.binary_variables_name_weight[v.name], list): - for el in self.binary_variables_name_weight[v.name]: - if not isinstance(el, str): - if ( - next(iter(el[0].variables)) in solution - and solution[next(iter(el[0].variables))] == 1 - ): - if len(el) > 1: - temp += el[1] - else: - temp += 1 - if next(iter(el[0].variables)) in solution and len(el) == 3: - temp += el[2] - if next(iter(el[0].variables)) not in solution: - print("The variable is not found\n") - return False - else: - if next(iter(self.binary_variables_name_weight[v.name][0].variables)) in solution: - if ( - solution[next(iter(self.binary_variables_name_weight[v.name][0].variables))] == 1 - ) and len(self.binary_variables_name_weight[v.name]) > 1: - temp += self.binary_variables_name_weight[v.name][1] - if ( - solution[next(iter(self.binary_variables_name_weight[v.name][0].variables))] == 1 - ) and len(self.binary_variables_name_weight[v.name]) == 1: - temp += 1 - if len(self.binary_variables_name_weight[v.name]) == 3: - temp += self.binary_variables_name_weight[v.name][2] - else: - print("The variable is not found\n") - return False - converted_solution[var].append(temp) - elif isinstance(v, list): - converted_solution[var].append([]) - k = 0 - for v1 in v: - if not isinstance(v1, list): - if v1.name in self.binary_variables_name_weight: - temp = 0.0 - if isinstance(self.binary_variables_name_weight[v1.name], list): - for el in self.binary_variables_name_weight[v1.name]: - if not isinstance(el, str): - if ( - next(iter(el[0].variables)) in solution - and solution[next(iter(el[0].variables))] == 1 - ): - if len(el) > 1: - temp += el[1] - else: - temp += 1 - if next(iter(el[0].variables)) in solution and len(el) == 3: - temp += el[2] - if next(iter(el[0].variables)) not in solution: - print("The variable is not found\n") - return False - else: - if ( - next(iter(self.binary_variables_name_weight[v1.name][0].variables)) - in solution - ): - if ( - solution[ - next(iter(self.binary_variables_name_weight[v1.name][0].variables)) - ] - == 1 - ) and len(self.binary_variables_name_weight[v1.name]) > 0: - if len(self.binary_variables_name_weight[v1.name]) > 1: - temp += self.binary_variables_name_weight[v1.name][1] - else: - temp += 1 - if len(self.binary_variables_name_weight[v1.name]) == 3: - temp += self.binary_variables_name_weight[v1.name][2] - else: - print("The variable is not found\n") - return False - - converted_solution[var][j].append(temp) - else: - converted_solution[var][j].append([]) - for v2 in v: - if not isinstance(v2, list) and v2.name in self.binary_variables_name_weight: - temp = 0.0 - if isinstance(self.binary_variables_name_weight[v2.name], list): - for el in self.binary_variables_name_weight[v2.name]: - if ( - not isinstance(el, str) - and next(iter(el[0].variables)) in solution - and solution[next(iter(el[0].variables))] == 1 - ): - if len(el) > 1: - temp += el[1] - else: - temp += 1 - if ( - not isinstance(el, str) - and next(iter(el[0].variables)) in solution - and len(el) == 3 - ): - temp += el[2] - if next(iter(el[0].variables)) not in solution: - print("The variable is not found\n") - return False - else: - if ( - next(iter(self.binary_variables_name_weight[v2.name][0].variables)) - in solution - ): - if ( - solution[ - next( - iter( - self.binary_variables_name_weight[v2.name][0].variables - ) - ) - ] - == 1 - ) and len(self.binary_variables_name_weight[v2.name]) > 1: - temp += self.binary_variables_name_weight[v2.name][1] - if len(self.binary_variables_name_weight[v2.name]) == 3: - temp += self.binary_variables_name_weight[v2.name][2] - else: - print("The variable is not found\n") - return False - converted_solution[var][j][k].append(temp) - k += 1 - j += 1 - + temp = self.converted_solution_single_var(converted_solution, var, solution) + if isinstance(temp, bool): + return False + converted_solution = temp return converted_solution @@ -669,7 +601,7 @@ def _dictionary_encoding( i += 1 # Add the needed constraint - constraints.append((format(expand(var_sum).evalf()) + " = 1", True, False, False)) # type: ignore[no-untyped-call] + constraints.append((format(expand(var_sum).evalf()) + " = 1", True, False, False)) return binary_variables_name_weight, constraints, i def _unitary_encoding( @@ -699,9 +631,11 @@ def _unitary_encoding( binary_variables_name_weight[self.name].append("unitary") for w in range(1, samples + 1): if w == 1: - binary_variables_name_weight[self.name].append( - (boolean_var(letter + format(i)), w * unitary_weight, min_val) - ) + binary_variables_name_weight[self.name].append(( + boolean_var(letter + format(i)), + w * unitary_weight, + min_val, + )) else: binary_variables_name_weight[self.name].append((boolean_var(letter + format(i)), w * unitary_weight)) i += 1 @@ -737,9 +671,11 @@ def _domain_well_encoding( binary_variables_name_weight[self.name].append("domain well") for w in range(1, samples + 1): if w == 1: - binary_variables_name_weight[self.name].append( - (boolean_var(letter + format(i)), w * unitary_weight, min_val) - ) + binary_variables_name_weight[self.name].append(( + boolean_var(letter + format(i)), + w * unitary_weight, + min_val, + )) else: binary_variables_name_weight[self.name].append((boolean_var(letter + format(i)), w * unitary_weight)) constraints.append((letter + format(i) + ">=" + letter + format(i - 1), True, False, False)) @@ -820,9 +756,11 @@ def _arithmetic_progression_encoding( binary_variables_name_weight[self.name].append("arithmetic progression") for w in range(1, samples): if w == 1: - binary_variables_name_weight[self.name].append( - (boolean_var(letter + format(i)), w * unitary_weight, min_val) - ) + binary_variables_name_weight[self.name].append(( + boolean_var(letter + format(i)), + w * unitary_weight, + min_val, + )) else: binary_variables_name_weight[self.name].append((boolean_var(letter + format(i)), w * unitary_weight)) i += 1 @@ -875,9 +813,11 @@ def _bounded_coefficient_encoding( eta = floor(v / ux) binary_variables_name_weight[self.name] = [] binary_variables_name_weight[self.name].append("bounded coefficient") - binary_variables_name_weight[self.name].append( - (boolean_var(letter + format(i)), base**lower_power, min_val) - ) + binary_variables_name_weight[self.name].append(( + boolean_var(letter + format(i)), + base**lower_power, + min_val, + )) i += 1 for k in range(lower_power + 1, ro): @@ -920,7 +860,7 @@ def create(self, name: str, unipolar: bool = True) -> Symbol: class Discrete(Variable): - """child class of discrete variables""" + """child class of discrete variables for representing variables that can assume a finite number of values""" def create(self, name: str, values: list[float]) -> Symbol: """function for creating the new discrete variable. @@ -1040,67 +980,65 @@ def move_to_binary( binary_variables_name_weight, i, constraints, values, letter ) self._encoding_mechanism = "dictionary" - else: - if self._encoding_mechanism == "dictionary": + elif self._encoding_mechanism == "dictionary": + values = list(np.arange(self._min, self._max + self.precision, self.precision)) + binary_variables_name_weight, constraints, i = self._dictionary_encoding( + binary_variables_name_weight, i, constraints, values, letter + ) + elif self._encoding_mechanism == "unitary": + binary_variables_name_weight, i = self._unitary_encoding( + binary_variables_name_weight, i, self._max, self._min, self.precision, letter + ) + elif self._encoding_mechanism == "domain well": + binary_variables_name_weight, constraints, i = self._domain_well_encoding( + binary_variables_name_weight, i, self._max, self._min, constraints, self.precision, letter + ) + elif self._encoding_mechanism.startswith("logarithmic"): + try: + base = int(self._encoding_mechanism.split(" ")[1]) + binary_variables_name_weight, i = self._logarithmic_encoding( + binary_variables_name_weight, i, self._max, self._min, base, int(self.precision), letter + ) + self.precision = base**self.precision + except TypeError: values = list(np.arange(self._min, self._max + self.precision, self.precision)) binary_variables_name_weight, constraints, i = self._dictionary_encoding( binary_variables_name_weight, i, constraints, values, letter ) - elif self._encoding_mechanism == "unitary": - binary_variables_name_weight, i = self._unitary_encoding( - binary_variables_name_weight, i, self._max, self._min, self.precision, letter - ) - elif self._encoding_mechanism == "domain well": - binary_variables_name_weight, constraints, i = self._domain_well_encoding( - binary_variables_name_weight, i, self._max, self._min, constraints, self.precision, letter - ) - elif self._encoding_mechanism.startswith("logarithmic"): - try: - base = int(self._encoding_mechanism.split(" ")[1]) - binary_variables_name_weight, i = self._logarithmic_encoding( - binary_variables_name_weight, i, self._max, self._min, base, int(self.precision), letter - ) - self.precision = base**self.precision - except TypeError: - values = list(np.arange(self._min, self._max + self.precision, self.precision)) - binary_variables_name_weight, constraints, i = self._dictionary_encoding( - binary_variables_name_weight, i, constraints, values, letter - ) - self._encoding_mechanism = "dictionary" + self._encoding_mechanism = "dictionary" - elif self._encoding_mechanism == "arithmetic progression": - binary_variables_name_weight, i = self._arithmetic_progression_encoding( - binary_variables_name_weight, i, self._max, self._min, self.precision, letter + elif self._encoding_mechanism == "arithmetic progression": + binary_variables_name_weight, i = self._arithmetic_progression_encoding( + binary_variables_name_weight, i, self._max, self._min, self.precision, letter + ) + elif self._encoding_mechanism.startswith("bounded coefficient"): + try: + ux = int(self._encoding_mechanism.split(" ")[2]) + binary_variables_name_weight, i = self._bounded_coefficient_encoding( + binary_variables_name_weight, + i, + ux, + self._max, + self._min, + 2, + int(log2(self.precision)), + letter, ) - elif self._encoding_mechanism.startswith("bounded coefficient"): - try: - ux = int(self._encoding_mechanism.split(" ")[2]) - binary_variables_name_weight, i = self._bounded_coefficient_encoding( - binary_variables_name_weight, - i, - ux, - self._max, - self._min, - 2, - int(log(self.precision, 2)), - letter, - ) - except TypeError: - values = list(np.arange(self._min, self._max + self.precision, self.precision)) - binary_variables_name_weight, constraints, i = self._dictionary_encoding( - binary_variables_name_weight, i, constraints, values, letter - ) - self._encoding_mechanism = "dictionary" - else: - if (1 / self.precision) % 2 == 0: - binary_variables_name_weight, i = self._logarithmic_encoding( - binary_variables_name_weight, i, self._max, self._min, 2, int(log(self.precision, 2)), letter - ) - self._encoding_mechanism = "logarithmic 2" - else: - binary_variables_name_weight, i = self._arithmetic_progression_encoding( - binary_variables_name_weight, i, self._max, self._min, self.precision, letter - ) - self._encoding_mechanism = "arithmetic progression" + except TypeError: + values = list(np.arange(self._min, self._max + self.precision, self.precision)) + binary_variables_name_weight, constraints, i = self._dictionary_encoding( + binary_variables_name_weight, i, constraints, values, letter + ) + self._encoding_mechanism = "dictionary" + elif (1 / self.precision) % 2 == 0: + binary_variables_name_weight, i = self._logarithmic_encoding( + binary_variables_name_weight, i, self._max, self._min, 2, int(log2(self.precision)), letter + ) + self._encoding_mechanism = "logarithmic 2" + else: + binary_variables_name_weight, i = self._arithmetic_progression_encoding( + binary_variables_name_weight, i, self._max, self._min, self.precision, letter + ) + self._encoding_mechanism = "arithmetic progression" return binary_variables_name_weight, constraints, i diff --git a/tests/test_evaluation.py b/tests/test_evaluation.py index 1fdc018..ca42fe5 100644 --- a/tests/test_evaluation.py +++ b/tests/test_evaluation.py @@ -17,26 +17,6 @@ from mqt.qao.solvers import Solution, Solver from mqt.qao.variables import Variables -# from dwave.cloud import Client - - -def test_example() -> None: - """Expected type of final code: - Problem = Problem - variables = Problem.variables.add_....._variables(.....) - def f(var): - .... - Problem.objective_function.add_objective_function(f(var)) - Problem.constraints.add_constraints(....) - # With an eventual option for saving more information (Problem final size, etc.) - decoded_best_solution, Energy = Problem.solve() - # And eventually for knowing something about resolution statistics - Problem.statistics() - - """ - Variables() - assert 1 == 1 - def test_binary_only() -> None: """Test only the construction of binary variables""" @@ -967,20 +947,20 @@ def test_problem(lambda_strategy: str) -> None: reference_qubo_dict_re = {} for key in reference_qubo_dict: reference_qubo_dict_re[tuple(sorted(key))] = reference_qubo_dict[key] - if lambda_strategy == "upper_bound_only_positive" or lambda_strategy == "upper lower bound naive": - assert [52.25 * 1.1] * 2 == lambdas + if lambda_strategy in {"upper_bound_only_positive", "upper lower bound naive"}: + assert lambdas == [52.25 * 1.1] * 2 assert dict(sorted(qubo_re.items())) == dict(sorted(reference_qubo_dict_re.items())) elif lambda_strategy == "maximum_coefficient": - assert [10.0 * 1.1] * 2 == lambdas + assert lambdas == [10.0 * 1.1] * 2 assert dict(sorted(qubo_re.items())) == dict(sorted(reference_qubo_dict_re.items())) - elif lambda_strategy == "VLM" or lambda_strategy == "MOMC": - assert [12.0 * 1.1] * 2 == lambdas + elif lambda_strategy in {"VLM", "MOMC"}: + assert lambdas == [12.0 * 1.1] * 2 assert dict(sorted(qubo_re.items())) == dict(sorted(reference_qubo_dict_re.items())) elif lambda_strategy == "MOC": - assert [7 * 1.1, 6 * 1.1] == lambdas + assert lambdas == [7 * 1.1, 6 * 1.1] assert dict(sorted(qubo_re.items())) == dict(sorted(reference_qubo_dict_re.items())) elif lambda_strategy == "upper lower bound posiform and negaform method": - assert [31.625 * 1.1] * 2 == lambdas + assert lambdas == [31.625 * 1.1] * 2 assert dict(sorted(qubo_re.items())) == dict(sorted(reference_qubo_dict_re.items())) @@ -1011,7 +991,7 @@ def test_simulated_annealer_solver(lambda_strategy: str) -> None: solver = Solver() sol = solver.solve_simulated_annealing(problem, lambda_strategy=lambda_strategy) if isinstance(sol, Solution): - all_satisfy, each_satisfy = sol.check_constraint_optimal_solution() + all_satisfy, _each_satisfy = sol.check_constraint_optimal_solution() assert sol.best_solution == {"a": 0.0, "b": 3.0, "c": -1.5} assert sol.best_energy < -2.24 # (the range if for having no issues with numerical errors) assert sol.best_energy > -2.26 @@ -1080,7 +1060,7 @@ def test_simulated_annealer_solver_constrained(lambda_strategy: str, constraint_ solver = Solver() solution = solver.solve_simulated_annealing(problem, lambda_strategy=lambda_strategy) if isinstance(solution, Solution): - all_satisfy, each_satisfy = solution.check_constraint_optimal_solution() + all_satisfy, _each_satisfy = solution.check_constraint_optimal_solution() if constraint_expr == "c >= 1": assert solution.best_solution == {"a": 0.0, "b": -1.0, "c": 1.0} or not all_satisfy assert ( @@ -1174,7 +1154,7 @@ def test_simulated_annealer_solver_constrained_lambda_update_mechanism( ) solver.get_lambda_updates() if isinstance(solution, Solution): - all_satisfy, each_satisfy = solution.check_constraint_optimal_solution() + all_satisfy, _each_satisfy = solution.check_constraint_optimal_solution() if constraint_expr == "c >= 1": assert solution.best_solution == {"a": 0.0, "b": -1.0, "c": 1.0} or not all_satisfy assert ( @@ -1376,7 +1356,7 @@ def test_simulated_annealer_solver_constrained_lambda_update_mechanism_and_strat ) solver.get_lambda_updates() if isinstance(solution, Solution): - all_satisfy, each_satisfy = solution.check_constraint_optimal_solution() + all_satisfy, _each_satisfy = solution.check_constraint_optimal_solution() if constraint_expr == "c >= 1": assert solution.best_solution == {"a": 0.0, "b": -1.0, "c": 1.0} or not all_satisfy assert ( @@ -1472,7 +1452,7 @@ def test_simulated_annealing_cost_function_matrix( ) solver.get_lambda_updates() if isinstance(solution, Solution): - all_satisfy, each_satisfy = solution.check_constraint_optimal_solution() + all_satisfy, _each_satisfy = solution.check_constraint_optimal_solution() if constraint_expr == "M1_0_1 >= 1": assert ( solution.best_solution == {"M1": [[-1, 2]], "M2": [[2], [-1]]} @@ -1504,7 +1484,8 @@ def test_gas_solver_basic() -> None: solver = Solver() solution = solver.solve_grover_adaptive_search_qubo(problem, qubit_values=6, num_runs=10) if isinstance(solution, Solution): - all_satisfy, each_satisfy = solution.check_constraint_optimal_solution() + all_satisfy, _each_satisfy = solution.check_constraint_optimal_solution() + print(solution.best_solution) assert solution.best_solution == {"a": 1.0, "b": 0.0, "c": 1.0} print(solution.best_solution) assert solution.best_energy < -5.9 # (the range if for having no issues with numerical errors) @@ -1534,7 +1515,7 @@ def test_qaoa_solver_qubo_basic() -> None: num_runs=10, ) if isinstance(solution, Solution): - all_satisfy, each_satisfy = solution.check_constraint_optimal_solution() + all_satisfy, _each_satisfy = solution.check_constraint_optimal_solution() assert solution.best_solution == {"a": 1.0, "b": 0.0, "c": 1.0} print(solution.best_solution) assert solution.best_energy < -5.9 # (the range if for having no issues with numerical errors) @@ -1564,7 +1545,7 @@ def test_vqe_solver_qubo_basic() -> None: num_runs=10, ) if isinstance(solution, Solution): - all_satisfy, each_satisfy = solution.check_constraint_optimal_solution() + all_satisfy, _each_satisfy = solution.check_constraint_optimal_solution() assert solution.best_solution == {"a": 1.0, "b": 0.0, "c": 1.0} print(solution.best_solution) assert solution.best_energy < -5.9 # (the range if for having no issues with numerical errors)