# Import auxiliary libraries

# Import Qiskit
from qiskit import Aer
from qiskit.algorithms import QAOA, NumPyMinimumEigensolver
from qiskit.utils import QuantumInstance

from qiskit_optimization import QuadraticProgram
from qiskit_optimization.algorithms import MinimumEigenOptimizer

qp_ex = QuadraticProgram()

qp_ex.integer_var(lowerbound=0, upperbound=100, name='x')
qp_ex.integer_var(lowerbound=0, upperbound=100, name='y')

qp_ex.maximize(linear={'x': 100, 'y': 40})

qp_ex.linear_constraint(linear={'x': 100, 'y': 50}, sense='LE', rhs=3000, name='constraints_1')
qp_ex.linear_constraint(linear={'x': 10},           sense='LE', rhs=100,  name='constraints_2')

print(qp_ex.export_as_lp_string())

qp = QuadraticProgram()

qp.integer_var(lowerbound=0, upperbound=5, name='x')
qp.integer_var(lowerbound=0, upperbound=5, name='y')

qp.maximize(linear={'x': 3, 'y': 2})

qp.linear_constraint(linear={'x': 1, 'y': 2},  sense='LE', rhs=4, name='constraints_1')
qp.linear_constraint(linear={'x': 1        },  sense='LE', rhs=2, name='constraints_2')

print(qp.export_as_lp_string())

qins = QuantumInstance(backend=Aer.get_backend('qasm_simulator'), shots=1000, seed_simulator=0)

meo = MinimumEigenOptimizer(min_eigen_solver=QAOA(reps=1, quantum_instance=qins)) # Define QAOA solver

result = meo.solve(qp)

print('result:', result._variables_dict)
# print('status:', result._status)
# print('time:', result.min_eigen_solver_result.optimizer_time)

exact_mes = NumPyMinimumEigensolver()
exact = MinimumEigenOptimizer(exact_mes) # Using the exact classical numpy minimum eigen solver

exact_result = exact.solve(qp)

print('result:', exact_result._variables_dict)
# print('status:', exact_result._status)