Submit optimization jobs to Azure Quantum

In this article you will find the steps for how to submit optimization jobs to Azure Quantum using the Azure portal, Python, or Jupyter Notebooks.

As an example, this article follows a sample shipping company that has a difficult business problem: Balancing the loads of container ships at port. If you are interested in the problem details, see the shipping-loading sample.

Prerequisites

Create a new Notebook in your workspace

  1. Log in to the Azure portal and select a workspace.
  2. In the left blade, select Notebooks.
  3. Click My Notebooks and click Add New.
  4. In Kernel Type, select IPython.
  5. Type a name for the file, for example submit-optimization-job.ipynb, and click Create file.

Note

You can also upload a Notebook to your Azure Quantum workspace. For more information, see Upload notebooks.

When your new Notebook opens, it automatically creates the code for the first cell, based on your subscription and workspace information.

from azure.quantum import Workspace
workspace = Workspace (
    subscription_id = <your subscription ID>, 
    resource_group = <your resource group>,   
    name = <your workspace name>,          
    location = <your location>        
    )

Note

Unless otherwise noted, you should run each cell in order as you create it to avoid any compilation issues.

Click the triangular "play" icon to the left of the cell to run the code.

Problem instantiation

To submit a problem to Azure Quantum, you first need to create a Problem instance. This is a Python object that stores all the required information, such as the cost function details and the kind of problem you are modeling.

Next, define a function that takes an array of container weights and returns a Problem object that represents the cost function. The following function generalizes the Term creation for any number of weights by using some for loops. It takes an array of weights and returns a Problem object.

Select + Code and add the following code to the cell:

from typing import List
from azure.quantum.optimization import Problem, ProblemType, Term

def create_problem_for_container_weights(container_weights: List[int]) -> Problem:
    terms: List[Term] = []

    # Expand the squared summation
    for i in range(len(container_weights)):
        for j in range(len(container_weights)):
            if i == j:
                # Skip the terms where i == j as they form constant terms in an Ising problem and can be disregarded:
                # w_i∗w_j∗x_i∗x_j = w_i​*w_j∗(x_i)^2 = w_i∗w_j​​
                # for x_i = x_j, x_i ∈ {1, -1}
                continue
            
            terms.append(
                Term(
                    c = container_weights[i] * container_weights[j],
                    indices = [i, j]
                )
            )

    # Return an Ising-type problem
    return Problem(name="Ship Sample Problem", problem_type=ProblemType.ising, terms=terms)

Next, add a cell and define the list of containers and their weights and instantiate a problem:

# This array contains a list of the weights of the containers
container_weights = [1, 5, 9, 21, 35, 5, 3, 5, 10, 11]

# Create a problem for the list of containers:
problem = create_problem_for_container_weights(container_weights)

Submit the job to Azure Quantum

Now, submit the problem to Azure Quantum:

from azure.quantum.optimization import ParallelTempering
import time

# Instantiate a solver to solve the problem. 
solver = ParallelTempering(workspace, timeout=100)

# Optimize the problem
print('Submitting problem...')
start = time.time()
result = solver.optimize(problem)
time_elapsed = time.time() - start
print(f'Result in {time_elapsed} seconds: ', result)

Note

This guide uses Parameter-Free Parallel Tempering solver with a timeout of 100 seconds as an example of a QIO solver. For more information about available solvers, you can visit the Microsoft QIO provider documentation page.

Notice that the solver returns the results in the form of a Python dictionary, along with some metadata. Add a new cell with the following function to print a more human-readable summary of the solution:

def print_result_summary(result):
    # Print a summary of the result
    ship_a_weight = 0
    ship_b_weight = 0
    for container in result['configuration']:
        container_assignment = result['configuration'][container]
        container_weight = container_weights[int(container)]
        ship = ''
        if container_assignment == 1:
            ship = 'A'
            ship_a_weight += container_weight
        else:
            ship = 'B'
            ship_b_weight += container_weight

        print(f'Container {container} with weight {container_weight} was placed on Ship {ship}')

    print(f'\nTotal weights: \n\tShip A: {ship_a_weight} tonnes \n\tShip B: {ship_b_weight} tonnes\n')

