使用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'语句感到困惑。如果有人可以解释并查看上面的代码,我将不胜感激。
谢谢, 大卫
答案 0 :(得分:2)
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可靠性分析程序。对于他们所有人,变量泛滥?是真的,因此代码块可以运行。
第一行是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的值?从上次运行开始。