- Telecommunications
Ericsson: Quantum Optimization for 5G Spectrum Allocation
Ericsson
Ericsson's research labs formulated 5G spectrum allocation as a graph coloring QUBO and tested D-Wave hybrid solvers and QAOA on IBM hardware against classical Gurobi and simulated annealing baselines across 10-200 cell instances.
- Key Outcome
- D-Wave hybrid matched Gurobi solution quality on 50-200 cell spectrum allocation instances and ran 40% faster on medium instances. QAOA at p=2 was competitive on 10-cell instances. Ericsson identified hybrid quantum-classical decomposition as the most viable near-term path.
The Problem
A 5G network spanning a city involves thousands of base stations, each transmitting on one or more frequency channels. Adjacent cells must use different channels to avoid interference. This is graph coloring: assign colors (channels) to nodes (cells) so no two adjacent nodes share a color, using the minimum number of colors. Each saved channel band represents hundreds of millions in licensing costs.
Ericsson’s research team tested whether quantum solvers could find better spectrum assignments than classical methods on realistic network topologies.
Graph Coloring as QUBO
For each cell i and channel k, define x_{i,k} = 1 if cell i uses channel k. The QUBO penalizes two violations: each cell uses exactly one channel, and adjacent cells share no channel.
import dimod
import networkx as nx
def spectrum_allocation_qubo(graph: nx.Graph, n_channels: int,
A: float = 5.0, B: float = 3.0):
"""
Build QUBO for spectrum allocation (graph coloring).
Variable x[i*n_channels + k] = 1 means cell i uses channel k.
Penalty A: each cell uses exactly one channel (sum_k x_{i,k} = 1).
Penalty B: adjacent cells use different channels (x_{i,k} * x_{j,k} = 0).
"""
nodes = list(graph.nodes())
node_idx = {n: i for i, n in enumerate(nodes)}
Q = {}
var = lambda i, k: i * n_channels + k
for i in range(len(nodes)):
for k in range(n_channels):
v = var(i, k)
Q[(v, v)] = Q.get((v, v), 0) + A * (1 - 2)
for k2 in range(k + 1, n_channels):
Q[(v, var(i, k2))] = Q.get((v, var(i, k2)), 0) + 2 * A
for (u, w) in graph.edges():
i, j = node_idx[u], node_idx[w]
for k in range(n_channels):
vi, vj = var(i, k), var(j, k)
key = (min(vi, vj), max(vi, vj))
Q[key] = Q.get(key, 0) + B
return dimod.BinaryQuadraticModel.from_qubo(Q)
G = nx.convert_node_labels_to_integers(nx.hexagonal_lattice_graph(2, 2))
n_channels = 3
bqm = spectrum_allocation_qubo(G, n_channels)
print(f"Network: {G.number_of_nodes()} cells, {G.number_of_edges()} edges")
print(f"QUBO: {len(bqm.variables)} variables, {len(bqm.quadratic)} interactions")
Solving with D-Wave Hybrid and QAOA
For real network instances (50-200 cells), Ericsson used D-Wave’s hybrid solver, which partitions large QUBOs across quantum annealing and classical heuristics.
from dwave.system import LeapHybridSampler
from qiskit import QuantumCircuit
from qiskit.circuit import ParameterVector
from qiskit_aer import AerSimulator
from scipy.optimize import minimize
import numpy as np
# D-Wave hybrid solver for 50-200 cell instances
result = LeapHybridSampler().sample(bqm, time_limit=5, label="ericsson-5g-spectrum")
sample = result.first.sample
assignment = {i: k for i in range(G.number_of_nodes())
for k in range(n_channels) if sample.get(i * n_channels + k, 0) == 1}
conflicts = sum(1 for u, v in G.edges() if assignment.get(u) == assignment.get(v))
print(f"D-Wave: energy={result.first.energy:.2f} conflicts={conflicts}")
# QAOA on small instance (4-cell path graph, 2 channels)
p, small_G = 2, nx.path_graph(4)
small_bqm = spectrum_allocation_qubo(small_G, n_channels=2)
qubo_dict = dict(small_bqm.to_qubo()[0])
n_vars = small_G.number_of_nodes() * 2
gamma, beta = ParameterVector("g", p), ParameterVector("b", p)
qc = QuantumCircuit(n_vars, n_vars)
qc.h(range(n_vars))
for layer in range(p):
for (i, j), w in qubo_dict.items():
if i != j and w:
qc.rzz(2 * gamma[layer] * w, i, j)
for i in range(n_vars):
if qubo_dict.get((i, i), 0):
qc.rz(2 * gamma[layer] * qubo_dict[(i, i)], i)
for i in range(n_vars):
qc.rx(2 * beta[layer], i)
qc.measure(range(n_vars), range(n_vars))
sim = AerSimulator()
def cost(params):
bound = qc.assign_parameters(list(params[:p]) + list(params[p:]))
counts = sim.run(bound, shots=1024).result().get_counts()
return sum(small_bqm.energy({i: int(b) for i, b in enumerate(reversed(bs))}) * c
for bs, c in counts.items()) / 1024
res = minimize(cost, np.random.rand(2 * p) * np.pi, method="COBYLA")
print(f"QAOA p=2 energy: {res.fun:.3f}")
Results and Architecture
| Instance size | Gurobi | D-Wave hybrid | QAOA p=2 |
|---|---|---|---|
| 10 cells | Optimal (0.1s) | Optimal (2s) | Near-optimal |
| 50 cells | Optimal (4s) | Optimal (2.4s) | Not tested |
| 200 cells | Feasible (210s) | Feasible (3.5s) | Not tested |
D-Wave hybrid matched Gurobi solution quality up to 200 cells and ran 40% faster on 50-cell instances. QAOA at p=2 approached optimal on 10-cell simulator runs; real hardware required error mitigation and was impractical beyond 15 cells.
The most practical near-term architecture Ericsson identified uses classical decomposition: partition the full network into dense subgraphs, route each to the quantum solver, and assemble the global solution classically. This lets quantum solvers contribute value on subproblems sized to available qubit counts without requiring a monolithic quantum solution.
Learn more: D-Wave Ocean SDK Reference