Exemplo n.º 1
0
    def test_quadratic_constraints(self):
        num_constraints = 100000

        x = dimod.Binary('x')
        y = dimod.Binary('y')

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

        sampler.sample_cqm(cqm).resolve()  # smoke test
Exemplo n.º 2
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)
Exemplo n.º 3
0
 def test_qm(self):
     x = dimod.Binary('x')
     s = dimod.Spin('s')
     i = dimod.Integer('i')
     self.assertTrue((x + s + i).is_almost_equal(1.001 * (x + s + i),
                                                 places=2))
     self.assertFalse((x + s + i).is_almost_equal(1.1 * (x + s + i),
                                                  places=2))
Exemplo n.º 4
0
    def test_sample_CONSTRAINED_BINARY(self):
        # using Binary variables, with equality constraint:
        cqm = dimod.ConstrainedQuadraticModel()
        x, y, z = dimod.Binary('x'), dimod.Binary('y'), dimod.Binary('z')
        cqm.set_objective(x * y + 2 * y * z)
        cqm.add_constraint(x * y == 1)

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

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

        dimod.testing.assert_sampleset_energies_cqm(response, cqm)
Exemplo n.º 5
0
    def test_qm_Ge_constraint(self):
        i = dimod.Integer('i', upper_bound=7)
        j = dimod.Integer('j', upper_bound=9)
        x = dimod.Binary('x')

        cqm = CQM()
        cqm.add_constraint(i + j + x >= 5)

        bqm, inverter = dimod.cqm_to_bqm(cqm, lagrange_multiplier=1)

        for bin_sample in dimod.ExactSolver().sample(bqm).lowest().samples():
            int_sample = inverter(bin_sample)
            self.assertGreaterEqual(int_sample['i'] + int_sample['j'] + int_sample['x'], 5)
Exemplo n.º 6
0
    def test_qm_objective_only(self):
        i = dimod.Integer('i', upper_bound=7)
        j = dimod.Integer('j', upper_bound=9)
        x = dimod.Binary('x')

        qm = i*j + 5*j*x + 8*i + 3*x + 5
        cqm = CQM.from_qm(qm)

        bqm, inverter = dimod.cqm_to_bqm(cqm)

        sampleset = dimod.ExactSolver().sample(bqm)

        for bin_sample, energy in sampleset.data(['sample', 'energy']):
            int_sample = inverter(bin_sample)
            self.assertEqual(qm.energy(int_sample), energy)
Exemplo n.º 7
0
    def test_serializable(self):
        i = dimod.Integer('i', upper_bound=7)
        j = dimod.Integer('j', upper_bound=9)
        x = dimod.Binary('x')

        cqm = CQM()
        cqm.add_constraint(i + j + x >= 5)

        bqm, inverter = dimod.cqm_to_bqm(cqm, lagrange_multiplier=1)

        newinverter = dimod.constrained.CQMToBQMInverter.from_dict(
            json.loads(json.dumps(inverter.to_dict())))

        for bin_sample in dimod.ExactSolver().sample(bqm).lowest().samples():
            int_sample = newinverter(bin_sample)
            self.assertGreaterEqual(int_sample['i'] + int_sample['j'] + int_sample['x'], 5)
Exemplo n.º 8
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