- Manufacturing
Continental: QAOA for Autonomous Vehicle Path Planning
Continental AG
Continental's autonomous vehicle division formulated urban path planning as a QUBO problem and tested QAOA on small road network instances, alongside a quantum CNN for road sign classification using PennyLane.
- Key Outcome
- QAOA matched classical Dijkstra quality on 10-intersection instances. Quantum CNN matched classical accuracy with 4x fewer parameters on a small sign classification dataset. No practical advantage found yet. Continental identified QUBO formulation methodology as the primary contribution.
The Problem
Autonomous vehicles must compute optimal paths in real time through dense urban grids. With complex constraints added (turn penalties, lane restrictions, pedestrian zones, time-varying closures), path planning becomes NP-hard. Continental’s AV division tested whether QAOA could improve solution quality for constrained edge cases where classical planners struggle. A second thread explored quantum ML for road sign classification.
QUBO Formulation and QAOA
The road network is a directed graph. Binary variable x_{ij} = 1 means the path uses edge (i, j). The objective minimizes total edge cost. Flow conservation constraints enforce that routes are connected from source to destination.
import numpy as np
from qiskit_optimization import QuadraticProgram
from qiskit_optimization.converters import QuadraticProgramToQubo
from qiskit_algorithms import QAOA
from qiskit_algorithms.optimizers import COBYLA
from qiskit.primitives import Sampler
from qiskit_optimization.algorithms import MinimumEigenOptimizer
import heapq
# Small road network: 5 intersections, 8 directed edges
edges = [
(0, 1, 2.0), (0, 2, 4.5),
(1, 2, 1.5), (1, 3, 3.0),
(2, 3, 2.0), (2, 4, 5.0),
(3, 4, 1.5), (1, 4, 8.0),
]
n_nodes = 5
source, destination = 0, 4
qp = QuadraticProgram(name="PathPlanning")
for i, j, cost in edges:
qp.binary_var(name=f"x_{i}_{j}")
linear_costs = {f"x_{i}_{j}": cost for (i, j, cost) in edges}
qp.minimize(linear=linear_costs)
for node in range(n_nodes):
out = [f"x_{i}_{j}" for (i, j, _) in edges if i == node]
inn = [f"x_{i}_{j}" for (i, j, _) in edges if j == node]
sign = 1 if node != destination else -1
coeffs = {v: sign for v in out}
coeffs.update({v: -sign for v in inn})
rhs = 0 if node not in (source, destination) else 1
qp.linear_constraint(linear=coeffs, sense="==", rhs=rhs,
name=f"flow_{node}")
converter = QuadraticProgramToQubo()
qubo = converter.convert(qp)
print(f"QUBO variables: {qubo.get_num_vars()}")
# Run QAOA
qaoa = QAOA(sampler=Sampler(), optimizer=COBYLA(maxiter=300), reps=2)
result = MinimumEigenOptimizer(qaoa).solve(qubo)
print(f"QAOA objective: {result.fval:.3f}")
# Classical Dijkstra baseline
def dijkstra(edges, n, src, dst):
g = {i: [] for i in range(n)}
for (i, j, c) in edges: g[i].append((c, j))
d = {i: float("inf") for i in range(n)}; d[src] = 0
pq = [(0, src)]
while pq:
cost, u = heapq.heappop(pq)
if cost > d[u]: continue
for c, v in g[u]:
if d[u] + c < d[v]: d[v] = d[u] + c; heapq.heappush(pq, (d[v], v))
return d[dst]
print(f"Dijkstra: {dijkstra(edges, n_nodes, source, destination):.3f}")
Quantum CNN for Road Sign Classification
PennyLane’s quantum transfer learning approach connects a classical ResNet feature extractor to a small variational quantum circuit as the classification head.
import pennylane as qml
from pennylane import numpy as np
import torch
import torch.nn as nn
n_qubits = 4
dev = qml.device("default.qubit", wires=n_qubits)
@qml.qnode(dev, interface="torch")
def quantum_classifier(inputs, weights):
qml.AngleEmbedding(inputs, wires=range(n_qubits), rotation="Y")
qml.BasicEntanglerLayers(weights, wires=range(n_qubits))
return [qml.expval(qml.PauliZ(i)) for i in range(n_qubits)]
class HybridQCNN(nn.Module):
def __init__(self, n_classes):
super().__init__()
import torchvision.models as models
resnet = models.resnet18(pretrained=True)
self.features = nn.Sequential(*list(resnet.children())[:-1])
self.compress = nn.Linear(512, n_qubits)
self.q_weights = nn.Parameter(torch.randn(3, n_qubits))
self.out = nn.Linear(n_qubits, n_classes)
def forward(self, x):
f = self.features(x).squeeze(-1).squeeze(-1)
c = torch.tanh(self.compress(f)) * np.pi
q = torch.stack([
torch.tensor(quantum_classifier(c[i], self.q_weights),
dtype=torch.float32)
for i in range(x.shape[0])
])
return self.out(q)
# Quantum head: 3*4=12 params vs 5120 for a classical dense layer
Results and Assessment
QAOA at p=2 matched or approached Dijkstra optimality on 8 of 10 tested instances (5-10 intersections). Scaling to 15+ intersections required 30+ qubits where noise dominated. The hybrid quantum CNN matched classical ResNet accuracy (87% top-1) on a 10-class sign dataset with 4x fewer parameters in the classification head. No near-term advantage was demonstrated. Continental’s primary contribution is the QUBO flow conservation encoding, reusable when hardware reaches 50-100 clean qubits.
Learn more: Qiskit Reference | PennyLane Reference