kaiwu.qubo package#

Module contents#

模块: qubo

Function: QUBO modeling tool

kaiwu.qubo.binary(name: str)#

二进制变量, 可能的取值只有0,1.

Args:

name (str): 变量的唯一标识.

Returns:

dict: 名称为name的二进制变量.

Examples:
>>> import kaiwu as kw
>>> b = kw.qubo.binary("b")
>>> b
b

自 1.0.0 版本弃用: You can use the standard function kw.qubo.Binary().

kaiwu.qubo.spin(name: str)#

自旋变量, 可能的取值只有-1,1.

Args:

name (str): 变量的唯一标识.

Returns:

dict: 名称为name的自旋变量.

Examples:
>>> import kaiwu as kw
>>> s = kw.qubo.spin("s")
>>> s
2*s-1
kaiwu.qubo.constraint(qubo, name: str, strength=0)#

约束项QUBO.

Args:

qubo (QUBO): QUBO表达式.

name (str): 约束项的唯一标识.

strength (float): 约束强度, 目前不起作用, 都是硬约束.

Returns:

QuboExpression: 约束QUBO.

Examples:
>>> import kaiwu as kw
>>> b1, b2 = kw.qubo.Binary("b1"), kw.qubo.Binary("b2")
>>> cons1 = kw.qubo.constraint(2.1*b1*b2 + b2 - b1 + 2, "cons1")
>>> kw.qubo.details(cons1)
QUBO Details:
  Variables(Binary):b1, b2
  QUBO offset:      2
  QUBO coefficients:
    b2,    : 1
    b1, b2 : 2.1
    b1,    : -1
kaiwu.qubo.placeholder(name: str)#

占位符.

Args:

name (str): 占位符的唯一标识.

Returns:

dict: 名称为name的占位符.

Examples:
>>> import kaiwu as kw
>>> p = kw.qubo.placeholder("p")
>>> p
p

自 1.0.0 版本弃用: You can use the standard function kw.qubo.Placeholder().

class kaiwu.qubo.Binary(name: str)#

基类:QuboExpression

二进制变量, 可能的取值只有0,1.

Args:

name (str): 变量的唯一标识.

Returns:

dict: 名称为name的二进制变量.

Examples:
>>> import kaiwu as kw
>>> b = kw.qubo.Binary('z2')
>>> b
z2
auto_hobo_reduce = True#
feed(feed_dict)#

为占位符号赋值, 并返回赋值后的新表达式对象

Args:

feed_dict(dict): 需要赋值的占位符的值

Examples:
>>> import kaiwu as kw
>>> p = kw.qubo.Placeholder('p')
>>> a = kw.qubo.Binary('a')
>>> y = p * a
>>> kw.qubo.details(y)  
QUBO Details:
  Variables(Binary):a
  Placeholders:     p
  QUBO offset:      0
  QUBO coefficients:
    a, : p
>>> y= y.feed({'p': 2})
>>> kw.qubo.details(y)  
QUBO Details:
  Variables(Binary):a
  QUBO offset:      0
  QUBO coefficients:
    a, : 2
fromkeys(value=None, /)#

Create a new dictionary with keys from iterable and values set to value.

class kaiwu.qubo.Integer(name: str, min_value=0, max_value=127)#

基类:QuboExpression

返回表示整数变量的QUBO多项式,满足 min_value<= x <= min_value

x = a+\sum_{i=0}^{\lfloor \log_2 (b-a) \rfloor -1}{2^i*t_i} +
(b-a-2^{\lfloor \log_2 (b-a) \rfloor}+1)*y

Args:

name (str): 变量的唯一标识.

min_value: 整数变量的最小值

max_value: 整数变量的最大值

Returns:

dict: 名称为name的整数变量.

Examples:
>>> import kaiwu as kw
>>> var_i = kw.qubo.Integer("x", 1, 2)
>>> var_i
x[0]+1
auto_hobo_reduce = True#
feed(feed_dict)#

为占位符号赋值, 并返回赋值后的新表达式对象

Args:

feed_dict(dict): 需要赋值的占位符的值

