Advertisement
Guest User

Untitled

a guest
May 29th, 2016
57
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.92 KB | None | 0 0
  1. import numpy as np
  2.  
  3.  
  4. def swarm(func, bounds, ieqcons=[], f_ieqcons=None, args=(), kwargs={},
  5. swarmsize=100, omega=0.5, phip=0.5, phig=0.5, maxiter=100,
  6. minstep=1e-12, minfunc=1e-12, debug=False):
  7. """
  8. Perform a particle swarm optimization (PSO)
  9.  
  10. Parameters
  11. ==========
  12. func : function
  13. The function to be minimized
  14. bounds:
  15. The bounds of the design variable(s). In form [(lower, upper), ..., (lower, upper)]
  16.  
  17. Optional
  18. ========
  19. ieqcons : list
  20. A list of functions of length n such that ieqcons[j](x,*args) >= 0.0 in
  21. a successfully optimized problem (Default: [])
  22. f_ieqcons : function
  23. Returns a 1-D array in which each element must be greater or equal
  24. to 0.0 in a successfully optimized problem. If f_ieqcons is specified,
  25. ieqcons is ignored (Default: None)
  26. args : tuple
  27. Additional arguments passed to objective and constraint functions
  28. (Default: empty tuple)
  29. kwargs : dict
  30. Additional keyword arguments passed to objective and constraint
  31. functions (Default: empty dict)
  32. swarmsize : int
  33. The number of particles in the swarm (Default: 100)
  34. omega : scalar
  35. Particle velocity scaling factor (Default: 0.5)
  36. phip : scalar
  37. Scaling factor to search away from the particle's best known position
  38. (Default: 0.5)
  39. phig : scalar
  40. Scaling factor to search away from the swarm's best known position
  41. (Default: 0.5)
  42. maxiter : int
  43. The maximum number of iterations for the swarm to search (Default: 100)
  44. minstep : scalar
  45. The minimum stepsize of swarm's best position before the search
  46. terminates (Default: 1e-8)
  47. minfunc : scalar
  48. The minimum change of swarm's best objective value before the search
  49. terminates (Default: 1e-8)
  50. debug : boolean
  51. If True, progress statements will be displayed every iteration
  52. (Default: False)
  53.  
  54. Returns
  55. =======
  56. g : array
  57. The swarm's best known position (optimal design)
  58. f : scalar
  59. The objective value at ``g``
  60.  
  61. """
  62. lower_bound, upper_bound = [], []
  63. for variable_bounds in bounds:
  64. lower_bound.append(variable_bounds[0])
  65. upper_bound.append(variable_bounds[1])
  66.  
  67. assert len(lower_bound) == len(upper_bound), 'Lower- and upper-bounds must be the same length'
  68. assert hasattr(func, '__call__'), 'Invalid function handle'
  69. lower_bound = np.array(lower_bound)
  70. upper_bound = np.array(upper_bound)
  71. assert np.all(upper_bound > lower_bound), 'All upper-bound values must be greater than lower-bound values'
  72.  
  73. vhigh = np.abs(upper_bound - lower_bound)
  74. vlow = -vhigh
  75.  
  76. # Check for constraint function(s) #########################################
  77. obj = lambda x: func(x, *args, **kwargs)
  78. if f_ieqcons is None:
  79. if not len(ieqcons):
  80. if debug:
  81. print('No constraints given.')
  82. cons = lambda x: np.array([0])
  83. else:
  84. if debug:
  85. print('Converting ieqcons to a single constraint function')
  86. cons = lambda x: np.array([y(x, *args, **kwargs) for y in ieqcons])
  87. else:
  88. if debug:
  89. print('Single constraint function given in f_ieqcons')
  90. cons = lambda x: np.array(f_ieqcons(x, *args, **kwargs))
  91.  
  92. def is_feasible(x):
  93. check = np.all(cons(x) >= 0)
  94. return check
  95.  
  96. # Initialize the particle swarm ############################################
  97. S = swarmsize
  98. D = len(lower_bound) # the number of dimensions each particle has
  99. x = np.random.rand(S, D) # particle positions
  100. v = np.zeros_like(x) # particle velocities
  101. p = np.zeros_like(x) # best particle positions
  102. fp = np.zeros(S) # best particle function values
  103. g = [] # best swarm position
  104. fg = 1e100 # artificial best swarm position starting value
  105.  
  106. for i in range(S):
  107. # Initialize the particle's position
  108. x[i, :] = lower_bound + x[i, :] * (upper_bound - lower_bound)
  109.  
  110. # Initialize the particle's best known position
  111. p[i, :] = x[i, :]
  112.  
  113. # Calculate the objective's value at the current particle's
  114. fp[i] = obj(p[i, :])
  115.  
  116. # At the start, there may not be any feasible starting point, so just
  117. # give it a temporary "best" point since it's likely to change
  118. if i == 0:
  119. g = p[0, :].copy()
  120.  
  121. # If the current particle's position is better than the swarm's,
  122. # update the best swarm position
  123. if fp[i] < fg and is_feasible(p[i, :]):
  124. fg = fp[i]
  125. g = p[i, :].copy()
  126.  
  127. # Initialize the particle's velocity
  128. v[i, :] = vlow + np.random.rand(D) * (vhigh - vlow)
  129.  
  130. # Iterate until termination criterion met ##################################
  131. iteration_termination = 1
  132. while iteration_termination <= maxiter:
  133. rp = np.random.uniform(size=(S, D))
  134. rg = np.random.uniform(size=(S, D))
  135. for i in range(S):
  136.  
  137. # Update the particle's velocity
  138. v[i, :] = omega * v[i, :] + phip * rp[i, :] * (p[i, :] - x[i, :]) + \
  139. phig * rg[i, :] * (g - x[i, :])
  140.  
  141. # Update the particle's position, correcting lower and upper bound
  142. # violations, then update the objective function value
  143. x[i, :] = x[i, :] + v[i, :]
  144. mark1 = x[i, :] < lower_bound
  145. mark2 = x[i, :] > upper_bound
  146. x[i, mark1] = lower_bound[mark1]
  147. x[i, mark2] = upper_bound[mark2]
  148. fx = obj(x[i, :])
  149.  
  150. # Compare particle's best position (if constraints are satisfied)
  151. if fx < fp[i] and is_feasible(x[i, :]):
  152. p[i, :] = x[i, :].copy()
  153. fp[i] = fx
  154.  
  155. # Compare swarm's best position to current particle's position
  156. # (Can only get here if constraints are satisfied)
  157. if fx < fg:
  158. if debug:
  159. print('New best for swarm at iteration {:}: {:} {:}'.format(iteration_termination, x[i, :], fx))
  160.  
  161. tmp = x[i, :].copy()
  162. stepsize = np.sqrt(np.sum((g - tmp) ** 2))
  163. if np.abs(fg - fx) <= minfunc:
  164. print('Stopping search: Swarm best objective change less than {:}'.format(minfunc))
  165. return tmp, fx
  166. elif stepsize <= minstep:
  167. print('Stopping search: Swarm best position change less than {:}'.format(minstep))
  168. return tmp, fx
  169. else:
  170. g = tmp.copy()
  171. fg = fx
  172.  
  173. if debug:
  174. print('Best after iteration {:}: {:} {:}'.format(iteration_termination, g, fg))
  175. iteration_termination += 1
  176.  
  177. print('Stopping search: maximum iterations reached --> {:}'.format(maxiter))
  178.  
  179. if not is_feasible(g):
  180. print("However, the optimization couldn't find a feasible design. Sorry")
  181. return g, fg
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement