예제 #1
0
    def test_localsearch_friends(self):
        """When var flip decreases energy."""

        allvar = select_localsearch_adversaries(self.notb, {
            'a': 1,
            'b': 1,
            'c': 1
        },
                                                min_gain=None)
        self.assertEqual(allvar, ['c', 'a', 'b'])

        neutral = select_localsearch_adversaries(self.notb, {
            'a': 1,
            'b': 1,
            'c': 1
        },
                                                 min_gain=0.0)
        self.assertEqual(neutral, ['c', 'a'])

        nonevar = select_localsearch_adversaries(self.notb, {
            'a': 1,
            'b': 1,
            'c': 1
        },
                                                 min_gain=1.0)
        self.assertEqual(nonevar, [])

        friends = select_localsearch_adversaries(self.notb, {
            'a': 1,
            'b': 1,
            'c': 1
        },
                                                 min_gain=-10)
        self.assertEqual(friends, ['c', 'a', 'b'])
예제 #2
0
    def next(self, state):
        bqm = state.problem

        if self.max_size > len(bqm):
            raise ValueError(
                "subproblem size cannot be greater than the problem size")

        # select a new subset of `max_size` variables, making sure they differ
        # from previous iteration by at least `min_diff` variables
        sample = state.samples.change_vartype(bqm.vartype).first.sample
        variables = select_localsearch_adversaries(bqm,
                                                   sample,
                                                   min_gain=self.min_gain)

        # TODO: soft fail strategy? skip one iteration or relax vars selection?
        if len(variables) < self.min_diff:
            raise ValueError("less than min_diff variables identified as"
                             " contributors to min_gain energy increase")

        offset = 0
        next_vars = set(variables[offset:offset + self.max_size])
        while len(next_vars ^ self._prev_vars) < self.min_diff:
            offset += self.stride
            next_vars = set(variables[offset:offset + self.max_size])

        logger.debug("Select variables: %r (diff from prev = %r)", next_vars,
                     next_vars ^ self._prev_vars)
        self._prev_vars = next_vars

        # induce sub-bqm based on selected variables and global sample
        subbqm = bqm_induced_by(bqm, next_vars, sample)
        return state.updated(subproblem=subbqm)
    def test_localsearch_adversaries(self):
        """When var flip increases energy."""

        defvar = select_localsearch_adversaries(self.notall, {'a': 1, 'b': 1, 'c': -1})
        self.assertEqual(defvar, ['c', 'b', 'a'])

        allvar = select_localsearch_adversaries(self.notall, {'a': 1, 'b': 1, 'c': -1}, max_n=3, min_gain=-1)
        self.assertEqual(allvar, ['c', 'b', 'a'])

        subvar = select_localsearch_adversaries(self.notall, {'a': 1, 'b': 1, 'c': -1}, max_n=2, min_gain=-1)
        self.assertEqual(subvar, ['c', 'b'])

        subvar = select_localsearch_adversaries(self.notall, {'a': 1, 'b': 1, 'c': -1}, min_gain=1)
        self.assertEqual(subvar, ['c'])

        nonevar = select_localsearch_adversaries(self.notall, {'a': 1, 'b': 1, 'c': -1}, min_gain=10)
        self.assertEqual(nonevar, [])
예제 #4
0
    def next(self, state):
        bqm = state.problem
        sample = state.samples.change_vartype(bqm.vartype).first.sample

        size = self.size
        if self.size > len(bqm):
            logger.debug(
                "subproblem size greater than the problem size, adapting to problem size"
            )
            size = len(bqm)

        bqm_changed = bqm != self._rolling_bqm
        sample_changed = sample != self._prev_sample

        if bqm_changed:
            self._rewind_rolling(state)

        if sample_changed:
            self._prev_sample = sample

        if bqm_changed or sample_changed or not self._variables:
            self._variables = select_localsearch_adversaries(
                bqm, sample, min_gain=self.min_gain)

        if self.rolling:
            if len(self._unrolled_vars) >= self.rolling_history * len(bqm):
                logger.debug("Rolling reset at unrolled history size = %d",
                             len(self._unrolled_vars))
                self._rewind_rolling(state)
                # reset before exception, to be ready on a subsequent call
                if not self.silent_rewind:
                    raise EndOfStream

        novel_vars = [
            v for v in self._variables if v not in self._unrolled_vars
        ]
        next_vars = novel_vars[:size]

        logger.debug("Selected %d subproblem variables: %r", len(next_vars),
                     next_vars)

        if self.rolling:
            self._unrolled_vars.update(next_vars)

        # induce sub-bqm based on selected variables and global sample
        subbqm = bqm_induced_by(bqm, next_vars, sample)
        return state.updated(subproblem=subbqm)
예제 #5
0
    def next(self, state):
        bqm = state.problem

        if bqm != self._rolling_bqm:
            self._reset_rolling(state)

        if self.max_size > len(bqm):
            raise ValueError(
                "subproblem size cannot be greater than the problem size")

        sample = state.samples.change_vartype(bqm.vartype).first.sample
        variables = select_localsearch_adversaries(bqm,
                                                   sample,
                                                   min_gain=self.min_gain)

        if self.rolling and len(
                self._unrolled_vars
        ) + self.max_size > self.rolling_history * len(bqm):
            logger.debug("rolling reset at unrolled history size = %d",
                         len(self._unrolled_vars))
            # reset before exception, to be ready on a subsequent call
            self._reset_rolling(state)
            if not self.silent_reset:
                raise EndOfStream

        novel_vars = [v for v in variables if v not in self._unrolled_vars]
        next_vars = novel_vars[:self.max_size]

        logger.debug("Selected %d subproblem variables: %r", len(next_vars),
                     next_vars)

        if self.rolling:
            self._unrolled_vars.update(next_vars)

        # induce sub-bqm based on selected variables and global sample
        subbqm = bqm_induced_by(bqm, next_vars, sample)
        return state.updated(subproblem=subbqm)