r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1"""Classes that determine convergence of an algorithm run

2based on population stagnation or max raw score reached"""

3from ase.ga import get_raw_score

6class Convergence:

7 """

8 Base class for all convergence object to be based on.

9 It is necessary to supply the population instance, to be

10 able to obtain current and former populations.

11 """

13 def __init__(self, population_instance):

14 self.pop = population_instance

15 self.pops = {}

17 def converged(self):

18 """This function is called to find out if the algorithm

19 run has converged, it should return True or False.

20 Overwrite this in the inherited class."""

21 raise NotImplementedError

23 def populate_pops(self, to_gen):

24 """Populate the pops dictionary with how the population

25 looked after i number of generations."""

26 for i in range(to_gen):

27 if i not in self.pops.keys():

28 self.pops[i] = self.pop.get_population_after_generation(i)

31class GenerationRepetitionConvergence(Convergence):

32 """Returns True if the latest finished population is stagnated for

33 number_of_generations.

35 Parameters:

37 number_of_generations: int

38 How many generations need to be equal before convergence.

40 number_of_individuals: int

41 How many of the fittest individuals should be included in the

42 convergence test. Default is -1 meaning all in the population.

44 max_generations: int

45 The maximum number of generations the GA is allowed to run.

46 Default is indefinite.

47 """

49 def __init__(self, population_instance, number_of_generations,

50 number_of_individuals=-1, max_generations=100000000):

51 Convergence.__init__(self, population_instance)

52 self.numgens = number_of_generations

53 self.numindis = number_of_individuals

54 self.maxgen = max_generations

56 def converged(self):

57 size = self.pop.pop_size

58 cur_gen_num = self.pop.dc.get_generation_number(size)

60 if cur_gen_num >= self.maxgen:

61 return True

63 if cur_gen_num <= 1:

64 return False

66 cur_pop = self.pop.get_current_population()

68 for i in cur_pop[:self.numindis]])

69 if newest + self.numgens > cur_gen_num:

70 return False

72 self.populate_pops(cur_gen_num)

74 duplicate_gens = 1

75 latest_pop = self.pops[cur_gen_num - 1]

76 for i in range(cur_gen_num - 2, -1, -1):

77 test_pop = self.pops[i]

78 if test_pop[:self.numindis] == latest_pop[:self.numindis]:

79 duplicate_gens += 1

80 if duplicate_gens >= self.numgens:

81 return True

82 return False

85class RawScoreConvergence(Convergence):

86 """Returns True if the supplied max_raw_score has been reached"""

88 def __init__(self, population_instance, max_raw_score, eps=1e-3):

89 Convergence.__init__(self, population_instance)

90 self.max_raw_score = max_raw_score

91 self.eps = eps

93 def converged(self):

94 cur_pop = self.pop.get_current_population()

95 if abs(get_raw_score(cur_pop[0]) - self.max_raw_score) <= self.eps:

96 return True

97 return False

100class NeverConvergence:

101 """Test class that never converges."""

103 def __init__(self):

104 pass

106 def converged(self):

107 return False