If you need more control than the high-level Workflow API provides, you can use 'Factory Mode' to manually construct the components. This involves:
- Defining Hamiltonians: Use
Hamiltonian.classical_hamiltonian for the cost and X_mixer_hamiltonian for the mixer. - Creating Descriptors: Use
QAODescriptor to bundle the Hamiltonians and circuit depth p. - Generating Parameters: Use
create_qaoa_variational_params to generate initial variational parameters. - Instantiating Backend: Create a backend object (e.g.,
QAOAvectorizedBackendSimulator). - Optimizing: Pass the backend and parameters to a
ScipyOptimizer and call it.
The results are retrieved via optimizer_obj.qaoa_result.asdict().
from openqaoa.qaoa_components import Hamiltonian, QAOADescriptor, create_qaoa_variational_params
from openqaoa.utilities import X_mixer_hamiltonian
from openqaoa.backends.qaoa_backend import QAOAvectorizedBackendSimulator
from openqaoa.optimizers.qaoa_optimizer import ScipyOptimizer
# 1. Define Hamiltonians
terms = [(1,2),(2,3),(0,3),(4,0),(1,),(3,)]
coeffs = [1,2,3,4,3,5]
n_qubits = 5
cost_hamil = Hamiltonian.classical_hamiltonian(terms=terms, coeffs=coeffs, constant=0)
mixer_hamil = X_mixer_hamiltonian(n_qubits=n_qubits)
# 2. Create Descriptor and Params
qaoa_descriptor = QAOADescriptor(cost_hamil, mixer_hamil, p=1)
params = create_qaoa_variational_params(qaoa_descriptor, params_type='fourier', init_type='rand', q=1)
# 3. Setup Backend and Optimizer
backend_obj = QAOAvectorizedBackendSimulator(qaoa_descriptor=qaoa_descriptor, append_state=None, prepend_state=None, init_hadamard=True)
optimizer_dict = {'method': 'cobyla', 'maxiter': 200}
optimizer_obj = ScipyOptimizer(backend_obj, params, optimizer_dict)
# 4. Run
optimizer_obj()
print(optimizer_obj.qaoa_result.asdict())