Esempio n. 1
0
    def test_vartype(self):
        poly = {(0, 1, 2): 10, (0, 1): 5}  # make sure (0, 1) is most common

        self.assertEqual(dimod.make_quadratic(poly, 1.0, 'SPIN'),
                         dimod.make_quadratic(poly, 1.0, dimod.SPIN))
        self.assertEqual(dimod.make_quadratic(poly, 1.0, 'BINARY'),
                         dimod.make_quadratic(poly, 1.0, dimod.BINARY))
Esempio n. 2
0
    def test_quad_to_linear(self):
        J = {(0, 1): -1, (0, 1, 2): 1, (0, 1, 3): 1}
        h = {}
        off = .5

        poly = J.copy()
        poly.update({(v, ): bias for v, bias in h.items()})
        poly[()] = off

        bqm = make_quadratic(J,
                             10.0,
                             bqm=dimod.BinaryQuadraticModel.from_ising(
                                 h, {}, off))

        variables = set(h).union(*J)
        aux_variables = tuple(set(bqm.linear) - variables)
        variables = tuple(variables)
        self.assertTrue(aux_variables)
        for config in itertools.product((-1, 1), repeat=len(variables)):
            sample = dict(zip(variables, config))

            energy = poly_energy(sample, poly)

            reduced_energies = []
            for aux_config in itertools.product((-1, 1),
                                                repeat=len(aux_variables)):
                aux_sample = dict(zip(aux_variables, aux_config))
                aux_sample.update(sample)
                reduced_energies.append(bqm.energy(aux_sample))

            self.assertAlmostEqual(energy, min(reduced_energies))
Esempio n. 3
0
    def test_several_terms(self):
        poly = {(0, 1, 2): -1, (1, 2, 3): 1, (0, 2, 3): .5,
                (0,): .4,
                (): .5}

        bqm = make_quadratic(poly, 5.0,
                             bqm=dimod.BinaryQuadraticModel.empty(dimod.SPIN))

        variables = set().union(*poly)
        aux_variables = tuple(set(bqm.linear) - variables)
        variables = tuple(variables)
        self.assertTrue(aux_variables)
        for config in itertools.product((-1, 1), repeat=len(variables)):
            sample = dict(zip(variables, config))

            energy = poly_energy(sample, poly)

            reduced_energies = []
            for aux_config in itertools.product((-1, 1),
                                                repeat=len(aux_variables)):
                aux_sample = dict(zip(aux_variables, aux_config))
                aux_sample.update(sample)
                reduced_energies.append(bqm.energy(aux_sample))

            self.assertAlmostEqual(energy, min(reduced_energies))
Esempio n. 4
0
    def test_linear_and_offset(self):

        poly = {(0,): .5, tuple(): 1.3}

        bqm = dimod.make_quadratic(poly, 10.0, dimod.BINARY)

        self.assertEqual(bqm, dimod.BinaryQuadraticModel({0: .5}, {}, 1.3, dimod.BINARY))
Esempio n. 5
0
    def test_bug(self):
        # from a bug report 
        # https://support.dwavesys.com/hc/en-us/community/posts/360035719954-dimod-make-quadratic-returns-error
        H = {(0, 1, 0, 1): -4.61898,
             (0, 1, 1, 0): 4.61898,
             (0, 2, 0, 2): -5.18353,
             (0, 2, 2, 0): 5.18353,
             (1, 0, 0, 1): 4.61898,
             (1, 0, 1, 0): -4.61898,
             (1, 2, 2, 1): 4.97017,
             (2, 0, 0, 2): 5.18353,
             (2, 0, 2, 0): -5.18353,
             (2, 1, 1, 2): 4.97017,
             }

        bqm = make_quadratic(H, 1, 'BINARY')

        self.assertEqual(set(bqm), {0, 1, 2})  # should be no aux variables
Esempio n. 6
0
    def test_no_higher_order(self):
        poly = {(0, 1): -1, (1, 2): 1}

        bqm = make_quadratic(poly, 1.0, dimod.SPIN)

        variables = set().union(*poly)
        aux_variables = tuple(set(bqm.linear) - variables)
        variables = tuple(variables)
        for config in itertools.product((-1, 1), repeat=len(variables)):
            sample = dict(zip(variables, config))

            energy = poly_energy(sample, poly)

            reduced_energies = []
            for aux_config in itertools.product((-1, 1),
                                                repeat=len(aux_variables)):
                aux_sample = dict(zip(aux_variables, aux_config))
                aux_sample.update(sample)
                reduced_energies.append(bqm.energy(aux_sample))

            self.assertAlmostEqual(energy, min(reduced_energies))
