def test_retrieval(self):

        eq = {(-1, -1), (1, 1)}

        spec = pm.Specification(nx.path_graph(2), (0, 1), eq, vartype=pm.SPIN)
        widget = pm.get_penalty_model(spec)

        self.assertEqual(widget.model.linear, {0: 0, 1: 0})
        self.assertEqual(widget.model.quadratic, {(0, 1): -1})
Exemple #2
0
    def test_relabel_copy(self):
        graph = nx.circular_ladder_graph(12)
        decision_variables = (0, 2, 5)
        feasible_configurations = {(1, 1, 1): 0.}
        spec = pm.Specification(graph, decision_variables, feasible_configurations, vartype=dimod.SPIN)

        mapping = dict(enumerate('abcdefghijklmnopqrstuvwxyz'))

        new_spec = spec.relabel_variables(mapping, inplace=False)

        # create a test spec
        graph = nx.relabel_nodes(graph, mapping)
        decision_variables = (mapping[v] for v in decision_variables)
        test_spec = pm.Specification(graph, decision_variables, feasible_configurations, vartype=dimod.SPIN)

        self.assertEqual(new_spec, test_spec)
        self.assertEqual(new_spec.ising_linear_ranges, test_spec.ising_linear_ranges)
        self.assertEqual(new_spec.ising_quadratic_ranges, test_spec.ising_quadratic_ranges)
    def test_relabel_inplace_overlap(self):
        graph = nx.circular_ladder_graph(12)
        decision_variables = (0, 2, 5)
        feasible_configurations = {(1, 1, 1): 0.}
        spec = pm.Specification(graph, decision_variables, feasible_configurations, vartype=dimod.SPIN)

        mapping = {v: v + 5 for v in graph}

        new_spec = spec.relabel_variables(mapping, inplace=True)
Exemple #4
0
    def test_relabel_forwards_and_backwards(self):
        graph = nx.path_graph(4)
        graph.add_edge(0, 2)
        decision_variables = (0, 2)
        feasible_configurations = {(-1, -1): 0., (+1, +1): 0.}
        spec = pm.Specification(graph, decision_variables, feasible_configurations, vartype=dimod.SPIN)

        # make another one
        graph = nx.path_graph(4)
        graph.add_edge(0, 2)
        decision_variables = (0, 2)
        feasible_configurations = {(-1, -1): 0., (+1, +1): 0.}
        original_spec = pm.Specification(graph, decision_variables, feasible_configurations, vartype=dimod.SPIN)

        identity = {v: v for v in graph}

        new_label_sets = [(10, 1),
                          ('a', 'b'),
                          (1, 'b'),
                          ('1', '2', '3', '4'),
                          ('a', 'b', 'c', 'd')]
        new_label_sets.extend(itertools.permutations(graph))

        for new in new_label_sets:
            mapping = dict(enumerate(new))
            inv_mapping = {u: v for v, u in mapping.items()}

            # apply then invert with inplace=False
            copy_spec = spec.relabel_variables(mapping, inplace=False)
            inv_copy = copy_spec.relabel_variables(inv_mapping, inplace=False)
            self.assertEqual(inv_copy, original_spec)
            self.assertEqual(inv_copy.ising_linear_ranges, original_spec.ising_linear_ranges)
            self.assertEqual(inv_copy.ising_quadratic_ranges, original_spec.ising_quadratic_ranges)

            # apply then invert with inplace=True
            spec.relabel_variables(mapping, inplace=True)
            if mapping == identity:
                self.assertEqual(spec, original_spec)
            else:
                self.assertNotEqual(spec, original_spec)
            spec.relabel_variables(inv_mapping, inplace=True)
            self.assertEqual(spec, original_spec)
            self.assertEqual(spec.ising_linear_ranges, original_spec.ising_linear_ranges)
            self.assertEqual(spec.ising_quadratic_ranges, original_spec.ising_quadratic_ranges)