Examples:
>>> import kaiwu as kw
>>> p = kw.qubo.Placeholder('p')
>>> a = kw.qubo.Binary('a')
>>> y = p * a
>>> kw.qubo.details(y)  
QUBO Details:
  Variables(Binary):a
  Placeholders:     p
  QUBO offset:      0
  QUBO coefficients:
    a, : p
>>> y= y.feed({'p': 2})
>>> kw.qubo.details(y)  
QUBO Details:
  Variables(Binary):a
  QUBO offset:      0
  QUBO coefficients:
    a, : 2
fromkeys(value=None, /)#

Create a new dictionary with keys from iterable and values set to value.

class kaiwu.qubo.Placeholder(name: str)#

基类:QuboExpression

占位符

Args:

name (str): 占位符的唯一标识.

Returns:

dict: 名称为name的占位符.

Examples:
>>> import kaiwu as kw
>>> p = kw.qubo.Placeholder("p")
>>> p
p
auto_hobo_reduce = True#
feed(feed_dict)#

为占位符号赋值, 并返回赋值后的新表达式对象

Args:

feed_dict(dict): 需要赋值的占位符的值

Examples:
>>> import kaiwu as kw
>>> p = kw.qubo.Placeholder('p')
>>> a = kw.qubo.Binary('a')
>>> y = p * a
>>> kw.qubo.details(y)  
QUBO Details:
  Variables(Binary):a
  Placeholders:     p
  QUBO offset:      0
  QUBO coefficients:
    a, : p
>>> y= y.feed({'p': 2})
>>> kw.qubo.details(y)  
QUBO Details:
  Variables(Binary):a
  QUBO offset:      0
  QUBO coefficients:
    a, : 2
fromkeys(value=None, /)#

Create a new dictionary with keys from iterable and values set to value.

class kaiwu.qubo.QuboExpression#

基类:_Expression

QUBO表达式的基础数据结构

auto_hobo_reduce = True#
feed(feed_dict)#

为占位符号赋值, 并返回赋值后的新表达式对象

Args:

feed_dict(dict): 需要赋值的占位符的值

Examples:
>>> import kaiwu as kw
>>> p = kw.qubo.Placeholder('p')
>>> a = kw.qubo.Binary('a')
>>> y = p * a
>>> kw.qubo.details(y)  
QUBO Details:
  Variables(Binary):a
  Placeholders:     p
  QUBO offset:      0
  QUBO coefficients:
    a, : p
>>> y= y.feed({'p': 2})
>>> kw.qubo.details(y)  
QUBO Details:
  Variables(Binary):a
  QUBO offset:      0
  QUBO coefficients:
    a, : 2
fromkeys(value=None, /)#

Create a new dictionary with keys from iterable and values set to value.

kaiwu.qubo.get_min_penalty_for_equal_constraint(obj, cons)#

返回一次等式约束项cons对应的最小惩罚系数:把满足这个约束的解的某一位比特翻转一下的最坏情况。 这个惩罚系数有效是指能够保证原问题的可行解是目标函数的局部最优(在一位比特翻转的局部意义下)。

Args:

obj: 原目标函数的qubo表达式。

cons:线性的等式约束cons=0中的线性表达式。

Returns:

float: 一次等式约束项cons对应的最小惩罚系数.

Examples:
>>> import kaiwu as kw
>>> x = [kw.qubo.Binary("b"+str(i)) for i in range(3)]
>>> cons = kw.qubo.quicksum(x)-1
>>> obj = x[1]+2*x[2]
>>> kw.qubo.get_min_penalty_for_equal_constraint(obj,cons)
2.0
kaiwu.qubo.get_min_penalty(obj, cons)#

返回约束项cons对应的最小惩罚系数,惩罚项优先满足

Args:

obj: 原目标函数的qubo表达式。

cons:约束项的qubo表达式

Returns:

float: 返回约束项cons对应的最小惩罚系数.

Examples:
>>> import kaiwu as kw
>>> x = [kw.qubo.Binary("b"+str(i)) for i in range(3)]
>>> cons = kw.qubo.quicksum(x) - 1
>>> obj = x[1] + 2 * x[2]
>>> kw.qubo.get_min_penalty(obj, cons)
2.0
kaiwu.qubo.quicksum(qubo_expr_list: list)#

高性能的QUBO求和器.

Args:

qubo_expr_list (QUBO列表): 用于求和的QUBO表达式的列表.

Returns:

QuboExpression: 约束QUBO.

Examples:
>>> import kaiwu as kw
>>> qubo_list = [kw.qubo.Binary("b"+str(i)) for i in range(10)] # Variables are also QUBO
>>> output = kw.qubo.quicksum(qubo_list)
>>> kw.qubo.details(output)
QUBO Details:
  Variables(Binary):b0, b1, b2, b3, b4, b5, b6, b7, b8, b9
  QUBO offset:      0
  QUBO coefficients:
    b0, : 1
    b1, : 1
    b2, : 1
    b3, : 1
    b4, : 1
    b5, : 1
    b6, : 1
    b7, : 1
    b8, : 1
    b9, : 1
kaiwu.qubo.bisection(qubo_expr_list, func)#

二分方法,可以用于连续的计算,如连续的乘法,连续的异或等。使用二分方法可能会减少降阶产生的变量数

Args:

qubo_expr_list (QUBO列表): QUBO列表.

func (二元函数): 用于两个QUBU元素的计算

Returns:

QuboExpression: 约束QUBO.

Example1:
>>> import kaiwu as kw
>>> qubo_list = [kw.qubo.Binary("b"+str(i)) for i in range(10)] # 变量也是QUBO
>>> output = kw.qubo.bisection(qubo_list, lambda a,b: a+b)
>>> output
b9+b8+b7+b6+b5+b4+b3+b2+b1+b0
kaiwu.qubo.details(model, file_name='')#

细节查看器.

Args:

model : 想查看的模型.

file_name (str): 文件路径与文件名, 若为空, 则直接控制台打印.

Returns:

QuboExpression: 约束QUBO.

Examples:
>>> import kaiwu as kw
>>> qubo_list = [kw.qubo.Binary("b"+str(i)) for i in range(10)] # Variables are also QUBO
>>> output = kw.qubo.quicksum(qubo_list)
>>> kw.qubo.details(output)
QUBO Details:
  Variables(Binary):b0, b1, b2, b3, b4, b5, b6, b7, b8, b9
  QUBO offset:      0
  QUBO coefficients:
    b0, : 1
    b1, : 1
    b2, : 1
    b3, : 1
    b4, : 1
    b5, : 1
    b6, : 1
    b7, : 1
    b8, : 1
    b9, : 1
kaiwu.qubo.ndarray(shape: int | Tuple[int, ...] | List[int], name, var_func, var_func_param=None)#

基于 np.ndarray 的QUBO容器. 该容器支持各种 numpy 原生的向量化运算

Args:

shape (Union[int, Tuple[int, ...]]): 形状

name (str): 生成的变量的标识符.

var_func (class for func): 用于生成元素的方法或类. 第一个参数必须是name

var_func_param (tuple): var_func除了name以外的参数

Returns:

np.ndarray: 多维容器.

Examples:
>>> import numpy as np
>>> import kaiwu as kw
>>> A = kw.qubo.ndarray((2,3,4), "A", kw.qubo.Binary)
>>> A
QUBOArray([[[A[0][0][0], A[0][0][1], A[0][0][2], A[0][0][3]],
            [A[0][1][0], A[0][1][1], A[0][1][2], A[0][1][3]],
            [A[0][2][0], A[0][2][1], A[0][2][2], A[0][2][3]]],

           [[A[1][0][0], A[1][0][1], A[1][0][2], A[1][0][3]],
            [A[1][1][0], A[1][1][1], A[1][1][2], A[1][1][3]],
            [A[1][2][0], A[1][2][1], A[1][2][2], A[1][2][3]]]],
          dtype=object)
>>> A[1,2]
QUBOArray([A[1][2][0], A[1][2][1], A[1][2][2], A[1][2][3]], dtype=object)
>>> A[:, [0,2]]
QUBOArray([[[A[0][0][0], A[0][0][1], A[0][0][2], A[0][0][3]],
            [A[0][2][0], A[0][2][1], A[0][2][2], A[0][2][3]]],

           [[A[1][0][0], A[1][0][1], A[1][0][2], A[1][0][3]],
            [A[1][2][0], A[1][2][1], A[1][2][2], A[1][2][3]]]],
          dtype=object)
>>> B = kw.qubo.ndarray(3, "B", kw.qubo.Binary)
>>> B
QUBOArray([B[0], B[1], B[2]], dtype=object)
>>> C = kw.qubo.ndarray([3,3], "C", kw.qubo.Binary)
>>> C
QUBOArray([[C[0][0], C[0][1], C[0][2]],
           [C[1][0], C[1][1], C[1][2]],
           [C[2][0], C[2][1], C[2][2]]], dtype=object)
>>> D = 2 * B.dot(C) + 2
>>> kw.qubo.details(D[0])
QUBO Details:
  Variables(Binary):B[0], B[1], B[2], C[0][0], C[1][0], C[2][0]
  QUBO offset:      2
  QUBO coefficients:
    B[0], C[0][0] : 2
    B[1], C[1][0] : 2
    B[2], C[2][0] : 2

>>> E = B.sum()
>>> kw.qubo.details(E)
QUBO Details:
  Variables(Binary):B[0], B[1], B[2]
  QUBO offset:      0
  QUBO coefficients:
    B[0], : 1
    B[1], : 1
    B[2], : 1

>>> F = np.diag(C)
>>> F
QUBOArray([C[0][0], C[1][1], C[2][2]], dtype=object)
kaiwu.qubo.dot(mat_left, mat_right)#

矩阵乘法

Args:

mat_left (numpy.array): 矩阵1

mat_right (numpy.array): 矩阵2

Raises:

ValueError: 两个输入都必须是np.ndarray ValueError: 两个输入的维度必须匹配

Returns:

np.ndarray: 乘积矩阵

class kaiwu.qubo.QUBOArray#

基类:ndarray

基于 np.ndarray 的QUBO容器. 该容器支持各种 numpy 原生的向量化运算

is_array_less = <numpy.vectorize object>#
is_array_less_equal = <numpy.vectorize object>#
is_array_greater = <numpy.vectorize object>#
is_array_greater_equal = <numpy.vectorize object>#
is_array_equal = <numpy.vectorize object>#
dot(b, out=None)#

使用quicksum的矩阵乘法

Args:

b (QUBOArray): 另一个矩阵

Returns:

QUBOArray: 乘积

sum(axis=None, dtype=None, out=None, keepdims=False, initial=0, where=True)#

Return the sum of the array elements over the given axis.

Refer to numpy.sum for full documentation.

See Also#

numpy.sum : equivalent function

kaiwu.qubo.hobo_verify(reduced_hobo, sol_dict)#

验证所有hobo辅助变量是否满足.

Args:

reduced_hobo (QUBO): QUBO.

sol_dict (dict): 由get_sol_dict生成的结果字典。

Returns:

int: 未满足约束的辅助变量个数 dict: 记录各个辅助变量是否满足

Examples:
>>> import kaiwu as kw
>>> x1, x2, x3 = kw.qubo.Binary("x1"), kw.qubo.Binary("x2"), kw.qubo.Binary("x3")
>>> y1, y2, y3 = kw.qubo.Binary("y1"), kw.qubo.Binary("y2"), kw.qubo.Binary("y3")
>>> p1 = x1 * x2 + 2* y1 * y1
>>> p2 = x1 * y1 + y3
>>> result = p1 * p2
>>> kw.qubo.details(result)
QUBO Details:
  Variables(Binary):_x1_x2, _x1_y1, y1, y3
  QUBO offset:      0
  QUBO coefficients:
    y1, y3         : 2
    _x1_y1, y1     : 2
    _x1_x2, y3     : 1
    _x1_x2, _x1_y1 : 1
  HOBO Constraint:
    _x1_y1 : x1, y1
    _x1_x2 : x1, x2
>>> p = x1*x2*x3
>>> err_cnt, result_dic = kw.qubo.hobo_verify(p, {"x1":1,"x2":1,"x3":0,"_x1_x2":1})
>>> print(err_cnt)
0
class kaiwu.qubo.HoboReducer#

基类:object

完成建模后,进行QUBO表达式的降阶

Examples:
>>> import kaiwu as kw
>>> kw.qubo.QuboExpression.auto_hobo_reduce = False
>>> x = kw.qubo.ndarray(10, "x", kw.qubo.Binary)
>>> y1 = x[0]*x[1] + x[2]*x[3] + x[8]
>>> y2 = x[3]*x[4] + x[5]*x[6] + x[7]
>>> y3 = y1 * y2
>>> print(y3)  
'x[2]*x[3]*x[5]*x[6]+x[2]*x[3]*x[3]*x[4]+x[2]*x[3]*x[7]+x[0]*x[1]*x[5]*x[6]+x[0]*x[1]*x[3]*x[4]+'         'x[0]*x[1]*x[7]+x[5]*x[6]*x[8]+x[3]*x[4]*x[8]+x[7]*x[8]'
>>> reducer = kw.qubo.HoboReducer()
>>> y4 = reducer.reduce(y3)
>>> kw.qubo.details(y4)
QUBO Details:
  Variables(Binary):_x[0]_x[1], _x[2]_x[3], _x[3]_x[4], _x[5]_x[6], x[4], x[7], x[8]
  QUBO offset:      0
  QUBO coefficients:
    _x[2]_x[3], _x[5]_x[6] : 1
    _x[2]_x[3], x[4]       : 1
    _x[2]_x[3], x[7]       : 1
    _x[0]_x[1], _x[5]_x[6] : 1
    _x[0]_x[1], _x[3]_x[4] : 1
    _x[0]_x[1], x[7]       : 1
    _x[5]_x[6], x[8]       : 1
    _x[3]_x[4], x[8]       : 1
    x[7], x[8]             : 1
  HOBO Constraint:
    _x[2]_x[3] : x[2], x[3]
    _x[5]_x[6] : x[5], x[6]
    _x[0]_x[1] : x[0], x[1]
    _x[3]_x[4] : x[3], x[4]
reduce(qubo_expr, pairs=None)#

对QUBO表达式进行降阶

Args:

qubo_expr (QuboExpression): QUBO表达式

pairs (list): 预先定义要合并的变量, 通过元组的列表传入

Returns:

qubo_expr (QuboExpression): 降阶后的QUBO表达式

kaiwu.qubo.get_sol_dict(solution, vars_dict)#

根据解向量和变量字典生成结果字典.

Args:

solution (np.ndarray): 解向量(spin)。

vars_dict (dict): 变量字典,用cim_ising_model.get_variables()生成。

Returns:

dict: 结果字典。键为变量名,值为对应的spin值。

Examples:
>>> import kaiwu as kw
>>> import numpy as np
>>> a = kw.qubo.Binary("a")
>>> b = kw.qubo.Binary("b")
>>> c = kw.qubo.Binary("c")
>>> d = a + 2 * b + 4 * c
>>> d = kw.qubo.make(d)
>>> d_ising = kw.qubo.qubo_model_to_ising_model(d)
>>> vars = d_ising.get_variables()
>>> s = np.array([1, -1, 1])
>>> kw.qubo.get_sol_dict(s, vars)
{'a': 1.0, 'b': 0.0, 'c': 1.0}
kaiwu.qubo.get_val(qubo, sol_dict)#

根据结果字典将spin值带入qubo变量.

Args:

qubo (QUBO表达式): QUBO表达式

sol_dict (dict): 由get_sol_dict生成的结果字典。

Returns:

float: 带入qubo后所得的值

Examples:
>>> import kaiwu as kw
>>> import numpy as np
>>> a = kw.qubo.Binary("a")
>>> b = kw.qubo.Binary("b")
>>> c = kw.qubo.Binary("c")
>>> d = a + 2 * b + 4 * c
>>> d = kw.qubo.make(d)
>>> d_ising = kw.qubo.qubo_model_to_ising_model(d)
>>> vars = d_ising.get_variables()
>>> s = np.array([1, -1, 1])
>>> sol_dict = kw.qubo.get_sol_dict(s, vars)
>>> kw.qubo.get_val(d, sol_dict)
5.0
kaiwu.qubo.get_array_val(array, sol_dict)#

根据结果字典将spin值带入qubo数组变量.

Args:

array (QUBOArray): QUBO数组

sol_dict (dict): 由get_sol_dict生成的结果字典。

Returns:

np.ndarray: 带入qubo数组后所得的值数组

