qiskit-community / qiskit-aqua

Quantum Algorithms & Applications (**DEPRECATED** since April 2021 - see readme for more info)
https://qiskit.org/aqua
Apache License 2.0
573 stars 376 forks source link

the changes of cplex_ising.py based on the change in Terra #193

Closed chunfuchen closed 5 years ago

chunfuchen commented 5 years ago

Since terra changes the order of Pauli, we might need to address how cplex_ising to handle the Pauli label.

I made one version that works for the newest Terra but maybe there is a better to do that.

chunfuchen commented 5 years ago

here is the line I changed. https://github.com/Qiskit/aqua/blob/master/qiskit_aqua/algorithms/classical/cplex/cplex_ising.py#L154

@t-imamichi if you think it is okay, we can close this issue.

t-imamichi commented 5 years ago

I tried it with https://github.com/Qiskit/qiskit-tutorial/blob/master/community/aqua/optimization/maxcut.ipynb; but errors occur when importing get_algorithm_instance and get_input_instance. Can you check it? I cannot run aqua-master.

t-imamichi commented 5 years ago

I cannot find get_input_instance in aqua-master. Where can I find the information of the change?

chunfuchen commented 5 years ago

@t-imamichi Thanks for your help.

There are numerous changes in Aqua recently. One major change is that for the programmatic users, they won't be able to use get_xxx_instance anymore. They will construct the object directly, and the same thing for get_input_instance.

Let me paste an updated script for that notebook later.

chunfuchen commented 5 years ago

here you are


# coding: utf-8

# ## _*Using Qiskit Aqua for maxcut problems*_
# 
# This Qiskit Aqua Optimization notebook demonstrates how to use the VQE quantum algorithm to compute the max cut of a given graph. 
# 
# The problem is defined as follows. Given a graph $G = (V,E)$ with weights $w_{ij}$ on the edges, we are looking for a subset $S \subseteq V$ such that $\sum_{(i,j) \in E : i \in S, j \not\in S} w_{ij}$ is maximized.
# 
# The graph provided as an input is used first to generate an Ising Hamiltonian, which is then passed as an input to VQE.  As a reference, this notebook also computes the max cut using the Exact Eigensolver classical algorithm and the solver embedded in the commercial non-quantum IBM CPLEX product (if it is available in the system and the user has followed the necessary configuration steps in order for Qiskit Aqua to find it).  Please refer to the Qiskit Aqua Optimization documentation for installation and configuration details for CPLEX.

# In[2]:

from qiskit_aqua import Operator, run_algorithm
from qiskit_aqua.input import EnergyInput
from qiskit_aqua.translators.ising import maxcut
import numpy as np

# Here an Operator instance is created for our Hamiltonian. In this case the paulis are from an Ising Hamiltonian translated from the max cut problem. We load a small sample instance of the maxcut problem.

# In[3]:

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

# We also offer a function to generate a random graph as a input.

# In[4]:

if True:
    np.random.seed(8123179)
    w = maxcut.random_graph(4, edge_prob=0.5, weight_range=10)
    qubitOp, offset = maxcut.get_maxcut_qubitops(w)
    algo_input.qubit_op = qubitOp
print(w)

# Here we test for the presence of algorithms we want to use in this notebook. If Aqua is installed correctly `ExactEigensolver` and `VQE` will always be found. `CPLEX.Ising` is dependent on IBM CPLEX being installed (see introduction above). CPLEX is *not required* but if installed then this notebook will demonstrate the `CPLEX.Ising` algorithm , that uses CPLEX, to compute maxcut as well.

# In[4]:

# to_be_tested_algos = ['ExactEigensolver', 'CPLEX.Ising', 'VQE']
# operational_algos = []
# for algo in to_be_tested_algos:
#     try:
#         get_algorithm_instance(algo)
#         operational_algos.append(algo)
#     except:
#         print("{} is unavailable and will be skipped.".format(algo))
# print(operational_algos)

# We can now use the Operator without regard to how it was created. First we need to prepare the configuration params to invoke the algorithm. Here we will use the ExactEigensolver first to return the smallest eigenvalue. Backend is not required since this is computed classically not using quantum computation. We then add in the qubitOp Operator in dictionary format. Now the complete params can be passed to the algorithm and run. The result is a dictionary.

# In[5]:

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

params = {
    'problem': {'name': 'ising'},
    'algorithm': algorithm_cfg
}
result = run_algorithm(params,algo_input)
# print('objective function:', maxcut.maxcut_obj(result, offset))
x = maxcut.sample_most_likely(result['eigvecs'][0])
print('energy:', result['energy'])
print('maxcut objective:', result['energy'] + offset)
print('solution:', maxcut.get_graph_solution(x))
print('solution objective:', maxcut.maxcut_value(x, w))

# *Note*: IBM CPLEX is an _optional_ installation addition for Aqua. If installed then the Aqua CPLEX.Ising algorithm will be able to be used. If not, then solving this problem using this particular algorithm will simply be skipped. 
# 
# We change the configuration parameters to solve it with the CPLEX backend. The CPLEX backend can deal with a particular type of Hamiltonian called Ising Hamiltonian, which consists of only Pauli Z at most second order and often for combinatorial optimization problems that can be formulated as quadratic unconstrained binary optimization problems, such as the max-cut problem.
# 
# Note that for a maxcut problem, since we are computing a bipartition of the graph, every binary vector $x$ and its complement (i.e., the vector $y$ such that $y_j = 1 - x_j$ for all $j$) represent exactly the same solution, and will have the same objective function value. Different solution methods may return solutions that look different, but in fact have the same objective function value.

# In[7]:

try:
    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('maxcut objective:', result['energy'] + offset)
    x = np.array([x_dict[i] for i in sorted(x_dict.keys())])
    print('solution:', maxcut.get_graph_solution(x))
    print('solution objective:', maxcut.maxcut_value(x, w))
except Exception as e:
    print(e)

# Now we want VQE and so change it and add its other configuration parameters. VQE also needs and optimizer and variational form. While we can omit them from the dictionary, such that defaults are used, here we specify them explicitly so we can set their parameters as we desire.

# In[6]:

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

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

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': {'name': 'statevector_simulator'}
}

result = run_algorithm(params,algo_input)

x = maxcut.sample_most_likely(result['eigvecs'][0])
print('energy:', result['energy'])
print('time:', result['eval_time'])
print('maxcut objective:', result['energy'] + offset)
print('solution:', maxcut.get_graph_solution(x))
print('solution objective:', maxcut.maxcut_value(x, w))
t-imamichi commented 5 years ago

Thank you for the information. I checked the code and noticed a bug. I make a PR https://github.com/Qiskit/aqua/pull/203 Your maxcut scripts works well with the PR.