def test_pick_agent_index_to_move(self):
        agent_indices = get_agent_indices(self.test_array)
        unsatisfied_agent_index_indices = [0, 1, 2, 3, 5, 6, 7, 8]
        unsatisfied_agent_indices = \
         agent_indices[unsatisfied_agent_index_indices]

        expected_agent_index = _first_picker(unsatisfied_agent_indices)

        agent_index = _pick_agent_index_to_move(unsatisfied_agent_indices,
                                                _first_picker)

        with self.subTest(out=agent_index, expected=expected_agent_index):
            self.assertEqual(expected_agent_index, agent_index)
    def check_get_unsatisfied_agent_indices_expected_output(
            self, parameters, satisficers):
        agent_indices = get_agent_indices(self.test_array)

        for utility_function, expected_output in parameters:
            utility = ut.get_utility_for_array(utility_function,
                                               self.test_array)

            output = _get_unsatisfied_agent_indices(utility,
                                                    agent_indices,
                                                    satisficers=satisficers)
            expected_output = agent_indices[np.array(expected_output)]
            with self.subTest(ut=utility_function,
                              out=output,
                              expected=expected_output):
                self.assertTrue(np.array_equal(output, expected_output))
Пример #3
0
    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 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))
Пример #5
0
def is_simulation_halted(array, utility_function):

	utility = get_utility_for_array(utility_function, array, count_vacancies=True)
	agent_indices = get_agent_indices(array)

	if agent_indices.size == 0:
		return True

	unsatisfied_agent_indices = _get_unsatisfied_agent_indices(utility, agent_indices, satisficers=False)
	if unsatisfied_agent_indices.size == 0:
			return True		

	vacancy_indices = get_vacancy_indices(array)
	
	if vacancy_indices.size == 0:
		return True

	for agent_index in unsatisfied_agent_indices:
		better_vacancies = _get_better_vacancies(array, agent_index, utility, vacancy_indices, satisficers=False)
		if better_vacancies.size != 0:
			return False
	return True
Пример #6
0
def run_simulation(settings, callback=lambda arr, res, i: None):
	"""Run simulation with specified settings.
	Call the optional callback function after each iteration,
	passing the current array state, current result, and iteration number.
	Returns simulation result - segregation measures before each iteration.
	
	Args:
	    settings (SimulationSettings): settings
	    callback (callable, optional): Function to call after each iteration
	
	Returns:
	    SimulationResult: Result - segregation measures for each iteration
	"""
	global _stop


	settings.validate()
	result = SimulationResult(settings.segregation_measure_names)

	array = create_array(settings.grid_size, 
		settings.get_agent_type_proportions(), 
		settings.initial_random_allocation)

	# utility - function: (index) -> (0,1)
	utility = get_utility_for_array(settings.utility_function, array, 
		count_vacancies=settings.count_vacancies, radius=settings.radius)

	pickers = {
		'random': _random_picker,
		'first': _first_picker,
	}

	agent_pickers = dict(pickers, **{
		'roulette': _create_roulette_picker(
			settings.agent_roulette_base_weight, utility, for_agents=True),
	})

	vacancy_pickers = dict(pickers, **{
		'roulette': _create_roulette_picker(
			settings.vacancy_roulette_base_weight, utility, for_agents=False),
	})

	agent_picker = agent_pickers[settings.agent_picking_regime]
	vacancy_picker = vacancy_pickers[settings.vacancy_picking_regime]

	# if no agents, end simulation
	agent_indices = get_agent_indices(array)
	if agent_indices.shape[0] == 0:
		return result

	# _update_result(result, array, agent_indices,
		# settings.count_vacancies, settings.segregation_measure_names)

	for i in range(settings.iterations):

		while _pause:
			pass


		should_save_result = i % settings.save_period == 0

		if should_save_result:
			callback(array, result, i)

		is_simulation_halted = update_array(array, utility, 
			result, agent_picker, vacancy_picker, settings.count_vacancies, 
			settings.segregation_measure_names, settings.satisficers,
			should_save_result)

		# if no further moves are possible, exit simulation early
		if is_simulation_halted:
			# Get measures for final state and save (unless it was just saved)
			if not should_save_result:
				agent_indices = get_agent_indices(array)
				_update_result(result, array, agent_indices, 
					settings.count_vacancies, settings.segregation_measure_names)
				callback(array, result, i)
			break

		if _stop:
			break

	_stop = False

	return result
Пример #7
0
def update_array(array, utility, result, agent_picker, 
	vacancy_picker, count_vacancies, segregation_measure_names,
	satisficers=False, save_result=True):
	"""Do a single iteration of the simulation.
	
	Args:
	    array (ndarray): array
	    utility (callable): utility function - (agent index) -> (0, 1)
	    radius (int): neighborhood radius
	    result (SimulationResult): result object to store segregation measures 
	    	before updating array
	    satisficers (bool, optional): satisficer behavior setting
	"""
	agent_indices = get_agent_indices(array)

	if save_result:
		_update_result(result, array, agent_indices, count_vacancies, 
			segregation_measure_names)
	
	unsatisfied_agent_indices = _get_unsatisfied_agent_indices(utility, 
		agent_indices, satisficers=satisficers)

	# if all agents satisfied, end simulation
	if unsatisfied_agent_indices.size == 0:
		return True

	agent_index = _pick_agent_index_to_move(unsatisfied_agent_indices, 
		agent_picker)

	vacancy_indices = get_vacancy_indices(array)
	if vacancy_indices.size == 0:
		return True

	# if vacancy picker is roulette, consider all vacancies 
	if vacancy_picker.__name__ == 'roulette_picker':
		better_vacancy_indices = vacancy_indices
	else:
		better_vacancy_indices = _get_better_vacancies(array, agent_index, 
			utility, vacancy_indices, satisficers=satisficers)

	if better_vacancy_indices.size == 0:
		# if relocation regime is move first, and the first agent has no better
		# vacancy, the simulation will halt. If this happens, try all
		# unsatisfied agents in list and pick the first one which can find a
		# better vacancy. If none have a better vacancy, end the simulation.
		if agent_picker is _first_picker:
			for agent_index in unsatisfied_agent_indices:
				better_vacancy_indices = _get_better_vacancies(array, 
					agent_index, utility, vacancy_indices, 
					satisficers=satisficers)

				if better_vacancy_indices.size != 0:
					break
			else:
				return True
		else:
			return False
	agent_type = array[agent_index]	
	better_vacancy = _pick_better_vacancy_index(better_vacancy_indices, 
		vacancy_picker, agent_type)

	_move(array, agent_index, better_vacancy)

	return False
Пример #8
0
    def test_agent_indices(self):
        output = get_agent_indices(self.test_array)
        expected_output = self.agent_indices

        self.assertTrue(np.array_equal(output, expected_output))