de2.py 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. import numpy as np
  2. import random
  3. def de_cp(
  4. fobj, # objective function, serial eval
  5. bounds, # bounds array for the population
  6. pop=[], # already initialized population
  7. history=[], # previous history that will be appended to
  8. it_start=0, # the start index of the iteration
  9. mut=0.8, # mutation rate
  10. crossp=0.7, # crossover
  11. popsize=20, # the population size
  12. its=1000, # the number of iterations needed to run for
  13. **kwargs
  14. ):
  15. """
  16. This function performs diff evolution using fobj evaluated in parallel
  17. returns the last pop, fitness of pop, best individual and opt history
  18. """
  19. #mut = 0.8 + 0.6*np.random.random()
  20. dimensions = len(bounds)
  21. history=[]
  22. min_b, max_b = np.asarray(bounds).T
  23. if pop == []:
  24. pop = np.random.rand(popsize, dimensions)
  25. diff = np.fabs(min_b - max_b)
  26. pop_denorm = min_b + pop * diff
  27. fitness = np.asarray(fobj(pop_denorm, **kwargs))
  28. best_idx = np.argmin(fitness)
  29. best = pop_denorm[best_idx]
  30. for i in range(its):
  31. trialarr = np.zeros((popsize, dimensions))
  32. for j in range(popsize):
  33. idxs = [idx for idx in range(popsize) if idx != j]
  34. a, b, c = pop[np.random.choice(idxs, 3, replace = False)]
  35. #mutant = np.clip(a + mut * (b - c), 0, 1)
  36. mutant = np.clip(pop[best_idx] + mut * (b - c), 0, 1)
  37. cross_points = np.random.rand(dimensions) < crossp
  38. if not np.any(cross_points):
  39. cross_points[np.random.randint(0, dimensions)] = True
  40. trialarr[j] = np.where(cross_points, mutant, pop[j])
  41. trial_denorm = min_b + trialarr * diff
  42. f = fobj(trial_denorm, **kwargs)
  43. for j in range(popsize):
  44. if f[j] < fitness[j]:
  45. fitness[j] = f[j]
  46. pop[j] = trialarr[j]
  47. if f[j] < fitness[best_idx]:
  48. best_idx = j
  49. best = trial_denorm[j]
  50. if (i+1)%20 == 0:
  51. print(i, fitness[best_idx])
  52. history.append([i, fitness[best_idx]])
  53. return pop, best_idx, fitness[best_idx], best
  54. def de_c(
  55. fobj, # objective function, serial eval
  56. bounds, # bounds array for the population
  57. pop=[], # already initialized population
  58. history=[], # previous history that will be appended to
  59. it_start=0, # the start index of the iteration
  60. mut=0.8, # mutation rate
  61. crossp=0.8, # crossover
  62. popsize=20, # the population size
  63. its=1000, # the number of iterations needed to run for
  64. **kwargs
  65. ):
  66. """
  67. This function performs diff evolution using fobj evaluated serially.
  68. returns the best, fitness of the best, and opt history
  69. """
  70. dimensions = len(bounds)
  71. min_b, max_b = np.asarray(bounds).T
  72. diff = np.fabs(min_b - max_b)
  73. if pop == []:
  74. pop = np.random.rand(popsize, dimensions)
  75. pop_denorm = min_b + pop * diff
  76. fitness = np.asarray([fobj(ind, **kwargs) for ind in pop_denorm])
  77. best_idx = np.argmin(fitness)
  78. best = pop_denorm[best_idx]
  79. for i in range(its):
  80. for j in range(popsize):
  81. idxs = [idx for idx in range(popsize) if idx != j]
  82. a, b, c = pop[np.random.choice(idxs, 3, replace=False)]
  83. mutant = np.clip(a + mut * (b - c), 0, 1)
  84. # #TODO: Here we can chage the strategy for instance
  85. # if i >=150:
  86. # if random.random() >=0.82:
  87. # mutant = np.clip(a + mut * (b - c), 0, 1)
  88. # else:
  89. # mutant = np.clip(pop[best_idx] + mut * (b - c), 0, 1)
  90. cross_points = np.random.rand(dimensions) < crossp
  91. if not np.any(cross_points):
  92. cross_points[np.random.randint(0, dimensions)] = True
  93. trial = np.where(cross_points, mutant, pop[j])
  94. trial_denorm = min_b + trial * diff
  95. f = fobj(trial_denorm, **kwargs)
  96. if f < fitness[j]:
  97. fitness[j] = f
  98. pop[j] = trial
  99. if f < fitness[best_idx]:
  100. best_idx = j
  101. best = trial_denorm
  102. if i % 5 == 0:
  103. print(i, fitness[best_idx])
  104. history.append([i + it_start, fitness[best_idx]])
  105. return best, fitness[best_idx], history
  106. def de_g(
  107. fobj, # objsctive function, parallel eval
  108. bounds, # bounds array for the population
  109. mut=0.8, # mutation rate
  110. crossp=0.7, # crossover
  111. popsize=20, # the population size
  112. its=1000, # the number of iterations needed to run for
  113. **kwargs
  114. ):
  115. """
  116. This function performs diff evolution using fobj evaluated in parallel
  117. returns the last pop, fitness of pop, best individual and opt history
  118. """
  119. dimensions = len(bounds)
  120. history=[]
  121. pop = np.random.rand(popsize, dimensions)
  122. min_b, max_b = np.asarray(bounds).T
  123. diff = np.fabs(min_b - max_b)
  124. pop_denorm = min_b + pop * diff
  125. fitness = np.asarray(fobj(pop_denorm, **kwargs))
  126. best_idx = np.argmin(fitness)
  127. best = pop_denorm[best_idx]
  128. for i in range(its):
  129. trialarr = np.zeros((popsize, dimensions))
  130. for j in range(popsize):
  131. idxs = [idx for idx in range(popsize) if idx != j]
  132. a, b, c = pop[np.random.choice(idxs, 3, replace = False)]
  133. #mutant = np.clip(a + mut * (b - c), 0, 1)
  134. mutant = np.clip(pop[best_idx] + mut * (b - c), 0, 1)
  135. cross_points = np.random.rand(dimensions) < crossp
  136. if not np.any(cross_points):
  137. cross_points[np.random.randint(0, dimensions)] = True
  138. trialarr[j] = np.where(cross_points, mutant, pop[j])
  139. trial_denorm = min_b + trialarr * diff
  140. f = fobj(trial_denorm, **kwargs)
  141. for j in range(popsize):
  142. if f[j] < fitness[j]:
  143. fitness[j] = f[j]
  144. pop[j] = trialarr[j]
  145. if f[j] < fitness[best_idx]:
  146. best_idx = j
  147. best = trial_denorm[j]
  148. # if i%50 == 0:
  149. # print(i, fitness[best_idx])
  150. history.append([i, fitness[best_idx]])
  151. return pop, fitness, best, history