Exemple #5
0
    def test_relabel_forwards_and_backwards(self):
        graph = nx.path_graph(4)
        graph.add_edge(0, 2)
        decision_variables = (0, 2)
        feasible_configurations = {(-1, -1): 0., (+1, +1): 0.}
        spec = pm.Specification(graph, decision_variables, feasible_configurations, vartype=dimod.SPIN)
        linear = {v: 0 for v in graph}
        quadratic = {edge: -1 for edge in graph.edges}
        model = dimod.BinaryQuadraticModel(linear, quadratic, 0.0, vartype=dimod.SPIN)
        widget = pm.PenaltyModel.from_specification(spec, model, 2., -2)

        # make another one
        graph = nx.path_graph(4)
        graph.add_edge(0, 2)
        decision_variables = (0, 2)
        feasible_configurations = {(-1, -1): 0., (+1, +1): 0.}
        spec = pm.Specification(graph, decision_variables, feasible_configurations, vartype=dimod.SPIN)
        linear = {v: 0 for v in graph}
        quadratic = {edge: -1 for edge in graph.edges}
        model = dimod.BinaryQuadraticModel(linear, quadratic, 0.0, vartype=dimod.SPIN)
        original_widget = pm.PenaltyModel.from_specification(spec, model, 2., -2)

        new_label_sets = [(10, 1),
                          ('a', 'b'),
                          (1, 'b'),
                          ('1', '2', '3', '4'),
                          ('a', 'b', 'c', 'd')]
        new_label_sets.extend(itertools.permutations(graph))

        for new in new_label_sets:
            mapping = dict(enumerate(new))
            inv_mapping = {u: v for v, u in mapping.items()}

            # apply then invert with copy=False
            widget.relabel_variables(mapping, inplace=True)
            widget.relabel_variables(inv_mapping, inplace=True)
            self.assertEqual(widget, original_widget)

            # apply then invert with copy=True
            copy_widget = widget.relabel_variables(mapping, inplace=False)
            inv_copy = copy_widget.relabel_variables(inv_mapping, inplace=False)
            self.assertEqual(inv_copy, original_widget)
    def test_typical(self):
        graph = nx.complete_graph(3)
        spec = pm.Specification(graph, [0, 1], {(-1, -1): 0, (+1, +1): 0}, dimod.SPIN)

        widget = mip.get_penalty_model(spec)

        # some quick test to see that the penalty model propogated in
        for v in graph:
            self.assertIn(v, widget.model.linear)
        for (u, v) in graph.edges:
            self.assertIn(u, widget.model.adj[v])
Exemple #7
0
    def test_linear_ranges_specified(self):
        graph = nx.barbell_graph(4, 16)
        decision_variables = (0, 4, 3)
        feasible_configurations = {(0, 0, 1): 0.}

        spec = pm.Specification(graph, decision_variables, feasible_configurations,
                                ising_linear_ranges={v: [-v, 2] for v in graph},
                                vartype=dimod.BINARY)

        # check default energy ranges
        for v in graph:
            self.assertEqual(spec.ising_linear_ranges[v], [-v, 2])

        spec = pm.Specification(graph, decision_variables, feasible_configurations,
                                ising_linear_ranges={v: (-v, 2) for v in graph},
                                vartype=dimod.BINARY)

        # check default energy ranges
        for v in graph:
            self.assertEqual(spec.ising_linear_ranges[v], [-v, 2])
Exemple #8
0
    def test_construction_typical(self):
        graph = nx.complete_graph(10)
        decision_variables = (0, 4, 5)
        feasible_configurations = {(-1, -1, -1): 0.}

        spec = pm.Specification(graph, decision_variables, feasible_configurations, vartype=dimod.SPIN)

        self.assertEqual(spec.graph, graph)  # literally the same object
        self.assertEqual(spec.decision_variables, decision_variables)
        self.assertEqual(spec.feasible_configurations, feasible_configurations)
        self.assertIs(spec.vartype, dimod.SPIN)
