kaiwu.core._qubo_model 源代码
"""
模块: qubo
功能: 提供QUBOModel相关的功能
"""
import logging
import numpy as np
from kaiwu.core._binary_model import BinaryModel
from kaiwu.core._binary_expression import Binary, quicksum
from kaiwu.core._matrix import ndarray
from kaiwu.core._error import KaiwuError
logger = logging.getLogger(__name__)
def _qubo_check(quadratic):
for key in quadratic:
if len(key) > 2:
raise KaiwuError("Items higher than quadratic.")
[文档]
class QuboModel(BinaryModel):
"""支持添加约束的QUBO模型类
Args:
objective (QuboExpression, optional): 目标函数. 默认为None
"""
def __init__(self, objective=None):
super().__init__(objective)
self.qubo_expr_made = None
self.made = False
self.variables = None
self.matrix = None
def _on_objective_change(self):
"""当目标函数发生变化时调用,重置相关状态"""
self.invalidate_made_state()
[文档]
def invalidate_made_state(self):
"""Invalidate the made state when the model changes"""
self.made = False
self.qubo_expr_made = None
self.matrix = None
[文档]
def make(self):
"""返回合并后的QUBO表达式
Returns:
BinaryExpression: 合并的约束表达式
"""
if self.made:
return self.qubo_expr_made
constraint_list = self.get_constraints_expr_list()
self.qubo_expr_made = self.objective + quicksum(constraint_list)
_qubo_check(self.qubo_expr_made.coefficient)
self.variables = self.qubo_expr_made.get_variables()
self.made = True
return self.qubo_expr_made
[文档]
def get_matrix(self):
"""获取QUBO矩阵
Returns:
numpy.ndarray: QUBO矩阵
"""
self.compile_constraints()
self.make()
self.matrix = np.zeros((len(self.variables), len(self.variables)))
for key in self.qubo_expr_made.coefficient:
if len(key) == 2:
self.matrix[self.variables[key[0]], self.variables[key[1]]] = (
self.qubo_expr_made.coefficient[key]
)
else:
self.matrix[self.variables[key[0]], self.variables[key[0]]] = (
self.qubo_expr_made.coefficient[key]
)
return self.matrix
[文档]
def get_variables(self):
"""获取qubo模型的variables"""
self.compile_constraints()
self.make()
return self.variables
[文档]
def get_offset(self):
"""获取qubo模型的offset"""
return self.objective.offset
[文档]
def get_sol_dict(self, qubo_solution):
"""根据解向量生成结果字典."""
self.compile_constraints()
self.make()
return dict(
(k, 1 if qubo_solution[idx] > 0 else 0)
for k, idx in self.variables.items()
if k != "__spin__"
)
[文档]
def calculate_qubo_value(qubo_matrix, offset, binary_configuration):
"""Q值计算器.
Args:
qubo_matrix (np.ndarray): QUBO矩阵.
offset (float): 常数项
binary_configuration (np.ndarray): 二进制配置
Returns:
output (float): Q值.
Examples:
>>> import numpy as np
>>> import kaiwu as kw
>>> matrix = np.array([[1., 0., 0.],
... [0., 1., 0.],
... [0., 0., 1.]])
>>> offset = 1.8
>>> binary_configuration = np.array([0, 1, 0])
>>> qubo_value = kw.core.calculate_qubo_value(matrix, offset, binary_configuration)
>>> print(qubo_value)
2.8
"""
return (binary_configuration.dot(qubo_matrix)).dot(binary_configuration) + offset
[文档]
def qubo_matrix_to_qubo_model(qubo_mat):
"""将qubo矩阵转化为qubo模型
Args:
qubo_mat (np.ndarray): QUBO矩阵
Returns:
QuboModel: QUBO模型
Examples:
>>> import numpy as np
>>> import kaiwu as kw
>>> matrix = -np.array([[0, 8],
... [0, 0]])
>>> kw.core.qubo_matrix_to_qubo_model(matrix).objective
-8*b[0]*b[1]
"""
vars_b = ndarray(len(qubo_mat), "b", Binary)
return QuboModel(vars_b.dot(qubo_mat).dot(vars_b))
if __name__ == "__main__":
import doctest
doctest.testmod()