Netlogo: вложенные операторы if / ifelse - PullRequest
0 голосов
/ 17 октября 2019

Создаю свою первую ПРО с использованием Netlogo, и у меня возникли проблемы с инструкциями ifelse и их использованием. Я моделирую реакцию агентов на затопленные свойства. Концепции таковы:

Если агент затоплен, он рассмотрит вопрос о принятии защитных мер (если они этого еще не сделали). Если агент принял защитные меры и залит, успешность меры рассчитывается.

Мой код выглядит следующим образом:

    to process-property
  let $random-flood-number random-float 1
  ask properties [
    set flood-damage-list-consequent replace-item 1 flood-damage-list-consequent (item 1 flood-damage-list-initial * (1 - PLP-reduction))
    set flood-damage-list-consequent replace-item 2 flood-damage-list-consequent (item 2 flood-damage-list-initial * (1 - PLP-reduction))'
    ifelse $random-flood-number < probability-flooding
    [
      set flooded? TRUE
      set number-of-times-flooded (number-of-times-flooded + 1)
      if plp-adopted? != TRUE [
        calculate-adoption-intention
      ]
    ]
    [
      set flooded? FALSE
    ]
  ]

  ask properties with [plp-adopted? = TRUE] [
    plp-reliability-analysis
  ]

end

    to plp-reliability-analysis
  if plp-abandoned? = TRUE [stop]
  if flooded? = TRUE [
  if number-of-times-flooded > 1 [
    let plp-reliability-factor 0.77 ;;This variable represents the probability of success that Manual PLP will offer full reduction in damage. Taken from JBA (2012;2014).
    ifelse random-float 1 < plp-reliability-factor
      [
        set plp-deployed-successful? TRUE
        set PLP-reduction 0.25
        set successful-flood-damage-reduction (sum flood-damage-list-initial * PLP-reduction)
      ]
      [
        set plp-deployed-successful? FALSE
        set PLP-reduction 0.9
        set unsuccessful-flood-damage-reduction (sum flood-damage-list-initial * PLP-reduction)
        calculate-abandonment-intention
      ]
    ]
  ]
end

Я написал следующий код как ошибкупроверка, которую я продолжаю получать:

if flooded? = FALSE and plp-deployed-successful? = TRUE [error["Properties should only deploy PLP when they are flooded"]]

Я считаю, что проблема заключается в выражениях ifelse в процедуре "plp-надежность-analysis". Я новичок в Netlogo и не понимаю, когда использовать операторы if или ifelse. Если бы кто-то мог объяснить и взглянуть на приведенный выше код, я был бы очень признателен.

Спасибо, Дэвид

1 Ответ

2 голосов
/ 18 октября 2019

Разница между if и ifelse заключается в том, что:

  • if используется, когда вы хотите запустить какой-то фрагмент кода только при определенных условиях
  • ifelse используется, когда вы хотите запустить какой-то фрагмент кода при определенных условиях и другой фрагмент кода, если условие не выполняется.

Посмотрите на эту сокращенную версию вашего кода. Обратите внимание, что я переместил открывающую скобку в начало строки, чтобы выровнять начало и конец блоков кода. Я также ставлю конечную скобку на той же строке для очень коротких блоков кода, но скобки такие же, как у вас.

to process-property
  let $random-flood-number random-float 1
  ask properties
  [ ifelse $random-flood-number < probability-flooding
    [ set flooded? TRUE ]
    [ set flooded? FALSE ]
  ]
  ask properties with [plp-adopted? = TRUE]
  [ plp-reliability-analysis
  ]
end

to plp-reliability-analysis
  if flooded? = TRUE
  [ if number-of-times-flooded > 1
    [ let plp-reliability-factor 0.77
      ifelse random-float 1 < plp-reliability-factor
      [ set plp-deployed-successful? TRUE ]
      [ set plp-deployed-successful? FALSE ]
    ]
  ]
end

Вы рисуете случайное число и присваиваете его переменной $ random-flood-number,Затем вы просите каждого агента по недвижимости сравнить это число со значением probability-flooding. Тем не менее, вы никогда не рисуете новое случайное число. Так что, если это верно для одного свойства, оно будет верно для всех свойств. Учитывая, что это модель наводнения, она предположительно является преднамеренной, так как наводнения в равной степени затрагивают все дома.

Представьте, что нарисовано небольшое число, и все они затоплены. Все те, с plp-приняты? затем отправляются в процедуру анализа надежности plp. Для всех них переменная затоплена? Значение true, поэтому блок кода выполняется.

Первая строка - if number-of-times-flooded > 1. В первый раз, когда происходит флуд, число раз затопления изменяется с 0 на 1. Это провалит тест (вы имели в виду использовать> = вместо>?), А остальная часть кода не будет запущена,Он просто перейдет к конечной скобке.

[ let plp-reliability-factor 0.77
  ifelse random-float 1 < plp-reliability-factor
  [ set plp-deployed-successful? TRUE ]
  [ set plp-deployed-successful? FALSE ]
]

Но для второго и более поздних кодов он запустится, и в 77% свойств будет записан plp как успешный, а для других - неудачный.

Итак, как вы можете получить некоторые свойства, имеющие комбинацию ложного затопления? и true plp-deployed-success?.

Теперь прыгните вперед во времени и произошло 2 (или более) наводнения. Только что произошло наводнение, так что 77% недвижимости с plp-приняты? есть истинный plp-развернутый-успешный? На этот раз нет наводнения и все свойства затоплены? установить в ложь. Те с плп-усыновлены? отправляются в процедуру анализа надежности plp. Однако затоплены? теперь ложно, поэтому блок кода не запускается, и они сохраняют свои значения plp-deployed-success? с предыдущего пробега.

...