Exemple #9
0
    def test_relabel(self):
        graph = nx.path_graph(3)
        decision_variables = (0, 2)
        feasible_configurations = {(-1, -1): 0., (+1, +1): 0.}
        spec = pm.Specification(graph,
                                decision_variables,
                                feasible_configurations,
                                vartype=dimod.SPIN)
        linear = {v: 0 for v in graph}
        quadratic = {edge: -1 for edge in graph.edges}
        model = dimod.BinaryQuadraticModel(linear,
                                           quadratic,
                                           0.0,
                                           vartype=dimod.SPIN)
        widget = pm.PenaltyModel.from_specification(spec, model, 2., -2)

        # now set up the same widget with 0 relabelled to 'a'
        graph = nx.path_graph(3)
        graph = nx.relabel_nodes(graph, {0: 'a'})
        decision_variables = ('a', 2)
        feasible_configurations = {(-1, -1): 0., (+1, +1): 0.}
        spec = pm.Specification(graph,
                                decision_variables,
                                feasible_configurations,
                                vartype=dimod.SPIN)
        linear = {v: 0 for v in graph}
        quadratic = {edge: -1 for edge in graph.edges}
        model = dimod.BinaryQuadraticModel(linear,
                                           quadratic,
                                           0.0,
                                           vartype=dimod.SPIN)
        test_widget = pm.PenaltyModel.from_specification(spec, model, 2., -2)

        # without copy
        new_widget = widget.relabel_variables({0: 'a'}, inplace=False)
        self.assertEqual(test_widget, new_widget)
        self.assertEqual(new_widget.decision_variables, ('a', 2))

        widget.relabel_variables({0: 'a'}, inplace=True)
        self.assertEqual(widget, test_widget)
        self.assertEqual(widget.decision_variables, ('a', 2))
Exemple #10
0
    def test_relabel_inplace(self):
        graph = nx.circular_ladder_graph(12)
        decision_variables = (0, 2, 5)
        feasible_configurations = {(1, 1, 1): 0.}
        spec = pm.Specification(graph, decision_variables, feasible_configurations, vartype=dimod.SPIN)

        mapping = {i: v for i, v in enumerate('abcdefghijklmnopqrstuvwxyz') if i in graph}

        new_spec = spec.relabel_variables(mapping, inplace=True)

        self.assertIs(new_spec, spec)  # should be the same object
        self.assertIs(new_spec.graph, spec.graph)

        # create a test spec
        graph = nx.relabel_nodes(graph, mapping)
        decision_variables = (mapping[v] for v in decision_variables)
        test_spec = pm.Specification(graph, decision_variables, feasible_configurations, vartype=dimod.SPIN)

        self.assertEqual(new_spec, test_spec)
        self.assertEqual(new_spec.ising_linear_ranges, test_spec.ising_linear_ranges)
        self.assertEqual(new_spec.ising_quadratic_ranges, test_spec.ising_quadratic_ranges)
    def test_nonzero_configuration(self):
        """MaxGap is currently not supporting non-zero feasible states. This is checking that
        non-zero feasible state problems don't get run.
        """
        graph = nx.complete_graph(3)
        spec = pm.Specification(graph, [0, 1], {
            (-1, 1): 0,
            (-1, -1): -2
        }, dimod.SPIN)

        with self.assertRaises(ImpossiblePenaltyModel):
            maxgap.get_penalty_model(spec)
Exemple #12
0
    def test_vartype_specified(self):
        graph = nx.complete_graph(12)
        decision_variables = (0, 2, 5)
        feasible_configurations = {(1, 1, 1): 0.}

        spec = pm.Specification(graph, decision_variables, feasible_configurations, vartype=dimod.SPIN)
        self.assertIs(spec.vartype, dimod.SPIN)

        spec = pm.Specification(graph, decision_variables, feasible_configurations, vartype=dimod.BINARY)
        self.assertIs(spec.vartype, dimod.BINARY)

        # now set up a spec that can only have one vartype
        graph = nx.complete_graph(12)
        decision_variables = (0, 2, 5)
        feasible_configurations = {(1, 1, -1): 0.}

        spec = pm.Specification(graph, decision_variables, feasible_configurations, vartype=dimod.SPIN)
        self.assertIs(spec.vartype, dimod.SPIN)

        # the feasible_configurations are spin
        with self.assertRaises(ValueError):
            spec = pm.Specification(graph, decision_variables, feasible_configurations, vartype=dimod.BINARY)
Exemple #13
0
    def test_ranges_default(self):
        graph = nx.barbell_graph(4, 16)
        decision_variables = (0, 4, 3)
        feasible_configurations = {(0, 0, 0): 0.}

        spec = pm.Specification(graph, decision_variables, feasible_configurations, vartype=dimod.BINARY)

        for v in graph:
            self.assertEqual(spec.ising_linear_ranges[v], [-2, 2])

        for u, v in graph.edges:
            self.assertEqual(spec.ising_quadratic_ranges[u][v], [-1, 1])
            self.assertEqual(spec.ising_quadratic_ranges[v][u], [-1, 1])
Exemple #14
0
    def test_bad_relabel(self):
        graph = nx.path_graph(4)
        graph.add_edge(0, 2)
        decision_variables = (0, 2)
        feasible_configurations = {(-1, -1): 0., (+1, +1): 0.}
        spec = pm.Specification(graph, decision_variables, feasible_configurations, vartype=dimod.SPIN)

        mapping = {0: 2, 1: 1}

        with self.assertRaises(ValueError):
            spec.relabel_variables(mapping, inplace=False)

        with self.assertRaises(ValueError):
            spec.relabel_variables(mapping, inplace=True)
Exemple #15
0
    def test_bad_energy_range(self):
        graph = nx.path_graph(3)
        decision_variables = (0, 2)
        feasible_configurations = {(-1, -1): 0., (+1, +1): 0.}
        spec = pm.Specification(graph, decision_variables, feasible_configurations, vartype=dimod.SPIN)

        linear = {v: -3 for v in graph}
        quadratic = {edge: -1 for edge in graph.edges}
        model = dimod.BinaryQuadraticModel(linear, quadratic, 0.0, vartype=dimod.SPIN)
        with self.assertRaises(ValueError):
            widget = pm.PenaltyModel.from_specification(spec, model, 2., -2)

        linear = {v: 0 for v in graph}
        quadratic = {edge: 5 for edge in graph.edges}
        model = dimod.BinaryQuadraticModel(linear, quadratic, 0.0, vartype=dimod.SPIN)
        with self.assertRaises(ValueError):
            widget = pm.PenaltyModel.from_specification(spec, model, 2., -2)
Exemple #16
0
def gate_model(gate_type, fault=True):
    labels, configurations = GATES[gate_type]
    if fault:
        configurations = fault_gate(configurations, FAULT_GAP)
    num_variables = len(next(iter(configurations)))
    for size in range(num_variables, num_variables + 4):  # reasonable margin
        G = nx.complete_graph(size)
        nx.relabel_nodes(G, dict(enumerate(labels)), copy=False)
        spec = pm.Specification(G, labels, configurations, dimod.SPIN)
        try:
            pmodel = pm.get_penalty_model(spec)
            if pmodel is not None:
                return pmodel
        except pm.ImpossiblePenaltyModel:
            pass

    raise ValueError("unable to get the penalty model from factories")
Exemple #17
0
    def test_arbitrary_labels_on_k44(self):
        dbfile = self.database

        graph = nx.Graph()
        for i in range(3):
            for j in range(3, 6):
                graph.add_edge(i, j)

        decision_variables = (0, 5)
        feasible_configurations = ((0, 0), (1, 1))  # equality

        spec = pm.Specification(graph,
                                decision_variables,
                                feasible_configurations,
                                vartype=dimod.BINARY)

        linear = {v: 0 for v in graph}
        quadratic = {edge: 0 for edge in graph.edges}
        if decision_variables in quadratic:
            quadratic[decision_variables] = -1
        else:
            u, v = decision_variables
            assert (v, u) in quadratic
            quadratic[(v, u)] = -1
        model = dimod.BinaryQuadraticModel(linear,
                                           quadratic,
                                           0.0,
                                           vartype=dimod.SPIN)
        pmodel = pm.PenaltyModel.from_specification(spec, model, 2, -1)

        # now cache the pmodel to make sure there is something to find

        for thingy in itertools.permutations(range(6)):
            mapping = dict(enumerate(thingy))
            pmodel = pmodel.relabel_variables(mapping, inplace=False)
            pmc.cache_penalty_model(pmodel, database=dbfile)

        # now relabel some variables
        mapping = {1: '1', 2: '2', 3: '3', 4: '4'}

        new_spec = spec.relabel_variables(mapping, inplace=True)

        # retrieve from the new_spec
        # now try to retrieve it
        retreived_pmodel = pmc.get_penalty_model(new_spec, database=dbfile)
Exemple #18
0
    def test_quadratic_ranges_partially_specified(self):
        graph = nx.barbell_graph(4, 16)
        decision_variables = (0, 4, 3)
        feasible_configurations = {(0, 0, 1): 0.}

        spec = pm.Specification(graph, decision_variables, feasible_configurations,
                                ising_quadratic_ranges={0: {1: [0, 1], 2: [-1, 0]}, 2: {0: [-1, 0]}},
                                vartype=dimod.BINARY)

        ising_quadratic_ranges = spec.ising_quadratic_ranges
        for u in ising_quadratic_ranges:
            for v in ising_quadratic_ranges[u]:
                self.assertIs(ising_quadratic_ranges[u][v], ising_quadratic_ranges[v][u])
        for u, v in graph.edges:
            self.assertIn(v, ising_quadratic_ranges[u])
            self.assertIn(u, ising_quadratic_ranges[v])

        self.assertEqual(ising_quadratic_ranges[0][1], [0, 1])
Exemple #19
0
    def test_one_variable_insert_retrieve(self):
        """Test case when there is no quadratic contribution (i.e. cache will
        receive an empty value for the quadratic contribution)
        """
        dbfile = self.database

        # generate one variable model (i.e. no quadratic terms)
        spec = pm.Specification(graph=nx.complete_graph(1),
                                decision_variables=[0],
                                feasible_configurations=[(-1, )],
                                min_classical_gap=2,
                                vartype='SPIN')
        pmodel = pm.get_penalty_model(spec)

        # insert model into cache
        pmc.cache_penalty_model(pmodel, database=dbfile)

        # retrieve model back from cache
        retrieved_model = pmc.get_penalty_model(spec, database=dbfile)
        self.assertEqual(pmodel, retrieved_model)
    def test_retrieval(self):
        # put some stuff in the database

        spec = pm.Specification(nx.path_graph(2), (0, 1), {(-1, -1), (1, 1)},
                                vartype=pm.SPIN)
        model = dimod.BinaryQuadraticModel({
            0: 0,
            1: 0
        }, {(0, 1): -1},
                                           0.0,
                                           vartype=pm.SPIN)
        widget = pm.PenaltyModel.from_specification(spec, model, 2, -1)

        for cache in pm.iter_caches():
            cache(widget)

        # now try to get it back
        new_widget = pm.get_penalty_model(spec)

        self.assertEqual(widget, new_widget)
Exemple #21
0
    def test_binary_specification(self):
        dbfile = self.database

        # set up a specification and a corresponding penaltymodel
        graph = nx.Graph()
        for i in 'abcd':
            for j in 'efgh':
                graph.add_edge(i, j)

        decision_variables = ('a', 'e')
        feasible_configurations = ((0, 0), (1, 1))  # equality

        spec = pm.Specification(graph,
                                decision_variables,
                                feasible_configurations,
                                vartype=dimod.BINARY)

        linear = {v: 0 for v in graph}
        quadratic = {edge: 0 for edge in graph.edges}
        if decision_variables in quadratic:
            quadratic[decision_variables] = -1
        else:
            u, v = decision_variables
            assert (v, u) in quadratic
            quadratic[(v, u)] = -1
        model = dimod.BinaryQuadraticModel(linear,
                                           quadratic,
                                           0.0,
                                           vartype=dimod.SPIN)
        pmodel = pm.PenaltyModel.from_specification(spec, model, 2, -1)

        # now cache the pmodel to make sure there is something to find
        pmc.cache_penalty_model(pmodel, database=dbfile)

        # now try to retrieve it
        retreived_pmodel = pmc.get_penalty_model(spec, database=dbfile)

        self.assertIs(retreived_pmodel.model.vartype, dimod.BINARY)

        # check that the specification is equal to the retreived_pmodel
        self.assertTrue(spec.__eq__(retreived_pmodel))
Exemple #22
0
    def test_and_on_k44(self):
        graph = nx.Graph()
        for i in range(3):
            for j in range(3, 6):
                graph.add_edge(i, j)

        decision_variables = (0, 2, 3)
        feasible_configurations = AND(2)

        mapping = {0: '0', 1: '1', 2: '2', 3: '3'}
        graph = nx.relabel_nodes(graph, mapping)
        decision_variables = tuple(mapping[x] for x in decision_variables)

        spin_configurations = tuple([tuple([2 * i - 1 for i in b]) for b in feasible_configurations])
        spec = pm.Specification(graph, decision_variables, spin_configurations, vartype=dimod.SPIN)

        pm0 = mip.get_penalty_model(spec)

        self.check_generated_ising_model(pm0.feasible_configurations, pm0.decision_variables,
                                         pm0.model.linear, pm0.model.quadratic, pm0.ground_energy - pm0.model.offset,
                                         pm0.classical_gap)
def gate_model(gate_type, fault=True):
    labels, configurations = GATES[gate_type]
    if fault:
        configurations = fault_gate(configurations, FAULT_GAP)
    size = len(next(iter(configurations)))
    while True:
        G = nx.complete_graph(size)
        nx.relabel_nodes(G, dict(enumerate(labels)), copy=False)
        spec = pm.Specification(G, labels, configurations, dimod.SPIN)
        try:
            pmodel = pm.get_penalty_model(spec)
            if not pmodel:
                raise LookupError("failed to get penalty model from factory")
            # print("penalty model fits on K{}".format(size))
            break
        except pm.ImpossiblePenaltyModel:
            # print("penalty model does not fit on K{}".format(size))
            size += 1

    # print('h: {}'.format(pmodel.model.linear))
    # print('J: {}\n'.format(pmodel.model.quadratic))
    return pmodel
Exemple #24
0
    def test_construction(self):

        # build a specification
        graph = nx.complete_graph(10)
        decision_variables = (0, 4, 5)
        feasible_configurations = {(-1, -1, -1): 0.}
        spec = pm.Specification(graph, decision_variables, feasible_configurations, vartype=dimod.SPIN)

        # build a model
        model = dimod.BinaryQuadraticModel({v: 0 for v in graph},
                                           {edge: 0 for edge in graph.edges},
                                           0.0,
                                           vartype=dimod.SPIN)

        # build a PenaltyModel explicitly
        pm0 = pm.PenaltyModel(graph, decision_variables, feasible_configurations, dimod.SPIN, model, .1, 0)

        # build from spec
        pm1 = pm.PenaltyModel.from_specification(spec, model, .1, 0)

        # should result in equality
        self.assertEqual(pm0, pm1)
    def test_penalty_model_insert_retrieve(self):
        conn = self.clean_connection

        graph = nx.path_graph(3)
        decision_variables = (0, 2)
        feasible_configurations = {(-1, -1): 0., (+1, +1): 0.}
        spec = pm.Specification(graph, decision_variables, feasible_configurations, dimod.SPIN)

        linear = {v: 0 for v in graph}
        quadratic = {edge: -1 for edge in graph.edges}
        model = dimod.BinaryQuadraticModel(linear, quadratic, 0.0, vartype=dimod.SPIN)

        widget = pm.PenaltyModel.from_specification(spec, model, 2., -2)

        with conn as cur:
            pmc.insert_penalty_model(cur, widget)

        with conn as cur:
            pms = list(pmc.iter_penalty_model_from_specification(cur, spec))

            self.assertEqual(len(pms), 1)
            widget_, = pms
            self.assertEqual(widget_, widget)
Exemple #26
0
    def test_binary_specification(self):
        graph = nx.Graph()
        for i in range(4):
            for j in range(4, 8):
                graph.add_edge(i, j)

        decision_variables = (0, 1)
        feasible_configurations = ((0, 0), (1, 1))  # equality

        spec = pm.Specification(graph,
                                decision_variables,
                                feasible_configurations,
                                vartype=dimod.BINARY)
        widget = mip.get_penalty_model(spec)

        self.assertIs(widget.model.vartype, dimod.BINARY)

        # test the correctness of the widget
        energies = {}
        for decision_config in itertools.product((0, 1), repeat=2):
            energies[decision_config] = float('inf')

            for aux_config in itertools.product((0, 1), repeat=6):
                sample = dict(enumerate(decision_config + aux_config))
                energy = widget.model.energy(sample)

                energies[decision_config] = min(energies[decision_config],
                                                energy)

        for decision_config, energy in energies.items():
            if decision_config in feasible_configurations:
                self.assertAlmostEqual(energy, widget.ground_energy)
            else:
                self.assertGreaterEqual(
                    energy,
                    widget.ground_energy + widget.classical_gap - 10**-6)
Exemple #27
0
    def test_typical(self):
        dbfile = self.database

        # insert a penalty model
        graph = nx.path_graph(3)
        decision_variables = (0, 2)
        feasible_configurations = {(-1, -1): 0., (+1, +1): 0.}
        spec = pm.Specification(graph, decision_variables,
                                feasible_configurations, dimod.SPIN)
        linear = {v: 0 for v in graph}
        quadratic = {edge: -1 for edge in graph.edges}
        model = dimod.BinaryQuadraticModel(linear,
                                           quadratic,
                                           0.0,
                                           vartype=dimod.SPIN)
        widget = pm.PenaltyModel.from_specification(spec, model, 2., -2)

        # cache the penaltymodel
        pmc.cache_penalty_model(widget, database=dbfile)

        # retrieve it
        widget_ = pmc.get_penalty_model(spec, database=dbfile)

        self.assertEqual(widget_, widget)
Exemple #28
0
@author: ahaemm
'''

import penaltymodel.core as pm
import networkx as nx
import dimod
from penaltymodel.cache.interface import cache_penalty_model

### create penalty model for the [(1,0), (0,0), (0,1)] constraint between x_i_t, x_j_k;
variables = ['i_t', 'j_k']

feasible_configs = {(1, 0), (0, 0), (0, 1)}

graph = nx.Graph()
graph.add_edges_from([('i_t', 'j_k')])
spec = pm.Specification(graph, variables, feasible_configs, dimod.BINARY)
qubo = dimod.BinaryQuadraticModel({
    'i_t': 0.,
    'j_k': 0.
}, {('i_t', 'j_k'): 1.}, 0.0, dimod.BINARY)

ground_energy = qubo.energy({'i_t': 1., 'j_k': 0.})
print(ground_energy)

pModel = pm.PenaltyModel.from_specification(spec, qubo, 2, 0)
cache_penalty_model(
    pModel,
    'c:\\Users\\ahaemm\\workspace\\dwave\\env\\data\\dwave-penaltymodel-cache\\penaltymodel_cache_v0.4.0.db'
)

### t = 2, t' = 1,2,3
Exemple #29
0
def stitch(csp, min_classical_gap=2.0, max_graph_size=8):
    """Build a binary quadratic model with minimal energy levels at solutions to the specified constraint satisfaction
    problem.

    Args:
        csp (:obj:`.ConstraintSatisfactionProblem`):
            Constraint satisfaction problem.

        min_classical_gap (float, optional, default=2.0):
            Minimum energy gap from ground. Each constraint violated by the solution increases
            the energy level of the binary quadratic model by at least this much relative
            to ground energy.

        max_graph_size (int, optional, default=8):
            Maximum number of variables in the binary quadratic model that can be used to
            represent a single constraint.

    Returns:
        :class:`~dimod.BinaryQuadraticModel`

    Notes:
        For a `min_classical_gap` > 2 or constraints with more than two variables, requires
        access to factories from the penaltymodel_ ecosystem to construct the binary quadratic
        model.

    .. _penaltymodel: https://github.com/dwavesystems/penaltymodel

    Examples:
        This example creates a binary-valued constraint satisfaction problem
        with two constraints, :math:`a = b` and :math:`b \\ne c`, and builds
        a binary quadratic model such that
        each constraint violation by a solution adds the default minimum energy gap.

        >>> import operator
        >>> csp = dwavebinarycsp.ConstraintSatisfactionProblem(dwavebinarycsp.BINARY)
        >>> csp.add_constraint(operator.eq, ['a', 'b'])  # a == b
        >>> csp.add_constraint(operator.ne, ['b', 'c'])  # b != c
        >>> bqm = dwavebinarycsp.stitch(csp)

        Variable assignments that satisfy the CSP above, violate one, then two constraints,
        produce energy increases of the default minimum classical gap:

        >>> bqm.energy({'a': 0, 'b': 0, 'c': 1})  # doctest: +SKIP
        -2.0
        >>> bqm.energy({'a': 0, 'b': 0, 'c': 0})  # doctest: +SKIP
        0.0
        >>> bqm.energy({'a': 1, 'b': 0, 'c': 0}) #  doctest: +SKIP
        2.0

        This example creates a binary-valued constraint satisfaction problem
        with two constraints, :math:`a = b` and :math:`b \\ne c`, and builds
        a binary quadratic model with a minimum energy gap of 4.
        Note that in this case the conversion to binary quadratic model adds two
        ancillary variables that must be minimized over when solving.

        >>> import operator
        >>> import itertools
        >>> csp = dwavebinarycsp.ConstraintSatisfactionProblem(dwavebinarycsp.BINARY)
        >>> csp.add_constraint(operator.eq, ['a', 'b'])  # a == b
        >>> csp.add_constraint(operator.ne, ['b', 'c'])  # b != c
        >>> bqm = dwavebinarycsp.stitch(csp, min_classical_gap=4.0)
        >>> list(bqm)   # doctest: +SKIP
        ['a', 'aux1', 'aux0', 'b', 'c']

        Variable assignments that satisfy the CSP above, violate one, then two constraints,
        produce energy increases of the specified minimum classical gap:

        >>> min([bqm.energy({'a': 0, 'b': 0, 'c': 1, 'aux0': aux0, 'aux1': aux1}) for
        ... aux0, aux1 in list(itertools.product([0, 1], repeat=2))])  # doctest: +SKIP
        -6.0
        >>> min([bqm.energy({'a': 0, 'b': 0, 'c': 0, 'aux0': aux0, 'aux1': aux1}) for
        ... aux0, aux1 in list(itertools.product([0, 1], repeat=2))])  # doctest: +SKIP
        -2.0
        >>> min([bqm.energy({'a': 1, 'b': 0, 'c': 0, 'aux0': aux0, 'aux1': aux1}) for
        ... aux0, aux1 in list(itertools.product([0, 1], repeat=2))])  # doctest: +SKIP
        2.0

        This example finds for the previous example the minimum graph size.

        >>> import operator
        >>> csp = dwavebinarycsp.ConstraintSatisfactionProblem(dwavebinarycsp.BINARY)
        >>> csp.add_constraint(operator.eq, ['a', 'b'])  # a == b
        >>> csp.add_constraint(operator.ne, ['b', 'c'])  # b != c
        >>> for n in range(8, 1, -1):
        ...     try:
        ...         bqm = dwavebinarycsp.stitch(csp, min_classical_gap=4.0, max_graph_size=n)
        ...     except dwavebinarycsp.exceptions.ImpossibleBQM:
        ...         print(n+1)
        ...
        3

    """

    # ensure we have penaltymodel factory available
    try:
        dwavebinarycsp.assert_penaltymodel_factory_available()
    except AssertionError as e:
        raise RuntimeError(e)

    def aux_factory():
        for i in count():
            yield 'aux{}'.format(i)

    aux = aux_factory()

    bqm = dimod.BinaryQuadraticModel.empty(csp.vartype)

    # developer note: we could cache them and relabel, for now though let's do the simple thing
    # penalty_models = {}
    for const in csp.constraints:
        configurations = const.configurations

        if len(const.variables) > max_graph_size:
            msg = (
                "The given csp contains a constraint {const} with {num_var} variables. "
                "This cannot be mapped to a graph with {max_graph_size} nodes. "
                "Consider checking whether your constraint is irreducible."
                "").format(const=const,
                           num_var=len(const.variables),
                           max_graph_size=max_graph_size)
            raise ImpossibleBQM(msg)

        pmodel = None

        if len(const) == 0:
            # empty constraint
            continue

        # at the moment, penaltymodel-cache cannot handle 1-variable PMs, so
        # we handle that case here
        if min_classical_gap <= 2.0 and len(
                const) == 1 and max_graph_size >= 1:
            bqm.update(_bqm_from_1sat(const))
            continue

        # developer note: we could cache them and relabel, for now though let's do the simple thing
        # if configurations in penalty_models:
        #     raise NotImplementedError

        for G in iter_complete_graphs(const.variables, max_graph_size + 1,
                                      aux):

            # construct a specification
            spec = pm.Specification(graph=G,
                                    decision_variables=const.variables,
                                    feasible_configurations=configurations,
                                    min_classical_gap=min_classical_gap,
                                    vartype=csp.vartype)

            # try to use the penaltymodel ecosystem
            try:
                pmodel = pm.get_penalty_model(spec)
            except pm.ImpossiblePenaltyModel:
                # hopefully adding more variables will make it possible
                continue

            if pmodel.classical_gap >= min_classical_gap:
                break

        # developer note: we could cache them and relabel, for now though let's do the simple thing
        # penalty_models[configurations] = pmodel

        else:
            msg = ("No penalty model can be built for constraint {}".format(
                const))
            raise ImpossibleBQM(msg)

        bqm.update(pmodel.model)

    return bqm
Exemple #30
0
 def test_construction_empty(self):
     spec = pm.Specification(nx.Graph(), [], {}, dimod.SPIN)
     self.assertEqual(len(spec), 0)