Skip to content
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
68 commits
Select commit Hold shift + click to select a range
3d1435e
add docplex.mp translator
t-imamichi May 10, 2021
29a1036
revise type
t-imamichi May 10, 2021
6f61abf
Merge branch 'main' into translator2
t-imamichi May 10, 2021
a3622f4
revert a comment
t-imamichi May 10, 2021
63f1a86
update docstring
t-imamichi May 10, 2021
683286b
make _load_model private and qp.load static
t-imamichi May 11, 2021
4271523
Merge branch 'main' into translator2
t-imamichi May 18, 2021
65aa7ea
add is_installed
t-imamichi May 19, 2021
57dbfe7
add is_installed check
t-imamichi May 19, 2021
2d1dd9e
Merge branch 'main' into translator2
t-imamichi May 26, 2021
3d63fb0
Merge branch 'main' into translator2
t-imamichi May 27, 2021
d970362
update
t-imamichi May 27, 2021
4d3cb38
Merge branch 'main' into translator2
t-imamichi May 28, 2021
ffc8183
Merge branch 'main' into translator2
t-imamichi Jun 3, 2021
43e147c
(wip) add gurobi translaor and tests
t-imamichi Jun 3, 2021
e8036f6
(wip) add gurobi translaor and tests
t-imamichi Jun 3, 2021
c95cde9
fix
t-imamichi Jun 3, 2021
2549508
fix lint
t-imamichi Jun 4, 2021
083b2f1
Merge branch 'main' into translator2
t-imamichi Jun 7, 2021
dcf6659
add reno
t-imamichi Jun 7, 2021
1950452
add LPFileTranslator
t-imamichi Jun 7, 2021
962c32e
fix reno
t-imamichi Jun 7, 2021
733b87f
fix docstrings
t-imamichi Jun 7, 2021
208723f
update
t-imamichi Jun 7, 2021
6c04ebd
fix a unit test
t-imamichi Jun 7, 2021
8688824
rename qp.save with qp.export
t-imamichi Jun 7, 2021
2b6d7ce
integrate export_as_string with export
t-imamichi Jun 7, 2021
95faeea
simplify
t-imamichi Jun 7, 2021
f584b25
update
t-imamichi Jun 7, 2021
42a1953
fix
t-imamichi Jun 7, 2021
cac131f
rename model -> source
t-imamichi Jun 7, 2021
c19b5a1
simplify
t-imamichi Jun 7, 2021
088b44c
update reno and docstring
t-imamichi Jun 7, 2021
1dc4323
update
t-imamichi Jun 8, 2021
dfa1197
fix docstring
t-imamichi Jun 8, 2021
b828d2c
fix error message
t-imamichi Jun 8, 2021
3591b39
revert qp.export_as_lp_string and qp.export
t-imamichi Jun 8, 2021
7afe376
revise types
t-imamichi Jun 8, 2021
35a2cb9
Merge branch 'main' into translator2
t-imamichi Jun 9, 2021
3709c9b
revise the design
t-imamichi Jun 9, 2021
6bb3f82
update pylintdict
t-imamichi Jun 9, 2021
498f966
revert to_gurobi -> to_gurobipy
t-imamichi Jun 9, 2021
8bb85e9
revert a file
t-imamichi Jun 9, 2021
1c032e3
revert read and write lp files to qp
t-imamichi Jun 9, 2021
b155d33
change order
t-imamichi Jun 9, 2021
7da9930
update docstring
t-imamichi Jun 9, 2021
136c089
simplify
t-imamichi Jun 9, 2021
9b943d9
fix lint
t-imamichi Jun 9, 2021
6a0c961
update reno
t-imamichi Jun 9, 2021
49fd297
update
t-imamichi Jun 9, 2021
52172b9
update import
t-imamichi Jun 9, 2021
a1c67ed
update
t-imamichi Jun 9, 2021
7d88230
rename package gurobi to gurobipy
t-imamichi Jun 11, 2021
15e3200
revise error messages and docstrings
t-imamichi Jun 12, 2021
9b973ec
update applications
t-imamichi Jun 13, 2021
a68b2f2
use from_docplex_mp and to_docplex_mp
t-imamichi Jun 13, 2021
e25e7a9
update tutorials
t-imamichi Jun 13, 2021
5276258
Merge branch 'translator2' of github.com:t-imamichi/qiskit-optimizati…
t-imamichi Jun 13, 2021
b139757
update reno
t-imamichi Jun 13, 2021
ee9aba3
Merge branch 'main' into translator2
t-imamichi Jun 13, 2021
a21d2c5
add october to pylintdict
t-imamichi Jun 13, 2021
89b9f16
revert test_docplex and revise test_feasibility
t-imamichi Jun 13, 2021
66eca8b
fix unused import
t-imamichi Jun 13, 2021
87f477e
Merge branch 'main' into translator2
t-imamichi Jun 13, 2021
d36157c
revise deprecation message
t-imamichi Jun 13, 2021
958726a
remove test_docplex
t-imamichi Jun 14, 2021
a81b1ad
Revert "remove test_docplex"
t-imamichi Jun 14, 2021
cfe0b82
change stacklevel=2 of deprecation warning and surpress deprecation w…
t-imamichi Jun 14, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
130 changes: 50 additions & 80 deletions qiskit_optimization/problems/quadratic_program.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
from collections.abc import Sequence
from enum import Enum
from math import fsum, isclose
from typing import Dict, List, Optional, Tuple, Union, cast
from typing import Any, Dict, List, Optional, Tuple, Union, cast

