def test_find_nearest(self): swarms = set() swarm1 = swarm.Swarm(1, 10, BasicProblem()) swarm1.mode_location = np.array([0, 0]) swarms.add(swarm1) swarm2 = swarm.Swarm(1, 10, BasicProblem()) swarm2.mode_location = np.array([0.1, 0.2]) swarms.add(swarm2) swarm3 = swarm.Swarm(1, 10, BasicProblem()) swarm3.mode_location = np.array([-0.2, -0.5]) swarms.add(swarm3) swarm4 = swarm.Swarm(1, 10, BasicProblem()) swarm4.mode_location = np.array([-0.09, 0.05]) swarms.add(swarm4) best_swarm, distance = swarm1.find_nearest(swarms) expected_distance = math.sqrt(-0.09 * -0.09 + 0.05 * 0.05) # Swarm 4 is the nearest self.assertEqual(best_swarm, swarm4) self.assertAlmostEqual(distance, expected_distance, msg="Unexpected distance returned") # Should update the internal store of the distance self.assertAlmostEqual(swarm1.dist, expected_distance, msg="Unexpected distance stored in class")
def test_merge_swarms_two_swarms_merge(self): problem = swarm_tests.BasicProblem() my_nmmso = nmmso.Nmmso(problem, 10, 100, tol_val=0.2) my_nmmso.swarms = set() s1 = swarm.Swarm(1, 10, problem) s2 = swarm.Swarm(2, 10, problem) # give swarm 1 2 particles s1.mode_location = np.array([0.50, 0.60]) s1.mode_value = sum(pow(s1.mode_location, 2)) swarm_tests.SwarmTests.add_particle_to_swarm(s1, 0, [1.1, 1.2], 10.0, [1.3, 1.4], 11.0, [1.5, 1.6]) swarm_tests.SwarmTests.add_particle_to_swarm(s1, 1, [2.1, 2.2], 20.0, [2.3, 2.4], 21.0, [2.5, 2.6]) # give swarm 2 3 particles s2.mode_location = np.array([0.51, 0.61]) s2.mode_value = sum(pow(s2.mode_location, 2)) swarm_tests.SwarmTests.add_particle_to_swarm(s2, 0, [3.1, 3.2], 30.0, [3.3, 3.4], 31.0, [3.5, 3.6]) swarm_tests.SwarmTests.add_particle_to_swarm(s2, 1, [4.1, 4.2], 40.0, [4.3, 4.4], 41.0, [4.5, 4.6]) swarm_tests.SwarmTests.add_particle_to_swarm(s2, 2, [5.1, 5.2], 50.0, [5.3, 5.4], 51.0, [5.5, 5.6]) my_nmmso.swarms.add(s1) my_nmmso.swarms.add(s2) my_nmmso._merge_swarms() # Merge to give only one active mode self.assertEqual(len(my_nmmso.swarms), 1) # That active mode should have 5 particles s = next(iter(my_nmmso.swarms)) # Just getting hold of the item in the set self.assertEqual(s.number_of_particles, 5)
def test_evolve_with_low_number_of_swarms(self, random_sample_mock, random_rand_mock): problem = swarm_tests.BasicProblem() my_nmmso = nmmso.Nmmso(problem, 10, tol_val=0.2, max_evol=10) my_nmmso.swarms = set() s1 = swarm.Swarm(1, 10, problem) s2 = swarm.Swarm(2, 10, problem) s3 = swarm.Swarm(3, 10, problem) # Mock call in test_evolve select swarms 1 and 3 random_sample_mock.return_value = [s1, s3] # Mock call in Swarm.UNI to select to crossover 2nd element but not first random_rand_mock.return_value = np.array([0.1, 0.6]) s1.mode_location = np.array([0.01, 0.11]) s2.mode_location = np.array([0.02, 0.12]) s3.mode_location = np.array([0.03, 0.13]) my_nmmso._add_swarm(s1) my_nmmso._add_swarm(s2) my_nmmso._add_swarm(s3) my_nmmso._evolve() self.assertEqual(len(my_nmmso.swarms), 4) new_swarm = NmmsoTests.get_swarm_by_id(my_nmmso, 4) np.testing.assert_array_almost_equal(new_swarm.new_location, np.array([0.01, 0.13]))
def test_distance_to(self): """Tests distance_to method""" s1 = swarm.Swarm(1, 10, BasicProblem()) s1.mode_location = np.array([0.2, 0.5]) s2 = swarm.Swarm(2, 10, BasicProblem()) s2.mode_location = np.array([0.1, 0.9]) self.assertAlmostEqual(s1.distance_to(s2), np.sqrt(0.1**2 + 0.4**2))
def test_evaluate_when_new_value_is_not_best(self): """Tests the basic evaluate method when the new value is not greater than the current best.""" s = swarm.Swarm(1, 10, BasicProblem()) original_mode_location = np.array([0.9, 0.8]) original_y = 0.9 * 0.9 + 0.8 * 0.8 s.shifted_loc = 1 s.mode_location = original_mode_location s.mode_value = original_y s.pbest_locations[1, :] = original_mode_location s.pbest_values[1] = original_y new_location = np.array([0.4, 0.4]) y = 0.4 * 0.4 * 2 s.new_location = new_location s.evaluate(y) self.assertAlmostEqual(s.mode_value, original_y) np.testing.assert_array_almost_equal(s.mode_location, original_mode_location) np.testing.assert_array_almost_equal(s.history_locations[1, :], new_location) self.assertAlmostEqual(s.history_values[1], y) np.testing.assert_array_almost_equal(s.pbest_locations[1, :], original_mode_location) self.assertAlmostEqual(s.pbest_values[1], original_y)
def test_swarm_tuples_in_a_set(self): """Tests that tuples created by create_swarm_tuple work as expected in a set""" problem = swarm_tests.BasicProblem() s1 = swarm.Swarm(1, 4, problem) s2 = swarm.Swarm(2, 4, problem) s = set() t1 = nmmso.Nmmso._create_swarm_tuple(s1, s2) t2 = nmmso.Nmmso._create_swarm_tuple(s1, s2) s.add(t1) s.add(t2) self.assertEqual(len(s),1)
def test_initialise_with_uniform_crossover(self, mock_rand): """Tests initialise_with_uniform_crossover""" swarm1 = swarm.Swarm(1, 10, BasicProblem()) swarm1.mode_location = np.array([0.0, 0.0]) swarm2 = swarm.Swarm(2, 10, BasicProblem()) swarm2.mode_location = np.array([0.1, 0.2]) mock_rand.return_value = np.array([0.6, 0.1]) s = swarm.Swarm(3, 10, BasicProblem()) s.initialise_with_uniform_crossover(swarm1, swarm2) np.testing.assert_array_almost_equal(s.new_location, [0.1, 0]) self.assertAlmostEqual(s.mode_value, 0.1 * 0.1) self.assertEqual(s.converged, False) self.assertEqual(s.changed, True)
def test_increment_when_add_new_particle_and_initial_velocities_are_rejected( self, mock_uniform_sphere_points, mock_random_rand): """Tests increment method when a new particle is added and initial velocities are rejected.""" my_swarm = swarm.Swarm(1, 10, BasicProblem()) my_swarm.dist = 0.5 my_swarm.number_of_particles = 1 my_swarm.mode_location = np.array([0.1, 0.2]) # We mock two calls to uniform sphere points, first to compute the new location, then to compute # the velocity side_effect = list() side_effect.append([np.array([0.3, 0.4])]) # for new location for i in range(22): side_effect.append([np.array([300, 400])]) # for velocity mock_uniform_sphere_points.side_effect = side_effect mock_random_rand.return_value = np.array([0.22, 0.33]) my_swarm.increment() self.assertEqual(my_swarm.number_of_particles, 2) self.assertEqual(my_swarm.shifted_loc, 1) np.testing.assert_array_almost_equal( my_swarm.new_location, np.array([0.1 + 0.3 * 0.5 / 2.0, 0.2 + 0.4 * 0.5 / 2.0])) np.testing.assert_array_almost_equal( my_swarm.velocities[1, :], np.array([0.22 * 2.0 - 1, 0.33 * 2.0 - 1]))
def test_merge_swarm_fitter_midpoint_midpoint_greater_swarm2_greater_swarm1(self): """Test merges when midpoint is greater than swarm 1 and which greater than swarm 2""" # Using our inverse fitness function # Swarm 1 [-0.4, -0.4] fitness = -0.32 # Swarm 2 [0.3, 0.3] fitness = -0.18 # midpoint will be: [-0.05,-0.05] fitness = -0.005 # To make the midpoint greater than the values of the swarms easier to use the inverse fitness problem = swarm_tests.BasicProblem(inverse=True) my_nmmso = nmmso.Nmmso(problem, 10, 100, tol_val=0.1) my_nmmso.swarms = set() s1 = swarm.Swarm(1, 10, problem) s2 = swarm.Swarm(2, 10, problem) s1.mode_location = np.array([0.30, 0.30]) s1.mode_value = -1 * (0.3 * 0.3 + 0.30 * 0.30) # Don't really care about these values - just need to get them back in merged swarm swarm_tests.SwarmTests.add_particle_to_swarm(s1, 0, [-1.1, 1.2], 10.0, [-1.3, -1.4], 11.0, [-1.5, 1.6]) swarm_tests.SwarmTests.add_particle_to_swarm(s1, 1, [-2.1, 2.2], 20.0, [-2.3, -2.4], 21.0, [-2.5, 2.6]) s2.mode_location = np.array([-0.40, -0.40]) s2.mode_value = -1.0 * (0.4*0.4 + 0.4*0.4) swarm_tests.SwarmTests.add_particle_to_swarm(s2, 0, [3.1, 3.2], 30.0, [3.3, 3.4], 31.0, [3.5, 3.6]) swarm_tests.SwarmTests.add_particle_to_swarm(s2, 1, [4.1, 4.2], 40.0, [4.3, 4.4], 41.0, [4.5, 4.6]) swarm_tests.SwarmTests.add_particle_to_swarm(s2, 2, [5.1, 5.2], 50.0, [5.3, 5.4], 51.0, [5.5, 5.6]) my_nmmso.swarms.add(s1) my_nmmso.swarms.add(s2) my_nmmso._merge_swarms() self.assertEqual(len(my_nmmso.swarms), 1) # That active mode should have 5 particles s = next(iter(my_nmmso.swarms)) # Just getting hold of the item in the set self.assertEqual(s.number_of_particles, 5) # midpoint now swarm location midpoint = np.array([(0.3 - -0.4) / 2 + -0.4, (0.3 - -0.4) / 2 + -0.4]) np.testing.assert_array_almost_equal(s.mode_location, midpoint) self.assertAlmostEqual(s.mode_value, -sum(pow(midpoint, 2)))
def test_hive_when_midpoint_is_maximum(self, mock_randrange): problem = swarm_tests.BasicProblem(inverse=True) s1 = swarm.Swarm(1, 4, problem) s2 = swarm.Swarm(2, 4, problem) s2.number_of_particles = 3 # fewer than max swarm size s1.number_of_particles = 4 s1.history_locations[0, :] = np.array([0.01, 0.02]) s1.history_locations[1, :] = np.array([0.11, 0.12]) s1.history_locations[2, :] = np.array([0.21, 0.22]) s1.history_locations[3, :] = np.array([0.31, 0.32]) for i in range(4): s1.history_values[i] = -sum(np.power(s1.history_locations[i, :], 2)) s1.mode_location = np.array([-0.4, -0.4]) s1.mode_value = -sum(np.power(s1.mode_location, 2)) my_nmmso = nmmso.Nmmso(problem, 4, tol_val=0.2, max_evol=10) my_nmmso.swarms = set() my_nmmso._add_swarm(s1) my_nmmso._add_swarm(s2) mock_randrange.return_value = 3 number_of_new_samples = my_nmmso._hive() self.assertEqual(number_of_new_samples, 1) original_swarm = NmmsoTests.get_swarm_by_id(my_nmmso, 1) # Should have stored the mid point as the now mode location and value, no other changes self.assertEqual(len(my_nmmso.swarms), 2) mid_loc_x = 0.5*(-0.4-0.31)+0.31 mid_loc_y = 0.5*(-0.4-0.32)+0.32 mid_loc = np.array([mid_loc_x, mid_loc_y]) mid_loc_val = -sum(np.power(mid_loc, 2)) np.testing.assert_allclose(original_swarm.mode_location, mid_loc) self.assertAlmostEqual(original_swarm.mode_value, mid_loc_val) np.testing.assert_allclose(original_swarm.history_locations[0, :], np.array([0.01, 0.02]))
def test_merge_swarm_fitter_midpoint_swarm1_greater_midpoint_greater_swarm2(self): """Test merges when midpoint is greater than swarm 1 and which greater than swarm 2""" # Swarm 2 [0.1, 0.1] fitness = 0.02 # Swarm 1 [0.4, 0.4] fitness = 0.32 # midpoint will be: [0.25,0.25] fitness = 0.125 problem = swarm_tests.BasicProblem() my_nmmso = nmmso.Nmmso(problem, 10, 100, tol_val=0.1) my_nmmso.swarms = set() s1 = swarm.Swarm(1, 10, problem) s2 = swarm.Swarm(2, 10, problem) s1.mode_location = np.array([0.40, 0.40]) s1.mode_value = 0.4 * 0.4 + 0.4 * 0.4 swarm_tests.SwarmTests.add_particle_to_swarm(s1, 0, [3.1, 3.2], 30.0, [3.3, 3.4], 31.0, [3.5, 3.6]) swarm_tests.SwarmTests.add_particle_to_swarm(s1, 1, [4.1, 4.2], 40.0, [4.3, 4.4], 41.0, [4.5, 4.6]) swarm_tests.SwarmTests.add_particle_to_swarm(s1, 2, [5.1, 5.2], 50.0, [5.3, 5.4], 51.0, [5.5, 5.6]) s2.mode_location = np.array([0.1, 0.1]) s2.mode_value = 0.1 * 0.1 + 0.1 * 0.1 # Don't really care about these values - just need to get them back in merged swarm swarm_tests.SwarmTests.add_particle_to_swarm(s2, 0, [-1.1, 1.2], 10.0, [-1.3, -1.4], 11.0, [-1.5, 1.6]) swarm_tests.SwarmTests.add_particle_to_swarm(s2, 1, [-2.1, 2.2], 20.0, [-2.3, -2.4], 21.0, [-2.5, 2.6]) my_nmmso.swarms.add(s1) my_nmmso.swarms.add(s2) my_nmmso._merge_swarms() self.assertEqual(len(my_nmmso.swarms), 1) # That active mode should have 5 particles s = next(iter(my_nmmso.swarms)) # Just getting hold of the item in the set self.assertEqual(s.number_of_particles, 5) # swarm 1 does not move loc = np.array([0.4, 0.4]) np.testing.assert_array_almost_equal(s.mode_location, loc) self.assertAlmostEqual(s.mode_value, sum(pow(loc, 2)))
def test_set_initial_location(self): """Tests that the initial location is inside the range when the range does not include zero.""" my_swarm = swarm.Swarm(1, 4, BasicProblemWithRangeExcludingZero()) # ensure the new location is always in bounds for i in range(1000): my_swarm.set_initial_location() if sum(my_swarm.new_location < [2, 2]) + sum( my_swarm.new_location > [4, 4]) > 0: self.fail("Initial location was out of bounds")
def test_merge_swarms_two_swarms_do_not_merge(self): problem = swarm_tests.BasicProblem() my_nmmso = nmmso.Nmmso(problem, 10, 100, tol_val=0.2) my_nmmso.swarms = set() s1 = swarm.Swarm(1, 10, problem) # give swarm 1 2 particles s1.mode_location = np.array([0.50, 0.60]) swarm_tests.SwarmTests.add_particle_to_swarm(s1, 0, [1.1, 1.2], 10.0, [1.3, 1.4], 11.0, [1.5, 1.6]) swarm_tests.SwarmTests.add_particle_to_swarm(s1, 1, [2.1, 2.2], 20.0, [2.3, 2.4], 21.0, [2.5, 2.6]) my_nmmso.swarms.add(s1) # there's only 1 swarm, so merging shouldn't do anything my_nmmso._merge_swarms() self.assertEqual(len(my_nmmso.swarms), 1) # there should still be only 1 swarm self.assertEqual(s1.number_of_particles, 2) # nothing should have changed.... # now generate a new swarm s2 = swarm.Swarm(2, 10, problem) # give swarm 2 3 particles s2.mode_location = np.array([0.51, 0.61]) swarm_tests.SwarmTests.add_particle_to_swarm(s2, 0, [3.1, 3.2], 30.0, [3.3, 3.4], 31.0, [3.5, 3.6]) swarm_tests.SwarmTests.add_particle_to_swarm(s2, 1, [4.1, 4.2], 40.0, [4.3, 4.4], 41.0, [4.5, 4.6]) swarm_tests.SwarmTests.add_particle_to_swarm(s2, 2, [5.1, 5.2], 50.0, [5.3, 5.4], 51.0, [5.5, 5.6]) my_nmmso.swarms.add(s2) # If neither swarm has changed, they shouldn't merge s1.changed = False s2.changed = False my_nmmso._merge_swarms() self.assertEqual(len(my_nmmso.swarms), 2) # there should still be 2 swarms self.assertEqual(s1.number_of_particles, 2) # nothing should have changed.... self.assertEqual(s2.number_of_particles, 3) # nothing should have changed....
def test_evolve_with_high_number_of_swarms_and_choose_to_select_fittest(self, random_rand_mock, random_random_mock): problem = swarm_tests.BasicProblem() my_nmmso = nmmso.Nmmso(problem, 10, tol_val=0.2, max_evol=2) my_nmmso.swarms = set() s1 = swarm.Swarm(1, 10, problem) s2 = swarm.Swarm(2, 10, problem) s3 = swarm.Swarm(3, 10, problem) s1.mode_location = np.array([0.01, 0.11]) s1.mode_value = 10.0 s2.mode_location = np.array([0.02, 0.12]) s2.mode_value = 0.0 s3.mode_location = np.array([0.03, 0.13]) s3.mode_value = 20.0 my_nmmso._add_swarm(s1) my_nmmso._add_swarm(s2) my_nmmso._add_swarm(s3) # Mock call to random.random to specify that the option of choosing the fittest is to be used random_random_mock.return_value = 0.2 # Because max_evol is set to 3 and swarms 1 and 3 are the fittest they should always be the two selected # so no need to mock the random selection - the code has to choose 2 from 2. # Mock call in Swarm.UNI to select to crossover 2nd element but not first random_rand_mock.return_value = np.array([0.1, 0.6]) my_nmmso._evolve() self.assertEqual(len(my_nmmso.swarms), 4) new_swarm = NmmsoTests.get_swarm_by_id(my_nmmso, 4) # The crossover could happen either way round so there are two options for the new location self.assertTrue( np.allclose(new_swarm.new_location, np.array([0.01, 0.13])) or np.allclose(new_swarm.new_location, np.array([0.03, 0.11])))
def test_hive_when_midpoint_not_valley(self, mock_randrange): problem = swarm_tests.BasicProblem() s1 = swarm.Swarm(1, 4, problem) s2 = swarm.Swarm(2, 4, problem) s2.number_of_particles = 3 # fewer than max swarm size s1.number_of_particles = 4 s1.history_locations[0, :] = np.array([0.01, 0.02]) s1.history_locations[1, :] = np.array([0.11, 0.12]) s1.history_locations[2, :] = np.array([0.21, 0.22]) s1.history_locations[3, :] = np.array([0.31, 0.32]) for i in range(4): s1.history_values[i] = sum(np.power(s1.history_locations[i, :], 2)) s1.mode_location = np.array([-0.4, -0.4]) s1.mode_value = sum(np.power(s1.mode_location, 2)) my_nmmso = nmmso.Nmmso(problem, 4, tol_val=0.2, max_evol=10) my_nmmso.swarms = set() my_nmmso._add_swarm(s1) my_nmmso._add_swarm(s2) mock_randrange.return_value = 0 number_of_new_samples = my_nmmso._hive() self.assertEqual(number_of_new_samples, 1) original_swarm = NmmsoTests.get_swarm_by_id(my_nmmso, 1) # Nothing should have changed self.assertEqual(len(my_nmmso.swarms), 2) np.testing.assert_allclose(original_swarm.mode_location, np.array([-0.4, -0.4])) np.testing.assert_allclose(original_swarm.history_locations[0, :], np.array([0.01, 0.02]))
def test_initialise_new_swarm_velocities_without_rejection( self, mock_uniform_sphere_points): """Tests initialise_new_swarm function where the uniform sphere approach works.""" mock_uniform_sphere_points.return_value = [np.array([0.5, 0.6])] s = swarm.Swarm(1, 10, BasicProblem()) s.mode_location = np.array([0.01, -0.02]) s.dist = 0.5 s.initialise_new_swarm_velocities() np.testing.assert_array_almost_equal(s.velocities[0, :], np.array([0.135, 0.13]))
def test_initialise_new_swarm_velocities_with_rejection( self, mock_uniform_sphere_points, mock_random_rand): """Tests initialise_new_swarm code to ensure the rejections occur and the second approach is used.""" mock_random_rand.return_value = np.array([0.9, 0.2]) mock_uniform_sphere_points.return_value = np.array([0.5, 0.6]) s = swarm.Swarm(1, 10, BasicProblem()) s.mode_location = np.array([0.01, -0.02]) s.dist = 10.0 s.initialise_new_swarm_velocities() np.testing.assert_array_almost_equal(s.velocities[0, :], np.array([0.8, -0.6]))
def test_merge_that_requires_combining(self): """Tests the merge function when not all particles can be kept.""" """Test the merge function when both swarms' particles can be kept.""" s1 = swarm.Swarm(1, 3, BasicProblem()) s2 = swarm.Swarm(2, 3, BasicProblem()) # give swarm 1 2 particles SwarmTests.add_particle_to_swarm(s1, 0, [1.1, 1.2], 10.0, [1.3, 1.4], 11.0, [1.5, 1.6]) SwarmTests.add_particle_to_swarm(s1, 1, [3.1, 3.2], 30.0, [3.3, 3.4], 31.0, [3.5, 3.6]) # give swarm 2 3 particles SwarmTests.add_particle_to_swarm(s2, 0, [5.1, 5.2], 50.0, [5.3, 5.4], 51.0, [5.5, 5.6]) SwarmTests.add_particle_to_swarm(s2, 1, [4.1, 4.2], 40.0, [4.3, 4.4], 41.0, [4.5, 4.6]) SwarmTests.add_particle_to_swarm(s2, 2, [2.1, 2.2], 20.0, [2.3, 2.4], 21.0, [2.5, 2.6]) # merge s1.merge(s2) # result should have 5 particles self.assertEqual(s1.number_of_particles, 3) for i in range(3): ii = i + 2 np.testing.assert_array_almost_equal( s1.history_locations[i, :], np.array([ii + 1.1, ii + 1.2])) self.assertAlmostEqual(s1.history_values[i], (ii + 1) * 10.0) np.testing.assert_array_almost_equal( s1.pbest_locations[i, :], np.array([ii + 1.3, ii + 1.4])) self.assertAlmostEqual(s1.pbest_values[i], (ii + 1) * 10.0 + 1.0) np.testing.assert_array_almost_equal( s1.velocities[i, :], np.array([ii + 1.5, ii + 1.6]))
def test_increment_when_move_an_existing_particle_and_locations_rejected( self, mock_random_range, mock_random_rand): """Tests increment method when a existing particle is moved and locations are rejected""" my_swarm = swarm.Swarm(1, 4, BasicProblem()) mode_loc = np.array([0.1, 0.2]) hist_loc = np.array([0.3, 0.4]) pbest_loc = np.array([0.22, 0.23]) vel = np.array([0.01, 0.02]) my_swarm.dist = 0.5 my_swarm.number_of_particles = 4 my_swarm.mode_location = mode_loc my_swarm.history_locations[2, :] = hist_loc my_swarm.pbest_locations[2, :] = pbest_loc my_swarm.velocities[2, :] = vel r1 = np.array([300, 0.04]) r2 = np.array([0.01, -200]) side_effect = [] for x in range(22): side_effect.append(r1) side_effect.append(r2) side_effect.append(np.array([0.25])) side_effect.append(np.array([0.50])) # We mock the choice of which particle to move mock_random_range.return_value = 2 # Mock the two calls to np.random.rand mock_random_rand.side_effect = side_effect my_swarm.increment() self.assertEqual(my_swarm.number_of_particles, 4) self.assertEqual(my_swarm.shifted_loc, 2) temp_vel = np.array([0.5 * (0.3 - (-1.0)), 0.25 * (1.0 - 0.4)]) new_loc = hist_loc + temp_vel np.testing.assert_array_almost_equal(my_swarm.new_location, new_loc) np.testing.assert_array_almost_equal(my_swarm.velocities[2, :], temp_vel)
def test_evaluate_first(self): """Tests evaluate_first""" s = swarm.Swarm(1, 10, BasicProblem()) new_location = np.array([0.4, 0.4]) y = 0.4 * 0.4 * 2 s.new_location = new_location s.evaluate_first() self.assertAlmostEqual(s.mode_value, y) np.testing.assert_array_almost_equal(s.mode_location, new_location) np.testing.assert_array_almost_equal(s.history_locations[0, :], new_location) self.assertAlmostEqual(s.history_values[0], y) np.testing.assert_array_almost_equal(s.pbest_locations[0, :], new_location) self.assertAlmostEqual(s.pbest_values[0], y)
def test_increment_when_move_an_existing_particle(self, mock_random_range, mock_random_rand): """Tests increment method when a existing particle is moved""" my_swarm = swarm.Swarm(1, 4, BasicProblem()) mode_loc = np.array([0.1, 0.2]) hist_loc = np.array([0.3, 0.4]) pbest_loc = np.array([0.22, 0.23]) vel = np.array([0.01, 0.02]) my_swarm.dist = 0.5 my_swarm.number_of_particles = 4 my_swarm.mode_location = mode_loc my_swarm.history_locations[2, :] = hist_loc my_swarm.pbest_locations[2, :] = pbest_loc my_swarm.velocities[2, :] = vel r1 = np.array([0.03, 0.04]) r2 = np.array([0.01, 0.02]) # We mock the choice of which particle to move mock_random_range.return_value = 2 # Mock the two calls to np.random.rand mock_random_rand.side_effect = [r1, r2] my_swarm.increment() self.assertEqual(my_swarm.number_of_particles, 4) self.assertEqual(my_swarm.shifted_loc, 2) temp_vel = 0.1 * vel + 2.0 * r1 * (mode_loc - hist_loc) + 2.0 * r2 * ( pbest_loc - hist_loc) new_loc = hist_loc + temp_vel np.testing.assert_array_almost_equal(my_swarm.new_location, new_loc) np.testing.assert_array_almost_equal(my_swarm.velocities[2, :], temp_vel)
def test_increment_when_add_new_particle(self, mock_uniform_sphere_points): """Tests increment method when a new particle is added.""" my_swarm = swarm.Swarm(1, 10, BasicProblem()) my_swarm.dist = 0.5 my_swarm.number_of_particles = 1 my_swarm.mode_location = np.array([0.1, 0.2]) # We mock two calls to uniform sphere points, first to compute the new location, then to compute # the velocity mock_uniform_sphere_points.side_effect = [[np.array([0.3, 0.4])], [np.array([0.2, 0.1])]] my_swarm.increment() self.assertEqual(my_swarm.number_of_particles, 2) self.assertEqual(my_swarm.shifted_loc, 1) np.testing.assert_array_almost_equal( my_swarm.new_location, np.array([0.1 + 0.3 * 0.5 / 2.0, 0.2 + 0.4 * 0.5 / 2.0])) np.testing.assert_array_almost_equal( my_swarm.velocities[1, :], np.array([0.1 + 0.2 * 0.5 / 2.0, 0.2 + 0.1 * 0.5 / 2.0]))
def test_evaluate_new_locations(self): """Test for evaluate_new_locations""" problem = swarm_tests.BasicProblem() my_nmmso = nmmso.Nmmso(problem, 10, tol_val=0.2, max_evol=10) my_nmmso.swarms = set() # Create 4 swarms - 1 and 2 will have a new location whose value is better than the current best, # for swarms 3 and 4 this is not the case. We will give the subset of only swarms 1 and 2 to # the evaluate_new_locations function. This swarm 1 should be shifted by one of the other three # should be. s1 = swarm.Swarm(1, 10, problem) s2 = swarm.Swarm(2, 10, problem) s3 = swarm.Swarm(3, 10, problem) s4 = swarm.Swarm(4, 10, problem) s1.mode_location = np.array([0.01, 0.11]) s1.new_location = np.array([0.50, 0.60]) # this is a location with a better value s1.mode_value = sum(s1.mode_location*s1.mode_location) s1.shifted_loc = 0 s2.mode_location = np.array([0.02, 0.12]) s2.new_location = np.array([0.01, 0.11]) # this is a location with a worse value s2.mode_value = sum(s2.mode_location*s2.mode_location) s2.shifted_loc = 0 s3.mode_location = np.array([0.03, 0.13]) s3.new_location = np.array([0.4, 0.6]) # this is a location with a better value s3.mode_value = sum(s3.mode_location*s3.mode_location) s3.shifted_loc = 0 s4.mode_location = np.array([0.04, 0.14]) s4.new_location = np.array([0.01, 0.01]) # this is a location with a worse value s4.mode_value = sum(s4.mode_location*s4.mode_location) s4.shifted_loc = 0 my_nmmso._add_swarm(s1) my_nmmso._add_swarm(s2) my_nmmso._add_swarm(s3) my_nmmso._add_swarm(s4) number_of_new_locations = my_nmmso._evaluate_new_locations(set([s1, s2])) # Test the changed flag self.assertEqual(s1.changed, True) self.assertEqual(s2.changed, False) self.assertEqual(s3.changed, False) self.assertEqual(s4.changed, False) # Test that locations have been updated where appropriate np.testing.assert_allclose(s1.mode_location, np.array([0.50, 0.60])) # only that that should have been updated np.testing.assert_allclose(s2.mode_location, np.array([0.02, 0.12])) np.testing.assert_allclose(s3.mode_location, np.array([0.03, 0.13])) np.testing.assert_allclose(s4.mode_location, np.array([0.04, 0.14])) # Check the mode values are correct self.assertEqual(s1.mode_value, sum(s1.mode_location * s1.mode_location)) self.assertEqual(s2.mode_value, sum(s2.mode_location * s2.mode_location)) self.assertEqual(s3.mode_value, sum(s3.mode_location * s3.mode_location)) self.assertEqual(s4.mode_value, sum(s4.mode_location * s4.mode_location)) self.assertEqual(number_of_new_locations, 2) # 2 swarms were in the evaluate call
def test_hive_when_midpoint_in_valley_velocity_rejected(self, mock_randrange, mock_usp, mock_random_random): seed_particle_location = np.array([0.31, 0.32]) seed_particle_value = sum(np.power(seed_particle_location, 2)) problem = swarm_tests.BasicProblem() s1 = swarm.Swarm(1, 4, problem) s2 = swarm.Swarm(2, 4, problem) s2.number_of_particles = 3 # fewer than max swarm size s1.number_of_particles = 4 s1.history_locations[0, :] = np.array([0.01, 0.02]) s1.history_locations[1, :] = np.array([0.11, 0.12]) s1.history_locations[2, :] = np.array([0.21, 0.22]) s1.history_locations[3, :] = seed_particle_location for i in range(4): s1.history_values[i] = sum(np.power(s1.history_locations[i, :], 2)) s1.mode_location = np.array([-0.4, -0.4]) s1.mode_value = sum(np.power(s1.mode_location, 2)) my_nmmso = nmmso.Nmmso(problem, 4, tol_val=0.2, max_evol=10) my_nmmso.swarms = set() my_nmmso._add_swarm(s1) my_nmmso._add_swarm(s2) mock_randrange.return_value = 3 mock_usp.return_value = [np.array([20, 20])] # huge numbers so will be out of bounds and rejected mock_random_random.return_value = np.array([0.33, 0.44]) number_of_new_samples = my_nmmso._hive() self.assertEqual(len(my_nmmso.swarms), 3) new_swarm = NmmsoTests.get_swarm_by_id(my_nmmso, 3) np.testing.assert_allclose(new_swarm.mode_location, seed_particle_location) self.assertAlmostEqual(new_swarm.mode_value, seed_particle_value) self.assertEqual(new_swarm.number_of_particles, 1) np.testing.assert_allclose(new_swarm.history_locations[0, :], seed_particle_location) np.testing.assert_allclose(new_swarm.pbest_locations[0, :], seed_particle_location) self.assertAlmostEqual(new_swarm.pbest_values[0], seed_particle_value) self.assertAlmostEqual(new_swarm.history_values[0], seed_particle_value) self.assertEqual(new_swarm.changed, True) self.assertEqual(new_swarm.converged, False) self.assertEqual(number_of_new_samples, 1) original_swarm = NmmsoTests.get_swarm_by_id(my_nmmso, 1) mid_loc_x = 0.5*(-0.4-0.31)+0.31 mid_loc_y = 0.5*(-0.4-0.32)+0.32 mid_loc = np.array([mid_loc_x, mid_loc_y]) mid_loc_val = sum(np.power(mid_loc, 2)) np.testing.assert_allclose(original_swarm.history_locations[3, :], mid_loc) self.assertAlmostEqual(original_swarm.history_values[3], mid_loc_val) np.testing.assert_allclose(original_swarm.pbest_locations[3, :], mid_loc) self.assertAlmostEqual(original_swarm.pbest_values[3], mid_loc_val) # d = math.sqrt(sum(np.power(s1.mode_location-seed_particle_location, 2))) vel_x = 0.33 * 2 - 1 vel_y = 0.44 * 2 - 1 vel = np.array([vel_x, vel_y]) np.testing.assert_allclose(original_swarm.velocities[3, :], vel)
def _new_swarm(self): return s.Swarm(self.next_swarm_id, self.swarm_size, self.problem, self.listener)