Esempio n. 7
0
    def test_binary_polynomial(self):

        HUBO = {(0, 1, 2): .5, (0, 1): 1.3, (2, 4, 1): -1, (3, 2): -1}

        bqm = dimod.make_quadratic(HUBO, 1000.0, dimod.BINARY)

        variables = set().union(*HUBO)
        aux_variables = tuple(set(bqm.linear) - variables)
        variables = tuple(variables)
        self.assertTrue(aux_variables)
        for config in itertools.product((0, 1), repeat=len(variables)):
            sample = dict(zip(variables, config))

            energy = poly_energy(sample, {}, HUBO, offset=0.0)

            reduced_energies = []
            for aux_config in itertools.product((0, 1), repeat=len(aux_variables)):
                aux_sample = dict(zip(aux_variables, aux_config))
                aux_sample.update(sample)
                reduced_energies.append(bqm.energy(aux_sample))

            self.assertAlmostEqual(energy, min(reduced_energies))
Esempio n. 8
0
    def test_several_terms(self):
        h = {0: .4, 1: 0, 2: 0, 3: 0}
        J = {(0, 1, 2): -1, (1, 2, 3): 1, (0, 2, 3): .5}
        off = .5

        bqm = dimod.make_quadratic(J, 5.0, bqm=dimod.BinaryQuadraticModel.from_ising(h, {}, off))

        variables = set(h).union(*J)
        aux_variables = tuple(set(bqm.linear) - variables)
        variables = tuple(variables)
        self.assertTrue(aux_variables)
        for config in itertools.product((-1, 1), repeat=len(variables)):
            sample = dict(zip(variables, config))

            energy = poly_energy(sample, h, J, offset=off)

            reduced_energies = []
            for aux_config in itertools.product((-1, 1), repeat=len(aux_variables)):
                aux_sample = dict(zip(aux_variables, aux_config))
                aux_sample.update(sample)
                reduced_energies.append(bqm.energy(aux_sample))

            self.assertAlmostEqual(energy, min(reduced_energies))
Esempio n. 9
0
    def test_simple(self):
        h = {0: 0, 1: 0, 2: 0}
        J = {(0, 1, 2): -1}
        off = 0

        bqm = dimod.make_quadratic(J, 5.0, dimod.SPIN)

        variables = set(h).union(*J)
        aux_variables = tuple(set(bqm.linear) - variables)
        variables = tuple(variables)
        self.assertTrue(aux_variables)
        for config in itertools.product((-1, 1), repeat=len(variables)):
            sample = dict(zip(variables, config))

            energy = poly_energy(sample, h, J, offset=off)

            reduced_energies = []
            for aux_config in itertools.product((-1, 1), repeat=len(aux_variables)):
                aux_sample = dict(zip(aux_variables, aux_config))
                aux_sample.update(sample)
                reduced_energies.append(bqm.energy(aux_sample))

            self.assertAlmostEqual(energy, min(reduced_energies))
Esempio n. 10
0
 def test_empty(self):
     bqm = make_quadratic({}, 1.0, dimod.SPIN)
     self.assertEqual(bqm, dimod.BinaryQuadraticModel.empty(dimod.SPIN))
