Агентно-ориентированная симуляция GAMA

Вопрос или проблема

У меня есть два агента на платформе 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) для сравнения значений.

Вот несколько предложений для исправления и улучшения вашего кода:

  1. Исправьте условие в действии goback, чтобы оно корректно проверяло, достиг ли агент своей исходной позиции:
if (self.location == original_location) {
  1. Также, чтобы упростить логику возврата, можно улучшить условие при проверке позиции у агента 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". Убедитесь, что проводите необходимые тестирования для проверки корректности работы логики в вашей симуляции. Если у вас возникнут дальнейшие вопросы или проблемы, не стесняйтесь обращаться!

Оцените материал
Добавить комментарий

Капча загружается...