import numpy as np
from docplex.mp.constr import LinearConstraint as DocplexLinearConstraint
Expand All @@ -35,22 +35,24 @@
from docplex.mp.model_reader import ModelReader
from docplex.mp.quad import QuadExpr
from docplex.mp.vartype import BinaryVarType, ContinuousVarType, IntegerVarType
from numpy import ndarray, zeros
from scipy.sparse import spmatrix

from numpy import ndarray, zeros
from qiskit.exceptions import MissingOptionalLibraryError
from qiskit.opflow import I, ListOp, OperatorBase, PauliOp, PauliSumOp, SummedOp
from qiskit.quantum_info import Pauli
from scipy.sparse import spmatrix

from ..exceptions import QiskitOptimizationError
from ..infinity import INFINITY
from .constraint import Constraint, ConstraintSense
from .linear_constraint import LinearConstraint
from .linear_expression import LinearExpression
from .quadratic_constraint import QuadraticConstraint
from .quadratic_expression import QuadraticExpression
from .quadratic_objective import QuadraticObjective
from .variable import Variable, VarType
from ..exceptions import QiskitOptimizationError
from ..infinity import INFINITY
from ..translators.model_translator import ModelTranslator
from ..translators.utils import _load_model

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -869,6 +871,41 @@ def maximize(
self, constant, linear, quadratic, QuadraticObjective.Sense.MAXIMIZE
)

@staticmethod
def load(model: Any) -> "QuadraticProgram":
"""Loads this quadratic program from an optimization model.

Note that this supports only basic functions of docplex as follows:
- quadratic objective function
- linear / quadratic constraints
- binary / integer / continuous variables

Args:
model: The optimization model to be loaded.

Returns:
the quadratic program corresponding to the model.

Raises:
QiskitOptimizationError: if the model contains unsupported elements.
"""
return _load_model(model)

def save(self, translator: Optional[ModelTranslator] = None) -> Any:
Comment thread
t-imamichi marked this conversation as resolved.
Outdated
"""Returns an optimization model corresponding to this quadratic program.

Returns:
The optimization model corresponding to this quadratic program.

Raises:
QiskitOptimizationError: if non-supported elements (should never happen).
"""
if translator is None:
from qiskit_optimization.translators.docplex import DocplexMpTranslator

translator = DocplexMpTranslator()
return translator.qp_to_model(self)

def from_docplex(self, model: Model) -> None:
"""Loads this quadratic program from a docplex model.

Expand All @@ -884,6 +921,10 @@ def from_docplex(self, model: Model) -> None:
QiskitOptimizationError: if the model contains unsupported elements.
"""

# warnings.warn("The to_docplex method is deprecated and will be "
# "removed in a future release. Instead use the"
# "to_model() method", DeprecationWarning)

# clear current problem
self.clear()