Esempio n. 11
0
    def compile(self, strength=5.0):
        """Returns the compiled :class:`Model`.
        
        This method reduces the degree of the expression if the degree is higher than 2,
        and convert it into :class:`.Model` which has information about QUBO.
        
        Args:
            strength (float): The strength of the reduction constraint.
                Insufficient strength can result in the binary quadratic model
                not having the same minimizations as the polynomial.

        Returns:
            :class:`Model`: The model compiled from the :class:`.Express`.
        
        Examples:
            In this example, there is a higher order term :math:`abcd`. It is decomposed as
            [[``a*d``, ``c``], ``b``] hierarchically and converted into QUBO.
            By calling :func:`to_qubo()` of the :obj:`model`, we get the resulting QUBO.
            
            >>> from pyqubo import Binary
            >>> a, b, c, d = Binary("a"), Binary("b"), Binary("c"), Binary("d")
            >>> model = (a*b*c + a*b*d).compile()
            >>> pprint(model.to_qubo()) # doctest: +SKIP
            ({('a', 'a'): 0.0,
              ('a', 'a*b'): -10.0,
              ('a', 'b'): 5.0,
              ('a*b', 'a*b'): 15.0,
              ('a*b', 'b'): -10.0,
              ('a*b', 'c'): 1.0,
              ('a*b', 'd'): 1.0,
              ('b', 'b'): 0.0,
              ('c', 'c'): 0,
              ('d', 'd'): 0},
             0.0)
        """
        def compile_param_if_express(val):
            if isinstance(val, Express):
                return val._compile_param()
            else:
                return val

        # Constraint for AND(multiplier, multiplicand) = product
        def binary_product(multiplier, multiplicand, product, weight):
            return {
                BinaryProd({product}): 3.0 * weight,
                BinaryProd({multiplicand, product}): -2.0 * weight,
                BinaryProd({multiplier, product}): -2.0 * weight,
                BinaryProd({multiplier, multiplicand}): weight
            }

        # When the label contains PROD_SYM, elements of products should be sorted
        # such that the resulting label is uniquely determined.
        def normalize_label(label):
            s = Express.PROD_SYM
            if s in label:
                return s.join(sorted(label.split(s)))
            else:
                return label

        # Expand the expression to polynomial
        expanded, constraints, penalties = Express._expand(self)
        expanded = Express._merge_term(expanded, penalties)

        # Make polynomials quadratic
        offset = 0.0
        pubo = {}
        for term_key, value in expanded.items():
            if term_key.is_constant():
                offset = value
            else:
                pubo[tuple(term_key.keys)] = value
        bqm = dimod.make_quadratic(pubo, strength, dimod.BINARY)
        bqm_qubo, bqm_offset = bqm.to_qubo()

        # Extracts product constrains
        product_consts = {}
        for (a, b), v in bqm.info['reduction'].items():
            prod = normalize_label(v['product'])
            a = normalize_label(a)
            b = normalize_label(b)
            product_consts["AND({},{})={}".format(a, b, prod)]\
                = binary_product(a, b, prod, strength)

        # Normalize labels and compile values of the QUBO
        compiled_qubo = {}
        for (label1, label2), value in bqm_qubo.items():
            norm_label1 = normalize_label(label1)
            norm_label2 = normalize_label(label2)

            # Sort the tuple of labels such that the created key is uniquely determined.
            if norm_label2 > norm_label1:
                label_key = (norm_label1, norm_label2)
            else:
                label_key = (norm_label2, norm_label1)
            # Compile values of the QUBO
            compiled_qubo[label_key] = compile_param_if_express(value)
        compiled_qubo = CompiledQubo(
            compiled_qubo, compile_param_if_express(offset + bqm_offset))

        # compile values of constraint
        compiled_constraints = {}
        for label, constraint in Express._merge_dict(constraints,
                                                     product_consts).items():
            compiled_constraints[label] =\
                CompiledConstraint({prod: compile_param_if_express(value)
                                    for prod, value in constraint.items()})

        # Merge structures
        uniq_variables = Express._unique_vars(self)
        structure = reduce(Express._merge_dict,
                           [var.structure for var in uniq_variables])

        return Model(compiled_qubo, structure, compiled_constraints)
Esempio n. 12
0

def get_dic_from_matrix(matrix):
    d = {}
    for i in product(*[range(s) for s in matrix.shape]):
        if matrix[i]:
            d[i] = matrix[i]
    return d


set_up_linear_members()
set_up_quadratic_members()
set_up_cubic_memebers()
# print(get_dic_from_matrix(I))

poly = {
    **get_dic_from_matrix(I),
    **get_dic_from_matrix(J),
    **get_dic_from_matrix(H)
}

# used to make cubic-quadratic conversion
strength = 5

bqm = dimod.make_quadratic(poly, strength, dimod.BINARY)
print(bqm.num_variables)
sampler = neal.SimulatedAnnealingSampler()
result = sampler.sample(bqm, num_reads=20)
# sampler = LeapHybridSampler()
# sampleset = sampler.sample(bqm)
Esempio n. 13
0
 def get_results(self):
     strength = 5
     bqm = dimod.make_quadratic(self.poly, strength, dimod.BINARY)
     sampler = neal.SimulatedAnnealingSampler()
     result = sampler.sample(bqm, num_reads=200)
     return result.lowest().first.sample