def test_update_array_multiple_utilities(self): array = np.array([[0, 0, 0], [0, 1, 1], [1, 2, 2]]) utilities = [create_flat_utility(0.25), create_flat_utility(0.75)] utility = get_utility_for_array(utilities, array, True) result = SimulationResult() #dummy result output = update_array(array, utility, result, _first_picker, _first_picker, False, ['entropy_average']) expected_output = np.array([[1, 0, 0], [0, 1, 0], [1, 2, 2]]) self.assertTrue(np.array_equal(array, expected_output))
def test_update_array_roulette_vacancy_picker_01(self): array = np.array([[0, 0, 0], [0, 1, 1], [1, 2, 2]]) utility = get_utility_for_array(create_flat_utility(0.5), array, True) states_for_picked = [ (0.1, np.array([[0, 0, 2], [0, 1, 1], [1, 0, 2]])), (0.2, np.array([[2, 0, 0], [0, 1, 1], [1, 0, 2]])), (1.2, np.array([[2, 0, 0], [0, 1, 1], [1, 0, 2]])), (2.3, np.array([[0, 2, 0], [0, 1, 1], [1, 0, 2]])), (3.4, np.array([[0, 0, 0], [2, 1, 1], [1, 0, 2]])), (3.5, np.array([[0, 0, 0], [2, 1, 1], [1, 0, 2]])), ] result = SimulationResult() for picked_value, expected_state in states_for_picked: array = np.array([[0, 0, 0], [0, 1, 1], [1, 2, 2]]) vacancy_picker = _create_roulette_picker(0.1, utility, False, lambda *a: picked_value) agent_picker = _create_roulette_picker(0.0, utility, True, lambda *a: 0.0) update_array(array, utility, result, agent_picker, vacancy_picker, True, ['entropy_average'], True) with self.subTest(v=picked_value, out=array, exp=expected_state): self.assertTrue(np.array_equal(array, expected_state))
def test_run_simulation_vacancies_counted(self): iteration_states = [ np.array([ [0, 0, 0, 0], [0, 0, 0, 0], [1, 1, 1, 1], [2, 2, 2, 2], ]), np.array([ [2, 0, 0, 0], [0, 0, 0, 0], [1, 1, 1, 1], [0, 2, 2, 2], ]), np.array([ [2, 2, 0, 0], [0, 0, 0, 0], [1, 1, 1, 1], [0, 0, 2, 2], ]), np.array([ [2, 2, 2, 0], [0, 0, 0, 0], [1, 1, 1, 1], [0, 0, 0, 2], ]), np.array([ [2, 2, 2, 2], [0, 0, 0, 0], [1, 1, 1, 1], [0, 0, 0, 0], ]), None ] # simulation halted, should not fail at none def callback(array, result, iteration): expected_output = iteration_states[iteration] with self.subTest(i=iteration, out=array, expected=expected_output): self.assertTrue(np.array_equal(array, expected_output)) settings = SimulationSettings( grid_size=4, vacancy_proportion=0.5, agent_proportions=(0.5, 0.5), initial_random_allocation=False, utility_function=create_flat_utility(0.5), satisficers=False, agent_picking_regime='first', vacancy_picking_regime='first', count_vacancies=True, radius=1, iterations=len(iteration_states), save_period=1) result = run_simulation(settings, callback) clusters = [2, 3, 3, 3, 2] with self.subTest(): self.assertEqual(result.get_measures()['clusters'], clusters)
def test_get_unsatisfied_agent_indices_satisficers(self): parameters = [ (ut.create_flat_utility(0.5), [0, 1, 2, 3, 4, 5, 6, 7, 8]), (ut.create_peaked_utility(0.5), [0, 1, 2, 3, 4, 5, 6, 7, 8]), (ut.create_spiked_utility(0.5), [0, 1, 2, 3, 4, 5, 6, 7, 8]), ] self.check_get_unsatisfied_agent_indices_expected_output( parameters, True)
def test_simulation_random_vacancy_picker(self): # array = [ # np.array([ # [0, 0, 0, 0], # [1, 1, 1, 1], # [1, 1, 1, 1], # [1, 1, 2, 2] # ]), # ] possible_states = [ np.array([[1, 0, 0, 0], [1, 1, 1, 1], [1, 1, 0, 1], [1, 1, 2, 2]]), np.array([[0, 1, 0, 0], [1, 1, 1, 1], [1, 1, 0, 1], [1, 1, 2, 2]]), np.array([[0, 0, 1, 0], [1, 1, 1, 1], [1, 1, 0, 1], [1, 1, 2, 2]]), np.array([[0, 0, 0, 1], [1, 1, 1, 1], [1, 1, 0, 1], [1, 1, 2, 2]]), ] possible_states_reached = set() def callback(array, result, iteration): if iteration == 1: with self.subTest(out=np.copy(array)): is_possible_state = False for i, state in enumerate(possible_states): if np.array_equal(array, state): is_possible_state = True possible_states_reached.add(i) break self.assertTrue(is_possible_state) settings = SimulationSettings(grid_size=4, vacancy_proportion=0.25, agent_proportions=(10 / 12, 2 / 12), initial_random_allocation=False, utility_function=create_flat_utility(1 / 8), satisficers=False, agent_picking_regime='first', vacancy_picking_regime='random', radius=1, iterations=2, save_period=1) # Assume all states should be reached in 30 tries for i in range(30): run_simulation(settings, callback) with self.subTest(): self.assertEqual(len(possible_states_reached), len(possible_states))
def test_update_array_no_better_vacancies_first_picker(self): no_better_vacancies_array = np.array([[0, 2, 0, 0], [1, 1, 1, 1], [1, 1, 1, 1], [0, 2, 0, 2]]) result = SimulationResult() expected_output = True utility = get_utility_for_array(create_flat_utility(0.5), no_better_vacancies_array) output = update_array(no_better_vacancies_array, utility, result, _first_picker, _first_picker, False, ['entropy_average']) self.assertEqual(output, expected_output)
def test_update_array_all_agents_satisfied_should_end_simulation(self): all_satisfied_array = np.array([[0, 0, 0, 0], [1, 1, 1, 1], [1, 1, 1, 1], [0, 0, 0, 0]]) result = SimulationResult() expected_output = True utility = get_utility_for_array(create_flat_utility(0.5), all_satisfied_array) output = update_array(all_satisfied_array, utility, result, _first_picker, _first_picker, False, ['entropy_average']) self.assertEqual(output, expected_output)
def test_flat_utility(self): # step threshold, exepcted output for 0.0 - 1.0, step 0.1 test_data = [ (0.0, [1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]), (0.25, [1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]), (0.5, [1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0]), (0.75, [1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0]), (1.0, [1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0]), ] for threshold, exepcted_output_list in test_data: flat_utility = create_flat_utility(threshold) self.check_expected_output_for_range_0_1('flat_' + str(threshold), flat_utility, exepcted_output_list)
def test_satisfied_percent(self): test_arrays = [(np.array([[0, 1, 1, 0], [1, 1, 0, 1], [0, 2, 2, 0], [0, 1, 2, 0]]), 8 * 100 / 9), (np.array([[0, 1, 2, 0], [1, 2, 2, 1], [1, 2, 2, 0], [1, 1, 1, 0]]), 9 * 100 / 12), (np.array([[1, 1, 1, 0], [1, 1, 0, 2], [0, 1, 2, 2], [0, 1, 2, 2]]), 100)] utility_function = create_flat_utility(0.5) for array, exepcted_output in test_arrays: ut = get_utility_for_array(utility_function, array, True) agent_indices = get_agent_indices(array) sp = satisfied_percent(ut, agent_indices) with self.subTest(): self.assertEqual(sp, exepcted_output)
def test_simulation_satisficers(self): iteration_states = [ np.array([ [0, 0, 0, 0], [0, 0, 0, 0], [1, 1, 1, 1], [1, 1, 1, 1], ]), ] + ([ np.array([ [1, 0, 0, 0], [0, 0, 0, 0], [0, 1, 1, 1], [1, 1, 1, 1], ]), np.array([ [0, 1, 0, 0], [0, 0, 0, 0], [0, 1, 1, 1], [1, 1, 1, 1], ]), ] * 100) # oscillates forever def callback(array, result, iteration): expected_output = iteration_states[iteration] with self.subTest(i=iteration, out=array, expected=expected_output): self.assertTrue(np.array_equal(array, expected_output)) settings = SimulationSettings( grid_size=4, vacancy_proportion=0.5, agent_proportions=(1.0, ), initial_random_allocation=False, utility_function=create_flat_utility(0.5), satisficers=True, agent_picking_regime='first', vacancy_picking_regime='first', radius=1, iterations=len(iteration_states), save_period=1) result = run_simulation(settings, callback) clusters = [1] + ([2, 2] * 100) with self.subTest(): self.assertEqual(result.get_measures()['clusters'], clusters)
def test_value_error_outside_0_1(self): functions = { 'flat': create_flat_utility(0.5), 'peaked': create_peaked_utility(0.5), 'peaked_cutoff': create_peaked_utility(0.5, True), 'spiked': create_spiked_utility(0.5), 'create_flat': create_flat_utility, 'create_peaked': create_peaked_utility, 'create_spiked': create_spiked_utility, } error_inputs = [-10, -1, -0.1, -0.00001, 1.00001, 1.1, 2, 10] for name, function in functions.items(): for error_input in error_inputs: with self.subTest(name=name, input=error_input): with self.assertRaises(ValueError): function(error_input)
def check_better_vacancy_expected_output(self, parameters, satisficers): utility = get_utility_for_array(create_flat_utility(0.5), self.test_array) agent_indices = get_agent_indices(self.test_array) vacancy_indices = get_vacancy_indices(self.test_array) for unsatisfied_agent_index, expected_output_indices in parameters: expected_output = vacancy_indices[expected_output_indices] i = agent_indices[unsatisfied_agent_index] output = _get_better_vacancies(self.test_array, i, utility, vacancy_indices, satisficers=satisficers) with self.subTest(i=unsatisfied_agent_index, out=output, expected=expected_output): self.assertTrue(np.array_equal(output, expected_output))
def test_simulation_halted(self): all_satisfied_array = np.array([ [0, 0, 0, 0], [0, 0, 0, 0], [1, 1, 1, 1], [1, 1, 1, 1], ]) callback_count = [0] expected_callback_count = 1 def callback(array, result, iteration): expected_output = all_satisfied_array with self.subTest(): self.assertTrue(np.array_equal(array, expected_output)) callback_count[0] += 1 settings = SimulationSettings( grid_size=4, vacancy_proportion=0.5, agent_proportions=(1.0, ), initial_random_allocation=False, utility_function=create_flat_utility(0.5), satisficers=False, agent_picking_regime='first', vacancy_picking_regime='first', radius=1, iterations=100, save_period=1) result = run_simulation(settings, callback) clusters = [1] with self.subTest(): self.assertEqual(result.get_measures()['clusters'], clusters) with self.subTest(): self.assertEqual(callback_count[0], expected_callback_count)
def start_simulation(): global images images = [] global simulation_result simulation_result = [] settings = SimulationSettings( grid_size=int(app.getSpinBox("Grid size")), vacancy_proportion=float(app.getSpinBox("Vacancy proportion")), agent_proportions=(0.5, 0.5), utility_function=create_flat_utility( float(app.getSpinBox("Agent tolerance"))), count_vacancies=True, iterations=int(app.getSpinBox("Iterations")), segregation_measure_names=['entropy_average', 'clusters', 'unlike_neighbor_fraction_average'], save_period=1 ) schelling.simulation.run_simulation(settings, gui_callback) print("done") global running running = False
if __name__ == '__main__': # pragma: no cover """ This will run the Schelling Model simulation for 10000 iterations. Every 100 iterations the state will be printed to console and the array will be saved as an image. The simulation result, containing segregation measures for each iteration will be saved as JSON and a plot will be shown. """ from schelling.simulation import run_simulation, get_save_state_callback from schelling.utility_functions import create_flat_utility from schelling.arr_to_img import image_save, to_image from schelling.simulation_settings import SimulationSettings import os settings = SimulationSettings( grid_size=40, vacancy_proportion=0.2, agent_proportions=(0.5, 0.5), utility_function=create_flat_utility(5/8), iterations=10000, save_period=100 ) # assuming ./image/ directory exists save_callback = get_save_state_callback('./image/', settings.iterations, verbose=True) simulation_result = run_simulation(settings, callback=save_callback) simulation_result.save_JSON('result.json') simulation_result.plot_measures()