【问题标题】:Netlogo: Nested if/ifelse statementsNetlogo:嵌套的 if/ifelse 语句
【发布时间】:2019-10-17 18:56:12
【问题描述】:

使用 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”语句感到困惑。如果有人可以解释并查看上面的代码,我将不胜感激。

谢谢, 大卫

【问题讨论】:

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


    【解决方案1】:

    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-reliability-analysis 程序。对于他们所有人来说,变量被淹没了?为真,因此代码块运行。

    第一行是if number-of-times-flooded &gt; 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-deployed-successful?。

    现在及时向前跳跃,发生 2 次(或更多)洪水。一场洪水刚刚发生,那么77% 的房产有plp-adopted?有真正的 plp 部署成功吗?这一次,没有洪水,所有的财产都被淹了?设置为假。那些用plp收养的?被发送到 plp-reliability-analysis 程序。然而,被淹?现在为假,因此代码块不会运行并且它们保留其 plp-deployed-successful 的值?从上一次运行。

    【讨论】:

    • 属性所在的每个补丁都有不同的概率泛洪值,因此根据抽取的随机数,某些属性可能会被泛洪,而其他属性可能不会。 plp-reliability-factor不代表77%的属性,而是plp的成功率。因此,如果随机数 > 0.77,则表示不成功。我了解您保留他们的 plp-deployed-successful 价值观是什么意思?真的。如果一个属性被采用,但没有被淹没,我如何确保该属性不会尝试计算 plp-deployed-successful?是真/假
    • (1) 好的,不同的属性可能有不同的值,但你仍然只绘制一个随机数。如果你绘制一个低随机数,很多属性会泛滥,如果你绘制一个高随机数,那么没有属性会泛滥。 (2) 如果一个变量应该只运行一个刻度,那么只需将其设置为 false 作为您在 tick 命令之前所做的最后一件事。
    猜你喜欢
    • 2013-08-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-01
    • 2021-09-26
    相关资源
    最近更新 更多