我试图在沿着x轴和y轴的世界中找到一组海龟之间的中点。
是显而易见的解决方案let mid-point list mean [xcor] turtles mean [ycor] turtles
但是当世界变形时,这会返回一个与我正在寻找的结果不同的结果。即如果两只海龟在25 x 25世界中分别处于[0 -25]和[0 23],我想返回[0 24](或者[0 24.5]?)。但是均值方法返回[0 1]。有没有人对如何做到这一点有一个很好的建议?一种方法是找到距相关海龟的距离最小的补丁,但我更愿意找到确切的点。
这有意义吗?有什么建议吗?
答案 0 :(得分:2)
我首先误解了这个问题,并认为这只是找到只有两只海龟之间的中点,所以我建议:
to setup
clear-all
resize-world -25 25 -25 25
create-turtles 2
ask turtle 0 [ setxy 0 -25 ]
ask turtle 1 [ setxy 0 23 ]
show midpoint turtle 0 turtle 1
end
to-report midpoint [ t1 t2 ]
let result (list)
ask t1 [
hatch 1 [
face t2
forward distance t2 / 2
set result list xcor ycor
die
]
]
report result
end
如果启用了世界包装,则运行设置将打印[0 24.5]
。
但亚瑟指出,他实际想要的是找到整个集海龟的中点(即centroid)。经过一番思考,我意识到我可以采用一种非常相似的方法:
points
); seeker
"乌龟会四处移动,直到找到质心。除了直觉,我没有数学证明这是有效的,但是当世界包装被关闭时,它确实给出与"平均坐标相同的结果"方法,所以我认为它也适用于包装 on 。它也适用于[0 24.5]
案例。如果我错了,我很乐意得到纠正。
这是:
to setup
clear-all
ask n-of (2 + random 10) patches [ sprout 1 ]
; Show centroid with the "seeker" method
show centroid turtles
; Show centroid calculated with mean coordinates for comparison.
; If wrapping is on, it will probably be different from
; `centroid turtles`. If wrapping is off, it should be the
; same, with very small floating point variations:
show list mean [xcor] of turtles mean [ycor] of turtles
end
to-report centroid [ set-of-turtles ]
let points (list)
ask set-of-turtles [
hatch 1 [ set points lput self points ]
]
report seek-centroid first points but-first points 2
end
to-report seek-centroid [ seeker points n ]
if-else not empty? points [
let target first points
ask seeker [
face target
forward distance target / n
]
ask target [ die ]
report seek-centroid seeker but-first points (n + 1)
]
[
let result [ list xcor ycor ] of seeker
ask seeker [ die ]
report result
]
end
注意:在调用ask first points [ pen-down ]
之前添加report seek-centroid ...
是了解算法运作方式的有趣方法。
答案 1 :(得分:2)
考虑单位区间内带点的1D情况。您可以将其视为围绕圆形的点,并且您想要某种平均点的概念。这属于[定向统计](https://en.wikipedia.org/wiki/Directional_statistics)的领域,是一个非常重要的工作。一种方法可能是将圆圈视为位于平面中,取其平均值,计算其角度,在圆上给出一个点,然后在圆上给出一个点。
维基百科提到“计算一系列角度的平均值(在[0°,360°)区间内)的一种简单方法是计算每个角度的余弦和正弦的平均值,并通过计算得到角度反正切。“有一篇文章Mean of circular quantities我认为这会给你一个你想到的概念。
你可以分别对待x和y。计算
let X-sin-mean mean [sin (xcor * 2 * pi /25)]
let X-cos-mean mean [cos (xcor * 2 * pi /25)]
let Y-sin-mean mean [sin (ycor * 2 * pi /25)]
let Y-cos-mean mean [cos (ycor * 2 * pi /25)]
let X-angle-mean [atan2 X-sin-mean X-cos-mean]
let Y-angle-mean [atan2 Y-sin-mean Y-cos-mean]
let X-mean (X-angle-mean * 25 / ( 2 * pi))
let Y-mean (Y-angle-mean * 25 / ( 2 * pi))
我的netlogo语法可能有点错误。我希望你能得到主旨。
答案 2 :(得分:2)
要获取包含中心点的补丁,您可以执行
min-one-of patches [ sum [ distance myself ] of turtles ]
答案 3 :(得分:2)
question on the mean heading of turtles让我想到了基于circular means的这个问题的另一个解决方案。基本上,您可以采用x坐标和y坐标的圆形平均值。这是代码:
;; lower and upper should be equivalent on the circle, but upper > lower in the reals
;; For circles, lower = 0 and upper = 360.
;; For clocks, lower = 0 and upper = 12 (or 24)
;; For x-coordinates, lower = min-pxcor - .5 and upper = max-pxcor + .5
to-report circular-mean [ lower upper vals ]
let width upper - lower
let angles map [ 360 * (? - lower) / width ] vals
let mean-x mean map [ cos ? ] angles
let mean-y mean map [ sin ? ] angles
; not doing turtle headings here, so we flip atan's arguments
report width * (atan mean-y mean-x) / 360 + lower
end
to-report mean-xcor [ xs ]
report (circular-mean (min-pxcor - .5) (max-pxcor + .5) xs)
end
to-report mean-ycor [ ys ]
report (circular-mean (min-pycor - .5) (max-pycor + .5) ys)
end
这确实将这两个维度视为循环。如果您将尺寸视为圆形,则会在该圆上找到与所有其他点之间的最小平方距离的点,其中距离是点之间的欧氏距离,而不是圆周围的距离(即大多数答案一直在使用。)
答案 4 :(得分:0)
这个SO问题有几个答案,讨论how hard this problem is和a few algorithms for solving it。不幸的是,这不是微不足道的。算法都是迭代的(例如梯度下降的变化),解空间有许多局部最优。