de2.py 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. import numpy as np
  2. def de_c(
  3. fobj, # objective function, serial eval
  4. bounds, # bounds array for the population
  5. pop=[], # already initialized population
  6. history=[], # previous history that will be appended to
  7. it_start=0, # the start index of the iteration
  8. mut=0.8, # mutation rate
  9. crossp=0.7, # crossover
  10. popsize=20, # the population size
  11. its=1000, # the number of iterations needed to run for
  12. **kwargs
  13. ):
  14. """
  15. This function performs diff evolution using fobj evaluated serially.
  16. returns the best, fitness of the best, and opt history
  17. """
  18. dimensions = len(bounds)
  19. min_b, max_b = np.asarray(bounds).T
  20. diff = np.fabs(min_b - max_b)
  21. if pop == []:
  22. pop = np.random.rand(popsize, dimensions)
  23. pop_denorm = min_b + pop * diff
  24. fitness = np.asarray([fobj(ind, **kwargs) for ind in pop_denorm])
  25. best_idx = np.argmin(fitness)
  26. best = pop_denorm[best_idx]
  27. for i in range(its):
  28. for j in range(popsize):
  29. idxs = [idx for idx in range(popsize) if idx != j]
  30. a, b, c = pop[np.random.choice(idxs, 3, replace=False)]
  31. #TODO: Here we can chage the strategy for instance
  32. mutant = np.clip(pop[best_idx] + mut * (b - c), 0, 1)
  33. cross_points = np.random.rand(dimensions) < crossp
  34. if not np.any(cross_points):
  35. cross_points[np.random.randint(0, dimensions)] = True
  36. trial = np.where(cross_points, mutant, pop[j])
  37. trial_denorm = min_b + trial * diff
  38. f = fobj(trial_denorm, **kwargs)
  39. if f < fitness[j]:
  40. fitness[j] = f
  41. pop[j] = trial
  42. if f < fitness[best_idx]:
  43. best_idx = j
  44. best = trial_denorm
  45. # if i % 20 == 0:
  46. # print(i, fitness[best_idx])
  47. history.append([i + it_start, fitness[best_idx]])
  48. return best, fitness[best_idx], history
  49. def de_g(
  50. fobj, # objsctive function, parallel eval
  51. bounds, # bounds array for the population
  52. mut=0.8, # mutation rate
  53. crossp=0.7, # crossover
  54. popsize=20, # the population size
  55. its=1000, # the number of iterations needed to run for
  56. **kwargs
  57. ):
  58. """
  59. This function performs diff evolution using fobj evaluated in parallel
  60. returns the last pop, fitness of pop, best individual and opt history
  61. """
  62. dimensions = len(bounds)
  63. history=[]
  64. pop = np.random.rand(popsize, dimensions)
  65. min_b, max_b = np.asarray(bounds).T
  66. diff = np.fabs(min_b - max_b)
  67. pop_denorm = min_b + pop * diff
  68. fitness = np.asarray(fobj(pop_denorm, **kwargs))
  69. best_idx = np.argmin(fitness)
  70. best = pop_denorm[best_idx]
  71. for i in range(its):
  72. trialarr = np.zeros((popsize, dimensions))
  73. for j in range(popsize):
  74. idxs = [idx for idx in range(popsize) if idx != j]
  75. a, b, c = pop[np.random.choice(idxs, 3, replace = False)]
  76. #mutant = np.clip(a + mut * (b - c), 0, 1)
  77. mutant = np.clip(pop[best_idx] + mut * (b - c), 0, 1)
  78. cross_points = np.random.rand(dimensions) < crossp
  79. if not np.any(cross_points):
  80. cross_points[np.random.randint(0, dimensions)] = True
  81. trialarr[j] = np.where(cross_points, mutant, pop[j])
  82. trial_denorm = min_b + trialarr * diff
  83. f = fobj(trial_denorm, **kwargs)
  84. for j in range(popsize):
  85. if f[j] < fitness[j]:
  86. fitness[j] = f[j]
  87. pop[j] = trialarr[j]
  88. if f[j] < fitness[best_idx]:
  89. best_idx = j
  90. best = trial_denorm[j]
  91. # if i%50 == 0:
  92. # print(i, fitness[best_idx])
  93. history.append([i, fitness[best_idx]])
  94. return pop, fitness, best, history