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()