Esempio n. 1
0
    def test_large(self):
        # submit large CQMs of binary, spin, integer and mixed
        num_variables = 5000

        objectives = dict()

        objectives['binary'] = dimod.BQM(num_variables, 'BINARY')
        objectives['spin'] = dimod.BQM(num_variables, 'SPIN')

        objectives['integer'] = integer = dimod.QM()
        integer.add_variables_from('INTEGER', range(num_variables))

        objectives['mixed'] = mixed = dimod.QM()
        mixed.add_variables_from('INTEGER', range(num_variables // 3))
        mixed.add_variables_from(
            'SPIN', range(mixed.num_variables, mixed.num_variables + (num_variables // 3)))
        mixed.add_variables_from('BINARY', range(mixed.num_variables, num_variables))

        for vartype, model in objectives.items():
            with self.subTest(f"one constraint, vartype={vartype}"):
                cqm = dimod.ConstrainedQuadraticModel()
                cqm.set_objective(model)
                cqm.add_constraint(model, rhs=1, sense='==')
                sampleset = sampler.sample_cqm(cqm)
                self.assertConsistent(cqm, sampleset)

            with self.subTest(f"no constraints, vartype={vartype}"):
                cqm = dimod.ConstrainedQuadraticModel()
                cqm.set_objective(model)
                sampleset = sampler.sample_cqm(cqm)
                self.assertConsistent(cqm, sampleset)
Esempio n. 2
0
    def test_small(self):
        # submit 3-variable CQMs of binary, spin, integer and mixed
        objectives = dict()

        objectives['binary'] = dimod.BQM({'a': 1, 'b': 1, 'c': 1}, {}, 0, 'BINARY')
        objectives['spin'] = dimod.BQM({'a': 1, 'b': 1, 'c': 1}, {}, 0, 'SPIN')

        objectives['integer'] = integer = dimod.QM()
        integer.add_variables_from('INTEGER', 'abc')

        objectives['mixed'] = mixed = dimod.QM()
        mixed.add_variable('BINARY', 'a')
        mixed.add_variable('SPIN', 'b')
        mixed.add_variable('INTEGER', 'c')

        for vartype, model in objectives.items():
            with self.subTest(f"one constraint, vartype={vartype}"):
                cqm = dimod.ConstrainedQuadraticModel()
                cqm.set_objective(model)
                cqm.add_constraint(model, rhs=1, sense='==')
                sampleset = sampler.sample_cqm(cqm)
                self.assertConsistent(cqm, sampleset)

            with self.subTest(f"no constraints, vartype={vartype}"):
                cqm = dimod.ConstrainedQuadraticModel()
                cqm.set_objective(model)
                sampleset = sampler.sample_cqm(cqm)
                self.assertConsistent(cqm, sampleset)
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}

        cqm = make_quadratic_cqm(poly, dimod.SPIN, cqm=dimod.ConstrainedQuadraticModel())

        variables = set().union(*poly)
        aux_variables = tuple(set(cqm.variables) - 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)
                if cqm.check_feasible(aux_sample):
                    reduced_energies.append(cqm.objective.energy(aux_sample))

            self.assertAlmostEqual(energy, min(reduced_energies))
Esempio n. 4
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

        cqm0 = dimod.ConstrainedQuadraticModel()
        cqm0.set_objective(dimod.BinaryQuadraticModel.from_ising(h, {}, off))
        cqm = make_quadratic_cqm(J, dimod.SPIN, cqm=cqm0)

        variables = set(h).union(*J)
        aux_variables = tuple(set(cqm.variables) - 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)
                if cqm.check_feasible(aux_sample):
                    reduced_energies.append(cqm.objective.energy(aux_sample))

            self.assertAlmostEqual(energy, min(reduced_energies))
Esempio n. 5
0
    def test_sample_CONSTRAINED_MIXED(self):
        # Using various Vartypes, including the `add_discrete` method
        cqm = dimod.ConstrainedQuadraticModel()
        x = {(u, v): dimod.Binary((u, v))
             for u, v in product(['u1', 'u2'], range(3))}

        cqm.add_discrete([('u1', v) for v in range(3)], label='u1')
        cqm.add_discrete([('u2', v) for v in range(3)], label='u2')

        y, z = dimod.Spin('y'), dimod.Integer('z',
                                              lower_bound=1,
                                              upper_bound=3)

        obj1 = x[('u1', 0)] * y - x[('u2', 1)] * y
        obj2 = x[('u1', 0)] * z + 2 * x[('u1', 2)] * x[('u2', 2)]

        cqm.set_objective(obj1 + obj2)
        cqm.add_constraint(z == 2)

        response = dimod.ExactCQMSolver().sample_cqm(cqm)

        # every possible combination should be present, respecting the discrete constraints
        self.assertEqual(len(response), 54)
        self.assertEqual(response.record.sample.shape,
                         (54, len(cqm.variables)))

        # only 18 samples should be feasible
        feasible_responses = response.filter(lambda d: d.is_feasible)
        self.assertEqual(len(feasible_responses), 18)

        dimod.testing.assert_sampleset_energies_cqm(response, cqm)
Esempio n. 6
0
    def test_linear_constraints(self):
        num_constraints = 100000

        x = dimod.Binary('x')

        cqm = dimod.ConstrainedQuadraticModel()
        for _ in range(num_constraints):
            cqm.add_constraint(x == 1)

        sampler.sample_cqm(cqm).resolve()  # smoke test
Esempio n. 7
0
    def test_kwargs(self):
        bqm = dimod.BinaryQuadraticModel({}, {}, 0.0, dimod.SPIN)
        with self.assertWarns(SamplerUnknownArgWarning):
            sampleset = dimod.ExactSolver().sample(bqm, a=1, b="abc")

        dqm = dimod.DiscreteQuadraticModel()
        with self.assertWarns(SamplerUnknownArgWarning):
            sampleset = dimod.ExactDQMSolver().sample_dqm(dqm, a=1, b="abc")

        cqm = dimod.ConstrainedQuadraticModel()
        with self.assertWarns(SamplerUnknownArgWarning):
            sampleset = dimod.ExactCQMSolver().sample_cqm(cqm, a=1, b="abc")
Esempio n. 8
0
    def test_sample_CONSTRAINED_SPIN(self):
        # using Spin variables, with inequality constraint:
        cqm = dimod.ConstrainedQuadraticModel()
        x, y, z = dimod.Spin('x'), dimod.Spin('y'), dimod.Spin('z')
        cqm.set_objective(x * y + 2 * y * z)
        cqm.add_constraint(x * y <= 0)

        response = dimod.ExactCQMSolver().sample_cqm(cqm)

        # every possible combination should be present
        self.assertEqual(len(response), 8)
        self.assertEqual(response.record.sample.shape, (8, len(cqm.variables)))

        # four samples should be feasible
        feasible_responses = response.filter(lambda d: d.is_feasible)
        self.assertEqual(len(feasible_responses), 4)

        dimod.testing.assert_sampleset_energies_cqm(response, cqm)
Esempio n. 9
0
    def test_sample_CONSTRAINED_INTEGER(self):
        # using Integer variables, with inequality constraint:
        cqm = dimod.ConstrainedQuadraticModel()
        x, y, z = dimod.Integer(
            'x', lower_bound=1, upper_bound=3), dimod.Integer(
                'y', lower_bound=4,
                upper_bound=5), dimod.Integer('z',
                                              lower_bound=-2,
                                              upper_bound=1)
        cqm.set_objective(x * y + 2 * y * z)
        cqm.add_constraint(x * z >= 1)

        response = dimod.ExactCQMSolver().sample_cqm(cqm)

        # every possible combination should be present
        self.assertEqual(len(response), 24)
        self.assertEqual(response.record.sample.shape,
                         (24, len(cqm.variables)))

        # only six samples should be feasible
        feasible_responses = response.filter(lambda d: d.is_feasible)
        self.assertEqual(len(feasible_responses), 6)

        dimod.testing.assert_sampleset_energies_cqm(response, cqm)
Esempio n. 10
0
 def test_empty(self):
     cqm = make_quadratic_cqm({}, dimod.SPIN)
     self.assertTrue(cqm.is_almost_equal(dimod.ConstrainedQuadraticModel()))
Esempio n. 11
0
def graph_partition_cqm(G, num_partitions):
    """Find a constrained quadratic model for the graph's partitions.

    Defines an CQM with ground states corresponding to a
    balanced k-partition of G and uses the sampler to sample from it.
    A k-partition is a collection of k subsets of the vertices
    of G such that each vertex is in exactly one subset, and
    the number of edges between vertices in different subsets
    is as small as possible. If G is a weighted graph, the sum
    of weights over those edges are minimized.
    
    Parameters
    ----------
    G : NetworkX graph
        The graph to partition.
    num_partitions : int
        The number of subsets in the desired partition.

    Returns
    -------
    cqm : :class:`dimod.ConstrainedQuadraticModel`
        A constrained quadratic model with ground states corresponding to a
        partition problem. The nodes of `G` are discrete logical variables
        of the CQM, where the cases are the different partitions the node
        can be assigned to. The objective is given as the number of edges
        connecting nodes in different partitions.

    """
    partition_size = G.number_of_nodes() / num_partitions
    partitions = range(num_partitions)
    cqm = dimod.ConstrainedQuadraticModel()

    # Variables will be added using the discrete method in CQM
    x = {vk: dimod.Binary(vk) for vk in itertools.product(G.nodes, partitions)}

    for v in G.nodes:
        cqm.add_discrete(((v, k) for k in partitions), label=v)

    if not math.isclose(partition_size, int(partition_size)):
        # if number of nodes don't divide into num_partitions,
        # accept partitions of size ceil() or floor()
        floor, ceil = int(partition_size), int(partition_size + 1)
        for k in partitions:
            cqm.add_constraint(dimod.quicksum(
                (x[u, k] for u in G.nodes)) >= floor,
                               label='equal_partition_low_%s' % k)
            cqm.add_constraint(dimod.quicksum(
                (x[u, k] for u in G.nodes)) <= ceil,
                               label='equal_partition_high_%s' % k)
    else:
        # each partition must have partition_size elements
        for k in partitions:
            cqm.add_constraint(dimod.quicksum(
                (x[u, k] for u in G.nodes)) == int(partition_size),
                               label='equal_partition_%s' % k)

    cuts = 0
    for (u, v, d) in G.edges(data=True):
        for k in partitions:
            w = d.get('weight', 1)
            cuts += w * x[u, k] * x[v, k]

    if cuts:
        cqm.set_objective(-cuts)

    return cqm
Esempio n. 12
0
    def test_sample_CONSTRAINED_empty(self):
        cqm = dimod.ConstrainedQuadraticModel()
        response = dimod.ExactCQMSolver().sample_cqm(cqm)

        self.assertEqual(response.record.sample.shape, (0, 0))