Вопрос или проблема
У меня есть два агента на платформе GAMA: 1. пользователь воды 2. орган власти. Мне нужна помощь, чтобы агент пользователя воды переместился к агенту органа власти, чтобы получить разрешение на использование воды, а затем вернуться на свое исходное положение. Орган власти движется к источнику воды и затем возвращается на свое исходное положение. Вот код GAML.
global {
//глобальные атрибуты
float distance_to_intercept <- 100.0;
int number_of_water_source <-2;
int number_of_water_user <-2;
int number_of_authority <-1;
init{
//создаем виды
create water_source number:number_of_water_source;
create water_user number:number_of_water_user;
create pangani_board number:number_of_authority;
}
}
species water_source{
//атрибуты
string source_name;
string source_type;
string source_catchment_name;
float water_capacity;
//аспект, чтобы представлять агентов этого вида в симуляции
aspect default{
draw circle(1)color:#blue border:#black;
}
}
species water_user skills:[moving]{
pangani_board target;
//атрибуты
float amount_requested <-5.0;
float amount_granted;
string water_use;
string source_type;
string source_name;
string catchment_name;
bool is_returning;
point location <- {rnd(100), rnd(100)}; // Случайное начальное местоположение
point original_location <- location; // Сохраняем исходное местоположение
//инициализация скорости агента
init {
speed <- 0.0;
is_returning <- false; // Инициализация is_returning в false
}
//запрос на получение разрешения на использование воды
reflex request_water_use_permit {
ask authority{
myself.amount_granted<- grant_water_use_permit(myself.amount_requested);
}
}
//движение к органу власти
reflex search_target when: target=nil and not is_returning {
ask authority at_distance(distance_to_intercept) {
myself.target <- self;
myself.speed <- 0.05; // Установить скорость на 0.05, когда цель найдена
}
}
reflex follow when: target!=nil {
speed <- 0.0025;
do goto target: target;
float tolerance <- 0.9; // Допуск для сравнения местоположений
if (abs(self.location.x - target.location.x) < tolerance and abs(self.location.y - target.location.y) < tolerance) { // Проверяем, достиг ли пользователь воды органа власти в пределах допуска
speed <- 0.0; // Остановить агента
do goback; // Выполняем действие goback
}
}
action goback {
is_returning <- true; // Устанавливаем флаг is_returning в true
speed <- 0.5; // Сбрасываем скорость до исходного значения
do goto target: original_location; // Возвращаемся на исходное местоположение
if (self.location = original_location) { // Проверяем, достиг ли пользователь воды исходного местоположения
speed <- 0.0; // Остановить агента
target <- nil; // Сбрасываем цель в nil, чтобы предотвратить повторную активацию рефлекса search_target
// is_returning <- false; // Сбрасываем флаг is_returning в false
write("Агент вернулся на исходное местоположение"); // Логируем возврат
}
}
//аспект, чтобы представлять агентов этого вида в симуляции
aspect default{
draw circle(1)color:#red border:#black;
}
}
species authority{
//атрибуты
float amount_abstracted;
point location <- {50, 50}; // Фиксированное местоположение органа власти
float grant_water_use_permit(float amount_requested){
float requested_amount<-amount_requested;
if (requested_amount>=15 and requested_amount<=26.975){
amount_abstracted <-23.18;
}else if(requested_amount=10){
amount_abstracted <-3.98;
}else if(requested_amount<=2.0){
amount_abstracted <-2.62;
}else if (requested_amount<=5.0){
amount_abstracted <-2.87;
}else{
amount_abstracted<-0.0;
}
return amount_abstracted;
}
//аспект, чтобы представлять агентов этого вида в симуляции
aspect default{
draw circle(1)color:#yellow border:#black;
}
}
experiment water_allocation type:gui{
output{
display my_agents{
species water_source aspect:default;
species water_user aspect:default;
species authority aspect:default;
}
}
}
Я попытался заставить пользователя воды переместиться к органу власти, используя приведенный выше код. Он действительно перемещается, но не возвращается на свое исходное местоположение.
Ответ или решение
Конечно! Ваша проблема заключается в том, что агент "water_user" не возвращается на свою исходную позицию после выполнения задачи. Давайте рассмотрим некоторые изменения в коде, которые могут помочь решить эту проблему.
Во-первых, в вашей функции goback
есть небольшая ошибка в условии проверки. Вместо того чтобы использовать if (self.location = original_location)
, вы должны использовать if (self.location == original_location)
для сравнения значений.
Вот несколько предложений для исправления и улучшения вашего кода:
- Исправьте условие в действии
goback
, чтобы оно корректно проверяло, достиг ли агент своей исходной позиции:
if (self.location == original_location) {
- Также, чтобы упростить логику возврата, можно улучшить условие при проверке позиции у агента
water_user
и добавить небольшую задержку после визита к агентуauthority
, прежде чем он вернется на исходную позицию.
Полный исправленный код может выглядеть следующим образом:
global {
// Глобальные атрибуты
float distance_to_intercept <- 100.0;
int number_of_water_source <- 2;
int number_of_water_user <- 2;
int number_of_authority <- 1;
init {
// Создание видов
create water_source number:number_of_water_source;
create water_user number:number_of_water_user;
create pangani_board number:number_of_authority;
}
}
species water_source {
// Атрибуты
string source_name;
string source_type;
string source_catchment_name;
float water_capacity;
// Визуализация вида
aspect default {
draw circle(1) color:#blue border:#black;
}
}
species water_user skills:[moving] {
pangani_board target;
// Атрибуты
float amount_requested <- 5.0;
float amount_granted;
bool is_returning;
point location <- {rnd(100), rnd(100)}; // Случайное начальное положение
point original_location <- location; // Хранение исходного положения
init {
speed <- 0.0;
is_returning <- false; // Инициализация флага возвращения
}
// Запрос разрешения на использование воды
reflex request_water_use_permit {
ask authority {
myself.amount_granted <- grant_water_use_permit(myself.amount_requested);
}
}
// Поиск цели
reflex search_target when: target=nil and not is_returning {
ask authority at_distance(distance_to_intercept) {
myself.target <- self;
myself.speed <- 0.05; // Установите скорость, когда цель найдена
}
}
// Следование к цели
reflex follow when: target!=nil {
speed <- 0.0025;
do goto target: target;
float tolerance <- 0.9; // Допуск для сравнения местоположения
if (abs(self.location.x - target.location.x) < tolerance and abs(self.location.y - target.location.y) < tolerance) {
speed <- 0.0; // Остановите агента
do goback; // Вызов действия возврата
}
}
action goback {
is_returning <- true; // Установите флаг на возвращение
speed <- 0.5; // Сбросить скорость до первоначального значения
do goto target: original_location; // Вернуться на исходное местоположение
float tolerance <- 0.9; // Допуск для сравнения местоположения
if (abs(self.location.x - original_location.x) < tolerance and abs(self.location.y - original_location.y) < tolerance) {
speed <- 0.0; // Остановите агента
target <- nil; // Обнулить цель, чтобы избежать повторного активации
is_returning <- false; // Сбросить флаг на возвращение
write("Agent has returned to original location"); // Лог возврата
}
}
// Визуализация вида
aspect default {
draw circle(1) color:#red border:#black;
}
}
species authority {
// Атрибуты
float amount_abstracted;
point location <- {50, 50}; // Фиксированное положение для authority
float grant_water_use_permit(float amount_requested) {
float requested_amount <- amount_requested;
if (requested_amount >= 15 and requested_amount <= 26.975) {
amount_abstracted <- 23.18;
} else if (requested_amount == 10) {
amount_abstracted <- 3.98;
} else if (requested_amount <= 2.0) {
amount_abstracted <- 2.62;
} else if (requested_amount <= 5.0) {
amount_abstracted <- 2.87;
} else {
amount_abstracted <- 0.0;
}
return amount_abstracted;
}
// Визуализация вида
aspect default {
draw circle(1) color:#yellow border:#black;
}
}
experiment water_allocation type:gui {
output {
display my_agents {
species water_source aspect:default;
species water_user aspect:default;
species authority aspect:default;
}
}
}
Эти изменения должны помочь вашему агенту "water_user" успешно вернуться на исходную позицию после обращения к агенту "authority". Убедитесь, что проводите необходимые тестирования для проверки корректности работы логики в вашей симуляции. Если у вас возникнут дальнейшие вопросы или проблемы, не стесняйтесь обращаться!