import numpy as np

from qiskit_aqua import Operator, run_algorithm
from qiskit_aqua.translators.ising import stableset
from qiskit_aqua.input import EnergyInput
from qiskit_aqua.algorithms.classical.cplex.cplex_ising import CPLEX_Ising
from qiskit import Aer

w = stableset.parse_gset_format('sample.maxcut')
qubitOp, offset = stableset.get_stableset_qubitops(w)
algo_input = EnergyInput(qubitOp)

if True:
    np.random.seed(8123179)
    w = stableset.random_graph(5, edge_prob=0.5)
    qubitOp, offset = stableset.get_stableset_qubitops(w)
    algo_input.qubit_op = qubitOp
print(w)

to_be_tested_algos = ['ExactEigensolver', 'CPLEX.Ising', 'VQE']
print(to_be_tested_algos)

algorithm_cfg = {
    'name': 'ExactEigensolver',
}

params = {
    'problem': {'name': 'ising'},
    'algorithm': algorithm_cfg
}
result = run_algorithm(params,algo_input)

x = stableset.sample_most_likely(result['eigvecs'][0])
print('energy:', result['energy'])
print('stable set objective:', result['energy'] + offset)
print('solution:', stableset.get_graph_solution(x))
print('solution objective and feasibility:', stableset.stableset_value(x, w))

cplex_installed = True
try:
    CPLEX_Ising.check_pluggable_valid()
except Exception as e:
    cplex_installed = False


if cplex_installed:
    algorithm_cfg = {
        'name': 'CPLEX.Ising',
        'display': 0
    }

    params = {
        'problem': {'name': 'ising'},
        'algorithm': algorithm_cfg
    }

    result = run_algorithm(params, algo_input)

    x_dict = result['x_sol']
    print('energy:', result['energy'])
    print('time:', result['eval_time'])
    print('stable set objective:', result['energy'] + offset)
    x = np.array([x_dict[i] for i in sorted(x_dict.keys())])
    print('solution:', stableset.get_graph_solution(x))
    print('solution objective and feasibility:', stableset.stableset_value(x, w))

algorithm_cfg = {
    'name': 'VQE',
    'operator_mode': 'matrix'
}

optimizer_cfg = {
    'name': 'L_BFGS_B',
    'maxfun': 2000
}

var_form_cfg = {
    'name': 'RYRZ',
    'depth': 3,
    'entanglement': 'linear'
}

params = {
    'problem': {'name': 'ising'},
    'algorithm': algorithm_cfg,
    'optimizer': optimizer_cfg,
    'variational_form': var_form_cfg
}

backend = Aer.get_backend('statevector_simulator')
result = run_algorithm(params, algo_input, backend=backend)

x = stableset.sample_most_likely(result['eigvecs'][0])
print('energy:', result['energy'])
print('time:', result['eval_time'])
print('stable set objective:', result['energy'] + offset)
print('solution:', stableset.get_graph_solution(x))
print('solution objective and feasibility:', stableset.stableset_value(x, w))