Expand Down Expand Up @@ -1034,81 +1075,10 @@ def to_docplex(self) -> Model:
Raises:
QiskitOptimizationError: if non-supported elements (should never happen).
"""

# initialize model
mdl = Model(self.name)

# add variables
var = {}
for idx, x in enumerate(self.variables):
if x.vartype == Variable.Type.CONTINUOUS:
var[idx] = mdl.continuous_var(lb=x.lowerbound, ub=x.upperbound, name=x.name)
elif x.vartype == Variable.Type.BINARY:
var[idx] = mdl.binary_var(name=x.name)
elif x.vartype == Variable.Type.INTEGER:
var[idx] = mdl.integer_var(lb=x.lowerbound, ub=x.upperbound, name=x.name)
else:
# should never happen
raise QiskitOptimizationError("Unsupported variable type: {}".format(x.vartype))

# add objective
objective = self.objective.constant
for i, v in self.objective.linear.to_dict().items():
objective += v * var[cast(int, i)]
for (i, j), v in self.objective.quadratic.to_dict().items():
objective += v * var[cast(int, i)] * var[cast(int, j)]
if self.objective.sense == QuadraticObjective.Sense.MINIMIZE:
mdl.minimize(objective)
else:
mdl.maximize(objective)

# add linear constraints
for i, l_constraint in enumerate(self.linear_constraints):
name = l_constraint.name
rhs = l_constraint.rhs
if rhs == 0 and l_constraint.linear.coefficients.nnz == 0:
continue
linear_expr = 0
for j, v in l_constraint.linear.to_dict().items():
linear_expr += v * var[cast(int, j)]
sense = l_constraint.sense
if sense == Constraint.Sense.EQ:
mdl.add_constraint(linear_expr == rhs, ctname=name)
elif sense == Constraint.Sense.GE:
mdl.add_constraint(linear_expr >= rhs, ctname=name)
elif sense == Constraint.Sense.LE:
mdl.add_constraint(linear_expr <= rhs, ctname=name)
else:
# should never happen
raise QiskitOptimizationError("Unsupported constraint sense: {}".format(sense))

# add quadratic constraints
for i, q_constraint in enumerate(self.quadratic_constraints):
name = q_constraint.name
rhs = q_constraint.rhs
if (
rhs == 0
and q_constraint.linear.coefficients.nnz == 0
and q_constraint.quadratic.coefficients.nnz == 0
):
continue
quadratic_expr = 0
for j, v in q_constraint.linear.to_dict().items():
quadratic_expr += v * var[cast(int, j)]
for (j, k), v in q_constraint.quadratic.to_dict().items():
quadratic_expr += v * var[cast(int, j)] * var[cast(int, k)]
sense = q_constraint.sense
if sense == Constraint.Sense.EQ:
mdl.add_constraint(quadratic_expr == rhs, ctname=name)
elif sense == Constraint.Sense.GE:
mdl.add_constraint(quadratic_expr >= rhs, ctname=name)
elif sense == Constraint.Sense.LE:
mdl.add_constraint(quadratic_expr <= rhs, ctname=name)
else:
# should never happen
raise QiskitOptimizationError("Unsupported constraint sense: {}".format(sense))

return mdl
# warnings.warn("The to_docplex method is deprecated and will be "
Comment thread
t-imamichi marked this conversation as resolved.
Outdated
# "removed in a future release. Instead use the"
# "to_model() method", DeprecationWarning)
return self.save()

def export_as_lp_string(self) -> str:
Comment thread
t-imamichi marked this conversation as resolved.
"""Returns the quadratic program as a string of LP format.
Expand Down
42 changes: 42 additions & 0 deletions qiskit_optimization/translators/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# This code is part of Qiskit.
#
# (C) Copyright IBM 2021.
#
# This code is licensed under the Apache License, Version 2.0. You may
# obtain a copy of this license in the LICENSE.txt file in the root directory
# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
#
# Any modifications or derivative works of this code must retain this
# copyright notice, and modified files need to carry a notice indicating
# that they have been altered from the originals.

"""
Optimization model translators (:mod:`qiskit_optimization.translators`)
===================================================================

.. currentmodule:: qiskit_optimization.translators

Translators between an optimization model and a quadratic program
Comment thread
t-imamichi marked this conversation as resolved.
Outdated

Base class for translators
=======================================

.. autosummary::
:toctree: ../stubs/
:nosignatures:

ModelTranslator
Comment thread
t-imamichi marked this conversation as resolved.
Outdated

Translators
======================
.. autosummary::
:toctree: ../stubs/
:nosignatures:

DocplexTranslator
Comment thread
t-imamichi marked this conversation as resolved.
Outdated
"""

from .model_translator import ModelTranslator
from .docplex import DocplexMpTranslator

_all = ["ModelTranslator", "DocplexMpTranslator"]
Loading