View on GitHub
Open this notebook in GitHub to run it yourself
QAOA Knapsack
In Part I we looked at specific high-level language concepts, their meaning and use. In this part, we apply these concepts to design a full algorithm. We will consider alternative ways to implement the Quantum Approximate Optimization Algorithm (QAOA). In particular, we will compare two approaches to expressing the hard constraint of the knapsack problem - using a penalty term in phase rotations and using a digital (computational-basis) conditional. The goal of the exercise is to demonstrate the use of quantum expressions in different modes, and their combination. It is not meant as a comprehensive study of hard constraints in QAOA, nor does it consider many other factors that determine QAOA performance and results (a rich and active field of research). There are 3 code exercises in this notebook with the corresponding heading and a code snippet containingTODO comments.
Make sure to complete the code in the snippets before running the cell.
Solutions are provided at the end of the notebook. Don’t continue to the next exercise until you have completed the previous one and compared against the solution.
Warm-Up: QAOA Pattern in Qmod (Max-Cut Example)
We start by reviewing a simple demonstration of the QAOA algorithm. It solves a trivial case of the max-cut problem (but can easily be generalized to arbitrary graphs). The purpose of this code is just to get acquainted with the Qmod implementation, and define a couple of the building blocks that we shall reuse later.Output:
Output:
ExecutionSession.variational_minimize method which uses gradient descent to optimize the parameters of the ansatz.
The cost function is defined as the expectation value of the cost operator, which is defined in the maxcut_cost function above.
The initial parameters are set to a linear schedule, which is a common heuristic for QAOA.
The optimal solution to this trivial max-cut problem is the partition into node sets {0} and {1, 2}.
The QAOA cost layer for graph problems can be expressed directly in Qmod using phase statement with a bitwise expression.
The Knapsack Problem
The general definition of the knapsack problem is the following: Given a set of items, determine how many items to put in the knapsack to maximize their summed value.- Input:
- Item count of each kind , where .
- Item weights, denoted as .
- Item values, denoted as .
- Weight constraint .
- Output:
- Item assignment that maximizes the value: subject to a weight constraint: .
- The feasible value for a given assignment is the value sum if the constraint is satisfied and otherwise zero.
- 2 item types:
- with ,
- with ,
Exercise 1: Modeling the Knapsack Problem
In this exercise we will model the knapsack problem in Qmod.- Use quantum numeric variables as fields of a quantum struct to represent the item counts.
- Use quantum expressions to represent the value and weight, as well as the constraint.
Output:
The assignment a=3 and b=2 is the optimal solution for our toy model with value 19, but any violation of the constraint is value
Having defined the variables using Qmod types, the problem can be captured directly in Qmod expressions.
Execution Utility Function
You can skip this section if you are not interested in the details of the execution flow we shall subsequently use. They are not important for our exercise. With the above general problem description we can define a helper function that optimizes the anasatz parameters for our knapsack problem and displays the results. The flow is not different from the example we saw above. , but note that we optimize on a function that reflects a linear gradiant for both the knapsack value and the violation of the constraint. Based on the optimized parameters, we sample the ansatz and calculate the probability of samples that satisfy the constraint, the average value of the feasible samples, and the overall value average. We will compare the different ansatz structures, keeping all other parameters fixed, and specifically using the same logic to obtain these results.Representing Hard Constraints as Cost
The cost operator in QAOA is typically defined in terms of QUBO expressions, or more generally low-degree polynomials over problem variables. In Qmod this is directly expressible using the phase statement. But logical operators are not allowed in the phase expression, because they cannot be reduced to low-degree polynomials. The feasible value defined by the problem is the value sum if the constraint is satisfied and otherwise zero. An expression of this form cannot be used directly in phase statement. A common approach is to add to the overall cost a penalty term for violating the constraint. For equality constraints we can square the difference between the variable expression and its target to obtain a non-negative penalty. However, in the knapsack case we need to represent an inequality constraint. An inequality expression can be rewritten as an equality by introducing a non-negative slack (“don’t-care”) variable that represents the difference between the left and right sides of the inequality. When evaluating an assignment the slack variable is disregarded. As an example, the constraint can be expressed as . In this case the penalty will be . The cost layer multiplies the penalty term can be given more significance by multiplying it by a constant “penalty factor”, e.g. . The penalty approach has the downside of not representing the true semantics of the problem. It incentivises assignments that have high value with only a small violation of the constraint. But our problem is defined in terms of a hard constraint, where even a small violation means zero actual value. In Exercise 2 we will define the cost operator in terms of the constraint penalty term, and in Exercise 3 we will define it to accurately capture the Boolean condition.Exercise 2: The Knapsack Constraint as a Penalty Term
In this exercise we will implement the knapsack problem using a penalty term to represent the constraint.-
Use the fields of struct
KnapsackVarsPenaltyto express the penalty term. - Define the cost layer in terms of the value sum and the penalty term.
- Execute the algorithm and observe the results:
- What is the probability of a feasible sample? What is the average value of the feasible samples?
- How many iterations did it take to converge to a solution?
Output:
Output:

Output:
Output:
Output:
The overall score is the expectation value of assignments, computed on a large sample.The table shows a small sample from the same distribution, with assignments and their value.Value 0 typically means a violation of the constraint.
The cost function, including the penalty for the violation of an inequality constraint can be expressed in Qmod directly as a second degree polynomial.
Exercise 3: The Knapsack Constraint as a Boolean Condition
In this exercise we will implement the knapsack problem using a Boolean condition to represent the constraint.- Use the fields of struct
KnapsackVars(from Exercise 1) to express the cost layer as a phase shift for the value sum, conditioned on the constraint. - Look at the quantum program visualization and note the structure of the cost layer.
- Execute the algorithm and inspect the results:
- How does the probability of a feasible sample and the average value compare to the penalty-term approach?
- How many iterations did it take to converge to a solution with this ansatz structure?
Output:
Output:

Output:
Output:
Output:
The optimizer converges with fewer iterations using the more accurate ansatz, compared to the one in Exercise 2.The expectation value of the distribution is often also improved, but this varies and is sensitive to the random decisions of the optimizer.
The QAOA cost layer in Qmod can comprise computational-basis conditions and polynomial evaluation in the phase, which together represent the true semantics of the problem.Note that phase oracle in Grover search (as shown in Part I, Exercise 5) can be seen as a special case of such a QAOA cost layer, with only a Boolean condition and no phase preference between the “good” states.
Solutions
Solution to Exercise 1
Output:
Solution to Exercise 2

Output:
Output:
Output:
Solution to Exercise 3

Output:
Output:
Output: