Esempio n. 1
0
 def test_default_fold(self):
     bqm = dimod.BinaryQuadraticModel({'a': 1}, {}, 0, dimod.SPIN)
     states = States(
         State.from_sample(min_sample(bqm), bqm),  # energy: -1
         State.from_sample(max_sample(bqm), bqm),  # energy: +1
     )
     best = ArgMin().run(states).result()
     self.assertEqual(best.samples.first.energy, -1)
Esempio n. 2
0
    def test_basic(self):
        bqm = dimod.BinaryQuadraticModel({}, {'ab': 1, 'bc': -1, 'ca': 1}, 0, dimod.SPIN)
        state = State.from_sample(min_sample(bqm), bqm)
        antistate = State.from_sample(max_sample(bqm), bqm)

        result = GreedyPathMerge().run(States(state, antistate)).result()

        self.assertEqual(result.samples.first.energy, -3.0)
 def test_from_samples(self):
     s1 = [0, 1]
     s2 = {0: 1, 1: 0}
     bqm = dimod.BinaryQuadraticModel({0: 1, 1: 2}, {}, 0.0, 'BINARY')
     self.assertEqual(State.from_sample(s1, bqm).samples.first.energy, 2.0)
     self.assertEqual(State.from_sample(s2, bqm).samples.first.energy, 1.0)
     self.assertEqual(State.from_samples([s1, s1], bqm).samples.first.energy, 2.0)
     self.assertEqual(State.from_samples([s2, s2], bqm).samples.first.energy, 1.0)
     self.assertEqual(State.from_samples([sample_as_dict(s1), s2], bqm).samples.first.energy, 1.0)
Esempio n. 4
0
 def test_custom_fold(self):
     bqm = dimod.BinaryQuadraticModel({'a': 1}, {}, 0, dimod.SPIN)
     states = States(
         State.from_sample(min_sample(bqm), bqm),  # energy: -1
         State.from_sample(max_sample(bqm), bqm),  # energy: +1
     )
     fold = ArgMin(key=lambda s: -s.samples.first.energy)
     best = fold.run(states).result()
     self.assertEqual(best.samples.first.energy, 1)
Esempio n. 5
0
    def test_multiple(self):
        bqm = dimod.BinaryQuadraticModel({}, {'ab': 1}, 0, dimod.SPIN)

        states = States(State.from_sample({'a': 1, 'b': -1}, bqm),
                        State.from_sample({'a': -1, 'b': 1}, bqm))

        expected = State.from_samples([{'a': 1, 'b': -1}, {'a': -1, 'b': 1}], bqm)

        state = MergeSamples().run(states).result()

        self.assertEqual(state, expected)
Esempio n. 6
0
    def test_custom_key(self):
        """Custom key function works, here best state has the highest energy."""

        bqm = dimod.BinaryQuadraticModel({'a': 1}, {}, 0, dimod.SPIN)
        states = States(
            State.from_sample(min_sample(bqm), bqm),  # energy: -1
            State.from_sample(max_sample(bqm), bqm),  # energy: +1
        )

        tracker = TrackMin(key=lambda s: -s.samples.first.energy)
        for state in states:
            tracker.run(state).result()
        self.assertEqual(tracker.best.samples.first.energy, +1)
Esempio n. 7
0
    def test_default_tracking(self):
        """Best seen state is kept (default: state with sampleset with the lowest energy)"""

        bqm = dimod.BinaryQuadraticModel({'a': 1}, {}, 0, dimod.SPIN)
        min_state = State.from_sample(min_sample(bqm), bqm)  # energy: -1
        max_state = State.from_sample(max_sample(bqm), bqm)  # energy: +1

        tracker = TrackMin()
        _ = tracker.run(max_state).result()
        self.assertEqual(tracker.best.samples.first.energy, +1)
        _ = tracker.run(min_state).result()
        self.assertEqual(tracker.best.samples.first.energy, -1)
        _ = tracker.run(max_state).result()
        self.assertEqual(tracker.best.samples.first.energy, -1)
Esempio n. 8
0
    def test_aggregation(self):
        bqm = dimod.BinaryQuadraticModel({}, {'ab': 1}, 0, dimod.SPIN)

        states = States(State.from_sample({'a': 1, 'b': -1}, bqm),
                        State.from_sample({'a': 1, 'b': -1}, bqm))

        expected = State(
            problem=bqm,
            samples=dimod.SampleSet.from_samples_bqm(
                {'a': 1, 'b': -1}, bqm, num_occurrences=[2]))

        state = MergeSamples(aggregate=True).run(states).result()

        self.assertEqual(state, expected)