Examples:
>>> import kaiwu as kw
>>> import numpy as np
>>> x = kw.qubo.ndarray((2, 2), "x", kw.qubo.Binary)
>>> y = x.sum()
>>> y = kw.qubo.make(y)
>>> y_ising = kw.qubo.qubo_model_to_ising_model(y)
>>> vars = y_ising.get_variables()
>>> s = np.array([1, -1, 1, -1])
>>> sol_dict = kw.qubo.get_sol_dict(s, vars)
>>> kw.qubo.get_array_val(x, sol_dict)
array([[1., 0.],
       [1., 0.]])
kaiwu.qubo.make(qubo, q_check=True, hobo_constraint_strength=None)#

用于带占位符的QUBO的解析.

Args:

qubo (QUBO): QUBO.

q_check (bool): 是否检查, True则会检查QUBO错误

hobo_constraint_strength(float): 降阶惩罚项系数

Returns:

QuboExpression: QUBO或带占位符QUBO.

Examples:
>>> import kaiwu as kw
>>> p1, p2 = kw.qubo.placeholder("p1"), kw.qubo.placeholder("p2")
>>> b1, b2 = kw.qubo.Binary("b1"), kw.qubo.Binary("b2")
>>> q = p1*b1 + p2*b2 + (p1+p2)*b1*b2 + p1
>>> q = q.feed({'p1': 0, 'p2': 1})
>>> qm = kw.qubo.make(q)
>>> kw.qubo.details(qm)
QUBO Details:
  Variables(Binary):b1, b2
  QUBO offset:      0
  QUBO coefficients:
    b2,    : 1
    b1,    : 0
    b1, b2 : 1

>>> kw.qubo.details(q)
QUBO Details:
  Variables(Binary):b1, b2
  QUBO offset:      0
  QUBO coefficients:
    b2,    : 1
    b1,    : 0
    b1, b2 : 1
kaiwu.qubo.cim_ising_model(qubo)#

QUBO转CIM Ising模型.

Args:

qubo (QUBO): QUBO.

Returns:

CimIsing: CIM Ising模型.

Examples:
>>> import kaiwu as kw
>>> b1, b2 = kw.qubo.Binary("b1"), kw.qubo.Binary("b2")
>>> q = b1 + b2 + 2 * b1 * b2
>>> ci = kw.qubo.cim_ising_model(q)
>>> kw.qubo.details(ci)
CIM Ising Details:
  CIM Ising Matrix:
    [[-0.   -0.25 -0.5 ]
     [-0.25 -0.   -0.5 ]
     [-0.5  -0.5  -0.  ]]
  CIM Ising Bias: 1.5
  CIM Ising Variables: b1, b2, __spin__
  Variable type: binary
  QUBO Matrix:
    [[1. 2.]
     [0. 1.]]
  QUBO Offset: 0
  QUBO Variables: b1, b2

自 1.0.0 版本弃用: You can use the standard function kw.qubo.qubo_model_to_ising_model().

kaiwu.qubo.qubo_model_to_ising_model(qubo)#

QUBO转CIM Ising模型.

Args:

qubo (QUBO): QUBO.

Returns:

CimIsing: CIM Ising模型.

Examples:
>>> import kaiwu as kw
>>> b1, b2 = kw.qubo.Binary("b1"), kw.qubo.Binary("b2")
>>> q = b1 + b2 + b1*b2
>>> ci = kw.qubo.qubo_model_to_ising_model(q)
>>> kw.qubo.details(ci)
CIM Ising Details:
  CIM Ising Matrix:
    [[-0.    -0.125 -0.375]
     [-0.125 -0.    -0.375]
     [-0.375 -0.375 -0.   ]]
  CIM Ising Bias: 1.25
  CIM Ising Variables: b1, b2, __spin__
  Variable type: binary
  QUBO Matrix:
    [[1. 1.]
     [0. 1.]]
  QUBO Offset: 0
  QUBO Variables: b1, b2
kaiwu.qubo.ising_matrix_to_qubo_matrix(ising_mat, remove_linear_bit=True)#

Ising矩阵转QUBO矩阵

Args:

ising_mat (np.ndarray): Ising矩阵

remove_linear_bit (bool): QUBO转Ising时会增加一个辅助变量表示线性项。是否移除最后一个自旋变量。默认为True。

Returns:

tuple: QUBO矩阵和bias

  • qubo_mat (np.ndarray): QUBO矩阵

  • bias (float): QUBO与Ising相差的常数项

Examples:
>>> import numpy as np
>>> import kaiwu as kw
>>> matrix = -np.array([[ 0. ,  1. ,  0. ,  1. ,  1. ],
...                     [ 1. ,  0. ,  0. ,  1.,   1. ],
...                     [ 0. ,  0. ,  0. ,  1.,   1. ],
...                     [ 1. ,  1.,   1. ,  0. ,  1. ],
...                     [ 1. ,  1.,   1. ,  1. ,  0. ]])
>>> _qubo_mat, _ = kw.qubo.ising_matrix_to_qubo_matrix(matrix)
>>> _qubo_mat
array([[-4.,  8.,  0.,  8.],
       [-0., -4.,  0.,  8.],
       [-0., -0., -0.,  8.],
       [-0., -0., -0., -8.]])
kaiwu.qubo.qubo_matrix_to_ising_matrix(qubo_mat)#

QUBO矩阵转Ising矩阵

Args:

qubo_mat (np.ndarray): QUBO矩阵

Returns:
tuple: Ising矩阵和bias
  • ising_mat (np.ndarray): Ising矩阵

  • bias (float): QUBO与Ising相差的常数项

Examples:
>>> import numpy as np
>>> import kaiwu as kw
>>> matrix = -np.array([[-4.,  8.,  0.,  8.],
...                     [-0., -4.,  0.,  8.],
...                     [-0., -0., -0.,  8.],
...                     [-0., -0., -0., -8.]])
>>> _ising_mat, _ = kw.qubo.qubo_matrix_to_ising_matrix(matrix)
>>> _ising_mat
array([[-0.,  1., -0.,  1.,  1.],
       [ 1., -0., -0.,  1.,  1.],
       [-0., -0., -0.,  1.,  1.],
       [ 1.,  1.,  1., -0.,  1.],
       [ 1.,  1.,  1.,  1., -0.]])
kaiwu.qubo.qubo_model_to_qubo_matrix(qubo_expr)#

QUBO输出QUBO矩阵.

Args:

qubo_expr (QUBO): QUBO.

Returns:

dict: QUBO矩阵字典.

Examples:
>>> import kaiwu as kw
>>> b1, b2 = kw.qubo.Binary("b1"), kw.qubo.Binary("b2")
>>> q = b1 + b2 + b1*b2
>>> qubo_mol = kw.qubo.make(q)
>>> md = kw.qubo.qubo_model_to_qubo_matrix(qubo_mol)
>>> md
{'qubo_matrix': array([[1., 1.],
       [0., 1.]]), 'offset': 0, 'variables': {'bb1': 0, 'bb2': 1}}
kaiwu.qubo.qubo_matrix_to_qubo_model(qubo_mat)#

将qubo矩阵转化为qubo模型

Args:

qubo_mat (np.ndarray): QUBO矩阵

Returns:

QuboExpression: QUBO模型

Examples:
>>> import numpy as np
>>> import kaiwu as kw
>>> matrix = -np.array([[0, 8],
...                     [0, 0]])
>>> kw.qubo.qubo_matrix_to_qubo_model(matrix)
-8*b[0]*b[1]
kaiwu.qubo.check_qubo_matrix_bit_width(qubo_matrix, bit_width=8)#

校验QUBO矩阵元素位宽

将QUBO矩阵转为伊辛矩阵,通过校验伊辛矩阵的元素位宽来实现对QUBO矩阵的校验

Args:

qubo_matrix (np.ndarray): QUBO矩阵

bit_width (int): 位宽

Examples1:
>>> import numpy as np
>>> import kaiwu as kw
>>> _matrix = -np.array([[-480., 508., -48.],
...                      [ 508., -508., -48.],
...                      [ -48., -48., 60.]])
>>> kw.qubo.check_qubo_matrix_bit_width(_matrix)
Examples2(缩放后符合要求):
>>> import numpy as np
>>> import kaiwu as kw
>>> _matrix = -np.array([[-512.,  520.,  -48.],
...                      [ 520., -520.,  -48.],
...                      [ -48.,  -48.,   40.]])
>>> kw.qubo.check_qubo_matrix_bit_width(_matrix)
Examples3(缩放后也不符合要求):
>>> import numpy as np
>>> import kaiwu as kw
>>> _matrix = -np.array([[-488.,  516.,  -48.],
...                      [ 516., -516.,  -48.],
...                      [ -48.,  -48.,   60.]])
>>> kw.qubo.check_qubo_matrix_bit_width(_matrix)
Traceback (most recent call last):
...
ValueError: CIM only supports signed 8-bit number
kaiwu.qubo.adjust_qubo_matrix_precision(qubo_matrix, bit_width=8)#

