Skip to content

QUBOInstance

QUBOInstance(coefficients=None, device='cpu', dtype=torch.float32)

Represents a single instance of a Quadratic Unconstrained Binary Optimization (QUBO) problem.

ATTRIBUTE DESCRIPTION
coefficients

Tensor of shape (size, size), representing the QUBO coefficients.

TYPE: Tensor

device

Device where tensors are allocated (e.g., "cpu" or "cuda").

TYPE: str

dtype

Data type of the tensors (e.g., torch.float32).

TYPE: dtype

size

Size of the QUBO matrix (number of variables).

TYPE: int | None

solution

Solution to the QUBO problem, if available.

TYPE: QUBOSolution | None

density

Fraction of non-zero entries in the coefficient matrix.

TYPE: float | None

density_type

Classification of the density (e.g., sparse, dense).

TYPE: DensityType | None

Initializes a QUBOInstance.

PARAMETER DESCRIPTION
coefficients

Coefficients of the QUBO problem. Can be a dictionary, array-like object, or None.

TYPE: dict | ArrayLike | None DEFAULT: None

device

Device where tensors are allocated (default: "cpu").

TYPE: str DEFAULT: 'cpu'

dtype

Data type of the tensors (default: torch.float32).

TYPE: dtype DEFAULT: float32

Source code in qubosolver/qubo_instance.py
def __init__(
    self,
    coefficients: dict | ArrayLike | None = None,
    device: str = "cpu",
    dtype: torch.dtype = torch.float32,
):
    """
    Initializes a QUBOInstance.

    Args:
        coefficients (dict | ArrayLike | None):
            Coefficients of the QUBO problem. Can be a dictionary, array-like object, or None.
        device (str):
            Device where tensors are allocated (default: "cpu").
        dtype (torch.dtype):
            Data type of the tensors (default: torch.float32).
    """
    self.device = device
    self.dtype = dtype
    self.size: int | None
    self._coefficients: torch.Tensor | None = None
    self.solution: QUBOSolution | None = None
    self.density: float | None = None
    self.density_type: DensityType | None = None

    if coefficients is not None:
        self.coefficients = coefficients

coefficients property writable

Getter for the QUBO coefficient matrix.

RETURNS DESCRIPTION
Tensor

torch.Tensor: Tensor of shape (size, size) representing the QUBO coefficients.

__repr__()

Returns a string representation of the QUBOInstance.

RETURNS DESCRIPTION
str

A dictionary-like string summarizing the instance.

TYPE: str

Source code in qubosolver/qubo_instance.py
def __repr__(self) -> str:
    """
    Returns a string representation of the QUBOInstance.

    Returns:
        str: A dictionary-like string summarizing the instance.
    """
    return repr(
        f"QUBOInstance of size = {self.size},"
        f"density = {round(self.density, 2) if self.density else None},"
    )

evaluate_solution(solution)

Evaluates a solution for the QUBO problem.

PARAMETER DESCRIPTION
solution

Solution vector to evaluate.

TYPE: list | tuple | ArrayLike

RETURNS DESCRIPTION
float

The cost of the given solution.

TYPE: float

RAISES DESCRIPTION
ValueError

If the solution size does not match the QUBO size.

Source code in qubosolver/qubo_instance.py
def evaluate_solution(self, solution: list | tuple | ArrayLike) -> float:
    """
    Evaluates a solution for the QUBO problem.

    Args:
        solution (list | tuple | ArrayLike):
            Solution vector to evaluate.

    Returns:
        float:
            The cost of the given solution.

    Raises:
        ValueError: If the solution size does not match the QUBO size.
    """
    solution_tensor = convert_to_tensor(solution, device=self.device, dtype=self.dtype)
    if self._coefficients is None or solution_tensor.size(0) != self.size:
        raise ValueError("Solution size does not match the QUBO problem size.")
    cost = torch.matmul(
        solution_tensor, torch.matmul(self._coefficients, solution_tensor)
    ).item()
    solution = solution_tensor
    return float(cost)

set_coefficients(new_coefficients=None)

Updates the coefficients of the QUBO problem.

PARAMETER DESCRIPTION
new_coefficients

Dictionary of new coefficients to set. Keys are (row, column) tuples.

TYPE: dict[tuple[int, int], float] | None DEFAULT: None

Source code in qubosolver/qubo_instance.py
def set_coefficients(
    self, new_coefficients: dict[tuple[int, int], float] | None = None
) -> None:
    """
    Updates the coefficients of the QUBO problem.

    Args:
        new_coefficients (dict[tuple[int, int], float] | None):
            Dictionary of new coefficients to set. Keys are (row, column) tuples.
    """
    if not new_coefficients:
        return

    max_index = max(max(i, j) for i, j in new_coefficients.keys())
    if self.size and max_index >= self.size:
        self._expand_size(max_index + 1)

    indices = torch.tensor(list(new_coefficients.keys()), dtype=torch.long, device=self.device)
    values = torch.tensor(list(new_coefficients.values()), dtype=self.dtype, device=self.device)
    self._coefficients[indices[:, 0], indices[:, 1]] = values  # type: ignore[index]
    off_diagonal_mask = indices[:, 0] != indices[:, 1]
    symmetric_indices = indices[off_diagonal_mask]
    self._coefficients[symmetric_indices[:, 1], symmetric_indices[:, 0]] = values[  # type: ignore[index]
        off_diagonal_mask
    ]

    self.update_metrics()

update_metrics()

Updates the density metrics of the QUBO problem.

Source code in qubosolver/qubo_instance.py
def update_metrics(self) -> None:
    """
    Updates the density metrics of the QUBO problem.
    """
    if self._coefficients is not None:
        self.density = calculate_density(self._coefficients, self.size)
        self.density_type = classify_density(self.density)
    else:
        self.density = self.density_type = None