Source code for qlauncher.problems.problem_formulations.bqm

 1import ast
 2import numpy as np
 3from pyqubo import Spin
 4from qlauncher.base import adapter, formatter
 5from qlauncher.problems.problem_initialization import Raw
 6
 7
[docs] 8@adapter('qubo', 'bqm') 9def qubo_to_bqm(qubo_with_offset) -> dict: 10 qubo, offset = qubo_with_offset 11 bqm, _ = QUBOMatrix(qubo, offset).qubo_matrix_into_bqm() 12 return bqm
13 14
[docs] 15class QUBOMatrix: 16 def __init__(self, qubo_matrix, offset): 17 self.qubo_matrix = qubo_matrix 18 self.offset = offset 19 20 if type(self.qubo_matrix) == str: 21 self.qubo_matrix = np.array(ast.literal_eval(self.qubo_matrix)) 22 23 self.symetric = True 24 self._check_if_symetric() 25 26 def _check_if_symetric(self): 27 """ 28 Function to check if matrix is symetric 29 """ 30 self.symetric = (self.qubo_matrix.transpose() 31 == self.qubo_matrix).all() 32 if not self.symetric: 33 self.qubo_matrix = self._remove_lower_triangle(self.qubo_matrix) 34 35 def _remove_lower_triangle(self, matrix): 36 """ 37 Function to remove lower triangle from matrix 38 """ 39 for i in range(len(matrix)): 40 for j in range(len(matrix)): 41 if i > j: 42 matrix[i][j] = 0 43 return matrix 44 45 def _get_values_and_qubits(self, matrix): 46 """ 47 Function to get values and qubits from matrix in form of dictionary 48 where keys are indexes of qubits and values are values of matrix 49 The function does not take into account zeros in matrix 50 Example: 51 matrix = [[0,1,2],[1,0,3],[2,3,0]] 52 result = {(0,1):1, (0,2):2, (1,0):1, (1,2):3, (2,0):2, (2,1):3} 53 Function also return second value which is the number of qubits 54 """ 55 result = { 56 (x, y): c for y, r in enumerate(matrix) for x, c in enumerate(r) if c != 0 57 } 58 return result, len(matrix) 59
[docs] 60 def qubo_matrix_into_bqm(self): 61 values_and_qubits, number_of_qubits = self._get_values_and_qubits( 62 self.qubo_matrix 63 ) 64 qubits = [Spin(f"x{i}") for i in range(number_of_qubits)] 65 H = 0 66 for (x, y), value in values_and_qubits.items(): 67 if self.symetric: 68 H += value / len(set((x, y))) * qubits[x] * qubits[y] 69 else: 70 H += value * qubits[x] * qubits[y] 71 model = H.compile() 72 bqm = model.to_bqm() 73 bqm.offset += self.offset 74 return bqm, model
75 76
[docs] 77@formatter(Raw, 'bqm') 78def Rawbqm(problem: Raw): 79 return problem.instance