调整矩阵精度, 通过此接口调整后矩阵可能会有较大的精度损失,比如矩阵有一个数远大于其它数时,调整后矩阵精度损失严重无法使用

Args:

qubo_matrix (np.ndarray): 目标矩阵

bit_width (int): 精度范围,目前只支持8位,有一位是符号位

Returns:

np.ndarray: 符合精度要求的QUBO矩阵

Examples:
>>> import numpy as np
>>> import kaiwu as kw
>>> ori_qubo_mat1 = np.array([[0.89, 0.22, 0.198],
...                      [0.22, 0.23, 0.197],
...                      [0.198, 0.197, 0.198]])
>>> qubo_mat1 = kw.qubo.adjust_qubo_matrix_precision(ori_qubo_mat1)
>>> qubo_mat1
array([[348., 168., 152.],
       [ -0.,  92., 152.],
       [ -0.,  -0.,  80.]])
>>> ori_qubo_mat2 = np.array([[0.89, 0.22, 0.198],
...                           [0.22, 0.23, 0.197],
...                           [0.198, 0.197, 100]])
>>> qubo_mat2 = kw.qubo.adjust_qubo_matrix_precision(ori_qubo_mat2)
>>> qubo_mat2  # The solutions obtained by qubo_mat2 and ori_qubo_mat2 matrices are quite different
array([[  8.,  -0.,  -0.],
       [ -0.,   4.,  -0.],
       [ -0.,  -0., 508.]])
class kaiwu.qubo.QuboModel(objective=None)#

基类:object

支持添加约束的QUBO模型类

Args:

objective (QuboExpression, optional): 目标函数. 默认为None

constraint_dicts = {'hard_constraint': {}, 'soft_constraint': {}}#
set_objective(objective)#

设置目标函数

Args:

objective (QuboExpression): 目标函数表达式

add_constraint(constraint, name, penalty: float | None = None, constr_type: Literal['soft', 'hard'] = 'hard', expected_value=0, slack_expr=None)#

添加约束项

Args:

constraint (QuboExpression): 约束表达式

name (str, optional): 约束名称,默认按照"constraint1", "constraint2"等依次命名

penalty (float, optional): 约束项惩罚系数. 默认自动生成

constr_type (str, optional): 约束类型,可以设置为"soft"或"hard",默认为"hard"

expected_value (float, optional): 约束的预期值,即约束值为多少时视为满足,默认为0

slack_expr (QuboExpression): 松弛变量的QUBO表达式

make(hobo_constraint_strength=None)#

返回合并后的QUBO表达式

Args:

hobo_constraint_strength (float, optional): 自动降阶惩罚系数. 默认为自动生成

Returns:

QuboExpression: 合并的约束表达式

to_ising_model()#

转化为Ising模型

get_qubo_matrix(bit_width=None)#

获取QUBO矩阵,并调整精度

Args:

bit_width (int, optional): 矩阵的精度

Returns:

numpy.ndarray: QUBO矩阵

get_sol_dict(qubo_solution)#

根据解向量生成结果字典.

get_value(solution_dict)#

根据结果字典将变量值带入qubo变量.

Args:

solution_dict (dict): 由get_sol_dict生成的结果字典。

Returns:

float: 带入qubo后所得的值

verify_constraint(solution_dict, constr_type: Literal['soft', 'hard'] = 'hard')#

确认约束是否满足

Args:

solution_dict (dict): QUBO模型解字典

constr_type(str, optional): 约束类型,可以设置为"soft"或"hard",默认为"hard"

Returns:
tuple: 约束满足信息
  • int: 不满足的约束个数

  • dict: 包含约束值的字典

kaiwu.qubo.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_q = kw.qubo.calculate_qubo_value(matrix, offset, binary_configuration)
>>> print(qubo_q)
2.8