NetLogo:限制在某个补丁上收费的用户数量时出现问题

NetLogo: Issues when restricting number of users charging at a certain patch

我正在开展一个项目,模拟电动汽车充电对电网的影响以及 modeling/simulating 汽车用户的驾驶和充电习惯。我在我的代码中遇到一个无法解决的问题。

每个位置的充电端口数量有限。例如WORK一共有2个TERMINALS,所以只能有2个adopter同时在那里充电(先到先得)。我想要做的是,当 2 个采用者到达 WORK 时,他们开始收费(如果需要,即 "charging-status" = true)。任何其他采用者都等到那里有可用端口。完成充电的领养者即使不离开也应该为等待名单上的领养者腾出充电口。

这是我所做的部分工作(代码):

to go
    ...

    charge-car      ; sets the charging-status based on state-of-charge.

    ask adopters
    [
      if charging? and not marked?
      [
        ifelse remaining-ports != 0
        [
          set remaining-ports max list (remaining-ports - 1) 0
          set marked? true
        ]
        [set occupied? true]
      ]

      if marked? and not charging?
      [
        set remaining-ports min list (remaining-ports + 1) terminals
        set marked? false
        set occupied? false
      ]
    ]
    ask adopters with [charging? and marked?]
    [
      set color green
      let battery0 battery
      let charging-speed0 charging-speed
      let battery1 max list 0 ( battery + charging-speed0 )
      set battery min list battery1 battery-capacity
      let charged min list ( battery - battery0 ) charging-speed0
      set charge-demand charge-demand + charged
      set soc battery / battery-capacity
      set range-left battery / discharge-patch
    ]
  tick
end

现在,问题是:地图上有多个位置有充电端口。此代码在某些位置给出不同的结果,即使它对所有位置和代理都是相同的算法。例如,如果两个端口都在某些位置被占用,则 "occupied?" 对于某些位置将是正确的,而不是所有端口都已占用的位置。我的意思是,这显示出相当随机的反应。

谁能帮我解决这个问题?还有另一种方法可以做我想做的事吗?另外,如果您需要更多信息来了解我的情况,请告诉我。

谢谢!

编辑: 这是我 to go

的代码
to go
...
ask adopters
  [
    if patch-here = current-loc ; choose next target only when reached at a destination (current location)
    [
      choose-target
      set nearest-station min-one-of patches with [location = "charging-station"][distance myself]
    ] ; choose target based on start time and current location

    ; go to target only when NOT at the arbitrary target location
    if target != [0 0]
    [
      let dist-to-targ distance-between current-loc target
      let dist-to-station distance-between current-loc nearest-station
      ifelse dist-to-targ > range-left and dist-to-station < range-left
      [go-to-station nearest-station]
      [go-to-target]
    ]

    if charging = "Charge Car Now"
    [charge-car]
...
 ]

其中,charge-car

to charge-car
  if patch-here = current-loc and charging-point
  [
    ifelse soc < 1
    [
      if charge-power = 1
      [
        set charging-speed 1 / 12
        set charging-status true
      ]
      if charge-power = 2
      [
        set charging-speed 6.6 / 12
        set charging-status true
      ]
    ]
    [
      set charging-status false
      set color blue
    ]
  ]
end

并且 go-to-target

to go-to-target
  ifelse patch-here != target
  [
    ; move towards destination and use fuel
    face target
;    set marked? false
    set color blue
    ifelse distance target <= speed
    [set speed1 0.3 * distance target] ; decrease speed as target gets nearer
    [set speed1 speed]
    forward speed1
    set moving? true
    set charging-status false
    if marked?
    [
      set rem-term min list (rem-term + 1) terminals
      type patch-here type "Updated ports" print rem-term
      set marked? false
      set occupied? false
    ]

  ]
  [
    move-to target
    if target != [0 0]
    [set dist-trav distance-between current-loc target]
    set current-loc target
    set moving? false
    set dwell dwell-acq day-ind time-ind position [location] of target places ; calculate dwell time based on arrival time at target
    ifelse dwell < 0
    [
      set dwell 288 - (ticks mod 288) ; spend rest of the time till 24:00 at that location
      set dwell-flag 1
    ]
    [set dwell-flag 0]
    if current-loc = target
    [
      set arrival-time (ticks mod 288)
      set start-time (dwell + arrival-time) mod 288
      set target [0 0]
      set battery battery - (discharge-patch * dist-trav) ; discharge based on distance traveled per tick
      set soc battery / battery-capacity
      set range-left battery / discharge-patch
      if battery < 0
      [set battery 0]
      if soc < 0
      [set soc 0]
    ]
   ]
end

其中,rem-termremaining-ports 相同,charging-statuscharging? 相同。 我尝试在 go-to-target 函数中添加相同的代码,因为充电状态首先在那里发生变化,但我得到的结果没有显示任何变化。

我看不出您的代码有任何明显的错误。这种事情通常会发生,因为您有多个 ask turtles 块,并且您在第一个块中制定了意图,但直到第二个块才执行该行为。在你的情况下,我可以看到你更新了第一个块中的端口数,所以这并不直接适用。

但是,我想知道您是否在对您的 if 语句做类似的事情,海龟经过的块与您预期的不同,并且您提取的摘录中缺少相关代码。诊断此类问题的最简单方法是使用 print 语句。请参阅下面的一种可能性。

ask adopters
[ if charging? and not marked?
  [ ifelse remaining-ports > 0
    [ type patch-here print remaining-ports
      set remaining-ports remaining-ports - 1
      set marked? true
      type patch-here type "Updated ports" print remaining-ports
    ]
    [ set occupied? true ]
  ]
  if marked? and not charging?
  [ set remaining-ports min list (remaining-ports + 1) terminals
    set marked? false
    set occupied? false
  ]
]

请注意,为了清楚起见,我还针对 testing/updating 个剩余端口数更改了您的代码。

关于你关于列表的问题,将海龟添加到列表中没有问题(例如 set queue lput self queue),但如果你想要比这更详细的信息,请提出一个单独的问题。我强烈建议您在现有代码正常工作之前不要尝试为您的端口引入队列。