Esempio n. 9
0
    def test_validation(self):
        bqm1 = dimod.BinaryQuadraticModel({'a': 1}, {}, 0, dimod.SPIN)
        bqm2 = dimod.BinaryQuadraticModel({'b': 1}, {}, 0, dimod.SPIN)
        s1 = State.from_sample({'a': +1}, bqm1)
        s2 = State.from_sample({'b': -1}, bqm2)

        # two input states required
        with self.assertRaises(ValueError):
            inp = States(s1, s1, s1)
            IsoenergeticClusterMove().run(inp).result()

        # variables must match
        with self.assertRaises(ValueError):
            inp = States(s1, s2)
            IsoenergeticClusterMove().run(inp).result()
Esempio n. 10
0
    def test_rolling_subproblem_larger_than_rolling_history(self):
        """In case rolling history too small, just one problem is unrolled."""

        # 10 variables, 0 to 9 when ordered by energy increase on flip
        bqm = dimod.BinaryQuadraticModel({i: i for i in range(10)}, {}, 0.0, 'SPIN')
        sample = {i: 1 for i in range(10)}

        # exactly 1 five-variable problems should be produced
        state = State.from_sample(sample, bqm)
        eid = EnergyImpactDecomposer(size=5, rolling=True, rolling_history=0.3, silent_rewind=False)
        states = list(iter(partial(eid.next, state=state), None))

        self.assertEqual(len(states), 1)
        self.assertEqual(len(states[0].subproblem), 5)
        self.assertEqual(list(dict(states[0].subproblem.linear).values()), list(range(0,5)))

        # works even for subproblems as large as the input problem
        eid = EnergyImpactDecomposer(size=len(bqm), rolling=True, rolling_history=0.3, silent_rewind=False)
        states = list(iter(partial(eid.next, state=state), None))

        self.assertEqual(len(states), 1)
        self.assertEqual(len(states[0].subproblem), 10)
        self.assertEqual(list(dict(states[0].subproblem.linear).values()), list(range(0,10)))

        # but adapt to problem size if subproblem larger than problem
        eid = EnergyImpactDecomposer(size=11, rolling=True, rolling_history=0.3, silent_rewind=False)
        states = list(iter(partial(eid.next, state=state), None))

        self.assertEqual(len(states), 1)
        self.assertEqual(len(states[0].subproblem), 10)
        self.assertEqual(list(dict(states[0].subproblem.linear).values()), list(range(0,10)))
Esempio n. 11
0
    def test_multi_vars(self):
        """Multiple variables subproblem selection works, without gain limit."""

        state = State.from_sample({'a': 1, 'b': 1, 'c': -1}, self.notall)
        eid = EnergyImpactDecomposer(size=3, min_gain=None)
        nextstate = eid.next(state)
        self.assertDictEqual(dict(nextstate.subproblem.adj), dict(self.notall.adj))
Esempio n. 12
0
    def test_nontrivial_subproblem(self):
        """Check multi-variable multi-coupler subproblem creation.

        A 3by3 square lattice, with a 2x2 lattice subsolver, is the simplest 
        non-trivial test with edges in the decomposed problem.
        """
        problem_dims = (3, 3)
        #Vertical edges
        edgelist = [((i, j), (i + 1, j)) for i in range(problem_dims[0] - 1)
                    for j in range(problem_dims[1])]
        #Horizontal edges
        edgelist += [((i, j), (i, j + 1)) for i in range(problem_dims[0])
                     for j in range(problem_dims[1] - 1)]
        bqm = dimod.BinaryQuadraticModel.from_ising(
            {}, {edge: 1
                 for edge in edgelist})
        origin_embeddings = [{(i, j): None
                              for i in range(2) for j in range(2)}]
        state = State.from_sample(min_sample(bqm),
                                  bqm,
                                  origin_embeddings=origin_embeddings,
                                  problem_dims=problem_dims)

        # Creates one of 3x3 different subsubproblems, some of which are
        # disconnected, and some connected
        # Run multiple times to prevent coincidental agreement
        runnable = SublatticeDecomposer()
        for _ in range(10):
            state = runnable.next(state)
            self.assertEqual(len(state.subproblem.variables), 4)
            self.assertIn(next(iter(state.subproblem.variables)),
                          bqm.variables)
            self.assertEqual(len(state.embedding), 4)
            self.assertIn(next(iter(state.embedding.keys())), bqm.variables)
Esempio n. 13
0
    def test_trivial_subproblem(self):
        """Check single-variable no-coupler subproblem creation.

        A 2by2 square lattice (a square), with a single variable subsolver,
        is the simplest non-trivial test.
        """

        problem_dims = (2, 2)
        # Vertical edges
        edgelist = [((i, j), (i + 1, j)) for i in range(problem_dims[0] - 1)
                    for j in range(problem_dims[1])]
        # Horizontal edges
        edgelist += [((i, j), (i, j + 1)) for i in range(problem_dims[0])
                     for j in range(problem_dims[1] - 1)]
        bqm = dimod.BinaryQuadraticModel.from_ising(
            {}, {edge: 1
                 for edge in edgelist})
        origin_embeddings = [{(0, 0): [0]}]
        state = State.from_sample(min_sample(bqm),
                                  bqm,
                                  origin_embeddings=origin_embeddings,
                                  problem_dims=problem_dims)

        # Creates subproblems located randomly at (0, 0), (0, 1), (1, 0) and
        # (1, 1).
        runnable = SublatticeDecomposer()
        for _ in range(10):
            state = runnable.next(state)
            self.assertEqual(len(state.subproblem.variables), 1)
            self.assertIn(next(iter(state.subproblem.variables)),
                          bqm.variables)
            self.assertEqual(len(state.embedding), 1)
            self.assertIn(next(iter(state.embedding.keys())), bqm.variables)
Esempio n. 14
0
    def test_pfs_on_sequential_eid_calls_over_disconnected_problem_graph(self):
        # problem graph has two components, each one is 4-node cycle graph
        edges = {'ab': 1, 'bc': 1, 'cd': 1, 'da': 1,
                 'ef': 1, 'fg': 1, 'gh': 1, 'he': 1}
        biases = dict(zip(string.ascii_letters, range(8, 0, -1)))
        bqm = dimod.BinaryQuadraticModel(biases, edges, 0.0, 'SPIN')
        sample = {i: -1 for i in bqm.variables}

        state = State.from_sample(sample, bqm)
        eid = EnergyImpactDecomposer(size=3, traversal='pfs', rolling=True,
                                     rolling_history=1.0, silent_rewind=False)
        states = list(iter(partial(eid.next, state=state), None))

        # energy impact list is: [a..h], so of the 3 subproblems generated,
        # the middle one is disconnected with one var from first group and two
        # variables from the second

        # pfs is seeded with `a` and connected nodes in order of energy are picked
        self.assertEqual(set(states[0].subproblem.variables), set('abc'))

        # `d` left from the first component, and the seed for the next
        # subproblem is the next highest in energy `e`.
        # unlike in bfs, the order of `e`'s neighbors is well defined
        self.assertEqual(set(states[1].subproblem.variables), set('def'))

        # the second component is exhausted in search for 3 variable subproblem
        self.assertEqual(set(states[2].subproblem.variables), set('gh'))
Esempio n. 15
0
    def test_bfs_on_sequential_eid_calls_over_disconnected_problem_graph(self):
        # problem graph has two components, each one is 4-node cycle graph
        edges = {'ab': 1, 'bc': 1, 'cd': 1, 'da': 1,
                 'ef': 1, 'fg': 1, 'gh': 1, 'he': 1}
        biases = dict(zip(string.ascii_letters, range(8, 0, -1)))
        bqm = dimod.BinaryQuadraticModel(biases, edges, 0.0, 'SPIN')
        sample = {i: -1 for i in bqm.variables}

        state = State.from_sample(sample, bqm)
        eid = EnergyImpactDecomposer(size=3, traversal='bfs', rolling=True,
                                     rolling_history=1.0, silent_rewind=False)
        states = list(iter(partial(eid.next, state=state), None))

        # energy impact list is: [a..h], so of the 3 subproblems generated,
        # the middle one is disconnected with one var from first group and two
        # variables from the second

        # `c` has higher energy, but it's not connected to `a`, so `d` is picked
        self.assertEqual(set(states[0].subproblem.variables), set('abd'))

        # `c` is picked from the first component, and the seed for the next
        # subproblem is `e`. however, the order of `e`'s neighbors is not defined,
        # so if we need to pick just one, it could be `f` or `h`
        # (note: PFS has a defined order of neighbors)
        self.assertTrue(set('cefh').difference(states[1].subproblem.variables).issubset('fh'))
        self.assertEqual(len(states[1].subproblem.variables), 3)

        # the second component is exhausted in search for 3 variable subproblem
        third = set(states[2].subproblem.variables)
        self.assertTrue(third == set('gh') or third == set('gf'))
Esempio n. 16
0
def run(problems, solver_factories):
    results = OrderedDict()

    # reuse the cloud client
    qpu = EmbeddingComposite(DWaveSampler())

    for problem in problems:
        results[problem] = OrderedDict()

        with open(problem) as fp:
            bqm = dimod.BinaryQuadraticModel.from_coo(fp)

        for name, factory in solver_factories:
            case = '{!r} with {!r}'.format(problem, name)

            try:
                solver = factory(qpu=qpu)
                init_state = State.from_sample(min_sample(bqm), bqm)

                with tictoc(case) as timer:
                    solution = solver.run(init_state).result()

            except Exception as exc:
                print("FAILED {case}: {exc!r}".format(**locals()))
                results[problem][name] = repr(exc)

            else:
                print("case={case!r}"
                      " energy={solution.samples.first.energy!r},"
                      " wallclock={timer.dt!r}".format(**locals()))
                results[problem][name] = dict(
                    energy=solution.samples.first.energy, wallclock=timer.dt)
    def test_no_vars(self):
        """Failure due to no sub vars available."""

        state = State.from_sample({'a': 1, 'b': 1, 'c': -1}, self.notall)
        eid = EnergyImpactDecomposer(max_size=3, min_gain=5.0)
        with self.assertRaises(ValueError):
            nextstate = eid.next(state)
Esempio n. 18
0
    def test_pfs_on_impactful_far_subproblem(self):
        # problem graph has two components, each one is 4-node cycle graph
        # variable flip energy gains order variables: a, h..b
        edges = {
            'ab': 1,
            'bc': 1,
            'cd': 1,
            'da': 1,
            'ef': 1,
            'fg': 1,
            'gh': 1,
            'he': 1,
            'de': 0
        }
        biases = dict(zip(string.ascii_letters, range(8)))
        biases['a'] += 10
        bqm = dimod.BinaryQuadraticModel(biases, edges, 0.0, 'SPIN')
        sample = {i: -1 for i in bqm.variables}

        state = State.from_sample(sample, bqm)
        eid = EnergyImpactDecomposer(size=5, traversal='pfs')
        result = eid.run(state).result()

        # move towards second cluster and pick the highest energy variables from there
        self.assertEqual(set(result.subproblem.variables), set('adehg'))
Esempio n. 19
0
    def test_next_on_different_sized_constraints(self):
        bqm = dimod.BinaryQuadraticModel.empty(dimod.SPIN)

        variables = list('abcdefg')
        fixed_variables = list('abc')
        size = 3
        constraints = []

        # Set BQM and constraints of varying lengths
        for triplet in itertools.combinations(variables, size):
            for u, v in itertools.combinations(triplet, 2):
                bqm.add_interaction(u, v, -1)
            non_fixed_variables = set(triplet) - set(fixed_variables)
            constraints.append(non_fixed_variables)

        for fixed_variable in fixed_variables:
            bqm.fix_variable(fixed_variable, 1)

        # Get new state
        rcd = RandomConstraintDecomposer(size, constraints)
        state = State.from_sample(min_sample(bqm), bqm)
        newstate = rcd.run(state).result()

        self.assertIn('subproblem', newstate)
        self.assertTrue(len(newstate.subproblem) <= size)  # correct size
Esempio n. 20
0
    def test_energy_threshold_termination(self):
        class ExactSolver(Runnable):
            def next(self, state):
                return state.updated(
                    samples=dimod.ExactSolver().sample(state.problem))

        bqm = dimod.BinaryQuadraticModel({'a': 1}, {}, 0, dimod.SPIN)
        state = State.from_sample({'a': 1}, bqm)

        w = LoopUntilNoImprovement(
            ExactSolver(),
            key=operator.attrgetter('samples.first.energy'),
            terminate=partial(operator.ge, -1))
        s = w.run(state).result()
        self.assertEqual(s.samples.first.energy, -1)

        w = LoopUntilNoImprovement(ExactSolver(),
                                   key='samples.first.energy',
                                   terminate=partial(operator.ge, -1))
        s = w.run(state).result()
        self.assertEqual(s.samples.first.energy, -1)

        w = LoopUntilNoImprovement(ExactSolver(),
                                   terminate=partial(operator.ge, -1))
        s = w.run(state).result()
        self.assertEqual(s.samples.first.energy, -1)
Esempio n. 21
0
    def test_no_vars(self):
        """Failure due to no sub vars available."""

        state = State.from_sample({'a': 1, 'b': 1, 'c': -1}, self.notall)
        eid = EnergyImpactDecomposer(size=3, min_gain=5.0)
        nextstate = eid.next(state)
        self.assertEqual(len(nextstate.subproblem), 0)
Esempio n. 22
0
    def test_adaptive_vars(self):
        """Multiple variables subproblem selection works, with gain limit."""

        state = State.from_sample({'a': 1, 'b': 1, 'c': -1}, self.notall)
        eid = EnergyImpactDecomposer(size=3, min_gain=2.0)
        nextstate = eid.next(state)
        self.assertDictEqual(dict(nextstate.subproblem.linear), {'c': 2})
        self.assertDictEqual(dict(nextstate.subproblem.quadratic), {})
Esempio n. 23
0
    def test_one_var(self):
        """First-variable selection works."""

        state = State.from_sample({'a': 1, 'b': 1, 'c': -1}, self.notall)
        eid = EnergyImpactDecomposer(size=1, min_gain=0)
        nextstate = eid.next(state)
        self.assertDictEqual(dict(nextstate.subproblem.linear), {'c': 2})
        self.assertDictEqual(dict(nextstate.subproblem.quadratic), {})
Esempio n. 24
0
    def test_empty(self):
        bqm = dimod.BinaryQuadraticModel(dimod.SPIN)
        state = State.from_sample(random_sample(bqm), bqm)

        decomposer = ComponentDecomposer()
        state1 = decomposer.next(state)

        self.assertEqual(bqm, state1.subproblem)
Esempio n. 25
0
    def test_single(self):
        bqm = dimod.BinaryQuadraticModel({}, {'ab': 1}, 0, dimod.SPIN)

        states = States(State.from_sample({'a': 1, 'b': -1}, bqm))

        state = MergeSamples().run(states).result()

        self.assertEqual(state, states[0])
Esempio n. 26
0
    def test_energy_correctness(self):
        bqm = dimod.BinaryQuadraticModel.from_ising({'a': -1}, {})

        init = State.from_sample({'a': -1}, bqm)  # should be flipped
        new = RoofDualityDecomposer().run(init).result()

        self.assertEqual(
            new.samples.record.energy,
            bqm.energies((new.samples.record.sample, new.samples.variables)))
Esempio n. 27
0
    def test_simple(self):
        "Two output states created for two input samples, in correct order."

        bqm = dimod.BQM.from_ising({}, {'ab': 1})

        inp = State.from_samples([{'a': 1, 'b': 1}, {'a': -1, 'b': 1}], bqm)

        exp = States(State.from_sample({
            'a': 1,
            'b': 1
        }, bqm), State.from_sample({
            'a': -1,
            'b': 1
        }, bqm))

        out = ExplodeSamples().run(inp).result()

        self.assertEqual(out, exp)
Esempio n. 28
0
    def test_allfixed(self):
        bqm = dimod.BinaryQuadraticModel.from_ising({'a': -1}, {})

        init = State.from_sample({'a': -1}, bqm)  # should be flipped
        new = RoofDualityDecomposer().run(init).result()

        self.assertEqual(new.problem, bqm)
        self.assertEqual(new.subproblem,
                         dimod.BinaryQuadraticModel.from_ising({}, {}, -1))
        self.assertEqual(new.samples.record.sample, [1])
Esempio n. 29
0
    def test_greedy_problem_sampler_interface(self):
        bqm = dimod.BinaryQuadraticModel({'a': 1}, {}, 0, 'SPIN')

        workflow = GreedyProblemSampler(num_reads=10)

        init = State.from_sample({'a': 1}, bqm)
        result = workflow.run(init).result()

        self.assertEqual(result.samples.first.energy, -1)
        self.assertEqual(len(result.samples), 10)
Esempio n. 30
0
    def test_one_component(self):
        bqm = dimod.BinaryQuadraticModel({
            'a': 1,
            'b': -1
        }, {'ab': 1}, 0, dimod.SPIN)
        state = State.from_sample(random_sample(bqm), bqm)

        decomposer = ComponentDecomposer()
        state1 = decomposer.next(state)

        self.assertEqual(bqm, state1.subproblem)