Netlogo 除非删除重复和未连接的节点,否则Turtle无法在GIS生成的网络中选择到目标的路径

Netlogo 除非删除重复和未连接的节点,否则Turtle无法在GIS生成的网络中选择到目标的路径,netlogo,Netlogo,我一直在努力研究如何使海龟在基于GIS路线图的网络中从一个节点移动到另一个节点。问题是海龟不能使用nw:turtles on path to设置路径,除非我删除重复节点和未连接的节点(我使用的相关代码块来自其他人的模型)。以下是删除重复节点和未连接节点时的代码: foreach gis:feature-list-of roads-dataset [ vector-feature -> foreach gis:vertex-lists-of vector-feature [

我一直在努力研究如何使海龟在基于GIS路线图的网络中从一个节点移动到另一个节点。问题是海龟不能使用
nw:turtles on path to
设置路径,除非我删除重复节点和未连接的节点(我使用的相关代码块来自其他人的模型)。以下是删除重复节点和未连接节点时的代码:

    foreach gis:feature-list-of roads-dataset [ vector-feature ->
    foreach  gis:vertex-lists-of vector-feature [ vertex ->
      let previous-turtle nobody
      let first-turtle nobody
      foreach vertex [point ->
        let location gis:location-of point
        if not empty? location
        [ 
          create-nodes 1
          [ set myneighbours n-of 0 turtles
            set xcor item 0 location
            set ycor item 1 location
            set road-type gis:property-value vector-feature "Classification"
            ;set shape "circle"
            ;set size 0.5
            ifelse previous-turtle = nobody
            [ set first-turtle self ]
            [ create-link-with previous-turtle ]
            set hidden? true
            set previous-turtle self ]
        ]
      ]
    ] ]

    delete-duplicates
    ask nodes [ set myneighbours link-neighbors ]

    delete-not-connected
    ask nodes [ set myneighbours link-neighbors ]

    to delete-duplicates
      ask nodes [
        if count nodes-here with [ description = "road" ] > 1[
          ask other nodes-here with [ description = "road" ][

            ask myself [create-links-with other [link-neighbors] of myself]
            die]
        ]
        ]
    end   

    to delete-not-connected
       ask nodes [set test 0]
       ask one-of nodes [set test 1]
         repeat 500 [
           ask nodes with [test = 1]
           [ask myneighbours [set test 1]]]
       ask nodes with [test = 0][die]
    end

    to go
      ask person [
        if destination = 0 [ create-link select-destination ]
        if mypath = 0 [ select-path ]
        if mypath != 0 [ move ]
      ]
      tick
    end

    to create-link
      create-link-with min-one-of nodes [ distance myself ]
      ask links [ set hidden? true ]
    end

    to select-destination
      set destination one-of nodes with [ road-type = "main road" ]
    end

    to select-path
      set mypath nw:turtles-on-path-to destination
    end

    to move
     ifelse length mypath > 0
     [ move-to item 0 mypath set mypath remove-item 0 mypath ]
     [ stop ]
    end
这段代码运行得非常好。但是,删除重复和未连接的节点后,道路网络会发生扭曲-道路网络的外观与原始道路网络的外观不同。海龟能够在网络上移动的唯一方法是将代码保持在上面的格式。如果排除了
delete duplicates
delete not connected
,则
mypath
返回false

我有没有一种方法可以保持原始网络的外观,同时允许海龟设置一条路径并沿着它移动到目的地?如果不使用
delete duplicates
delete not connected
,海龟就不能设置路径,那么会出现什么问题


非常感谢您的支持。谢谢。

您确定有必要删除重复的
吗?我的猜测是,
delete not connected
之所以必要,是因为没有它,
select destination
可以选择海龟无法访问的节点。我马上就来解决这个问题。首先,我们应该讨论代码中的一些问题

首先,你让海龟们在他们和他们现在的位置之间建立一个链接。这有点奇怪,因为它本质上是说这只乌龟是道路网络上的一条道路,这是没有意义的。实际上,如果你想让海龟们选择新的目的地,这会变得很奇怪。它们仍将链接到它们开始的节点!这将允许他们在网络上“传送”。不好的!相反,我建议创建一个名为
current location
的海龟变量,它跟踪海龟所在的节点

所以,
create link
应该变成

to set-location
  set current-location min-one-of nodes [ distance myself ]
end
移动
然后变为(我从代码中删除了
停止
,因为它是不必要的):

选择路径
变成:

to select-path
  set mypath [ nw:turtles-on-path-to destination ] of current-location
end
实际上,我们可以进一步简化。因为乌龟在跟踪它当前的位置,所以你不再需要自己跟踪路径。相反,请删除
mypath
选择path
,然后将
move
更改为:

to move
  if current-location != destination [
    let next-node first [ nw:turtles-on-path-to destination ] of current-location
    set current-location next-node
    move-to current-location
  ]
end
to go
  ask person [
    if destination = 0 [
      set-location
      select-destination
    ]
    move
  ]
  tick
end
并将
go
更改为:

to move
  if current-location != destination [
    let next-node first [ nw:turtles-on-path-to destination ] of current-location
    set current-location next-node
    move-to current-location
  ]
end
to go
  ask person [
    if destination = 0 [
      set-location
      select-destination
    ]
    move
  ]
  tick
end
简单多了!请注意,由于
nw
记住了节点之间的最短路径,因此这应该仍然很快。如果你有一个非常大的网络或什么的,你仍然可以自己跟踪路径,如果你想的话,但我会先试试这个

好的,现在我们准备好修复断开连接的节点问题,而不删除网络中的任何内容。基本上,
selectdestination
应该只选择海龟可以到达的目的地。看起来是这样的:

(编辑:此代码不正确。请参阅下文)

其中我自己的
[nw:distance to myelf]将获得从当前位置(第一个
我自己
所指)到潜在目的地(第二个
我自己
所指)的距离
nw:distance to
将返回一个数字(距离),如果目标节点可以从源节点到达;否则它将返回
false
。所以
是数字吗?
检查以确保它确实还给了我们一个数字

希望这有助于解决您的问题,同时简化您的代码。重复的东西真的不重要。如果是的话,要么回复评论,要么编辑你的问题,我来看看

编辑:

感谢您上传您的模型和数据!我意识到我实际上把
select destination
过程搞砸了。应该是:

to select-destination
  set destination one-of [ nodes with [
    road-type = "road" and
    is-number? [ nw:distance-to myself ] of myself
  ] ] of current-location
end
也就是说,此人应该查询
当前位置
,寻找一条可到达的道路。显然,由于人没有连接到网络,他们无法直接获得可到达的道路

接下来,看起来一个重要的问题是数据实际上是极度断开的。您正在创建的网络包含5619个断开连接的组件,每个组件仅包含3-5个节点。所以海龟找不到它能到达的目的地也就不足为奇了

我认为你可能对数据的解释不正确。我希望从不同的功能列表创建的各种节点应该以某种方式连接起来,但你没有这样做(这就是为什么你会有这么多断开连接的组件)。不幸的是,这正是我所知的极限;我对地理信息系统知之甚少。我记得我的一个同事在做一个类似的项目,他必须做一些事情,比如合并彼此重叠的顶点。这会将网络生成代码转换为以下代码:

  foreach gis:feature-list-of roads-dataset [ vector-feature ->
    foreach  gis:vertex-lists-of vector-feature [ vertex ->
      let previous-turtle nobody
      foreach vertex [point ->
        let location gis:location-of point
        if not empty? location
        [
          let x item 0 location
          let y item 1 location
          let current-node one-of (turtles-on patch x y) with [ xcor = x and ycor = y ]
          if current-node = nobody [
            create-nodes 1 [
              setxy x y
              set shape "circle"
              set size 0.5
              set road-type "road"
              set hidden? true
              set current-node self
            ]
          ]
          ask current-node [
            if is-turtle? previous-turtle [
              create-link-with previous-turtle
            ]
            set previous-turtle self
          ]
        ]
      ]
    ]
  ]
这似乎表现正确。(我还清理了一些我们正在做的事情)也就是说,它查看在那个确切的位置是否已经有一个节点,并连接到那个节点,如果是的话,否则它会创建一个新节点

以下是完整的更新代码:

我还调整了其他一些事情:此人现在在
设置中设置了他们的位置,这很有意义:他们的位置应该在这之后正确更新。我在
go
的末尾添加了
tick
,这是所有车型都应该有的。您可能希望将视图更新更改为“在刻度上”。最后,我让这个人在到达目的地进行测试时选择一个新的位置。你可能想现在就把
go
变成一个永久按钮;你将看到一个人从一个地方到另一个地方。