print_result_summary(result)
Container 0 with weight 1 was placed on Ship A
Container 1 with weight 5 was placed on Ship B
Container 2 with weight 9 was placed on Ship A
Container 3 with weight 21 was placed on Ship A
Container 4 with weight 35 was placed on Ship B
Container 5 with weight 5 was placed on Ship B
Container 6 with weight 3 was placed on Ship B
Container 7 with weight 5 was placed on Ship B
Container 8 with weight 10 was placed on Ship A
Container 9 with weight 11 was placed on Ship A

Total weights: 
	Ship A: 52 tonnes 
	Ship B: 53 tonnes

Prerequisites

Set up

First, you must instantiate a Workspace object, which allows you to connect to the workspace you've previously deployed in Azure. Be sure to fill in the following settings, which can be retrieved from the Azure portal or by opening a command prompt and running az quantum workspace show through the Azure CLI. Open a new python file and run the following lines:

from azure.quantum import Workspace

# Copy the following settings for your workspace
workspace = Workspace ( 
	subscription_id = "", # Add your subscription_id 
	resource_group = "", # Add your resource_group 
	name = "", # Add your workspace name 
	location = ""  # Add your workspace location (for example, "westus") 
)

Problem instantiation

To submit a problem to Azure Quantum, you first need to create a Problem instance. This is a Python object that stores all the required information, such as the cost function details and the kind of problem you are modeling.

from typing import List
from azure.quantum.optimization import Problem, ProblemType, Term

def createProblemForContainerWeights(containerWeights: List[int]) -> Problem:
    terms: List[Term] = []

    # Expand the squared summation
    for i in range(len(containerWeights)):
        for j in range(len(containerWeights)):
            if i == j:
                # Skip the terms where i == j as they form constant terms in an Ising problem and can be disregarded.
                continue

            terms.append(
                Term(
                    c = containerWeights[i] * containerWeights[j],
                    indices = [i, j]
                )
            )

    # Return an Ising-type problem
    return Problem(name="Freight Balancing Problem", problem_type=ProblemType.ising, terms=terms)

Before submitting the problem to Azure Quantum, you instantiate it by defining a list of containers via their weights:

# This array contains the weights of all the containers
containerWeights = [1, 5, 9, 21, 35, 5, 3, 5, 10, 11]

# Create a problem for the given list of containers:
problem = createProblemForContainerWeights(containerWeights)

Submit the job to Azure Quantum

Now, submit the problem to Azure Quantum:

from azure.quantum.optimization import ParallelTempering
import time

# Instantiate a solver to solve the problem.
solver = ParallelTempering(workspace, timeout=100)

# Optimize the problem
print('Submitting problem...')
start = time.time()
result = solver.optimize(problem)
timeElapsed = time.time() - start
print(f'Result in {timeElapsed} seconds: ', result)

Note

This guide uses Parameter-Free Parallel Tempering solver with a timeout of 100 seconds as an example of a QIO solver. For more information about available solvers, you can visit the Microsoft QIO provider documentation page.

Notice that the solver returns the results in the form of a Python dictionary, along with some metadata. You can use the following function to print a more human-readable summary of the solution:

def printResultSummary(result):
    # Print a summary of the result
    containerAWeight = 0
    containerBWeight = 0
    for chunk in result['configuration']:
        chunkAssignment = result['configuration'][chunk]
        chunkWeight = containerWeights[int(chunk)]
        container = ''
        if chunkAssignment == 1:
            container = 'A'
            containerAWeight += chunkWeight
        else:
            container = 'B'
            containerBWeight += chunkWeight

        print(f'Container {container} with weight {container_weight} was placed on Ship {ship}')

    print(f'\nTotal weights: \n\tShip A: {ship_a_weight} tonnes \n\tShip B: {ship_b_weight} tonnes\n')

print_result_summary(result)
Container 0 with weight 1 was placed on Ship A
Container 1 with weight 5 was placed on Ship B
Container 2 with weight 9 was placed on Ship A
Container 3 with weight 21 was placed on Ship A
Container 4 with weight 35 was placed on Ship B
Container 5 with weight 5 was placed on Ship B
Container 6 with weight 3 was placed on Ship B
Container 7 with weight 5 was placed on Ship B
Container 8 with weight 10 was placed on Ship A
Container 9 with weight 11 was placed on Ship A

Total weights: 
	Ship A: 52 tonnes 
	Ship B: 53 tonnes

Prerequisites

