Netlogo:嵌套的if / ifelse语句

时间:2019-10-17 18:56:12

标签: if-statement netlogo agent-based-modeling

使用Netlogo构建我的第一个ABM,并遇到涉及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"]]

我认为问题出在“ plp-reliability-analysis”过程中的ifelse语句中。我是Netlogo的新手,对于何时使用'if'或'ifelse'语句感到困惑。如果有人可以解释并查看上面的代码,我将不胜感激。

谢谢, 大卫

1 个答案:

答案 0 :(得分:2)

ififelse之间的区别在于:

  • 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可靠性分析程序。对于他们所有人,变量泛滥?是真的,因此代码块可以运行。

第一行是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记录为成功,而其他属性则设置为不成功。

那么,您如何最终获得具有假洪水组合的某些属性?真正的plp部署成功了吗?。

现在及时跳跃,已经发生2次(或更多次)洪水。刚刚发生了洪水,那么77%的采用plp的物业被选中了吗?有真正的plp部署成功吗?这次没有洪水,所有财产都被洪水淹没了吗?设置为false。那些被plp采用的?被发送到plp可靠性分析程序。但是,淹没了吗?现在为false,因此代码块无法运行,并且它们保留了plp-deployed-successful的值?从上次运行开始。