de2.py 6.0 KB

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