@@ -70,10 +70,10 @@ def __init__(self, NO_OF_PARTICLES,
7070else :
7171
7272if heightl == 1 :
73- lbound = np . vstack ( lbound )
73+ lbound = lbound
7474
7575if heightu == 1 :
76- ubound = np . vstack ( ubound )
76+ ubound = ubound
7777
7878self .lbound = lbound
7979self .ubound = ubound
@@ -133,7 +133,7 @@ def __init__(self, NO_OF_PARTICLES,
133133# first chicken is a rooster, in case there's only 1 searching agent
134134# chicken_info = array of [CLASSIFICATION(0-4), GROUP(0-(RN-1)), MOTHER-HEN-ID]
135135# classificition: 0 = rooster, 1 = hen, 2 = mother hen, 3 = chicks
136- self .chicken_info = np .vstack ([0 ,0 ,- 1 ])
136+ self .chicken_info = np .array ([0 ,0 ,- 1 ])
137137
138138#randomly initialize the positions
139139self .M = np .vstack (np .multiply (self .rng .random ((np .max ([heightl ,
@@ -164,37 +164,36 @@ def __init__(self, NO_OF_PARTICLES,
164164for i in range (2 ,int (NO_OF_PARTICLES )+ 1 ):
165165# set initial location
166166self .M = \
167- np .hstack ([self .M ,
168- np .vstack (np .multiply (self .rng .random ((np .max ([heightl ,
169- widthl ]),
170- 1 )),
167+ np .vstack ([self .M ,
168+ np .multiply (self .rng .random ((1 ,np .max ([heightl ,widthl ]))),
171169variation )
172- + lbound ) ])
170+ + lbound ])
173171if classList [i - 1 ]== 0 :#rooster
174172# assign to the next group (i-1), and done.
175173self .chicken_info = \
176- np .hstack ([self .chicken_info ,
177- np . vstack ( [classList [i - 1 ],i - 1 ,- 1 ]) ])
174+ np .vstack ([self .chicken_info ,
175+ [classList [i - 1 ],i - 1 ,- 1 ]])
178176
179177elif (classList [i - 1 ]== 1 )or (classList [i - 1 ]== 2 ):#hen, mother hen
180178# assign to a random group.
181179hen_group = self .rng .choice (group_nums )
182180self .chicken_info = \
183- np .hstack ([self .chicken_info ,
184- np . vstack ( [classList [i - 1 ],hen_group ,- 1 ]) ])
181+ np .vstack ([self .chicken_info ,
182+ [classList [i - 1 ],hen_group ,- 1 ]])
185183
186184elif classList [i - 1 ]== 3 :#chick
187185# select a random hen to be the 'mother' and assign to group
188186groupAssigned = False
187+
189188while (groupAssigned == False ):
190- chicken_idx = self .rng .integers (0 ,i - 1 , endpoint = False )# index after a chick will always be the chick
191- if self .chicken_info [0 ][ chicken_idx ]== 2 :#is mother hen
189+ chicken_idx = self .rng .integers (0 ,i - 1 )# index after a chick will always be the chick
190+ if self .chicken_info [chicken_idx ][ 0 ]== 2 :#is mother hen
192191# get the group the random mother hen is from
193- mother_group = self .chicken_info [1 ][ chicken_idx ]
192+ mother_group = self .chicken_info [chicken_idx ][ 1 ]
194193# assign chick to group, and to that mother hen
195194self .chicken_info = \
196- np .hstack ([self .chicken_info ,
197- np . vstack ( [classList [i - 1 ],mother_group ,chicken_idx ]) ])
195+ np .vstack ([self .chicken_info ,
196+ [classList [i - 1 ],mother_group ,chicken_idx ]])
198197groupAssigned = True
199198
200199
@@ -232,12 +231,12 @@ def __init__(self, NO_OF_PARTICLES,
232231
233232self .output_size = output_size
234233self .Active = np .ones ((NO_OF_PARTICLES ))
235- self .Gb = sys .maxsize * np .ones ((np .max ([heightl ,widthl ]), 1 ))
236- self .F_Gb = sys .maxsize * np .ones ((output_size , 1 ))
234+ self .Gb = sys .maxsize * np .ones ((1 , np .max ([heightl ,widthl ])))
235+ self .F_Gb = sys .maxsize * np .ones ((1 , output_size ))
237236self .Pb = sys .maxsize * np .ones (np .shape (self .M ))
238- self .F_Pb = sys .maxsize * np .ones ((output_size , NO_OF_PARTICLES ))
239- self .weights = np .vstack ( np . array (weights ) )
240- self .targets = np .vstack ( np . array (targets ))
237+ self .F_Pb = sys .maxsize * np .ones ((NO_OF_PARTICLES , output_size ))
238+ self .weights = np .array (weights )
239+ self .targets = np .array (targets )
241240self .maxit = maxit
242241self .E_TOL = E_TOL
243242self .obj_func = obj_func
@@ -259,7 +258,7 @@ def __init__(self, NO_OF_PARTICLES,
259258def call_objective (self ,allow_update ):
260259if self .Active [self .current_particle ]:
261260# call the objective function. If there's an issue with the function execution, 'noError' returns False
262- newFVals ,noError = self .obj_func (np . vstack ( self .M [:, self .current_particle ]) ,self .output_size )
261+ newFVals ,noError = self .obj_func (self .M [self .current_particle ],self .output_size )
263262if noError == True :
264263self .Fvals = newFVals
265264if allow_update :
@@ -269,7 +268,7 @@ def call_objective(self, allow_update):
269268else :
270269self .allow_update = 0
271270return noError # return is for error reporting purposes only
272-
271+
273272# MOVEMENT MODELS
274273
275274def move_rooster (self ,particle ):
@@ -280,9 +279,9 @@ def move_rooster(self, particle):
280279rooster_arr = np .arange (self .RN )
281280random_rooster_idx = self .rng .choice (rooster_arr )
282281# use L2 norm for fitness to account for multi-objective funcs
283- random_rooster_fitness = np .linalg .norm (self .F_Pb [:, random_rooster_idx ])
282+ random_rooster_fitness = np .linalg .norm (self .F_Pb [random_rooster_idx ])
284283
285- this_rooster_fitness = np .linalg .norm (self .F_Pb [:, particle ])
284+ this_rooster_fitness = np .linalg .norm (self .F_Pb [particle ])
286285
287286if this_rooster_fitness <= random_rooster_fitness :
288287sig_squared = 1
@@ -295,8 +294,8 @@ def move_rooster(self, particle):
295294
296295
297296#update new location based on random()
298- self .M [:, particle ]= self .M [:, particle ]* (1 + self .rng .normal (0 ,sig_squared ))
299-
297+ self .M [particle ]= self .M [particle ]* (1 + self .rng .normal (0 ,sig_squared ))
298+
300299
301300def move_hen (self ,particle ):
302301#newLoc = oldLoc
@@ -308,23 +307,23 @@ def move_hen(self, particle):
308307# NOTE: FitnessRoosterGroupmate and FitnessRandomChickenInSwarm cannot be the same chicken
309308
310309# get the rooster information
311- group_rooster_idx = int (self .chicken_info [1 ][ particle ])#also the group index
312- rooster_loc = self .M [:, group_rooster_idx ]
313- fitness_rooster = np .linalg .norm (self .F_Pb [:, group_rooster_idx ])
310+ group_rooster_idx = int (self .chicken_info [particle ][ 1 ])#also the group index
311+ rooster_loc = self .M [group_rooster_idx ]
312+ fitness_rooster = np .linalg .norm (self .F_Pb [group_rooster_idx ])
314313
315314# get the random chicken information
316315# initial random
317316random_chicken_idx = self .rng .integers (0 ,self .number_of_particles )
318317# random cannot be the idx of the rooster, the current chicken, or be from a chick
319318while (random_chicken_idx == group_rooster_idx )or \
320319 (random_chicken_idx == particle )or \
321- (int (self .chicken_info [0 ][ random_chicken_idx ])== 3 ):
320+ (int (self .chicken_info [random_chicken_idx ][ 0 ])== 3 ):
322321random_chicken_idx = self .rng .integers (0 ,self .number_of_particles )
323322
324- random_chicken_loc = self .M [:, random_chicken_idx ]
325- fitness_random_chicken = np .linalg .norm (self .F_Pb [:, random_chicken_idx ])
323+ random_chicken_loc = self .M [random_chicken_idx ]
324+ fitness_random_chicken = np .linalg .norm (self .F_Pb [random_chicken_idx ])
326325
327- fitness_this_chicken = np .linalg .norm (self .F_Pb [:, particle ])
326+ fitness_this_chicken = np .linalg .norm (self .F_Pb [particle ])
328327
329328# epsilon = 'smallest system constant'. improvised.
330329epsilon = 10e-50
@@ -334,27 +333,27 @@ def move_hen(self, particle):
334333clipped_val = np .clip (((fitness_this_chicken - fitness_rooster )/ (np .abs (fitness_this_chicken )+ epsilon )),- 709.00 ,709.00 )
335334S1 = np .exp (clipped_val )
336335# S1*RANDOM(0-to-1)*(LocationRoosterGroupmate-thisChickenLocation)
337- term_1 = S1 * self .rng .uniform (0 ,1 )* (rooster_loc - self .M [:, particle ])
336+ term_1 = S1 * self .rng .uniform (0 ,1 )* (rooster_loc - self .M [particle ])
338337
339338#S2 = np.exp(float(fitness_random_chicken-fitness_this_chicken))
340339#np.exp(...) throws overflow errors. Using clip as a generic catch
341340clipped_val = np .clip ((fitness_random_chicken - fitness_this_chicken ),- 709.00 ,709.00 )
342341S2 = np .exp (clipped_val )
343342#S2*RANDOM(0-to-1)*(LoctionRandomChickenInSwarm-thisChickenLocation)
344- term_2 = S2 * self .rng .uniform (0 ,1 )* (random_chicken_loc - self .M [:, particle ])
343+ term_2 = S2 * self .rng .uniform (0 ,1 )* (random_chicken_loc - self .M [particle ])
345344
346345# new_loc = old_loc + term_1 + term_2
347- self .M [:, particle ]= self .M [:, particle ]+ term_1 + term_2
346+ self .M [particle ]= self .M [particle ]+ term_1 + term_2
348347
349348
350349def move_chick (self ,particle ):
351350#nextLoc = currentLoc + FL*(locationMother - currentLoc)
352351# NOTE: FL is a value 0 or 2 that determines if a chick follows the mother
353352# The chick RANDOMLY chooses between 0 or 2
354353
355- mother_idx = int (self .chicken_info [2 ][ particle ])# the the idx of the mother chicken
356- mother_loc = self .M [:, mother_idx ]
357- self .M [:, particle ]= self .M [:, particle ]+ self .rng .choice ([0 ,2 ])* (mother_loc - self .M [:, particle ])
354+ mother_idx = int (self .chicken_info [particle ][ 2 ])# the the idx of the mother chicken
355+ mother_loc = self .M [mother_idx ]
356+ self .M [particle ]= self .M [particle ]+ self .rng .choice ([0 ,2 ])* (mother_loc - self .M [particle ])
358357
359358def reorganize_swarm (self ):
360359# rank the chickens' fitness vals and establish hierarchial order
@@ -363,7 +362,7 @@ def reorganize_swarm(self):
363362#get the indexs that sort the personal best fitness from best (lowest) to worst
364363l2_norm_vals = []
365364for idx in range (0 ,self .number_of_particles ):
366- l2_norm_vals .append (np .linalg .norm (self .F_Pb [:, idx ]))
365+ l2_norm_vals .append (np .linalg .norm (self .F_Pb [idx ]))
367366
368367fitness_sort_idx = np .argsort (l2_norm_vals )# lowest are first
369368
@@ -374,8 +373,8 @@ def reorganize_swarm(self):
374373ctr = 0
375374
376375for idx in fitness_sort_idx :
377- temp_M [:, ctr ]= self .M [:, idx ]
378- temp_F_Pb [:, ctr ]= self .F_Pb [:, idx ]
376+ temp_M [ctr ]= self .M [idx ]
377+ temp_F_Pb [ctr ]= self .F_Pb [idx ]
379378temp_Active [ctr ]= self .Active [idx ]
380379ctr = ctr + 1
381380self .M = 1 * temp_M
@@ -428,10 +427,10 @@ def reorganize_swarm(self):
428427# CLASSIFICATION(0-4), GROUP(0-m), MOTHER-CHILD ID
429428groupAssigned = False
430429while (groupAssigned == False ):
431- chicken_idx = self .rng .integers (0 ,i )# index after a chick will always be the chick
432- if self .chicken_info [0 ][ chicken_idx ]== 2 :#is mother hen
430+ chicken_idx = self .rng .integers (0 ,i - 1 , endpoint = False )# index after a chick will always be the chick
431+ if self .chicken_info [chicken_idx ][ 0 ]== 2 :#is mother hen
433432# get the group the random mother hen is from
434- mother_group = self .chicken_info [1 ][ chicken_idx ]
433+ mother_group = self .chicken_info [chicken_idx ][ 1 ]
435434# assign chick to group, and to that mother hen
436435self .chicken_info = \
437436np .hstack ([self .chicken_info ,
@@ -443,12 +442,13 @@ def reorganize_swarm(self):
443442
444443def check_bounds (self ,particle ):
445444update = 0
446- for i in range (0 ,(np .shape (self .M )[0 ])):
447- if (self .lbound [i ]> self .M [i , particle ]) \
448- or (self .ubound [i ]< self .M [i , particle ]):
445+ for i in range (0 ,(np .shape (self .M )[1 ])):
446+ if (self .lbound [i ]> self .M [particle , i ]) \
447+ or (self .ubound [i ]< self .M [particle , i ]):
449448update = i + 1
450449return update
451450
451+
452452def validate_obj_function (self ,particle ):
453453# checks the the objective function resolves with the current particle.
454454# It is possible (and likely) that obj funcs without proper error handling
@@ -465,46 +465,42 @@ def random_bound(self, particle):
465465# The first condition checks if constraints are met,
466466# and the second determins if the values are to large (positive or negitive)
467467# and may cause a buffer overflow with large exponents (a bug that was found experimentally)
468- update = self .check_bounds (particle )or not self .constr_func (self .M [:,particle ])or not self .validate_obj_function (np .vstack (self .M [:,self .current_particle ]))
469-
468+ update = self .check_bounds (particle )or not self .constr_func (self .M [particle ])or not self .validate_obj_function (np .hstack (self .M [self .current_particle ]))
470469if update > 0 :
471- while (self .check_bounds (particle )> 0 )or (self .constr_func (self .M [:, particle ])== False )or (self .validate_obj_function (self .M [:, particle ])== False ):
470+ while (self .check_bounds (particle )> 0 )or (self .constr_func (self .M [particle ])== False )or (self .validate_obj_function (self .M [particle ])== False ):
472471variation = self .ubound - self .lbound
473- newVal = np .squeeze (self .rng .random ()*
474- np .multiply (np .ones ((np .shape (self .M )[0 ],1 )),
475- variation )+ self .lbound )
476-
477- self .M [:,particle ]= \
472+ self .M [particle ]= \
478473np .squeeze (self .rng .random ()*
479- np .multiply (np .ones ((np .shape (self .M )[0 ], 1 )),
474+ np .multiply (np .ones ((1 , np .shape (self .M )[1 ] )),
480475variation )+ self .lbound )
481476
482477def reflecting_bound (self ,particle ):
483478update = self .check_bounds (particle )
484- constr = self .constr_func (self .M [:, particle ])
479+ constr = self .constr_func (self .M [particle ])
485480if (update > 0 )and constr :
486- self .M [:, particle ]= 1 * self .Mlast
481+ self .M [particle ]= 1 * self .Mlast
487482NewV = np .multiply (- 1 ,self .V [update - 1 ,particle ])
488483self .V [update - 1 ,particle ]= NewV
489484if not constr :
490485self .random_bound (particle )
491486
492487def absorbing_bound (self ,particle ):
493488update = self .check_bounds (particle )
494- constr = self .constr_func (self .M [:, particle ])
489+ constr = self .constr_func (self .M [particle ])
495490if (update > 0 )and constr :
496- self .M [:, particle ]= 1 * self .Mlast
497- self .V [update - 1 , particle ]= 0
491+ self .M [particle ]= 1 * self .Mlast
492+ self .V [particle , update - 1 ]= 0
498493if not constr :
499494self .random_bound (particle )
500495
501496def invisible_bound (self ,particle ):
502- update = self .check_bounds (particle )or not self .constr_func (self .M [:, particle ])or not self .validate_obj_function (self .M [:, particle ])
497+ update = self .check_bounds (particle )or not self .constr_func (self .M [particle ])or not self .validate_obj_function (self .M [particle ])
503498if update > 0 :
504499self .Active [particle ]= 0
505500else :
506501pass
507502
503+
508504def handle_bounds (self ,particle ):
509505if self .boundary == 1 :
510506self .random_bound (particle )
@@ -520,12 +516,12 @@ def handle_bounds(self, particle):
520516def check_global_local (self ,Flist ,particle ):
521517
522518if np .linalg .norm (Flist )< np .linalg .norm (self .F_Gb ):
523- self .F_Gb = Flist
524- self .Gb = np .vstack ( np . array (self .M [:, particle ]) )
519+ self .F_Gb = np . array ([ Flist ])
520+ self .Gb = np .array (self .M [particle ])
525521
526- if np .linalg .norm (Flist )< np .linalg .norm (self .F_Pb [:, particle ]):
527- self .F_Pb [:, particle ]= np .squeeze (Flist )
528- self .Pb [:, particle ]= self .M [:, particle ]
522+ if np .linalg .norm (Flist )< np .linalg .norm (self .F_Pb [particle ]):
523+ self .F_Pb [particle ]= np .squeeze (Flist )
524+ self .Pb [particle ]= self .M [particle ]
529525
530526def converged (self ):
531527convergence = np .linalg .norm (self .F_Gb )< self .E_TOL
@@ -549,7 +545,7 @@ def step(self, suppress_output):
549545"Current Particle Active\n " + \
550546str (self .Active [self .current_particle ])+ "\n " + \
551547"Current Particle Location\n " + \
552- str (self .M [:, self .current_particle ])+ "\n " + \
548+ str (self .M [self .current_particle ])+ "\n " + \
553549"Absolute mean deviation\n " + \
554550str (self .absolute_mean_deviation_of_particles ())+ "\n " + \
555551"-----------------------------"
@@ -570,7 +566,7 @@ def step(self, suppress_output):
570566# roosters are always at the top of the list so that they're moved first.
571567# Then the hens are moved. It doesn't matter which type of hen is moved first.
572568# Chicks are moved last so that they can follow the mother hens
573- chicken_type = self .chicken_info [0 ][ self .current_particle ]
569+ chicken_type = self .chicken_info [self .current_particle ][ 0 ]
574570if chicken_type == 0 :#update rooster location
575571self .move_rooster (self .current_particle )
576572
@@ -647,7 +643,7 @@ def import_swarm(self, swarm_export, obj_func):
647643self .obj_func = obj_func
648644
649645def get_obj_inputs (self ):
650- return np .vstack (self .M [:, self .current_particle ])
646+ return np .vstack (self .M [self .current_particle ])
651647
652648def get_convergence_data (self ):
653649best_eval = np .linalg .norm (self .F_Gb )
@@ -661,11 +657,12 @@ def get_optimized_outs(self):
661657return self .F_Gb
662658
663659def absolute_mean_deviation_of_particles (self ):
664- mean_data = np .vstack (np .mean (self .M ,axis = 1 ) )
660+ mean_data = np .array (np .mean (self .M ,axis = 0 )). reshape ( 1 , - 1 )
665661abs_data = np .zeros (np .shape (self .M ))
666662for i in range (0 ,self .number_of_particles ):
667- abs_data [:,i ]= np .squeeze (np .abs (np .vstack (self .M [:,i ])- mean_data ))
668- abs_mean_dev = np .linalg .norm (np .mean (abs_data ,axis = 1 ))
663+ abs_data [i ]= np .squeeze (np .abs (self .M [i ]- mean_data ))
664+
665+ abs_mean_dev = np .linalg .norm (np .mean (abs_data ,axis = 0 ))
669666return abs_mean_dev
670667
671668def error_message_generator (self ,msg ):