I like to use as custom Mixer Hamiltonian for solving the TSP using QAOA. The mixer and cost hamiltonians are described here: https://arxiv.org/pdf/1709.03489.pdf - Chapter 5.1.
Therefore I need to write the custom mixer hamiltonian from equations 54 -58.
Here is the code:
import numpy as np
from qiskit import Aer
from qiskit.aqua import QuantumInstance
from qiskit.quantum_info.operators import Operator, Pauli
from qiskit.aqua.operators.list_ops import SummedOp
from qiskit.aqua.algorithms import QAOA
from qiskit.aqua.components.optimizers import SPSA
from qiskit.optimization.applications.ising importtsp
def pauli(pos, num_qubits, label):
label = 'I'*(pos) + label + 'I'*(num_qubits-pos-1)
assert(len(label) == num_qubits)
return Operator(Pauli(label=label))
def s_plus(number_of_nodes, city, time):
num_qubits = number_of_nodes**2
qubit = time * number_of_nodes + city
return pauli(qubit, num_qubits, "X") + pauli(qubit, num_qubits, "Y")
def s_minus(number_of_nodes, city, time):
num_qubits = number_of_nodes**2
qubit = time * number_of_nodes + city
return pauli(qubit, num_qubits, "X") - pauli(qubit, num_qubits, "Y")
def create_mixer_operators(n):
"""
Creates mixer operators for the QAOA.
It's based on equations 54 - 58 from https://arxiv.org/pdf/1709.03489.pdf
Indexing here comes directly from section 4.1.2 from paper 1709.03489, equations 54 - 58.
"""
mixer_operators = []
for t in range(n - 1):
for city_1 in range(n):
for city_2 in range(n):
i = t
u = city_1
v = city_2
first_part = 1
first_part *= s_plus(n, u, i)
first_part *= s_plus(n, v, i+1)
first_part *= s_minus(n, u, i+1)
first_part *= s_minus(n, v, i)
second_part = 1
second_part *= s_minus(n, u, i)
second_part *= s_minus(n, v, i+1)
second_part *= s_plus(n, u, i+1)
second_part *= s_plus(n, v, i)
mixer_operators.append(first_part + second_part)
return mixer_operators
seed = 10598
n = 3
p = 2
num_qubits = n ** 2
# Generate random tsp
ins = tsp.random_tsp(n, seed=seed)
qubitOp, offset = tsp.get_operator(ins)
# Running in quantum simulation
aqua_globals.random_seed = np.random.default_rng(seed)
backend = Aer.get_backend('qasm_simulator')
quantum_instance = QuantumInstance(backend, seed_simulator=seed, seed_transpiler=seed)
mixer = create_mixer_operators(n)
mixer_op = SummedOp(mixer)
spsa = SPSA(maxiter=300)
qaoa = QAOA(operator=qubitOp, mixer=mixer_op, p=p, optimizer=spsa, quantum_instance=quantum_instance)
circuits = qaoa.construct_circuit([0]*(2*p))
When runnning it I get:
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-113-bd68aaa30bfc> in <module>
----> 1 circuits = qaoa.construct_circuit([0]*(2*p))
~/masterarbeit/code/venv/lib/python3.6/site-packages/qiskit/aqua/algorithms/minimum_eigen_solvers/vqe.py in construct_circuit(self, parameter)
358 A list of the circuits used to compute the expectation value.
359 """
--> 360 expect_op = self.construct_expectation(parameter).to_circuit_op()
361
362 circuits = []
~/masterarbeit/code/venv/lib/python3.6/site-packages/qiskit/aqua/algorithms/minimum_eigen_solvers/vqe.py in construct_expectation(self, parameter)
331 wave_function = self.var_form.assign_parameters(param_dict)
332 else:
--> 333 wave_function = self.var_form.construct_circuit(parameter)
334
335 # Expectation was never created, try to create one
~/masterarbeit/code/venv/lib/python3.6/site-packages/qiskit/aqua/algorithms/minimum_eigen_solvers/qaoa/var_form.py in construct_circuit(self, parameters, q)
96
97 evolution = EvolutionFactory.build(self._cost_operator)
---> 98 circuit = evolution.convert(circuit)
99 return circuit.to_circuit()
100
~/masterarbeit/code/venv/lib/python3.6/site-packages/qiskit/aqua/operators/evolutions/pauli_trotter_evolution.py in convert(self, operator)
100 # # Sort into commuting groups
101 # operator = self._grouper.convert(operator).reduce()
--> 102 return self._recursive_convert(operator)
103
104 def _recursive_convert(self, operator: OperatorBase) -> OperatorBase:
~/masterarbeit/code/venv/lib/python3.6/site-packages/qiskit/aqua/operators/evolutions/pauli_trotter_evolution.py in _recursive_convert(self, operator)
127 return operator.primitive.__class__(converted_ops, coeff=operator.coeff)
128 elif isinstance(operator, ListOp):
--> 129 return operator.traverse(self.convert).reduce()
130
131 return operator
~/masterarbeit/code/venv/lib/python3.6/site-packages/qiskit/aqua/operators/list_ops/list_op.py in traverse(self, convert_fn, coeff)
161 return ListOp([convert_fn(op) for op in self.oplist], # type: ignore
162 combo_fn=self.combo_fn, coeff=coeff, abelian=self.abelian)
--> 163 return self.__class__([convert_fn(op) for op in self.oplist], # type: ignore
164 coeff=coeff, abelian=self.abelian)
165
~/masterarbeit/code/venv/lib/python3.6/site-packages/qiskit/aqua/operators/list_ops/list_op.py in <listcomp>(.0)
161 return ListOp([convert_fn(op) for op in self.oplist], # type: ignore
162 combo_fn=self.combo_fn, coeff=coeff, abelian=self.abelian)
--> 163 return self.__class__([convert_fn(op) for op in self.oplist], # type: ignore
164 coeff=coeff, abelian=self.abelian)
165
~/masterarbeit/code/venv/lib/python3.6/site-packages/qiskit/aqua/operators/evolutions/pauli_trotter_evolution.py in convert(self, operator)
100 # # Sort into commuting groups
101 # operator = self._grouper.convert(operator).reduce()
--> 102 return self._recursive_convert(operator)
103
104 def _recursive_convert(self, operator: OperatorBase) -> OperatorBase:
~/masterarbeit/code/venv/lib/python3.6/site-packages/qiskit/aqua/operators/evolutions/pauli_trotter_evolution.py in _recursive_convert(self, operator)
104 def _recursive_convert(self, operator: OperatorBase) -> OperatorBase:
105 if isinstance(operator, EvolvedOp):
--> 106 if not {'Pauli'} == operator.primitive_strings():
107 logger.warning('Evolved Hamiltonian is not composed of only Paulis, converting to '
108 'Pauli representation, which can be expensive.')
~/masterarbeit/code/venv/lib/python3.6/site-packages/qiskit/aqua/operators/evolutions/evolved_op.py in primitive_strings(self)
53
54 def primitive_strings(self) -> Set[str]:
---> 55 return self.primitive.primitive_strings() # type: ignore
56
57 @property
~/masterarbeit/code/venv/lib/python3.6/site-packages/qiskit/aqua/operators/list_ops/list_op.py in primitive_strings(self)
126
127 def primitive_strings(self) -> Set[str]:
--> 128 return reduce(set.union, [op.primitive_strings() for op in self.oplist])
129
130 @property
~/masterarbeit/code/venv/lib/python3.6/site-packages/qiskit/aqua/operators/list_ops/list_op.py in <listcomp>(.0)
126
127 def primitive_strings(self) -> Set[str]:
--> 128 return reduce(set.union, [op.primitive_strings() for op in self.oplist])
129
130 @property
AttributeError: 'Operator' object has no attribute 'primitive_strings'
How do I resolve the error? This is my first project with qiskit and I am not sure where to start.
tsp
anywhere in your code. Could you also post complete error message? $\endgroup$