Set up

  1. Run jupyter notebook from the terminal of your choice. This starts the notebook server and opens Jupyter in a browser. In the browser view, select the dropdown button on the right hand top corner and select Python 3 from the list to create a new notebook.
  2. Instantiate a Workspace object which allows you to connect to the workspace you've previously deployed in Azure. Be sure to fill in the following settings, which can be retrieved by running az quantum workspace show.
# This allows you to connect to the Workspace you've previously deployed in Azure. 
from  azure.quantum  import  Workspace  

# Copy the settings for your workspace below  
workspace = Workspace ( 
	subscription_id = "", # Add your subscription_id 
	resource_group = "", # Add your resource_group 
	name = "", # Add your workspace name 
	location = ""  # Add your workspace location (for example, "westus") )

Problem instantiation

To submit a problem to Azure Quantum, you first need to create a Problem instance. This is a Python object that stores all the required information, such as the cost function details and the kind of problem you are modeling.

Next, define a function that takes an array of container weights and returns a Problem object that represents the cost function. The following function generalizes the Term creation for any number of weights by using some for loops. It takes an array of weights and returns a Problem object.

from typing import List
from azure.quantum.optimization import Problem, ProblemType, Term

def create_problem_for_container_weights(container_weights: List[int]) -> Problem:
    terms: List[Term] = []

    # Expand the squared summation
    for i in range(len(container_weights)):
        for j in range(len(container_weights)):
            if i == j:
                # Skip the terms where i == j as they form constant terms in an Ising problem and can be disregarded:
                # w_i∗w_j∗x_i∗x_j = w_i​*w_j∗(x_i)^2 = w_i∗w_j​​
                # for x_i = x_j, x_i ∈ {1, -1}
                continue
            
            terms.append(
                Term(
                    c = container_weights[i] * container_weights[j],
                    indices = [i, j]
                )
            )

    # Return an Ising-type problem
    return Problem(name="Ship Sample Problem", problem_type=ProblemType.ising, terms=terms)

Next, define the list of containers and their weights and instantiate a problem:

# This array contains a list of the weights of the containers
container_weights = [1, 5, 9, 21, 35, 5, 3, 5, 10, 11]

# Create a problem for the list of containers:
problem = create_problem_for_container_weights(container_weights)

Submit the job to Azure Quantum

Now, submit the problem to Azure Quantum:

from azure.quantum.optimization import ParallelTempering
import time

# Instantiate a solver to solve the problem. 
solver = ParallelTempering(workspace, timeout=100)

# Optimize the problem
print('Submitting problem...')
start = time.time()
result = solver.optimize(problem)
time_elapsed = time.time() - start
print(f'Result in {time_elapsed} seconds: ', result)

Note

This guide uses Parameter-Free Parallel Tempering solver with a timeout of 100 seconds as an example of a QIO solver. For more information about available solvers, you can visit the Microsoft QIO provider documentation page.

Notice that the solver returns the results in the form of a Python dictionary, along with some metadata. You can use the following function to print a more human-readable summary of the solution:

def print_result_summary(result):
    # Print a summary of the result
    ship_a_weight = 0
    ship_b_weight = 0
    for container in result['configuration']:
        container_assignment = result['configuration'][container]
        container_weight = container_weights[int(container)]
        ship = ''
        if container_assignment == 1:
            ship = 'A'
            ship_a_weight += container_weight
        else:
            ship = 'B'
            ship_b_weight += container_weight

        print(f'Container {container} with weight {container_weight} was placed on Ship {ship}')

    print(f'\nTotal weights: \n\tShip A: {ship_a_weight} tonnes \n\tShip B: {ship_b_weight} tonnes\n')

print_result_summary(result)
Container 0 with weight 1 was placed on Ship A
Container 1 with weight 5 was placed on Ship B
Container 2 with weight 9 was placed on Ship A
Container 3 with weight 21 was placed on Ship A
Container 4 with weight 35 was placed on Ship B
Container 5 with weight 5 was placed on Ship B
Container 6 with weight 3 was placed on Ship B
Container 7 with weight 5 was placed on Ship B
Container 8 with weight 10 was placed on Ship A
Container 9 with weight 11 was placed on Ship A

Total weights: 
	Ship A: 52 tonnes 
	Ship B: 53 tonnes

Next steps

Now that you know how to submit jobs to Azure Quantum, continue to explore optimization with the following articles: