Class: MHL::ChargedSwarm
- Inherits:
-
GenericSwarmBehavior
- Object
- GenericSwarmBehavior
- MHL::ChargedSwarm
- Defined in:
- lib/mhl/charged_swarm.rb
Constant Summary collapse
- DEFAULT_CHARGED_TO_NEUTRAL_RATIO =
default composition is half charged, i.e., QPSO, and half neutral, i.e., traditional PSO (with inertia), swarms
1.0
Constants inherited from GenericSwarmBehavior
GenericSwarmBehavior::DEFAULT_ALPHA, GenericSwarmBehavior::DEFAULT_C1, GenericSwarmBehavior::DEFAULT_C2, GenericSwarmBehavior::DEFAULT_CHI, GenericSwarmBehavior::PHI
Instance Method Summary collapse
-
#initialize(size:, initial_positions:, initial_velocities:, charged_to_neutral_ratio: nil, alpha: nil, c1: nil, c2: nil, chi: nil, constraints: nil, logger: nil) ⇒ ChargedSwarm
constructor
A new instance of ChargedSwarm.
- #mutate ⇒ Object
Methods inherited from GenericSwarmBehavior
Constructor Details
#initialize(size:, initial_positions:, initial_velocities:, charged_to_neutral_ratio: nil, alpha: nil, c1: nil, c2: nil, chi: nil, constraints: nil, logger: nil) ⇒ ChargedSwarm
Returns a new instance of ChargedSwarm.
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
# File 'lib/mhl/charged_swarm.rb', line 11 def initialize(size:, initial_positions:, initial_velocities:, charged_to_neutral_ratio: nil, alpha: nil, c1: nil, c2: nil, chi: nil, constraints: nil, logger: nil) @size = size # retrieve ratio between charged (QPSO) and neutral (constrained PSO) particles ratio = (charged_to_neutral_ratio || DEFAULT_CHARGED_TO_NEUTRAL_RATIO).to_f unless ratio > 0.0 raise ArgumentError, 'Parameter :charged_to_neutral_ratio should be a real greater than zero!' end num_charged_particles = (@size * ratio).round @num_neutral_particles = @size - num_charged_particles # the particles are ordered, with neutral (PSO w/ inertia) particles # first and charged (QPSO) particles later @particles = Array.new(@size) do |index| if index < @num_neutral_particles Particle.new(initial_positions[index], initial_velocities[index]) else QuantumParticle.new(initial_positions[index]) end end # find problem dimension @dimension = initial_positions[0].size @iteration = 1 # define procedure to get dynamic value for alpha @get_alpha = if alpha and alpha.respond_to? :call alpha else ->(it) { (alpha || DEFAULT_ALPHA).to_f } end # get values for parameters C1 and C2 @c1 = (c1 || DEFAULT_C1).to_f @c2 = (c2 || DEFAULT_C2).to_f # define procedure to get dynamic value for chi @get_chi = if chi and chi.respond_to? :call chi else ->(it) { (chi || DEFAULT_CHI).to_f } end @constraints = constraints @logger = logger if @constraints and @logger @logger.info "ChargedSwarm called w/ constraints: #{@constraints}" end end |
Instance Method Details
#mutate ⇒ Object
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
# File 'lib/mhl/charged_swarm.rb', line 66 def mutate # get alpha parameter alpha = @get_alpha.call(@iteration) # get chi parameter chi = @get_chi.call(@iteration) # this calculates the C_n parameter (the centroid of the set of all the # particle attractors) as defined in equations 4.81 and 4.82 of [SUN11]. # # Note: we consider ALL the particles here, not just the charged (QPSO) # ones. As a result, the neutral particles influence the behavior of the # charged ones not only by defining the swarm attractor, but also the # centroid. attractors = @particles.map {|p| p.attractor[:position] } c_n = 0.upto(@dimension-1).map do |j| attractors.inject(0.0) {|s,attr| s += attr[j] } / @size.to_f end @particles.each_with_index do |p,i| # remember: the particles are kept in a PSO-first and QPSO-last order if i < @num_neutral_particles p.move(chi, @c1, @c2, @swarm_attractor) else p.move(alpha, c_n, @swarm_attractor) end if @constraints p.remain_within(@constraints) end end @iteration += 1 end |