Skip to content

Number Partitioning

In the Number Partitioning problem, the goal is to find, given a set of k positive numbers S={n1,,nk}, whether there exists a partition of this set of numbers into two disjoint sets R and SR such that the sum of the elements in both sets is as close as possible.

For example, given the set of numbers S={1,2,3,6,10}, one can find that there is a perfect number partition since we can take R={2,3,6} and SR={1,10}, so that |R|=|SR|=11.

A Kind of Knapsack Problem

The Number Partitioning problem can be seen as a special case of the Knapsack problem, where there are n items with same value, and the weight capacity is W=12iknk.

The Cost Function

The function to minimize can be defined as

C(σ)=(i=1kniσi)2=i,j=1kninjσiσj,

where σ{1,1}k. That is, a variable σi is attached to each number ni, and the variable's value determines on which side of the partition the number is assigned to. The smallest value C() can take is 0, which happens when σ is a perfect partition.

Since this formulation is already in terms of Ising variables, it can be used directly in QAOA.

Number Partitioning in OpenQAOA

The Number Partitioning problem is defined by a set of integers, you can thus define the problem as follows:

from openqaoa.problems import NumberPartition

int_set = [1,2,3,4,10]

np_prob = NumberPartition(numbers=int_set)
np_qubo = np_prob.qubo

We can then access the underlying cost hamiltonian

np_qubo.hamiltonian.expression
12.0Z1Z2+130+16.0Z1Z3+20.0Z0Z4+24.0Z2Z3+4.0Z0Z1+40.0Z1Z4+6.0Z0Z2+60.0Z2Z4+8.0Z0Z3+80.0Z3Z4

You may also check all details of the problem instance in the form of a dictionary:

> np_qubo.asdict()

{'constant': 130,
 'metadata': {},
 'n': 5,
 'problem_instance': {'n_numbers': 5,
                      'numbers': [1, 2, 3, 4, 10],
                      'problem_type': 'number_partition'},
 'terms': [[0, 1],
           [0, 2],
           [0, 3],
           [0, 4],
           [1, 2],
           [1, 3],
           [1, 4],
           [2, 3],
           [2, 4],
           [3, 4]],
 'weights': [4.0, 6.0, 8.0, 20.0, 12.0, 16.0, 40.0, 24.0, 60.0, 80.0]}