# Benchmarking Custom Optimization Problems

In this tutorial, we'll delve into quantum computing using LunaBench, focusing on creating datasets for custom optimization problems. This guide is designed for those with unique datasets and optimization challenges that aren't covered by our existing use case library. Whether you're looking to input various mathematical formats or benchmark specific quantum algorithms, this tutorial provides step-by-step instructions to help you achieve your goals.

Before we begin, ensure you have installed the LunaBench Python SDK.

Upon completing this tutorial, you will be able to:

- Compile custom datasets for QUBO problems, LP files, and other formats.
- Select suitable quantum algorithms and hardware for your benchmarking needs.
- Run a detailed benchmarking pipeline within LunaBench, tailored to your specific requirements.

## Example: Benchmarking QUBOs

Quadratic Unconstrained Binary Optimization (QUBO) is a crucial type of optimization problem in combinatorial optimization, where the goal is to find the best solution from a limited set of options. QUBOs use binary variables (0s and 1s) and aim to optimize a quadratic polynomial. QUBOs can be used to represent various complex problems, from logistics to machine learning.

In the context of quantum computing, QUBOs are particularly valuable. Quantum computers, with their ability to process complex problems differently from classical computers, find QUBO formats highly compatible. This compatibility is due to quantum computing's ability to evaluate multiple possibilities at once through quantum superposition, offering a potentially more efficient way to explore and find optimal solutions to QUBOs. Essentially, QUBOs provide a bridge for applying quantum computing's unique advantages to real-world optimization challenges.

If you are new to QUBOs or seek a deeper understanding, a comprehensive tutorial is available here. This resource offers valuable insights into the intricacies of QUBOs and their applications in quantum computing.

### 1. Creating a Dataset of QUBO Matrices

LunaBench is equipped to deal with a broad array of optimization problems, particularly excelling in those that can be formulated as QUBOs, which are crucial for quantum optimization. The field of optimization presents an extensive variety of challenges, many of which align with QUBO models.

Creating a dataset consisting of QUBO problems is very easy. You simply gather the QUBO matrices that represent the optimization challenges you're looking to solve as a dataset within a dictionary, where every key is a unique identifier for each scenario, and the value is the lineup of cars for that particular problem.

```
# Define the problem type as qubo
problem_name = "qubo"
# Define the dataset
dataset = {
"qubo_00": {
problem_name: [
[2, 1],
[1, 2]
]
},
"qubo_01": {
problem_name: [
[-2, 3],
[3, -2]
]
},
"qubo_02": {
problem_name: [
[2, 1, 0],
[1, 2, 1],
[0, 1, 2]
]
},
}
```

### 2. Selecting Algorithms for QUBO Benchmarking

For solving a dataset of QUBOs, choosing the right algorithms is crucial. LunaBench offers a vast selection tailored for a variety of optimization tasks, including more than just QUBO mathematical formats.

LunaBench provides the capability to execute operations on various Quantum Computing platforms, including D-Wave Systems and IBM.

To solve optimization problems with hybrid algorithms such as `QAOA`

or `VQE`

on the IBM backend, you can include the `ibm_config`

argument accompanied by a dictionary. This configuration should specify the `token`

key-value pair with a personal IBM token to facilitate execution on the IBM platform. Furthermore, options to customize the `channel`

, `backend`

, and additional settings are available, allowing for tailored execution parameters.

To execute on D-Wave Quantum Hardware, it is necessary to specify your D-Wave token within the algorithm configuration. For execution on IBM, please provide the IBM token in the algorithm configuration analogously.

For a statistically significant evaluation of the algorithms' performance, you can define the number of runs for each algorithm. This method ensures a thorough and accurate measurement of their effectiveness in different scenarios.

```
# Specify the algorithms and number of runs for each algorithm
algorithms = {
"qaoa": {
"qaoa_config": {
"optimizer": "COBYLA",
"max_iter": 3,
"ansatz_reps": 3,
"transpile_opt_level": 2
},
"ibm_config": {
"channel": "ibm_quantum",
"backend": "ibm_kyoto",
"token": "<TOKEN>",
"shots": 10
}
}
}
n_runs = 3
```

### 3. Launching the Benchmark Pipeline

With the QUBO dataset and our selected algorithms ready, we're now set to tackle the problem across all instances. This step involves utilizing LunaBench's capabilities to systematically work through the dataset. Instead of directly calling specific functions, think of this as instructing LunaBench to apply our chosen algorithms - SA and QAOA — to each scenario within our dataset.

```
from lunabench import solve_dataset
# Solve the entire dataset using your chosen algorithms
solved, result_id = solve_dataset(
problem_name=problem_name,
dataset=dataset,
solve_algorithms=algorithms,
n_runs=n_runs
)
```

Upon finishing the benchmarking process, you'll find the outcomes, along with additional details, neatly organized in a CSV file. This file is accessible at `luna_results/{$dataset_name}/solve/{$result_id}/solutions.csv`

. It's designed so that both the dataset name and the result ID align with the same time identifiers by default.

## Example: Benchmarking LP files

Linear Programming (LP) is a powerful optimization technique used to find the best outcome in a mathematical model whose requirements are represented by linear relationships. In LP, the objective is to maximize or minimize a linear objective function, subject to a set of linear equality or inequality constraints.

### 1. Creating a Dataset of LP files

In addition to QUBOs, LunaBench supports a wide variety of other mathematical formats. One such format are said LP files, which define a linear programming problem. LP files contain the mathematical representation of the problem, including details about the objective function, constraints, and variables involved, and can be uploaded directly to LunaBench.

```
# Create an example LP file
lp_str = """\* Example LP with Quadratic Objective *\\n
Maximize\n
obj: + [x^2 + y^2]/2 + 3 x + 4 y\n
Subject To\n
c1: x + 2 y <= 10\n
c2: 3 x + y >= 5\n
Bounds\n
0 <= x <= 5\n
0 <= y <= 5\n
End\n
#"""
with open("test.lp", "w") as f:
f.writelines(lp_str)
# Define the problem type as lp
problem_name = "lp"
# Define the dataset
dataset = {
"lp__00": {
problem_name: "test.lp"
}
}
```

### 2. Selecting LP Solvers and Launching the Pipeline

Just as with QUBOs, there are dedicated solvers designed to solve LPs. In this tutorial, we will use the SCIP solver, a powerful open-source solver that supports the LP file format. The remaining steps are identical to the pipeline for QUBOs.

```
# Specify the SCIP solver
algorithms = ["scip"]
n_runs = 3
# Solve the dataset
solved, result_id = solve_dataset(
problem_name=problem_name,
dataset=dataset,
solve_algorithms=algorithms,
n_runs=n_runs
)
```

## Other Optimization Formats

LunaBench supports not only QUBOs and LPs but also many other optimization formats. The supported formats are identical to those provided in LunaSolve. For more details, refer to our user guide on available optimization formats or LunaBench's Github page.