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

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions QHyper/.github/workflows/release.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
name: Release to PyPI

on:
push:
branches:
- production

jobs:
pypi-build-and-publish:
runs-on: ubuntu-latest
permissions:
id-token: write
steps:
- name: Check out code
uses: actions/checkout@v3

- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: 3.x

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install setuptools wheel twine

- name: Build
run: |
python setup.py sdist bdist_wheel

- name: Publish distribution 📦 to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
25 changes: 25 additions & 0 deletions QHyper/.github/workflows/tests.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
name: Test Knapsack

on: push

jobs:
test_knapsack:
runs-on: ubuntu-latest

steps:
- name: Check out code
uses: actions/checkout@v2

- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: "3.12"

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements/dev.txt

- name: Run pytest tests
run: |
pytest
18 changes: 18 additions & 0 deletions QHyper/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
venv/
__pycache__/
.ipynb_checkpoints/
checkpoint.pth
.vscode

docs/build
docs/source/generated/

paper

.idea
/.idea

/build/
/dist/
*.egg-info/
.DS_Store
28 changes: 28 additions & 0 deletions QHyper/.readthedocs.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# .readthedocs.yaml
# Read the Docs configuration file
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details

# Required
version: 2

# Set the version of Python and other tools you might need
build:
os: ubuntu-24.04
tools:
python: "3.12"
apt_packages:
- graphviz

# Build documentation in the docs/ directory with Sphinx
sphinx:
configuration: docs/source/conf.py
fail_on_warning: true

# If using Sphinx, optionally build your docs in additional formats such as PDF
# formats:
# - pdf

# Optionally declare the Python requirements required to build your docs
python:
install:
- requirements: requirements/dev.txt
21 changes: 21 additions & 0 deletions QHyper/LICENSE.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2022-2025 ACC Cyfronet AGH

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
7 changes: 7 additions & 0 deletions QHyper/QHyper/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# This work was supported by the EuroHPC PL infrastructure funded at the
# Smart Growth Operational Programme (2014-2020), Measure 4.2
# under the grant agreement no. POIR.04.02.00-00-D014/20-00

"""
API reference documentation for QHyper.
"""
125 changes: 125 additions & 0 deletions QHyper/QHyper/constraint.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
"""This module contains the Constraint class which is used to represent a, well,
constraint. It is used in the QUBO formulation to define the left and right
hand sides of the constraints, and the operator.

.. rubric:: Main class

.. autosummary::
:toctree: generated

Constraint -- implementation of the constraint.

.. rubric:: Enum Classes

.. autoclass:: MethodsForInequalities


.. rubric:: Functions

.. autofunction:: get_number_of_constraints

"""

import uuid
from enum import Enum

from QHyper.polynomial import Polynomial, PolynomialType


class MethodsForInequalities(Enum):
"""Enum class with different methods for handling inequalities.

There are two available methods for handling inequalities:
.. list-table::

* - SLACKS_LOG_2
- UNBALANCED_PENALIZATION
* - the method uses slack variables in number of log2(n)
- the method uses unbalanced penalization
"""
SLACKS_LOG_2 = 0
UNBALANCED_PENALIZATION = 1


SLACKS_LOG_2 = MethodsForInequalities.SLACKS_LOG_2
UNBALANCED_PENALIZATION = MethodsForInequalities.UNBALANCED_PENALIZATION


class Operator(Enum):
"""Enum class with different operators.
"""
EQ = "=="
GE = ">="
LE = "<="


class Constraint:
"""
A class representing the constraint.

Attributes
----------
lhs : PolynomialType
The left-hand side of the constraint.
rhs : PolynomialType, default 0
The right-hand side of the constraint.
operator : Operator, default Operator.EQ
The operator of the constraint. It can be ==, >=, <=.
method_for_inequalities : MethodsForInequalities, optional
The method to be used for inequalities. It can be SLACKS_LOG_2 or
UNBALANCED_PENALIZATION. It is required when the operator is not ==.
label : str, optional
The label of the constraint. If not provided, it will be set to a
random string.
group : int, default -1
The group of the constraint. It is used to group constraints together.
Example use is assigning same weight to the constraints with the same
group when creating qubo.
"""

def __init__(
self,
lhs: PolynomialType,
rhs: PolynomialType = 0,
operator: Operator = Operator.EQ,
method_for_inequalities: MethodsForInequalities | None = None,
label: str = "",
group: int = -1,
) -> None:
self.lhs = lhs if isinstance(lhs, Polynomial) else Polynomial(lhs)
self.rhs = rhs if isinstance(rhs, Polynomial) else Polynomial(rhs)
self.operator: Operator = operator

if operator != Operator.EQ and method_for_inequalities is None:
raise Exception(
"Method for inequalities must be "
"provided when operator is not =="
)
self.method_for_inequalities = method_for_inequalities
self._set_label(label)
self.group = group

def _set_label(self, label: str) -> None:
self.label = label or f"s{uuid.uuid4().hex}"

def __repr__(self) -> str:
return f"{self.lhs} {self.operator.value} {self.rhs}"

def get_variables(self) -> set[str]:
return self.lhs.get_variables() | self.rhs.get_variables()


def get_number_of_constraints(constraints: list[Constraint]) -> int:
"""Returns the number of unique groups in the constraints list.
"""

counter = 0
visited = set()

for c in constraints:
if c.group == -1:
counter += 1
elif c.group not in visited:
visited.add(c.group)
counter += 1
return counter
Loading
Loading