diff --git a/pyswarms/backend/operators.py b/pyswarms/backend/operators.py index 18db8d1e..57308a4e 100644 --- a/pyswarms/backend/operators.py +++ b/pyswarms/backend/operators.py @@ -13,12 +13,11 @@ # Import modules import numpy as np -from scipy.spatial import cKDTree # Create a logger logger = logging.getLogger(__name__) -def update_pbest(swarm): +def compute_pbest(swarm): """Takes a swarm instance and updates the personal best scores You can use this method to update your personal best positions. @@ -71,97 +70,7 @@ def update_pbest(swarm): else: return (new_pbest_pos, new_pbest_cost) -def update_gbest(swarm): - """Updates the global best given the cost and the position - - This method takes the current pbest_pos and pbest_cost, then returns - the minimum cost and position from the matrix. It should be used in - tandem with an if statement - - .. code-block:: python - - import pyswarms.backend as P - from pyswarms.backend.swarms import Swarm - - my_swarm = P.create_swarm(n_particles, dimensions) - - # If the minima of the pbest_cost is less than the best_cost - if np.min(pbest_cost) < best_cost: - # Update best_cost and position - swarm.best_pos, swarm.best_cost = P.update_gbest(my_swarm) - - Parameters - ---------- - swarm : pyswarms.backend.swarm.Swarm - a Swarm instance - - Returns - ------- - numpy.ndarray - Best position of shape :code:`(n_dimensions, )` - float - Best cost - """ - try: - best_pos = swarm.pbest_pos[np.argmin(swarm.pbest_cost)] - best_cost = np.min(swarm.pbest_cost) - except AttributeError: - msg = 'Please pass a Swarm class. You passed {}'.format(type(swarm)) - logger.error(msg) - raise - else: - return (best_pos, best_cost) - -def update_gbest_neighborhood(swarm, p, k): - """Updates the global best using a neighborhood approach - - This uses the cKDTree method from :code:`scipy` to obtain the nearest - neighbours - - Parameters - ---------- - swarm : pyswarms.backend.swarms.Swarm - a Swarm instance - k : int - number of neighbors to be considered. Must be a - positive integer less than :code:`n_particles` - p: int {1,2} - the Minkowski p-norm to use. 1 is the - sum-of-absolute values (or L1 distance) while 2 is - the Euclidean (or L2) distance. - - Returns - ------- - numpy.ndarray - Best position of shape :code:`(n_dimensions, )` - float - Best cost - """ - try: - # Obtain the nearest-neighbors for each particle - tree = cKDTree(swarm.position) - _, idx = tree.query(swarm.position, p=p, k=k) - - # Map the computed costs to the neighbour indices and take the - # argmin. If k-neighbors is equal to 1, then the swarm acts - # independently of each other. - if k == 1: - # The minimum index is itself, no mapping needed. - best_neighbor = swarm.pbest_cost[idx][:, np.newaxis].argmin(axis=1) - else: - idx_min = swarm.pbest_cost[idx].argmin(axis=1) - best_neighbor = idx[np.arange(len(idx)), idx_min] - # Obtain best cost and position - best_cost = np.min(swarm.pbest_cost[best_neighbor]) - best_pos = swarm.pbest_pos[np.argmin(swarm.pbest_cost[best_neighbor])] - except AttributeError: - msg = 'Please pass a Swarm class. You passed {}'.format(type(swarm)) - logger.error(msg) - raise - else: - return (best_pos, best_cost) - -def update_velocity(swarm, clamp): +def compute_velocity(swarm, clamp): """Updates the velocity matrix This method updates the velocity matrix using the best and current @@ -225,7 +134,7 @@ def update_velocity(swarm, clamp): else: return updated_velocity -def update_position(swarm, bounds): +def compute_position(swarm, bounds): """Updates the position matrix This method updates the position matrix given the current position and diff --git a/tests/backend/test_operators.py b/tests/backend/test_operators.py index de667ee5..3c1720a9 100644 --- a/tests/backend/test_operators.py +++ b/tests/backend/test_operators.py @@ -17,14 +17,6 @@ def test_update_pbest_return_values(swarm): assert (pos == expected_pos).all() assert (cost == expected_cost).all() -def test_update_gbest_return_values(swarm): - """Test if update_gbest() gives the expected return values""" - expected_cost = 1 - expected_pos = np.array([1,2,3]) - pos, cost = P.update_gbest(swarm) - assert cost == expected_cost - assert (pos == expected_pos).all() - @pytest.mark.parametrize('clamp', [None, (0,1), (-1,1)]) def test_update_velocity_return_values(swarm, clamp): """Test if update_velocity() gives the expected shape and range""" @@ -41,14 +33,3 @@ def test_update_position_return_values(swarm, bounds): assert p.shape == swarm.velocity.shape if bounds is not None: assert (bounds[0] <= p).all() and (bounds[1] >= p).all() - -@pytest.mark.parametrize('k', [1,2,3]) -@pytest.mark.parametrize('p', [1,2]) -def test_update_gbest_neighborhood(swarm, p, k): - """Test if update_gbest_neighborhood gives the expected return values""" - pos, cost = P.update_gbest_neighborhood(swarm, p=p, k=k) - expected_pos = np.array([1,2,3]) - expected_cost = 1 - print('k={} p={}, pos={} cost={}'.format(k,p,pos,cost)) - assert (pos == expected_pos).all() - assert cost == expected_cost \ No newline at end of file