예제 #1
0
 def __init__(self, *args, **kwargs):
     super(SimulatedAnnealer, self).__init__(*args, **kwargs)
     self._current = self.model.random_model_io()
     self._best = self._current  # assumes current is immutable
     self._lives = 4
     self._best_era = None
     self._current_era_energies = NumberLog(max_size=None)
예제 #2
0
    def __init__(self, *args, **kwargs):
        super(ParticleSwarmOptimizer, self).__init__(*args, **kwargs)

        self._flock = tuple(self._new_particle()
                            for _ in range(self.spec.population_size))
        self._evals = len(self._flock)
        self._current_flock_energies = NumberLog(p.energy for p in self._flock)
        self._best = min(self._flock, key=lambda x: x.energy)
        self._lives = 4
예제 #3
0
    def run(self, text_report=True):
        init_xs = tuple(self.model.random_input_vector()
                        for _ in xrange(self.spec.population_size))
        get_energy = lambda x: x.energy
        best_era = None

        report = base.StringBuilder() if text_report else base.NullObject()

        self._population = tuple(self.model.compute_model_io(xs)
                                 for xs in init_xs)

        best = min(self._population, key=get_energy)

        self._evals, lives = 0, 4

        for gen in xrange(self.spec.iterations):
            if self._evals > self.spec.iterations or lives <= 0:
                break

            prev_best_energy = best.energy

            self._population = self._breed_next_generation()

            best_in_generation = min(self._population, key=get_energy)
            best = min(best, best_in_generation, key=get_energy)

            report += str(best.energy)
            report += ('+' if x.energy < prev_best_energy else '.'
                       for x in self._population)
            report += '\n'

            energies = NumberLog(inits=(c.energy for c in self._population))
            try:
                improved = energies.better(prev_energies)
            except NameError:
                improved = False
            prev_energies = energies  # noqa: flake8 doesn't catch use above

            if improved:
                best_era = energies
            else:
                lives -= 1

        if best_era is None:
            best_era = energies

        return SearchReport(best=best.energy,
                            best_era=best_era,
                            evaluations=self._evals,
                            searcher=self.__class__,
                            spec=self.spec,
                            report=None)
예제 #4
0
    def run(self, text_report=False):
        for i in range(self.spec.generations):
            self._update()
            if self._lives <= 0 or self._evals >= self.spec.iterations:
                break

        best_flock_energies = NumberLog(p.energy for p in self._best_flock)
        return SearchReport(best=self._best,
                            best_era=best_flock_energies,
                            evaluations=self._evals,
                            searcher=self.__class__,
                            spec=self.spec,
                            report=None)
예제 #5
0
    def _update(self):
        self._prev_flock_energies = self._current_flock_energies

        for p in self._flock:
            p._update(self._best)
        self._evals += len(self._flock)
        self._current_flock_energies = NumberLog(p.energy for p in self._flock)

        self._best = min(self._best, *self._flock, key=lambda x: x.energy)
        if self._current_flock_energies.better(self._prev_flock_energies):
            self._best_flock = self._flock
        else:
            self._lives -= 1
예제 #6
0
    def run(self, text_report=True):
        n_candiates = self.spec.n_candiates
        self._frontier = [
            self.model.random_model_io() for _ in xrange(n_candiates)
        ]
        self._evals, lives = 0, 4

        for _ in xrange(self.spec.generations):
            if lives <= 0:
                break
            old_frontier_energies = NumberLog(x.energy for x in self._frontier)
            self._update_frontier()
            new_frontier_energies = NumberLog(x.energy for x in self._frontier)
            if not new_frontier_energies.better(old_frontier_energies):
                lives -= 1

        return SearchReport(
            best=min(self._frontier, key=lambda x: x.energy).energy,
            best_era=NumberLog(inits=(x.energy for x in self._frontier)),
            evaluations=self._evals,
            searcher=self.__class__,
            spec=self.spec,
            report=None)
예제 #7
0
    def _end_era(self):
        self._report += ('\n', '{: .2}'.format(self._best.energy), ' ')
        if not self._best_era:
            self._best_era = self._current_era_energies

        try:
            improved = self._current_era_energies.better(
                self._prev_era_energies)
        except AttributeError:
            improved = False
        if improved:
            self._best_era = self._current_era_energies
        else:
            self._lives -= 1

        self._prev_era_energies = self._current_era_energies
        self._current_era_energies = NumberLog(max_size=None)
예제 #8
0
    def _end_era(self):
        self._report += ('\n{: .2}'.format(self._best.energy), ' ')

        # _prev_era won't exist in era 0, so account for that case
        try:
            improved = self._current_era.better(self._prev_era)
        except AttributeError:
            improved = False
        self._prev_era = self._current_era

        # track best_era
        if improved or self._best_era is None:
            self._best_era = self._current_era
        else:
            self._lives -= 1

        if self._lives <= 0:
            self._terminate = True
        else:
            self._current_era = NumberLog()
예제 #9
0
    def run(self, text_report=True):
        '''run MaxWalkSat on self.model'''

        # current ModelIO to evaluate and mutate
        self._current = self.model.random_model_io()
        self._best = self._current
        # initialize and update log variables to track values by era
        self._current_era = NumberLog()
        self._current_era += self._current.energy
        self._best_era = None
        # bookkeeping variables
        self._evals = 0
        self._lives = 4
        self._report = StringBuilder() if text_report else NullObject()
        self._terminate = False

        while self._evals < self.spec.iterations and not self._terminate:
            # get the generator for a random independent variable

            if self.spec.p_mutation > random.random():
                # if not searching a dimension, mutate randomly
                self._update('+')
            else:
                # if doing a local search, choose a dimension
                dimension = base.random_index(self._current.xs)
                search_iv = self.model.xs[dimension]
                # then try points all along the dimension
                lo, hi = search_iv.lo, search_iv.hi
                for j in self._local_search_xs(lo, hi, 10):
                    self._update('|', dimension=dimension, value=j)

        return SearchReport(best=self._best.energy,
                            best_era=self._best_era,
                            evaluations=self._evals,
                            searcher=self.__class__,
                            spec=self.spec,
                            report=self._report)
예제 #10
0
 def setUp(self):  # noqa
     self.max_size = 64
     self.log = NumberLog(max_size=self.max_size)
     random.seed(7)