Netlogo - 在agentset中向其他人聚集(与所有乌龟相对)

时间:2014-12-15 16:05:08

标签: netlogo

很抱歉,这个问题可能有一个简单的答案,但我对Netlogo相对较新,并且花了几天的时间来处理这个问题无济于事,所以任何建议都非常受欢迎 - 谢谢。

植绒鱼类和鸟类有很好的植绒方法(参见MacLennan,2007(http://web.eecs.utk.edu/~mclennan/Classes/420-594-F07/NetLogo/Flock.html),基于Huth和Wissel(1992))和我想要为了适应这种植绒方法,这样你就不会蜂拥到最近的三个邻居(他们都是同一群体),而只是涌向你的代理人群中的那些人,,或者更具体地说,是你自己群体中的那些人(忽略那些)在它之外)。

据我所知,一个建议可能是在开始时创建两个不同的品种,例如:鹿和驼鹿,然后你只会涌向那些属于同一品种的人。但是,在我的例子中,我有代理人在每个滴答时重新评估哪个组最适合哪个组,并在组之间翻转(通过代理集定义)。

对于同质人群,原始代码(MacLennan,2007)如下:

TO GO ;--------------------------------------------------------------------------------------------

set i 0                                            ; initializes variables used in finding neighbors
set distance_1 1000
set distance_2 1000
set distance_3 1000

   ; (below) determines ID numbers and distances for three closest neighbors; each turtle is
   ;   first checked to be visible (i.e., out of blind spot and in front of obstacles), and then
   ;   its distance is compared with that of neighbor_3.  If a bird is closer than neighbor_3,
   ;   it is then compared with neighbor_2 and (if it's closer than neighbor_2) with neighbor_1;
   ;   variables are then re-assigned to accomodate the new neighbor as one of the closest three.

repeat count turtles
  [ifelse not ((i = who) or in_blind_spot? or behind_opaque_obstacle?)
     [set dist distance turtle i
      ifelse dist < distance_3
        [ifelse dist < distance_2
           [set neighbor_3 neighbor_2
            set distance_3 distance_2
            ifelse dist < distance_1
              [set neighbor_2 neighbor_1
               set distance_2 distance_1
               set neighbor_1 i
               set distance_1 dist]               
              [set neighbor_2 i
               set distance_2 dist
               repeat 2 [fd 0]]]                 ; (see note at end for explanantion of "fd 0")
           [set neighbor_3 i
            set distance_3 dist
            repeat 4 [fd 0]]]
        [repeat 6 [fd 0]]]
     [repeat 7 [fd 0]]
   set i i + 1]

set acceleration 0                                ; sets acceleration to zero

set target_1 calc_target neighbor_1 distance_1    ; calculates targets (see procedure below) based on
set target_2 calc_target neighbor_2 distance_2    ;   the headings and positions of each neighbor;
set target_3 calc_target neighbor_3 distance_3    ;   acceleration is set by the calc_target procedure

   ; (below) calculates a bird's composite target, weighting each individual target by the inverse
   ;   of distance to that neighbor

set target atan ((sin target_1) * 100 / distance_1 + (sin target_2) * 100 / distance_2 + (sin target_3) * 100 / distance_3)
                ((cos target_1) * 100 / distance_1 + (cos target_2) * 100 / distance_2 + (cos target_3) * 100 / distance_3)

   ; (below) turns bird towards target by a fraction specified by "flexibility"; random motion is also
   ;   included to an extent governed by "noise".  The "... + 540) mod 360) - 180" clause is necessary to
   ;   ensure that the bird turns in the right direction.  For example, if a bird is oriented at 0 degrees
   ;   and its target is 300 degrees, it should consider a 60 [ = ((0 - 300 + 540) mod 360) - 180] degree
   ;   turn to the left instead of a 300 [ = 300 - 0] degree turn to the right.

fd 1 + acceleration                               ; moves birds forward

end

我认为最简单的方法是保留尽可能多的原始代码,然后查看更改代码行

[set dist distance turtle i

因为乌龟意味着世界上的任何海龟,而不仅仅是我小组中的那些乌龟。

要做到这一点,我考虑过将我的agentset'group-members'临时转换为品种,以便我可以用groupmember i替换单词turtle i ...例如

create-groupies-from group-members
[set dist distance group-member i

但是,当我尝试使用create-<breed>-from代码时,我收到了错误 '已经定义了名为CREATE-GROUPIES-FROM的内容,甚至当这个品种被包括在品种中时[]

因此,我尝试调整代码,只考虑聚集其他群组成员,如下所示:

   to flock
set id-within-group 0                                            ; initializes variables used in finding neighbors
set distance_1 1000
set distance_2 1000
set distance_3 1000

set group-members turtle-set turtles with [group-id = [group-id] of myself] ; set those sharing a group id as my group-members
 (foreach (sort group-members) (n-values count group-members [?]) [ ; set each turtle in my agentset (group) with an ID no. 0 - n?
    ask ?1 [ set id-within-group ?2 ]
  ])
repeat count group-members ; repeat the next step as many times as there are group members
  [ifelse not (id-within-group = who)
     [
       set dist distance turtle id-within-group
       print "turtle id-within-group"
       print turtle id-within-group
       print dist
      ifelse dist < distance_3
        [ifelse dist < distance_2
           [set neighbor_3 neighbor_2
            set distance_3 distance_2
            ifelse dist < distance_1
              [set neighbor_2 neighbor_1
               set distance_2 distance_1
               set neighbor_1 id-within-group
               set distance_1 dist]               
              [set neighbor_2 id-within-group
               set distance_2 dist
               repeat 2 [fd 0]]]                 
           [set neighbor_3 id-within-group
            set distance_3 dist
            repeat 4 [fd 0]]]
        [repeat 6 [fd 0]]]
     [repeat 7 [fd 0]]
   print "_____________________"
   print "ID" print self
   print "group-id" print group-id
   ]

;]
set acceleration 0                                ; sets acceleration to zero

set target_1 calc_target neighbor_1 distance_1    ; calculates targets (see procedure below) based on
set target_2 calc_target neighbor_2 distance_2    ;   the headings and positions of each neighbor;
set target_3 calc_target neighbor_3 distance_3    ;   acceleration is set by the calc_target procedure


   ; (below) calculates a bird's composite target, weighting each individual target by the inverse
   ;   of distance to that neighbor

set target atan ((sin target_1) * 100 / distance_1 + (sin target_2) * 100 / distance_2 + (sin target_3) * 100 / distance_3)
                ((cos target_1) * 100 / distance_1 + (cos target_2) * 100 / distance_2 + (cos target_3) * 100 / distance_3)

   ; (below) turns bird towards target by a fraction specified by "flexibility"; random motion is also
   ;   included to an extent governed by "noise".  The "... + 540) mod 360) - 180" clause is necessary to
   ;   ensure that the bird turns in the right direction.  For example, if a bird is oriented at 0 degrees
   ;   and its target is 300 degrees, it should consider a 60 [ = ((0 - 300 + 540) mod 360) - 180] degree
   ;   turn to the left instead of a 300 [ = 300 - 0] degree turn to the right.

lt (flexibility / 100 * (((heading - target + 540) mod 360) - 180)) + (random noise) - (random noise)

fd 1 + acceleration                               ; moves birds forward

end

在我修改过的示例中,虽然这些组确实正确地分配了一个单独的ID组成员,但他们并没有蜂拥而至。此外,邻居,距离和target_1 - _3都具有相同的值,这是错误的。

我想知道是否有人对我遇到的一些问题有任何见解?任何解决方案或相关文献都会非常感激 - 谢谢!

2 个答案:

答案 0 :(得分:0)

首先,只是为了让您知道,海龟可以通过要求相关海龟将其品种属性设置为新品种来改变品种:ask ... [set breed ...](例如,请参阅NetLogo字典中的品种基元)。 / p>

尽管如此,我认为你和一个&#39;组合这样做是对的。属性和使用代理集来做你想要的。这就像你想要的但不正确。希望其他人能够改进它。

turtles-own
[ groupID ]

to setup

  create-turtles 20
  [ set groupID random 2
    set xcor random-xcor
    set ycor random-ycor
  ]

  ask turtles
  [ let close-friends min-n-of 3 turtles with [groupID = [groupID] of myself] [distance myself]
    ask close-friends
    [ face myself
      forward 1
    ]
  ]

end

这段代码(我认为)在同一组中找到三只最接近的海龟。然而,它将这三个移向了要求的乌龟,而不是让要求乌龟移动到那三个。我不知道如何做反过来而不用列表做丑陋的东西。

答案 1 :(得分:0)

好吧,这是一个更正的版本(我没有编辑上面的内容,因为这会弄乱评论)。仍然没有错误检查以确保组中有其他3个,但是这使用列表来解决第一个建议中的问题。它创建了agent-close-friends以包含最接近的三个(这是一行而不是所有嵌套距离检查)。该代理集转换为列表,然后代码循环遍历列表并移向列表成员。我仍然认为必须有更好的方法直接在代理集中循环,但至少可以这样做。

turtles-own
[ groupID ]

to setup
  clear-all
  create-turtles 20
  [ set groupID random 2
    set xcor random-xcor
    set ycor random-ycor
    set color 155 - 10 * groupID
  ]
  reset-ticks
end

to go
  ask turtles
  [ let close-friends min-n-of 3 turtles with [groupID = [groupID] of myself] [distance myself]
    let friend-list sort-on [distance myself] close-friends
    foreach friend-list
    [ face ?
      forward 1
    ]
  ]
  tick
end